|
@@ -32,6 +32,77 @@
|
|
|
|
|
|
#define NUMA_STATS_THRESHOLD (U16_MAX - 2)
|
|
#define NUMA_STATS_THRESHOLD (U16_MAX - 2)
|
|
|
|
|
|
|
|
+#ifdef CONFIG_NUMA
|
|
|
|
+int sysctl_vm_numa_stat = ENABLE_NUMA_STAT;
|
|
|
|
+
|
|
|
|
+/* zero numa counters within a zone */
|
|
|
|
+static void zero_zone_numa_counters(struct zone *zone)
|
|
|
|
+{
|
|
|
|
+ int item, cpu;
|
|
|
|
+
|
|
|
|
+ for (item = 0; item < NR_VM_NUMA_STAT_ITEMS; item++) {
|
|
|
|
+ atomic_long_set(&zone->vm_numa_stat[item], 0);
|
|
|
|
+ for_each_online_cpu(cpu)
|
|
|
|
+ per_cpu_ptr(zone->pageset, cpu)->vm_numa_stat_diff[item]
|
|
|
|
+ = 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* zero numa counters of all the populated zones */
|
|
|
|
+static void zero_zones_numa_counters(void)
|
|
|
|
+{
|
|
|
|
+ struct zone *zone;
|
|
|
|
+
|
|
|
|
+ for_each_populated_zone(zone)
|
|
|
|
+ zero_zone_numa_counters(zone);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* zero global numa counters */
|
|
|
|
+static void zero_global_numa_counters(void)
|
|
|
|
+{
|
|
|
|
+ int item;
|
|
|
|
+
|
|
|
|
+ for (item = 0; item < NR_VM_NUMA_STAT_ITEMS; item++)
|
|
|
|
+ atomic_long_set(&vm_numa_stat[item], 0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void invalid_numa_statistics(void)
|
|
|
|
+{
|
|
|
|
+ zero_zones_numa_counters();
|
|
|
|
+ zero_global_numa_counters();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static DEFINE_MUTEX(vm_numa_stat_lock);
|
|
|
|
+
|
|
|
|
+int sysctl_vm_numa_stat_handler(struct ctl_table *table, int write,
|
|
|
|
+ void __user *buffer, size_t *length, loff_t *ppos)
|
|
|
|
+{
|
|
|
|
+ int ret, oldval;
|
|
|
|
+
|
|
|
|
+ mutex_lock(&vm_numa_stat_lock);
|
|
|
|
+ if (write)
|
|
|
|
+ oldval = sysctl_vm_numa_stat;
|
|
|
|
+ ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
|
|
|
|
+ if (ret || !write)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ if (oldval == sysctl_vm_numa_stat)
|
|
|
|
+ goto out;
|
|
|
|
+ else if (sysctl_vm_numa_stat == ENABLE_NUMA_STAT) {
|
|
|
|
+ static_branch_enable(&vm_numa_stat_key);
|
|
|
|
+ pr_info("enable numa statistics\n");
|
|
|
|
+ } else {
|
|
|
|
+ static_branch_disable(&vm_numa_stat_key);
|
|
|
|
+ invalid_numa_statistics();
|
|
|
|
+ pr_info("disable numa statistics, and clear numa counters\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+out:
|
|
|
|
+ mutex_unlock(&vm_numa_stat_lock);
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
#ifdef CONFIG_VM_EVENT_COUNTERS
|
|
#ifdef CONFIG_VM_EVENT_COUNTERS
|
|
DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}};
|
|
DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}};
|
|
EXPORT_PER_CPU_SYMBOL(vm_event_states);
|
|
EXPORT_PER_CPU_SYMBOL(vm_event_states);
|