#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/vmstat.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/sched.h>
#include <linux/math64.h>
#include <linux/writeback.h>
#include <linux/compaction.h>
#include <linux/mm_inline.h>
#include <linux/page_owner.h>
#include <linux/sched/isolation.h>
#include "internal.h"
#ifdef CONFIG_NUMA
int sysctl_vm_numa_stat = …;
static void zero_zone_numa_counters(struct zone *zone)
{ … }
static void zero_zones_numa_counters(void)
{ … }
static void zero_global_numa_counters(void)
{ … }
static void invalid_numa_statistics(void)
{ … }
static DEFINE_MUTEX(vm_numa_stat_lock);
int sysctl_vm_numa_stat_handler(const struct ctl_table *table, int write,
void *buffer, size_t *length, loff_t *ppos)
{ … }
#endif
#ifdef CONFIG_VM_EVENT_COUNTERS
DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = …;
EXPORT_PER_CPU_SYMBOL(…);
static void sum_vm_events(unsigned long *ret)
{ … }
void all_vm_events(unsigned long *ret)
{ … }
EXPORT_SYMBOL_GPL(…);
void vm_events_fold_cpu(int cpu)
{ … }
#endif
atomic_long_t vm_zone_stat[NR_VM_ZONE_STAT_ITEMS] __cacheline_aligned_in_smp;
atomic_long_t vm_node_stat[NR_VM_NODE_STAT_ITEMS] __cacheline_aligned_in_smp;
atomic_long_t vm_numa_event[NR_VM_NUMA_EVENT_ITEMS] __cacheline_aligned_in_smp;
EXPORT_SYMBOL(…);
EXPORT_SYMBOL(…);
#ifdef CONFIG_NUMA
static void fold_vm_zone_numa_events(struct zone *zone)
{ … }
void fold_vm_numa_events(void)
{ … }
#endif
#ifdef CONFIG_SMP
int calculate_pressure_threshold(struct zone *zone)
{ … }
int calculate_normal_threshold(struct zone *zone)
{ … }
void refresh_zone_stat_thresholds(void)
{ … }
void set_pgdat_percpu_threshold(pg_data_t *pgdat,
int (*calculate_pressure)(struct zone *))
{ … }
void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
long delta)
{ … }
EXPORT_SYMBOL(…);
void __mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item,
long delta)
{ … }
EXPORT_SYMBOL(…);
void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
{ … }
void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item)
{ … }
void __inc_zone_page_state(struct page *page, enum zone_stat_item item)
{ … }
EXPORT_SYMBOL(…);
void __inc_node_page_state(struct page *page, enum node_stat_item item)
{ … }
EXPORT_SYMBOL(…);
void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
{ … }
void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item)
{ … }
void __dec_zone_page_state(struct page *page, enum zone_stat_item item)
{ … }
EXPORT_SYMBOL(…);
void __dec_node_page_state(struct page *page, enum node_stat_item item)
{ … }
EXPORT_SYMBOL(…);
#ifdef CONFIG_HAVE_CMPXCHG_LOCAL
static inline void mod_zone_state(struct zone *zone,
enum zone_stat_item item, long delta, int overstep_mode)
{ … }
void mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
long delta)
{ … }
EXPORT_SYMBOL(…);
void inc_zone_page_state(struct page *page, enum zone_stat_item item)
{ … }
EXPORT_SYMBOL(…);
void dec_zone_page_state(struct page *page, enum zone_stat_item item)
{ … }
EXPORT_SYMBOL(…);
static inline void mod_node_state(struct pglist_data *pgdat,
enum node_stat_item item, int delta, int overstep_mode)
{ … }
void mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item,
long delta)
{ … }
EXPORT_SYMBOL(…);
void inc_node_state(struct pglist_data *pgdat, enum node_stat_item item)
{ … }
void inc_node_page_state(struct page *page, enum node_stat_item item)
{ … }
EXPORT_SYMBOL(…);
void dec_node_page_state(struct page *page, enum node_stat_item item)
{ … }
EXPORT_SYMBOL(…);
#else
void mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
long delta)
{
unsigned long flags;
local_irq_save(flags);
__mod_zone_page_state(zone, item, delta);
local_irq_restore(flags);
}
EXPORT_SYMBOL(mod_zone_page_state);
void inc_zone_page_state(struct page *page, enum zone_stat_item item)
{
unsigned long flags;
struct zone *zone;
zone = page_zone(page);
local_irq_save(flags);
__inc_zone_state(zone, item);
local_irq_restore(flags);
}
EXPORT_SYMBOL(inc_zone_page_state);
void dec_zone_page_state(struct page *page, enum zone_stat_item item)
{
unsigned long flags;
local_irq_save(flags);
__dec_zone_page_state(page, item);
local_irq_restore(flags);
}
EXPORT_SYMBOL(dec_zone_page_state);
void inc_node_state(struct pglist_data *pgdat, enum node_stat_item item)
{
unsigned long flags;
local_irq_save(flags);
__inc_node_state(pgdat, item);
local_irq_restore(flags);
}
EXPORT_SYMBOL(inc_node_state);
void mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item,
long delta)
{
unsigned long flags;
local_irq_save(flags);
__mod_node_page_state(pgdat, item, delta);
local_irq_restore(flags);
}
EXPORT_SYMBOL(mod_node_page_state);
void inc_node_page_state(struct page *page, enum node_stat_item item)
{
unsigned long flags;
struct pglist_data *pgdat;
pgdat = page_pgdat(page);
local_irq_save(flags);
__inc_node_state(pgdat, item);
local_irq_restore(flags);
}
EXPORT_SYMBOL(inc_node_page_state);
void dec_node_page_state(struct page *page, enum node_stat_item item)
{
unsigned long flags;
local_irq_save(flags);
__dec_node_page_state(page, item);
local_irq_restore(flags);
}
EXPORT_SYMBOL(dec_node_page_state);
#endif
static int fold_diff(int *zone_diff, int *node_diff)
{ … }
static int refresh_cpu_vm_stats(bool do_pagesets)
{ … }
void cpu_vm_stats_fold(int cpu)
{ … }
void drain_zonestat(struct zone *zone, struct per_cpu_zonestat *pzstats)
{ … }
#endif
#ifdef CONFIG_NUMA
unsigned long sum_zone_node_page_state(int node,
enum zone_stat_item item)
{ … }
unsigned long sum_zone_numa_event_state(int node,
enum numa_stat_item item)
{ … }
unsigned long node_page_state_pages(struct pglist_data *pgdat,
enum node_stat_item item)
{ … }
unsigned long node_page_state(struct pglist_data *pgdat,
enum node_stat_item item)
{ … }
#endif
#ifdef CONFIG_COMPACTION
struct contig_page_info { … };
static void fill_contig_page_info(struct zone *zone,
unsigned int suitable_order,
struct contig_page_info *info)
{ … }
static int __fragmentation_index(unsigned int order, struct contig_page_info *info)
{ … }
unsigned int extfrag_for_order(struct zone *zone, unsigned int order)
{ … }
int fragmentation_index(struct zone *zone, unsigned int order)
{ … }
#endif
#if defined(CONFIG_PROC_FS) || defined(CONFIG_SYSFS) || \
defined(CONFIG_NUMA) || defined(CONFIG_MEMCG)
#ifdef CONFIG_ZONE_DMA
#define TEXT_FOR_DMA(xx) …
#else
#define TEXT_FOR_DMA …
#endif
#ifdef CONFIG_ZONE_DMA32
#define TEXT_FOR_DMA32(xx) …
#else
#define TEXT_FOR_DMA32 …
#endif
#ifdef CONFIG_HIGHMEM
#define TEXT_FOR_HIGHMEM …
#else
#define TEXT_FOR_HIGHMEM(xx) …
#endif
#ifdef CONFIG_ZONE_DEVICE
#define TEXT_FOR_DEVICE(xx) …
#else
#define TEXT_FOR_DEVICE …
#endif
#define TEXTS_FOR_ZONES(xx) …
const char * const vmstat_text[] = …;
#endif
#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMPACTION)) || \
defined(CONFIG_PROC_FS)
static void *frag_start(struct seq_file *m, loff_t *pos)
{ … }
static void *frag_next(struct seq_file *m, void *arg, loff_t *pos)
{ … }
static void frag_stop(struct seq_file *m, void *arg)
{ … }
static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat,
bool assert_populated, bool nolock,
void (*print)(struct seq_file *m, pg_data_t *, struct zone *))
{ … }
#endif
#ifdef CONFIG_PROC_FS
static void frag_show_print(struct seq_file *m, pg_data_t *pgdat,
struct zone *zone)
{ … }
static int frag_show(struct seq_file *m, void *arg)
{ … }
static void pagetypeinfo_showfree_print(struct seq_file *m,
pg_data_t *pgdat, struct zone *zone)
{ … }
static void pagetypeinfo_showfree(struct seq_file *m, void *arg)
{ … }
static void pagetypeinfo_showblockcount_print(struct seq_file *m,
pg_data_t *pgdat, struct zone *zone)
{ … }
static void pagetypeinfo_showblockcount(struct seq_file *m, void *arg)
{ … }
static void pagetypeinfo_showmixedcount(struct seq_file *m, pg_data_t *pgdat)
{ … }
static int pagetypeinfo_show(struct seq_file *m, void *arg)
{ … }
static const struct seq_operations fragmentation_op = …;
static const struct seq_operations pagetypeinfo_op = …;
static bool is_zone_first_populated(pg_data_t *pgdat, struct zone *zone)
{ … }
static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
struct zone *zone)
{ … }
static int zoneinfo_show(struct seq_file *m, void *arg)
{ … }
static const struct seq_operations zoneinfo_op = …;
#define NR_VMSTAT_ITEMS …
static void *vmstat_start(struct seq_file *m, loff_t *pos)
{ … }
static void *vmstat_next(struct seq_file *m, void *arg, loff_t *pos)
{ … }
static int vmstat_show(struct seq_file *m, void *arg)
{ … }
static void vmstat_stop(struct seq_file *m, void *arg)
{ … }
static const struct seq_operations vmstat_op = …;
#endif
#ifdef CONFIG_SMP
static DEFINE_PER_CPU(struct delayed_work, vmstat_work);
int sysctl_stat_interval __read_mostly = …;
#ifdef CONFIG_PROC_FS
static void refresh_vm_stats(struct work_struct *work)
{ … }
int vmstat_refresh(const struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{ … }
#endif
static void vmstat_update(struct work_struct *w)
{ … }
static bool need_update(int cpu)
{ … }
void quiet_vmstat(void)
{ … }
static void vmstat_shepherd(struct work_struct *w);
static DECLARE_DEFERRABLE_WORK(shepherd, vmstat_shepherd);
static void vmstat_shepherd(struct work_struct *w)
{ … }
static void __init start_shepherd_timer(void)
{ … }
static void __init init_cpu_node_state(void)
{ … }
static int vmstat_cpu_online(unsigned int cpu)
{ … }
static int vmstat_cpu_down_prep(unsigned int cpu)
{ … }
static int vmstat_cpu_dead(unsigned int cpu)
{ … }
#endif
struct workqueue_struct *mm_percpu_wq;
void __init init_mm_internals(void)
{ … }
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMPACTION)
static int unusable_free_index(unsigned int order,
struct contig_page_info *info)
{ … }
static void unusable_show_print(struct seq_file *m,
pg_data_t *pgdat, struct zone *zone)
{ … }
static int unusable_show(struct seq_file *m, void *arg)
{ … }
static const struct seq_operations unusable_sops = …;
DEFINE_SEQ_ATTRIBUTE(…);
static void extfrag_show_print(struct seq_file *m,
pg_data_t *pgdat, struct zone *zone)
{ … }
static int extfrag_show(struct seq_file *m, void *arg)
{ … }
static const struct seq_operations extfrag_sops = …;
DEFINE_SEQ_ATTRIBUTE(…);
static int __init extfrag_debug_init(void)
{ … }
module_init(…) …;
#endif
static unsigned long early_perpage_metadata[MAX_NUMNODES] __meminitdata;
void __meminit mod_node_early_perpage_metadata(int nid, long delta)
{ … }
void __meminit store_early_perpage_metadata(void)
{ … }