^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/mm/vmstat.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Manages VM statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * zoned VM statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2006 Silicon Graphics, Inc.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Christoph Lameter <christoph@lameter.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (C) 2008-2014 Christoph Lameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/cpumask.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/vmstat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/math64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/writeback.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/compaction.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/mm_inline.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/page_ext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/page_owner.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define NUMA_STATS_THRESHOLD (U16_MAX - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int sysctl_vm_numa_stat = ENABLE_NUMA_STAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* zero numa counters within a zone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static void zero_zone_numa_counters(struct zone *zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int item, cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) for (item = 0; item < NR_VM_NUMA_STAT_ITEMS; item++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) atomic_long_set(&zone->vm_numa_stat[item], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) for_each_online_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) per_cpu_ptr(zone->pageset, cpu)->vm_numa_stat_diff[item]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* zero numa counters of all the populated zones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void zero_zones_numa_counters(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct zone *zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) for_each_populated_zone(zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) zero_zone_numa_counters(zone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* zero global numa counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static void zero_global_numa_counters(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) for (item = 0; item < NR_VM_NUMA_STAT_ITEMS; item++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) atomic_long_set(&vm_numa_stat[item], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static void invalid_numa_statistics(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) zero_zones_numa_counters();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) zero_global_numa_counters();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static DEFINE_MUTEX(vm_numa_stat_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int sysctl_vm_numa_stat_handler(struct ctl_table *table, int write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) void *buffer, size_t *length, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int ret, oldval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) mutex_lock(&vm_numa_stat_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) oldval = sysctl_vm_numa_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (ret || !write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (oldval == sysctl_vm_numa_stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) else if (sysctl_vm_numa_stat == ENABLE_NUMA_STAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static_branch_enable(&vm_numa_stat_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) pr_info("enable numa statistics\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static_branch_disable(&vm_numa_stat_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) invalid_numa_statistics();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) pr_info("disable numa statistics, and clear numa counters\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mutex_unlock(&vm_numa_stat_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #ifdef CONFIG_VM_EVENT_COUNTERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) EXPORT_PER_CPU_SYMBOL(vm_event_states);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static void sum_vm_events(unsigned long *ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) memset(ret, 0, NR_VM_EVENT_ITEMS * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) for_each_online_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct vm_event_state *this = &per_cpu(vm_event_states, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) for (i = 0; i < NR_VM_EVENT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ret[i] += this->event[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * Accumulate the vm event counters across all CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * The result is unavoidably approximate - it can change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * during and after execution of this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) void all_vm_events(unsigned long *ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) get_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) sum_vm_events(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) put_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) EXPORT_SYMBOL_GPL(all_vm_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Fold the foreign cpu events into our own.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * This is adding to the events on one processor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * but keeps the global counts constant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) void vm_events_fold_cpu(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct vm_event_state *fold_state = &per_cpu(vm_event_states, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) for (i = 0; i < NR_VM_EVENT_ITEMS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) count_vm_events(i, fold_state->event[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) fold_state->event[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #endif /* CONFIG_VM_EVENT_COUNTERS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * Manage combined zone based / global counters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * vm_stat contains the global counters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) atomic_long_t vm_zone_stat[NR_VM_ZONE_STAT_ITEMS] __cacheline_aligned_in_smp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) atomic_long_t vm_numa_stat[NR_VM_NUMA_STAT_ITEMS] __cacheline_aligned_in_smp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) atomic_long_t vm_node_stat[NR_VM_NODE_STAT_ITEMS] __cacheline_aligned_in_smp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) EXPORT_SYMBOL(vm_zone_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) EXPORT_SYMBOL(vm_numa_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) EXPORT_SYMBOL(vm_node_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int calculate_pressure_threshold(struct zone *zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int watermark_distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * As vmstats are not up to date, there is drift between the estimated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * and real values. For high thresholds and a high number of CPUs, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * is possible for the min watermark to be breached while the estimated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * value looks fine. The pressure threshold is a reduced value such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * that even the maximum amount of drift will not accidentally breach
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * the min watermark
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) watermark_distance = low_wmark_pages(zone) - min_wmark_pages(zone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) threshold = max(1, (int)(watermark_distance / num_online_cpus()));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * Maximum threshold is 125
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) threshold = min(125, threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int calculate_normal_threshold(struct zone *zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int mem; /* memory in 128 MB units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * The threshold scales with the number of processors and the amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * of memory per zone. More memory means that we can defer updates for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * longer, more processors could lead to more contention.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * fls() is used to have a cheap way of logarithmic scaling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Some sample thresholds:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * Threshold Processors (fls) Zonesize fls(mem+1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * ------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * 8 1 1 0.9-1 GB 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * 16 2 2 0.9-1 GB 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * 20 2 2 1-2 GB 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * 24 2 2 2-4 GB 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * 28 2 2 4-8 GB 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * 32 2 2 8-16 GB 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * 4 2 2 <128M 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * 30 4 3 2-4 GB 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * 48 4 3 8-16 GB 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * 32 8 4 1-2 GB 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * 32 8 4 0.9-1GB 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * 10 16 5 <128M 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * 40 16 5 900M 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * 70 64 7 2-4 GB 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * 84 64 7 4-8 GB 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * 108 512 9 4-8 GB 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * 125 1024 10 8-16 GB 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * 125 1024 10 16-32 GB 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) mem = zone_managed_pages(zone) >> (27 - PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) threshold = 2 * fls(num_online_cpus()) * (1 + fls(mem));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Maximum threshold is 125
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) threshold = min(125, threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * Refresh the thresholds for each zone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) void refresh_zone_stat_thresholds(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct pglist_data *pgdat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct zone *zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* Zero current pgdat thresholds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) for_each_online_pgdat(pgdat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) for_each_online_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) per_cpu_ptr(pgdat->per_cpu_nodestats, cpu)->stat_threshold = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) for_each_populated_zone(zone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct pglist_data *pgdat = zone->zone_pgdat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) unsigned long max_drift, tolerate_drift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) threshold = calculate_normal_threshold(zone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) for_each_online_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int pgdat_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) per_cpu_ptr(zone->pageset, cpu)->stat_threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) = threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* Base nodestat threshold on the largest populated zone. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) pgdat_threshold = per_cpu_ptr(pgdat->per_cpu_nodestats, cpu)->stat_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) per_cpu_ptr(pgdat->per_cpu_nodestats, cpu)->stat_threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) = max(threshold, pgdat_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * Only set percpu_drift_mark if there is a danger that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * NR_FREE_PAGES reports the low watermark is ok when in fact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * the min watermark could be breached by an allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) tolerate_drift = low_wmark_pages(zone) - min_wmark_pages(zone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) max_drift = num_online_cpus() * threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (max_drift > tolerate_drift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) zone->percpu_drift_mark = high_wmark_pages(zone) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) max_drift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) void set_pgdat_percpu_threshold(pg_data_t *pgdat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int (*calculate_pressure)(struct zone *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct zone *zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) for (i = 0; i < pgdat->nr_zones; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) zone = &pgdat->node_zones[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (!zone->percpu_drift_mark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) threshold = (*calculate_pressure)(zone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) for_each_online_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) per_cpu_ptr(zone->pageset, cpu)->stat_threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) = threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * For use when we know that interrupts are disabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * or when we know that preemption is disabled and that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * particular counter cannot be updated from interrupt context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) long delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct per_cpu_pageset __percpu *pcp = zone->pageset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) s8 __percpu *p = pcp->vm_stat_diff + item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) long x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) x = delta + __this_cpu_read(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) t = __this_cpu_read(pcp->stat_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (unlikely(abs(x) > t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) zone_page_state_add(x, zone, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) __this_cpu_write(*p, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) EXPORT_SYMBOL(__mod_zone_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) void __mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) long delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct per_cpu_nodestat __percpu *pcp = pgdat->per_cpu_nodestats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) s8 __percpu *p = pcp->vm_node_stat_diff + item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) long x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (vmstat_item_in_bytes(item)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) VM_WARN_ON_ONCE(delta & (PAGE_SIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) delta >>= PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) x = delta + __this_cpu_read(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) t = __this_cpu_read(pcp->stat_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (unlikely(abs(x) > t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) node_page_state_add(x, pgdat, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) __this_cpu_write(*p, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) EXPORT_SYMBOL(__mod_node_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * Optimized increment and decrement functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * These are only for a single page and therefore can take a struct page *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * argument instead of struct zone *. This allows the inclusion of the code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * generated for page_zone(page) into the optimized functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * No overflow check is necessary and therefore the differential can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * incremented or decremented in place which may allow the compilers to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * generate better code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * The increment or decrement is known and therefore one boundary check can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * be omitted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * NOTE: These functions are very performance sensitive. Change only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * with care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Some processors have inc/dec instructions that are atomic vs an interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * However, the code must first determine the differential location in a zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * based on the processor number and then inc/dec the counter. There is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * guarantee without disabling preemption that the processor will not change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * in between and therefore the atomicity vs. interrupt cannot be exploited
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * in a useful way here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct per_cpu_pageset __percpu *pcp = zone->pageset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) s8 __percpu *p = pcp->vm_stat_diff + item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) s8 v, t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) v = __this_cpu_inc_return(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) t = __this_cpu_read(pcp->stat_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (unlikely(v > t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) s8 overstep = t >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) zone_page_state_add(v + overstep, zone, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) __this_cpu_write(*p, -overstep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct per_cpu_nodestat __percpu *pcp = pgdat->per_cpu_nodestats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) s8 __percpu *p = pcp->vm_node_stat_diff + item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) s8 v, t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) VM_WARN_ON_ONCE(vmstat_item_in_bytes(item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) v = __this_cpu_inc_return(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) t = __this_cpu_read(pcp->stat_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (unlikely(v > t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) s8 overstep = t >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) node_page_state_add(v + overstep, pgdat, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) __this_cpu_write(*p, -overstep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) void __inc_zone_page_state(struct page *page, enum zone_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) __inc_zone_state(page_zone(page), item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) EXPORT_SYMBOL(__inc_zone_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) void __inc_node_page_state(struct page *page, enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) __inc_node_state(page_pgdat(page), item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) EXPORT_SYMBOL(__inc_node_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct per_cpu_pageset __percpu *pcp = zone->pageset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) s8 __percpu *p = pcp->vm_stat_diff + item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) s8 v, t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) v = __this_cpu_dec_return(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) t = __this_cpu_read(pcp->stat_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (unlikely(v < - t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) s8 overstep = t >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) zone_page_state_add(v - overstep, zone, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) __this_cpu_write(*p, overstep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct per_cpu_nodestat __percpu *pcp = pgdat->per_cpu_nodestats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) s8 __percpu *p = pcp->vm_node_stat_diff + item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) s8 v, t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) VM_WARN_ON_ONCE(vmstat_item_in_bytes(item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) v = __this_cpu_dec_return(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) t = __this_cpu_read(pcp->stat_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (unlikely(v < - t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) s8 overstep = t >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) node_page_state_add(v - overstep, pgdat, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) __this_cpu_write(*p, overstep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) void __dec_zone_page_state(struct page *page, enum zone_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) __dec_zone_state(page_zone(page), item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) EXPORT_SYMBOL(__dec_zone_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) void __dec_node_page_state(struct page *page, enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) __dec_node_state(page_pgdat(page), item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) EXPORT_SYMBOL(__dec_node_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) #ifdef CONFIG_HAVE_CMPXCHG_LOCAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * If we have cmpxchg_local support then we do not need to incur the overhead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * that comes with local_irq_save/restore if we use this_cpu_cmpxchg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * mod_state() modifies the zone counter state through atomic per cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * Overstep mode specifies how overstep should handled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * 0 No overstepping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * 1 Overstepping half of threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * -1 Overstepping minus half of threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static inline void mod_zone_state(struct zone *zone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) enum zone_stat_item item, long delta, int overstep_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct per_cpu_pageset __percpu *pcp = zone->pageset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) s8 __percpu *p = pcp->vm_stat_diff + item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) long o, n, t, z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) z = 0; /* overflow to zone counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * The fetching of the stat_threshold is racy. We may apply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * a counter threshold to the wrong the cpu if we get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * rescheduled while executing here. However, the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * counter update will apply the threshold again and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * therefore bring the counter under the threshold again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * Most of the time the thresholds are the same anyways
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * for all cpus in a zone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) t = this_cpu_read(pcp->stat_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) o = this_cpu_read(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) n = delta + o;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (abs(n) > t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) int os = overstep_mode * (t >> 1) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* Overflow must be added to zone counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) z = n + os;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) n = -os;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) } while (this_cpu_cmpxchg(*p, o, n) != o);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) zone_page_state_add(z, zone, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) void mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) long delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) mod_zone_state(zone, item, delta, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) EXPORT_SYMBOL(mod_zone_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) void inc_zone_page_state(struct page *page, enum zone_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) mod_zone_state(page_zone(page), item, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) EXPORT_SYMBOL(inc_zone_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) void dec_zone_page_state(struct page *page, enum zone_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) mod_zone_state(page_zone(page), item, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) EXPORT_SYMBOL(dec_zone_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static inline void mod_node_state(struct pglist_data *pgdat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) enum node_stat_item item, int delta, int overstep_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct per_cpu_nodestat __percpu *pcp = pgdat->per_cpu_nodestats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) s8 __percpu *p = pcp->vm_node_stat_diff + item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) long o, n, t, z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (vmstat_item_in_bytes(item)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) VM_WARN_ON_ONCE(delta & (PAGE_SIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) delta >>= PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) z = 0; /* overflow to node counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * The fetching of the stat_threshold is racy. We may apply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * a counter threshold to the wrong the cpu if we get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * rescheduled while executing here. However, the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * counter update will apply the threshold again and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * therefore bring the counter under the threshold again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * Most of the time the thresholds are the same anyways
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * for all cpus in a node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) t = this_cpu_read(pcp->stat_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) o = this_cpu_read(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) n = delta + o;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (abs(n) > t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) int os = overstep_mode * (t >> 1) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* Overflow must be added to node counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) z = n + os;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) n = -os;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) } while (this_cpu_cmpxchg(*p, o, n) != o);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) node_page_state_add(z, pgdat, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) void mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) long delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) mod_node_state(pgdat, item, delta, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) EXPORT_SYMBOL(mod_node_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) void inc_node_state(struct pglist_data *pgdat, enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) mod_node_state(pgdat, item, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) void inc_node_page_state(struct page *page, enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) mod_node_state(page_pgdat(page), item, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) EXPORT_SYMBOL(inc_node_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) void dec_node_page_state(struct page *page, enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) mod_node_state(page_pgdat(page), item, -1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) EXPORT_SYMBOL(dec_node_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * Use interrupt disable to serialize counter updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) void mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) long delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) __mod_zone_page_state(zone, item, delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) EXPORT_SYMBOL(mod_zone_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) void inc_zone_page_state(struct page *page, enum zone_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct zone *zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) zone = page_zone(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) __inc_zone_state(zone, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) EXPORT_SYMBOL(inc_zone_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) void dec_zone_page_state(struct page *page, enum zone_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) __dec_zone_page_state(page, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) EXPORT_SYMBOL(dec_zone_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) void inc_node_state(struct pglist_data *pgdat, enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) __inc_node_state(pgdat, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) EXPORT_SYMBOL(inc_node_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) void mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) long delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) __mod_node_page_state(pgdat, item, delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) EXPORT_SYMBOL(mod_node_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) void inc_node_page_state(struct page *page, enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct pglist_data *pgdat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) pgdat = page_pgdat(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) __inc_node_state(pgdat, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) EXPORT_SYMBOL(inc_node_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) void dec_node_page_state(struct page *page, enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) __dec_node_page_state(page, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) EXPORT_SYMBOL(dec_node_page_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * Fold a differential into the global counters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * Returns the number of counters updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static int fold_diff(int *zone_diff, int *numa_diff, int *node_diff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int changes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (zone_diff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) atomic_long_add(zone_diff[i], &vm_zone_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) changes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (numa_diff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) atomic_long_add(numa_diff[i], &vm_numa_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) changes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (node_diff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) atomic_long_add(node_diff[i], &vm_node_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) changes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return changes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static int fold_diff(int *zone_diff, int *node_diff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) int changes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (zone_diff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) atomic_long_add(zone_diff[i], &vm_zone_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) changes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (node_diff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) atomic_long_add(node_diff[i], &vm_node_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) changes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return changes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) #endif /* CONFIG_NUMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * Update the zone counters for the current cpu.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * Note that refresh_cpu_vm_stats strives to only access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * node local memory. The per cpu pagesets on remote zones are placed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * in the memory local to the processor using that pageset. So the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * loop over all zones will access a series of cachelines local to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * the processor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * The call to zone_page_state_add updates the cachelines with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * statistics in the remote zone struct as well as the global cachelines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * with the global counters. These could cause remote node cache line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * bouncing and will have to be only done when necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * The function returns the number of global counters updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static int refresh_cpu_vm_stats(bool do_pagesets)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct pglist_data *pgdat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct zone *zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) int global_zone_diff[NR_VM_ZONE_STAT_ITEMS] = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) int global_numa_diff[NR_VM_NUMA_STAT_ITEMS] = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) int global_node_diff[NR_VM_NODE_STAT_ITEMS] = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) int changes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) for_each_populated_zone(zone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct per_cpu_pageset __percpu *p = zone->pageset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) v = this_cpu_xchg(p->vm_stat_diff[i], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) atomic_long_add(v, &zone->vm_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) global_zone_diff[i] += v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* 3 seconds idle till flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) __this_cpu_write(p->expire, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) int v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) v = this_cpu_xchg(p->vm_numa_stat_diff[i], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) atomic_long_add(v, &zone->vm_numa_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) global_numa_diff[i] += v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) __this_cpu_write(p->expire, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (do_pagesets) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * Deal with draining the remote pageset of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * processor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * Check if there are pages remaining in this pageset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * if not then there is nothing to expire.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (!__this_cpu_read(p->expire) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) !__this_cpu_read(p->pcp.count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * We never drain zones local to this processor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (zone_to_nid(zone) == numa_node_id()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) __this_cpu_write(p->expire, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (__this_cpu_dec_return(p->expire))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (__this_cpu_read(p->pcp.count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) drain_zone_pages(zone, this_cpu_ptr(&p->pcp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) changes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) for_each_online_pgdat(pgdat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) struct per_cpu_nodestat __percpu *p = pgdat->per_cpu_nodestats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) v = this_cpu_xchg(p->vm_node_stat_diff[i], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) atomic_long_add(v, &pgdat->vm_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) global_node_diff[i] += v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) changes += fold_diff(global_zone_diff, global_numa_diff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) global_node_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) changes += fold_diff(global_zone_diff, global_node_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return changes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * Fold the data for an offline cpu into the global array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * There cannot be any access by the offline cpu and therefore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * synchronization is simplified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) void cpu_vm_stats_fold(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct pglist_data *pgdat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct zone *zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) int global_zone_diff[NR_VM_ZONE_STAT_ITEMS] = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) int global_numa_diff[NR_VM_NUMA_STAT_ITEMS] = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) int global_node_diff[NR_VM_NODE_STAT_ITEMS] = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) for_each_populated_zone(zone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct per_cpu_pageset *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) p = per_cpu_ptr(zone->pageset, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (p->vm_stat_diff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) int v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) v = p->vm_stat_diff[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) p->vm_stat_diff[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) atomic_long_add(v, &zone->vm_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) global_zone_diff[i] += v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (p->vm_numa_stat_diff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) int v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) v = p->vm_numa_stat_diff[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) p->vm_numa_stat_diff[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) atomic_long_add(v, &zone->vm_numa_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) global_numa_diff[i] += v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) for_each_online_pgdat(pgdat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct per_cpu_nodestat *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) p = per_cpu_ptr(pgdat->per_cpu_nodestats, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (p->vm_node_stat_diff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) int v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) v = p->vm_node_stat_diff[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) p->vm_node_stat_diff[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) atomic_long_add(v, &pgdat->vm_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) global_node_diff[i] += v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) fold_diff(global_zone_diff, global_numa_diff, global_node_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) fold_diff(global_zone_diff, global_node_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * this is only called if !populated_zone(zone), which implies no other users of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * pset->vm_stat_diff[] exsist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) void drain_zonestat(struct zone *zone, struct per_cpu_pageset *pset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (pset->vm_stat_diff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int v = pset->vm_stat_diff[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) pset->vm_stat_diff[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) atomic_long_add(v, &zone->vm_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) atomic_long_add(v, &vm_zone_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (pset->vm_numa_stat_diff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) int v = pset->vm_numa_stat_diff[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) pset->vm_numa_stat_diff[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) atomic_long_add(v, &zone->vm_numa_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) atomic_long_add(v, &vm_numa_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) void __inc_numa_state(struct zone *zone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) enum numa_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct per_cpu_pageset __percpu *pcp = zone->pageset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) u16 __percpu *p = pcp->vm_numa_stat_diff + item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) u16 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) v = __this_cpu_inc_return(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (unlikely(v > NUMA_STATS_THRESHOLD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) zone_numa_state_add(v, zone, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) __this_cpu_write(*p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * Determine the per node value of a stat item. This function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * is called frequently in a NUMA machine, so try to be as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * frugal as possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) unsigned long sum_zone_node_page_state(int node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) enum zone_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct zone *zones = NODE_DATA(node)->node_zones;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) unsigned long count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) for (i = 0; i < MAX_NR_ZONES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) count += zone_page_state(zones + i, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * Determine the per node value of a numa stat item. To avoid deviation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * the per cpu stat number in vm_numa_stat_diff[] is also included.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) unsigned long sum_zone_numa_state(int node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) enum numa_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct zone *zones = NODE_DATA(node)->node_zones;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) unsigned long count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) for (i = 0; i < MAX_NR_ZONES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) count += zone_numa_state_snapshot(zones + i, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) * Determine the per node value of a stat item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) unsigned long node_page_state_pages(struct pglist_data *pgdat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) long x = atomic_long_read(&pgdat->vm_stat[item]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (x < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) unsigned long node_page_state(struct pglist_data *pgdat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) enum node_stat_item item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) VM_WARN_ON_ONCE(vmstat_item_in_bytes(item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return node_page_state_pages(pgdat, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) #ifdef CONFIG_COMPACTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct contig_page_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) unsigned long free_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) unsigned long free_blocks_total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) unsigned long free_blocks_suitable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * Calculate the number of free pages in a zone, how many contiguous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * pages are free and how many are large enough to satisfy an allocation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * the target size. Note that this function makes no attempt to estimate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * how many suitable free blocks there *might* be if MOVABLE pages were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * migrated. Calculating that is possible, but expensive and can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * figured out from userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) static void fill_contig_page_info(struct zone *zone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) unsigned int suitable_order,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct contig_page_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) unsigned int order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) info->free_pages = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) info->free_blocks_total = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) info->free_blocks_suitable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) for (order = 0; order < MAX_ORDER; order++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) unsigned long blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* Count number of free blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) blocks = zone->free_area[order].nr_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) info->free_blocks_total += blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) /* Count free base pages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) info->free_pages += blocks << order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) /* Count the suitable free blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (order >= suitable_order)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) info->free_blocks_suitable += blocks <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) (order - suitable_order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) * A fragmentation index only makes sense if an allocation of a requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * size would fail. If that is true, the fragmentation index indicates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) * whether external fragmentation or a lack of memory was the problem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) * The value can be used to determine if page reclaim or compaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) * should be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) static int __fragmentation_index(unsigned int order, struct contig_page_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) unsigned long requested = 1UL << order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (WARN_ON_ONCE(order >= MAX_ORDER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (!info->free_blocks_total)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) /* Fragmentation index only makes sense when a request would fail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (info->free_blocks_suitable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return -1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * Index is between 0 and 1 so return within 3 decimal places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * 0 => allocation would fail due to lack of memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * 1 => allocation would fail due to fragmentation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return 1000 - div_u64( (1000+(div_u64(info->free_pages * 1000ULL, requested))), info->free_blocks_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * Calculates external fragmentation within a zone wrt the given order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * It is defined as the percentage of pages found in blocks of size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * less than 1 << order. It returns values in range [0, 100].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) unsigned int extfrag_for_order(struct zone *zone, unsigned int order)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct contig_page_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) fill_contig_page_info(zone, order, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (info.free_pages == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return div_u64((info.free_pages -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) (info.free_blocks_suitable << order)) * 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) info.free_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) /* Same as __fragmentation index but allocs contig_page_info on stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) int fragmentation_index(struct zone *zone, unsigned int order)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) struct contig_page_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) fill_contig_page_info(zone, order, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return __fragmentation_index(order, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) #if defined(CONFIG_PROC_FS) || defined(CONFIG_SYSFS) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) defined(CONFIG_NUMA) || defined(CONFIG_MEMCG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) #ifdef CONFIG_ZONE_DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) #define TEXT_FOR_DMA(xx) xx "_dma",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) #define TEXT_FOR_DMA(xx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) #ifdef CONFIG_ZONE_DMA32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) #define TEXT_FOR_DMA32(xx) xx "_dma32",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) #define TEXT_FOR_DMA32(xx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) #ifdef CONFIG_HIGHMEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) #define TEXT_FOR_HIGHMEM(xx) xx "_high",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) #define TEXT_FOR_HIGHMEM(xx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) #define TEXTS_FOR_ZONES(xx) TEXT_FOR_DMA(xx) TEXT_FOR_DMA32(xx) xx "_normal", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) TEXT_FOR_HIGHMEM(xx) xx "_movable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) const char * const vmstat_text[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /* enum zone_stat_item counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) "nr_free_pages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) "nr_zone_inactive_anon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) "nr_zone_active_anon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) "nr_zone_inactive_file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) "nr_zone_active_file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) "nr_zone_unevictable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) "nr_zone_write_pending",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) "nr_mlock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) "nr_page_table_pages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) "nr_bounce",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) "nr_zspages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) "nr_free_cma",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) /* enum numa_stat_item counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) "numa_hit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) "numa_miss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) "numa_foreign",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) "numa_interleave",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) "numa_local",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) "numa_other",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) /* enum node_stat_item counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) "nr_inactive_anon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) "nr_active_anon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) "nr_inactive_file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) "nr_active_file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) "nr_unevictable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) "nr_slab_reclaimable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) "nr_slab_unreclaimable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) "nr_isolated_anon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) "nr_isolated_file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) "workingset_nodes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) "workingset_refault_anon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) "workingset_refault_file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) "workingset_activate_anon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) "workingset_activate_file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) "workingset_restore_anon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) "workingset_restore_file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) "workingset_nodereclaim",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) "nr_anon_pages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) "nr_mapped",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) "nr_file_pages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) "nr_dirty",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) "nr_writeback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) "nr_writeback_temp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) "nr_shmem",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) "nr_shmem_hugepages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) "nr_shmem_pmdmapped",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) "nr_file_hugepages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) "nr_file_pmdmapped",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) "nr_anon_transparent_hugepages",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) "nr_vmscan_write",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) "nr_vmscan_immediate_reclaim",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) "nr_dirtied",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) "nr_written",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) "nr_kernel_misc_reclaimable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) "nr_foll_pin_acquired",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) "nr_foll_pin_released",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) "nr_kernel_stack",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) #if IS_ENABLED(CONFIG_SHADOW_CALL_STACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) "nr_shadow_call_stack",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) /* enum writeback_stat_item counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) "nr_dirty_threshold",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) "nr_dirty_background_threshold",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) #if defined(CONFIG_VM_EVENT_COUNTERS) || defined(CONFIG_MEMCG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) /* enum vm_event_item counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) "pgpgin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) "pgpgout",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) "pswpin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) "pswpout",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) TEXTS_FOR_ZONES("pgalloc")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) TEXTS_FOR_ZONES("allocstall")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) TEXTS_FOR_ZONES("pgskip")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) "pgfree",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) "pgactivate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) "pgdeactivate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) "pglazyfree",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) "pgfault",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) "pgmajfault",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) "pglazyfreed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) "pgrefill",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) "pgreuse",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) "pgsteal_kswapd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) "pgsteal_direct",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) "pgscan_kswapd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) "pgscan_direct",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) "pgscan_direct_throttle",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) "pgscan_anon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) "pgscan_file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) "pgsteal_anon",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) "pgsteal_file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) "zone_reclaim_failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) "pginodesteal",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) "slabs_scanned",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) "kswapd_inodesteal",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) "kswapd_low_wmark_hit_quickly",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) "kswapd_high_wmark_hit_quickly",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) "pageoutrun",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) "pgrotated",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) "drop_pagecache",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) "drop_slab",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) "oom_kill",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) #ifdef CONFIG_NUMA_BALANCING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) "numa_pte_updates",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) "numa_huge_pte_updates",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) "numa_hint_faults",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) "numa_hint_faults_local",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) "numa_pages_migrated",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) #ifdef CONFIG_MIGRATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) "pgmigrate_success",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) "pgmigrate_fail",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) "thp_migration_success",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) "thp_migration_fail",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) "thp_migration_split",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) #ifdef CONFIG_COMPACTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) "compact_migrate_scanned",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) "compact_free_scanned",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) "compact_isolated",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) "compact_stall",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) "compact_fail",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) "compact_success",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) "compact_daemon_wake",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) "compact_daemon_migrate_scanned",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) "compact_daemon_free_scanned",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) #ifdef CONFIG_HUGETLB_PAGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) "htlb_buddy_alloc_success",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) "htlb_buddy_alloc_fail",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) #ifdef CONFIG_CMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) "cma_alloc_success",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) "cma_alloc_fail",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) "unevictable_pgs_culled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) "unevictable_pgs_scanned",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) "unevictable_pgs_rescued",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) "unevictable_pgs_mlocked",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) "unevictable_pgs_munlocked",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) "unevictable_pgs_cleared",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) "unevictable_pgs_stranded",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) #ifdef CONFIG_TRANSPARENT_HUGEPAGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) "thp_fault_alloc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) "thp_fault_fallback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) "thp_fault_fallback_charge",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) "thp_collapse_alloc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) "thp_collapse_alloc_failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) "thp_file_alloc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) "thp_file_fallback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) "thp_file_fallback_charge",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) "thp_file_mapped",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) "thp_split_page",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) "thp_split_page_failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) "thp_deferred_split_page",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) "thp_split_pmd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) "thp_split_pud",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) "thp_zero_page_alloc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) "thp_zero_page_alloc_failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) "thp_swpout",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) "thp_swpout_fallback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) #ifdef CONFIG_MEMORY_BALLOON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) "balloon_inflate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) "balloon_deflate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) #ifdef CONFIG_BALLOON_COMPACTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) "balloon_migrate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) #endif /* CONFIG_MEMORY_BALLOON */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) #ifdef CONFIG_DEBUG_TLBFLUSH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) "nr_tlb_remote_flush",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) "nr_tlb_remote_flush_received",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) "nr_tlb_local_flush_all",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) "nr_tlb_local_flush_one",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) #endif /* CONFIG_DEBUG_TLBFLUSH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) #ifdef CONFIG_DEBUG_VM_VMACACHE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) "vmacache_find_calls",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) "vmacache_find_hits",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) #ifdef CONFIG_SWAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) "swap_ra",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) "swap_ra_hit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) #ifdef CONFIG_SPECULATIVE_PAGE_FAULT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) "speculative_pgfault",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) "speculative_pgfault_file"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) #endif /* CONFIG_VM_EVENT_COUNTERS || CONFIG_MEMCG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) #endif /* CONFIG_PROC_FS || CONFIG_SYSFS || CONFIG_NUMA || CONFIG_MEMCG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) #if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMPACTION)) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) defined(CONFIG_PROC_FS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) static void *frag_start(struct seq_file *m, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) pg_data_t *pgdat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) loff_t node = *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) for (pgdat = first_online_pgdat();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) pgdat && node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) pgdat = next_online_pgdat(pgdat))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) --node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) return pgdat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) static void *frag_next(struct seq_file *m, void *arg, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) pg_data_t *pgdat = (pg_data_t *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) (*pos)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) return next_online_pgdat(pgdat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) static void frag_stop(struct seq_file *m, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) * Walk zones in a node and print using a callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) * If @assert_populated is true, only use callback for zones that are populated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) bool assert_populated, bool nolock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) void (*print)(struct seq_file *m, pg_data_t *, struct zone *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) struct zone *zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) struct zone *node_zones = pgdat->node_zones;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (assert_populated && !populated_zone(zone))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (!nolock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) spin_lock_irqsave(&zone->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) print(m, pgdat, zone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) if (!nolock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) spin_unlock_irqrestore(&zone->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static void frag_show_print(struct seq_file *m, pg_data_t *pgdat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct zone *zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) int order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) for (order = 0; order < MAX_ORDER; ++order)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) seq_printf(m, "%6lu ", zone->free_area[order].nr_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) * This walks the free areas for each zone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) static int frag_show(struct seq_file *m, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) pg_data_t *pgdat = (pg_data_t *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) walk_zones_in_node(m, pgdat, true, false, frag_show_print);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) static void pagetypeinfo_showfree_print(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) pg_data_t *pgdat, struct zone *zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) int order, mtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) for (mtype = 0; mtype < MIGRATE_TYPES; mtype++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) seq_printf(m, "Node %4d, zone %8s, type %12s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) pgdat->node_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) zone->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) migratetype_names[mtype]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) for (order = 0; order < MAX_ORDER; ++order) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) unsigned long freecount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) struct free_area *area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) struct list_head *curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) bool overflow = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) area = &(zone->free_area[order]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) list_for_each(curr, &area->free_list[mtype]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) * Cap the free_list iteration because it might
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * be really large and we are under a spinlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) * so a long time spent here could trigger a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) * hard lockup detector. Anyway this is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) * debugging tool so knowing there is a handful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) * of pages of this order should be more than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) * sufficient.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if (++freecount >= 100000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) overflow = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) seq_printf(m, "%s%6lu ", overflow ? ">" : "", freecount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) spin_unlock_irq(&zone->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) spin_lock_irq(&zone->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) /* Print out the free pages at each order for each migatetype */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) static int pagetypeinfo_showfree(struct seq_file *m, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) int order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) pg_data_t *pgdat = (pg_data_t *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) /* Print header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) seq_printf(m, "%-43s ", "Free pages count per migrate type at order");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) for (order = 0; order < MAX_ORDER; ++order)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) seq_printf(m, "%6d ", order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) walk_zones_in_node(m, pgdat, true, false, pagetypeinfo_showfree_print);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) static void pagetypeinfo_showblockcount_print(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) pg_data_t *pgdat, struct zone *zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) int mtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) unsigned long pfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) unsigned long start_pfn = zone->zone_start_pfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) unsigned long end_pfn = zone_end_pfn(zone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) unsigned long count[MIGRATE_TYPES] = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) page = pfn_to_online_page(pfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) /* Watch for unexpected holes punched in the memmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (!memmap_valid_within(pfn, page, zone))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (page_zone(page) != zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) mtype = get_pageblock_migratetype(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) if (mtype < MIGRATE_TYPES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) count[mtype]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) /* Print counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) for (mtype = 0; mtype < MIGRATE_TYPES; mtype++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) seq_printf(m, "%12lu ", count[mtype]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) /* Print out the number of pageblocks for each migratetype */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) static int pagetypeinfo_showblockcount(struct seq_file *m, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) int mtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) pg_data_t *pgdat = (pg_data_t *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) seq_printf(m, "\n%-23s", "Number of blocks type ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) for (mtype = 0; mtype < MIGRATE_TYPES; mtype++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) seq_printf(m, "%12s ", migratetype_names[mtype]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) walk_zones_in_node(m, pgdat, true, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) pagetypeinfo_showblockcount_print);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) * Print out the number of pageblocks for each migratetype that contain pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) * of other types. This gives an indication of how well fallbacks are being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) * contained by rmqueue_fallback(). It requires information from PAGE_OWNER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) * to determine what is going on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static void pagetypeinfo_showmixedcount(struct seq_file *m, pg_data_t *pgdat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) #ifdef CONFIG_PAGE_OWNER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) int mtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) if (!static_branch_unlikely(&page_owner_inited))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) drain_all_pages(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) seq_printf(m, "\n%-23s", "Number of mixed blocks ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) for (mtype = 0; mtype < MIGRATE_TYPES; mtype++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) seq_printf(m, "%12s ", migratetype_names[mtype]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) walk_zones_in_node(m, pgdat, true, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) pagetypeinfo_showmixedcount_print);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) #endif /* CONFIG_PAGE_OWNER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) * This prints out statistics in relation to grouping pages by mobility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) * It is expensive to collect so do not constantly read the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) static int pagetypeinfo_show(struct seq_file *m, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) pg_data_t *pgdat = (pg_data_t *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) /* check memoryless node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) if (!node_state(pgdat->node_id, N_MEMORY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) seq_printf(m, "Page block order: %d\n", pageblock_order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) seq_printf(m, "Pages per block: %lu\n", pageblock_nr_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) pagetypeinfo_showfree(m, pgdat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) pagetypeinfo_showblockcount(m, pgdat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) pagetypeinfo_showmixedcount(m, pgdat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) static const struct seq_operations fragmentation_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) .start = frag_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) .next = frag_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) .stop = frag_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) .show = frag_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static const struct seq_operations pagetypeinfo_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) .start = frag_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) .next = frag_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) .stop = frag_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) .show = pagetypeinfo_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) static bool is_zone_first_populated(pg_data_t *pgdat, struct zone *zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) int zid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) for (zid = 0; zid < MAX_NR_ZONES; zid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) struct zone *compare = &pgdat->node_zones[zid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (populated_zone(compare))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) return zone == compare;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) struct zone *zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) seq_printf(m, "Node %d, zone %8s", pgdat->node_id, zone->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (is_zone_first_populated(pgdat, zone)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) seq_printf(m, "\n per-node stats");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) seq_printf(m, "\n %-12s %lu", node_stat_name(i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) node_page_state_pages(pgdat, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) "\n pages free %lu"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) "\n min %lu"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) "\n low %lu"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) "\n high %lu"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) "\n spanned %lu"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) "\n present %lu"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) "\n managed %lu"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) "\n cma %lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) zone_page_state(zone, NR_FREE_PAGES),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) min_wmark_pages(zone),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) low_wmark_pages(zone),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) high_wmark_pages(zone),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) zone->spanned_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) zone->present_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) zone_managed_pages(zone),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) zone_cma_pages(zone));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) "\n protection: (%ld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) zone->lowmem_reserve[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) seq_printf(m, ", %ld", zone->lowmem_reserve[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) seq_putc(m, ')');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) /* If unpopulated, no other information is useful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (!populated_zone(zone)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) seq_printf(m, "\n %-12s %lu", zone_stat_name(i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) zone_page_state(zone, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) seq_printf(m, "\n %-12s %lu", numa_stat_name(i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) zone_numa_state_snapshot(zone, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) seq_printf(m, "\n pagesets");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) for_each_online_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) struct per_cpu_pageset *pageset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) pageset = per_cpu_ptr(zone->pageset, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) "\n cpu: %i"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) "\n count: %i"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) "\n high: %i"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) "\n batch: %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) pageset->pcp.count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) pageset->pcp.high,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) pageset->pcp.batch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) seq_printf(m, "\n vm stats threshold: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) pageset->stat_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) "\n node_unreclaimable: %u"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) "\n start_pfn: %lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) pgdat->kswapd_failures >= MAX_RECLAIM_RETRIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) zone->zone_start_pfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) * Output information about zones in @pgdat. All zones are printed regardless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) * of whether they are populated or not: lowmem_reserve_ratio operates on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) * set of all zones and userspace would not be aware of such zones if they are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) * suppressed here (zoneinfo displays the effect of lowmem_reserve_ratio).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) static int zoneinfo_show(struct seq_file *m, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) pg_data_t *pgdat = (pg_data_t *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) walk_zones_in_node(m, pgdat, false, false, zoneinfo_show_print);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) static const struct seq_operations zoneinfo_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) .start = frag_start, /* iterate over all zones. The same as in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) * fragmentation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) .next = frag_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) .stop = frag_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) .show = zoneinfo_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) #define NR_VMSTAT_ITEMS (NR_VM_ZONE_STAT_ITEMS + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) NR_VM_NUMA_STAT_ITEMS + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) NR_VM_NODE_STAT_ITEMS + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) NR_VM_WRITEBACK_STAT_ITEMS + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) (IS_ENABLED(CONFIG_VM_EVENT_COUNTERS) ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) NR_VM_EVENT_ITEMS : 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) static void *vmstat_start(struct seq_file *m, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) unsigned long *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (*pos >= NR_VMSTAT_ITEMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) BUILD_BUG_ON(ARRAY_SIZE(vmstat_text) < NR_VMSTAT_ITEMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) v = kmalloc_array(NR_VMSTAT_ITEMS, sizeof(unsigned long), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) m->private = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) if (!v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) v[i] = global_zone_page_state(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) v += NR_VM_ZONE_STAT_ITEMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) v[i] = global_numa_state(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) v += NR_VM_NUMA_STAT_ITEMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) v[i] = global_node_page_state_pages(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) v += NR_VM_NODE_STAT_ITEMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) global_dirty_limits(v + NR_DIRTY_BG_THRESHOLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) v + NR_DIRTY_THRESHOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) v += NR_VM_WRITEBACK_STAT_ITEMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) #ifdef CONFIG_VM_EVENT_COUNTERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) all_vm_events(v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) v[PGPGIN] /= 2; /* sectors -> kbytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) v[PGPGOUT] /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) return (unsigned long *)m->private + *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) static void *vmstat_next(struct seq_file *m, void *arg, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) (*pos)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) if (*pos >= NR_VMSTAT_ITEMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) return (unsigned long *)m->private + *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) static int vmstat_show(struct seq_file *m, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) unsigned long *l = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) unsigned long off = l - (unsigned long *)m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) seq_puts(m, vmstat_text[off]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) seq_put_decimal_ull(m, " ", *l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if (off == NR_VMSTAT_ITEMS - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) * We've come to the end - add any deprecated counters to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) * breaking userspace which might depend on them being present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) seq_puts(m, "nr_unstable 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) static void vmstat_stop(struct seq_file *m, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) kfree(m->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) m->private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) static const struct seq_operations vmstat_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) .start = vmstat_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) .next = vmstat_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) .stop = vmstat_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) .show = vmstat_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) #endif /* CONFIG_PROC_FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) static DEFINE_PER_CPU(struct delayed_work, vmstat_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) int sysctl_stat_interval __read_mostly = HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) static void refresh_vm_stats(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) refresh_cpu_vm_stats(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) int vmstat_refresh(struct ctl_table *table, int write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) void *buffer, size_t *lenp, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) * The regular update, every sysctl_stat_interval, may come later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) * than expected: leaving a significant amount in per_cpu buckets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) * This is particularly misleading when checking a quantity of HUGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) * pages, immediately after running a test. /proc/sys/vm/stat_refresh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) * which can equally be echo'ed to or cat'ted from (by root),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) * can be used to update the stats just before reading them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) * Oh, and since global_zone_page_state() etc. are so careful to hide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) * transiently negative values, report an error here if any of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) * the stats is negative, so we know to go looking for imbalance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) err = schedule_on_each_cpu(refresh_vm_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) val = atomic_long_read(&vm_zone_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) if (val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) pr_warn("%s: %s %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) __func__, zone_stat_name(i), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) for (i = 0; i < NR_VM_NUMA_STAT_ITEMS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) val = atomic_long_read(&vm_numa_stat[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) pr_warn("%s: %s %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) __func__, numa_stat_name(i), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) if (write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) *ppos += *lenp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) *lenp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) #endif /* CONFIG_PROC_FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) static void vmstat_update(struct work_struct *w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (refresh_cpu_vm_stats(true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) * Counters were updated so we expect more updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) * to occur in the future. Keep on running the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) * update worker thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) queue_delayed_work_on(smp_processor_id(), mm_percpu_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) this_cpu_ptr(&vmstat_work),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) round_jiffies_relative(sysctl_stat_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) * Switch off vmstat processing and then fold all the remaining differentials
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) * until the diffs stay at zero. The function is used by NOHZ and can only be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) * invoked when tick processing is not active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) * Check if the diffs for a certain cpu indicate that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) * an update is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) static bool need_update(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) struct zone *zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) for_each_populated_zone(zone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) struct per_cpu_pageset *p = per_cpu_ptr(zone->pageset, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) BUILD_BUG_ON(sizeof(p->vm_stat_diff[0]) != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) BUILD_BUG_ON(sizeof(p->vm_numa_stat_diff[0]) != 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) * The fast way of checking if there are any vmstat diffs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (memchr_inv(p->vm_stat_diff, 0, NR_VM_ZONE_STAT_ITEMS *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) sizeof(p->vm_stat_diff[0])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) if (memchr_inv(p->vm_numa_stat_diff, 0, NR_VM_NUMA_STAT_ITEMS *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) sizeof(p->vm_numa_stat_diff[0])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) * Switch off vmstat processing and then fold all the remaining differentials
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) * until the diffs stay at zero. The function is used by NOHZ and can only be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) * invoked when tick processing is not active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) void quiet_vmstat(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) if (system_state != SYSTEM_RUNNING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) if (!delayed_work_pending(this_cpu_ptr(&vmstat_work)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) if (!need_update(smp_processor_id()))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) * Just refresh counters and do not care about the pending delayed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) * vmstat_update. It doesn't fire that often to matter and canceling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) * it would be too expensive from this path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) * vmstat_shepherd will take care about that for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) refresh_cpu_vm_stats(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) * Shepherd worker thread that checks the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) * differentials of processors that have their worker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) * threads for vm statistics updates disabled because of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * inactivity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) static void vmstat_shepherd(struct work_struct *w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) static DECLARE_DEFERRABLE_WORK(shepherd, vmstat_shepherd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) static void vmstat_shepherd(struct work_struct *w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) get_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) /* Check processors whose vmstat worker threads have been disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) for_each_online_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) struct delayed_work *dw = &per_cpu(vmstat_work, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) if (!delayed_work_pending(dw) && need_update(cpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) queue_delayed_work_on(cpu, mm_percpu_wq, dw, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) put_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) schedule_delayed_work(&shepherd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) round_jiffies_relative(sysctl_stat_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) static void __init start_shepherd_timer(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) for_each_possible_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) INIT_DEFERRABLE_WORK(per_cpu_ptr(&vmstat_work, cpu),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) vmstat_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) schedule_delayed_work(&shepherd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) round_jiffies_relative(sysctl_stat_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) static void __init init_cpu_node_state(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) int node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) for_each_online_node(node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) if (cpumask_weight(cpumask_of_node(node)) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) node_set_state(node, N_CPU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) static int vmstat_cpu_online(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) refresh_zone_stat_thresholds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) node_set_state(cpu_to_node(cpu), N_CPU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) static int vmstat_cpu_down_prep(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) cancel_delayed_work_sync(&per_cpu(vmstat_work, cpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) static int vmstat_cpu_dead(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) const struct cpumask *node_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) int node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) node = cpu_to_node(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) refresh_zone_stat_thresholds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) node_cpus = cpumask_of_node(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) if (cpumask_weight(node_cpus) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) node_clear_state(node, N_CPU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) struct workqueue_struct *mm_percpu_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) void __init init_mm_internals(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) int ret __maybe_unused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) mm_percpu_wq = alloc_workqueue("mm_percpu_wq", WQ_MEM_RECLAIM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) ret = cpuhp_setup_state_nocalls(CPUHP_MM_VMSTAT_DEAD, "mm/vmstat:dead",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) NULL, vmstat_cpu_dead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) pr_err("vmstat: failed to register 'dead' hotplug state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "mm/vmstat:online",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) vmstat_cpu_online,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) vmstat_cpu_down_prep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) pr_err("vmstat: failed to register 'online' hotplug state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) get_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) init_cpu_node_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) put_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) start_shepherd_timer();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) proc_create_seq("vmstat", 0444, NULL, &vmstat_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_COMPACTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) * Return an index indicating how much of the available free memory is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) * unusable for an allocation of the requested size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) static int unusable_free_index(unsigned int order,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) struct contig_page_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) /* No free memory is interpreted as all free memory is unusable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) if (info->free_pages == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) return 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) * Index should be a value between 0 and 1. Return a value to 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) * decimal places.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) * 0 => no fragmentation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) * 1 => high fragmentation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) return div_u64((info->free_pages - (info->free_blocks_suitable << order)) * 1000ULL, info->free_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) static void unusable_show_print(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) pg_data_t *pgdat, struct zone *zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) unsigned int order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) struct contig_page_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) seq_printf(m, "Node %d, zone %8s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) pgdat->node_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) zone->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) for (order = 0; order < MAX_ORDER; ++order) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) fill_contig_page_info(zone, order, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) index = unusable_free_index(order, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) seq_printf(m, "%d.%03d ", index / 1000, index % 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) * Display unusable free space index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) * The unusable free space index measures how much of the available free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) * memory cannot be used to satisfy an allocation of a given size and is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) * value between 0 and 1. The higher the value, the more of free memory is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) * unusable and by implication, the worse the external fragmentation is. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) * can be expressed as a percentage by multiplying by 100.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) static int unusable_show(struct seq_file *m, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) pg_data_t *pgdat = (pg_data_t *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) /* check memoryless node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) if (!node_state(pgdat->node_id, N_MEMORY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) walk_zones_in_node(m, pgdat, true, false, unusable_show_print);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) static const struct seq_operations unusable_sops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) .start = frag_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) .next = frag_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) .stop = frag_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) .show = unusable_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) DEFINE_SEQ_ATTRIBUTE(unusable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) static void extfrag_show_print(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) pg_data_t *pgdat, struct zone *zone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) unsigned int order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) /* Alloc on stack as interrupts are disabled for zone walk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) struct contig_page_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) seq_printf(m, "Node %d, zone %8s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) pgdat->node_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) zone->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) for (order = 0; order < MAX_ORDER; ++order) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) fill_contig_page_info(zone, order, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) index = __fragmentation_index(order, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) seq_printf(m, "%d.%03d ", index / 1000, index % 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) * Display fragmentation index for orders that allocations would fail for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) static int extfrag_show(struct seq_file *m, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) pg_data_t *pgdat = (pg_data_t *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) walk_zones_in_node(m, pgdat, true, false, extfrag_show_print);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) static const struct seq_operations extfrag_sops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) .start = frag_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) .next = frag_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) .stop = frag_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) .show = extfrag_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) DEFINE_SEQ_ATTRIBUTE(extfrag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) static int __init extfrag_debug_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) struct dentry *extfrag_debug_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) extfrag_debug_root = debugfs_create_dir("extfrag", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) debugfs_create_file("unusable_index", 0444, extfrag_debug_root, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) &unusable_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) debugfs_create_file("extfrag_index", 0444, extfrag_debug_root, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) &extfrag_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) module_init(extfrag_debug_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) #endif