1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_VMSTAT_H 3 #define _LINUX_VMSTAT_H 4 5 #include <linux/types.h> 6 #include <linux/percpu.h> 7 #include <linux/mmzone.h> 8 #include <linux/vm_event_item.h> 9 #include <linux/atomic.h> 10 #include <linux/static_key.h> 11 #include <linux/mmdebug.h> 12 13 extern int sysctl_stat_interval; 14 15 #ifdef CONFIG_NUMA 16 #define ENABLE_NUMA_STAT 1 17 #define DISABLE_NUMA_STAT 0 18 extern int sysctl_vm_numa_stat; 19 DECLARE_STATIC_KEY_TRUE(vm_numa_stat_key); 20 int sysctl_vm_numa_stat_handler(const struct ctl_table *table, int write, 21 void *buffer, size_t *length, loff_t *ppos); 22 #endif 23 24 struct reclaim_stat { 25 unsigned nr_dirty; 26 unsigned nr_unqueued_dirty; 27 unsigned nr_congested; 28 unsigned nr_writeback; 29 unsigned nr_immediate; 30 unsigned nr_pageout; 31 unsigned nr_activate[ANON_AND_FILE]; 32 unsigned nr_ref_keep; 33 unsigned nr_unmap_fail; 34 unsigned nr_lazyfree_fail; 35 }; 36 37 /* Stat data for system wide items */ 38 enum vm_stat_item { 39 NR_DIRTY_THRESHOLD, 40 NR_DIRTY_BG_THRESHOLD, 41 NR_VM_STAT_ITEMS, 42 }; 43 44 #ifdef CONFIG_VM_EVENT_COUNTERS 45 /* 46 * Light weight per cpu counter implementation. 47 * 48 * Counters should only be incremented and no critical kernel component 49 * should rely on the counter values. 50 * 51 * Counters are handled completely inline. On many platforms the code 52 * generated will simply be the increment of a global address. 53 */ 54 55 struct vm_event_state { 56 unsigned long event[NR_VM_EVENT_ITEMS]; 57 }; 58 59 DECLARE_PER_CPU(struct vm_event_state, vm_event_states); 60 61 /* 62 * vm counters are allowed to be racy. Use raw_cpu_ops to avoid the 63 * local_irq_disable overhead. 64 */ 65 static inline void __count_vm_event(enum vm_event_item item) 66 { 67 raw_cpu_inc(vm_event_states.event[item]); 68 } 69 70 static inline void count_vm_event(enum vm_event_item item) 71 { 72 this_cpu_inc(vm_event_states.event[item]); 73 } 74 75 static inline void __count_vm_events(enum vm_event_item item, long delta) 76 { 77 raw_cpu_add(vm_event_states.event[item], delta); 78 } 79 80 static inline void count_vm_events(enum vm_event_item item, long delta) 81 { 82 this_cpu_add(vm_event_states.event[item], delta); 83 } 84 85 extern void all_vm_events(unsigned long *); 86 87 extern void vm_events_fold_cpu(int cpu); 88 89 #else 90 91 /* Disable counters */ 92 static inline void count_vm_event(enum vm_event_item item) 93 { 94 } 95 static inline void count_vm_events(enum vm_event_item item, long delta) 96 { 97 } 98 static inline void __count_vm_event(enum vm_event_item item) 99 { 100 } 101 static inline void __count_vm_events(enum vm_event_item item, long delta) 102 { 103 } 104 static inline void all_vm_events(unsigned long *ret) 105 { 106 } 107 static inline void vm_events_fold_cpu(int cpu) 108 { 109 } 110 111 #endif /* CONFIG_VM_EVENT_COUNTERS */ 112 113 #ifdef CONFIG_NUMA_BALANCING 114 #define count_vm_numa_event(x) count_vm_event(x) 115 #define count_vm_numa_events(x, y) count_vm_events(x, y) 116 #else 117 #define count_vm_numa_event(x) do {} while (0) 118 #define count_vm_numa_events(x, y) do { (void)(y); } while (0) 119 #endif /* CONFIG_NUMA_BALANCING */ 120 121 #ifdef CONFIG_DEBUG_TLBFLUSH 122 #define count_vm_tlb_event(x) count_vm_event(x) 123 #define count_vm_tlb_events(x, y) count_vm_events(x, y) 124 #else 125 #define count_vm_tlb_event(x) do {} while (0) 126 #define count_vm_tlb_events(x, y) do { (void)(y); } while (0) 127 #endif 128 129 #ifdef CONFIG_PER_VMA_LOCK_STATS 130 #define count_vm_vma_lock_event(x) count_vm_event(x) 131 #else 132 #define count_vm_vma_lock_event(x) do {} while (0) 133 #endif 134 135 #define __count_zid_vm_events(item, zid, delta) \ 136 __count_vm_events(item##_NORMAL - ZONE_NORMAL + zid, delta) 137 138 /* 139 * Zone and node-based page accounting with per cpu differentials. 140 */ 141 extern atomic_long_t vm_zone_stat[NR_VM_ZONE_STAT_ITEMS]; 142 extern atomic_long_t vm_node_stat[NR_VM_NODE_STAT_ITEMS]; 143 extern atomic_long_t vm_numa_event[NR_VM_NUMA_EVENT_ITEMS]; 144 145 #ifdef CONFIG_NUMA 146 static inline void zone_numa_event_add(long x, struct zone *zone, 147 enum numa_stat_item item) 148 { 149 atomic_long_add(x, &zone->vm_numa_event[item]); 150 atomic_long_add(x, &vm_numa_event[item]); 151 } 152 153 static inline unsigned long zone_numa_event_state(struct zone *zone, 154 enum numa_stat_item item) 155 { 156 return atomic_long_read(&zone->vm_numa_event[item]); 157 } 158 159 static inline unsigned long 160 global_numa_event_state(enum numa_stat_item item) 161 { 162 return atomic_long_read(&vm_numa_event[item]); 163 } 164 #endif /* CONFIG_NUMA */ 165 166 static inline void zone_page_state_add(long x, struct zone *zone, 167 enum zone_stat_item item) 168 { 169 atomic_long_add(x, &zone->vm_stat[item]); 170 atomic_long_add(x, &vm_zone_stat[item]); 171 } 172 173 static inline void node_page_state_add(long x, struct pglist_data *pgdat, 174 enum node_stat_item item) 175 { 176 atomic_long_add(x, &pgdat->vm_stat[item]); 177 atomic_long_add(x, &vm_node_stat[item]); 178 } 179 180 static inline unsigned long global_zone_page_state(enum zone_stat_item item) 181 { 182 long x = atomic_long_read(&vm_zone_stat[item]); 183 #ifdef CONFIG_SMP 184 if (x < 0) 185 x = 0; 186 #endif 187 return x; 188 } 189 190 static inline 191 unsigned long global_node_page_state_pages(enum node_stat_item item) 192 { 193 long x = atomic_long_read(&vm_node_stat[item]); 194 #ifdef CONFIG_SMP 195 if (x < 0) 196 x = 0; 197 #endif 198 return x; 199 } 200 201 static inline unsigned long global_node_page_state(enum node_stat_item item) 202 { 203 VM_WARN_ON_ONCE(vmstat_item_in_bytes(item)); 204 205 return global_node_page_state_pages(item); 206 } 207 208 static inline unsigned long zone_page_state(struct zone *zone, 209 enum zone_stat_item item) 210 { 211 long x = atomic_long_read(&zone->vm_stat[item]); 212 #ifdef CONFIG_SMP 213 if (x < 0) 214 x = 0; 215 #endif 216 return x; 217 } 218 219 /* 220 * More accurate version that also considers the currently pending 221 * deltas. For that we need to loop over all cpus to find the current 222 * deltas. There is no synchronization so the result cannot be 223 * exactly accurate either. 224 */ 225 static inline unsigned long zone_page_state_snapshot(struct zone *zone, 226 enum zone_stat_item item) 227 { 228 long x = atomic_long_read(&zone->vm_stat[item]); 229 230 #ifdef CONFIG_SMP 231 int cpu; 232 for_each_online_cpu(cpu) 233 x += per_cpu_ptr(zone->per_cpu_zonestats, cpu)->vm_stat_diff[item]; 234 235 if (x < 0) 236 x = 0; 237 #endif 238 return x; 239 } 240 241 #ifdef CONFIG_NUMA 242 /* See __count_vm_event comment on why raw_cpu_inc is used. */ 243 static inline void 244 __count_numa_event(struct zone *zone, enum numa_stat_item item) 245 { 246 struct per_cpu_zonestat __percpu *pzstats = zone->per_cpu_zonestats; 247 248 raw_cpu_inc(pzstats->vm_numa_event[item]); 249 } 250 251 static inline void 252 __count_numa_events(struct zone *zone, enum numa_stat_item item, long delta) 253 { 254 struct per_cpu_zonestat __percpu *pzstats = zone->per_cpu_zonestats; 255 256 raw_cpu_add(pzstats->vm_numa_event[item], delta); 257 } 258 259 extern unsigned long sum_zone_node_page_state(int node, 260 enum zone_stat_item item); 261 extern unsigned long sum_zone_numa_event_state(int node, enum numa_stat_item item); 262 extern unsigned long node_page_state(struct pglist_data *pgdat, 263 enum node_stat_item item); 264 extern unsigned long node_page_state_pages(struct pglist_data *pgdat, 265 enum node_stat_item item); 266 extern void fold_vm_numa_events(void); 267 #else 268 #define sum_zone_node_page_state(node, item) global_zone_page_state(item) 269 #define node_page_state(node, item) global_node_page_state(item) 270 #define node_page_state_pages(node, item) global_node_page_state_pages(item) 271 static inline void fold_vm_numa_events(void) 272 { 273 } 274 #endif /* CONFIG_NUMA */ 275 276 #ifdef CONFIG_SMP 277 void __mod_zone_page_state(struct zone *, enum zone_stat_item item, long); 278 void __inc_zone_page_state(struct page *, enum zone_stat_item); 279 void __dec_zone_page_state(struct page *, enum zone_stat_item); 280 281 void __mod_node_page_state(struct pglist_data *, enum node_stat_item item, long); 282 void __inc_node_page_state(struct page *, enum node_stat_item); 283 void __dec_node_page_state(struct page *, enum node_stat_item); 284 285 void mod_zone_page_state(struct zone *, enum zone_stat_item, long); 286 void inc_zone_page_state(struct page *, enum zone_stat_item); 287 void dec_zone_page_state(struct page *, enum zone_stat_item); 288 289 void mod_node_page_state(struct pglist_data *, enum node_stat_item, long); 290 void inc_node_page_state(struct page *, enum node_stat_item); 291 void dec_node_page_state(struct page *, enum node_stat_item); 292 293 extern void inc_node_state(struct pglist_data *, enum node_stat_item); 294 extern void __inc_zone_state(struct zone *, enum zone_stat_item); 295 extern void __inc_node_state(struct pglist_data *, enum node_stat_item); 296 extern void dec_zone_state(struct zone *, enum zone_stat_item); 297 extern void __dec_zone_state(struct zone *, enum zone_stat_item); 298 extern void __dec_node_state(struct pglist_data *, enum node_stat_item); 299 300 void quiet_vmstat(void); 301 void cpu_vm_stats_fold(int cpu); 302 void refresh_zone_stat_thresholds(void); 303 304 struct ctl_table; 305 int vmstat_refresh(const struct ctl_table *, int write, void *buffer, size_t *lenp, 306 loff_t *ppos); 307 308 void drain_zonestat(struct zone *zone, struct per_cpu_zonestat *); 309 310 int calculate_pressure_threshold(struct zone *zone); 311 int calculate_normal_threshold(struct zone *zone); 312 void set_pgdat_percpu_threshold(pg_data_t *pgdat, 313 int (*calculate_pressure)(struct zone *)); 314 #else /* CONFIG_SMP */ 315 316 /* 317 * We do not maintain differentials in a single processor configuration. 318 * The functions directly modify the zone and global counters. 319 */ 320 static inline void __mod_zone_page_state(struct zone *zone, 321 enum zone_stat_item item, long delta) 322 { 323 zone_page_state_add(delta, zone, item); 324 } 325 326 static inline void __mod_node_page_state(struct pglist_data *pgdat, 327 enum node_stat_item item, int delta) 328 { 329 if (vmstat_item_in_bytes(item)) { 330 /* 331 * Only cgroups use subpage accounting right now; at 332 * the global level, these items still change in 333 * multiples of whole pages. Store them as pages 334 * internally to keep the per-cpu counters compact. 335 */ 336 VM_WARN_ON_ONCE(delta & (PAGE_SIZE - 1)); 337 delta >>= PAGE_SHIFT; 338 } 339 340 node_page_state_add(delta, pgdat, item); 341 } 342 343 static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) 344 { 345 atomic_long_inc(&zone->vm_stat[item]); 346 atomic_long_inc(&vm_zone_stat[item]); 347 } 348 349 static inline void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item) 350 { 351 atomic_long_inc(&pgdat->vm_stat[item]); 352 atomic_long_inc(&vm_node_stat[item]); 353 } 354 355 static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) 356 { 357 atomic_long_dec(&zone->vm_stat[item]); 358 atomic_long_dec(&vm_zone_stat[item]); 359 } 360 361 static inline void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item) 362 { 363 atomic_long_dec(&pgdat->vm_stat[item]); 364 atomic_long_dec(&vm_node_stat[item]); 365 } 366 367 static inline void __inc_zone_page_state(struct page *page, 368 enum zone_stat_item item) 369 { 370 __inc_zone_state(page_zone(page), item); 371 } 372 373 static inline void __inc_node_page_state(struct page *page, 374 enum node_stat_item item) 375 { 376 __inc_node_state(page_pgdat(page), item); 377 } 378 379 380 static inline void __dec_zone_page_state(struct page *page, 381 enum zone_stat_item item) 382 { 383 __dec_zone_state(page_zone(page), item); 384 } 385 386 static inline void __dec_node_page_state(struct page *page, 387 enum node_stat_item item) 388 { 389 __dec_node_state(page_pgdat(page), item); 390 } 391 392 393 /* 394 * We only use atomic operations to update counters. So there is no need to 395 * disable interrupts. 396 */ 397 #define inc_zone_page_state __inc_zone_page_state 398 #define dec_zone_page_state __dec_zone_page_state 399 #define mod_zone_page_state __mod_zone_page_state 400 401 #define inc_node_page_state __inc_node_page_state 402 #define dec_node_page_state __dec_node_page_state 403 #define mod_node_page_state __mod_node_page_state 404 405 #define inc_zone_state __inc_zone_state 406 #define inc_node_state __inc_node_state 407 #define dec_zone_state __dec_zone_state 408 409 #define set_pgdat_percpu_threshold(pgdat, callback) { } 410 411 static inline void refresh_zone_stat_thresholds(void) { } 412 static inline void cpu_vm_stats_fold(int cpu) { } 413 static inline void quiet_vmstat(void) { } 414 415 static inline void drain_zonestat(struct zone *zone, 416 struct per_cpu_zonestat *pzstats) { } 417 #endif /* CONFIG_SMP */ 418 419 static inline void __zone_stat_mod_folio(struct folio *folio, 420 enum zone_stat_item item, long nr) 421 { 422 __mod_zone_page_state(folio_zone(folio), item, nr); 423 } 424 425 static inline void __zone_stat_add_folio(struct folio *folio, 426 enum zone_stat_item item) 427 { 428 __mod_zone_page_state(folio_zone(folio), item, folio_nr_pages(folio)); 429 } 430 431 static inline void __zone_stat_sub_folio(struct folio *folio, 432 enum zone_stat_item item) 433 { 434 __mod_zone_page_state(folio_zone(folio), item, -folio_nr_pages(folio)); 435 } 436 437 static inline void zone_stat_mod_folio(struct folio *folio, 438 enum zone_stat_item item, long nr) 439 { 440 mod_zone_page_state(folio_zone(folio), item, nr); 441 } 442 443 static inline void zone_stat_add_folio(struct folio *folio, 444 enum zone_stat_item item) 445 { 446 mod_zone_page_state(folio_zone(folio), item, folio_nr_pages(folio)); 447 } 448 449 static inline void zone_stat_sub_folio(struct folio *folio, 450 enum zone_stat_item item) 451 { 452 mod_zone_page_state(folio_zone(folio), item, -folio_nr_pages(folio)); 453 } 454 455 static inline void __node_stat_mod_folio(struct folio *folio, 456 enum node_stat_item item, long nr) 457 { 458 __mod_node_page_state(folio_pgdat(folio), item, nr); 459 } 460 461 static inline void __node_stat_add_folio(struct folio *folio, 462 enum node_stat_item item) 463 { 464 __mod_node_page_state(folio_pgdat(folio), item, folio_nr_pages(folio)); 465 } 466 467 static inline void __node_stat_sub_folio(struct folio *folio, 468 enum node_stat_item item) 469 { 470 __mod_node_page_state(folio_pgdat(folio), item, -folio_nr_pages(folio)); 471 } 472 473 static inline void node_stat_mod_folio(struct folio *folio, 474 enum node_stat_item item, long nr) 475 { 476 mod_node_page_state(folio_pgdat(folio), item, nr); 477 } 478 479 static inline void node_stat_add_folio(struct folio *folio, 480 enum node_stat_item item) 481 { 482 mod_node_page_state(folio_pgdat(folio), item, folio_nr_pages(folio)); 483 } 484 485 static inline void node_stat_sub_folio(struct folio *folio, 486 enum node_stat_item item) 487 { 488 mod_node_page_state(folio_pgdat(folio), item, -folio_nr_pages(folio)); 489 } 490 491 extern const char * const vmstat_text[]; 492 493 static inline const char *zone_stat_name(enum zone_stat_item item) 494 { 495 return vmstat_text[item]; 496 } 497 498 #ifdef CONFIG_NUMA 499 static inline const char *numa_stat_name(enum numa_stat_item item) 500 { 501 return vmstat_text[NR_VM_ZONE_STAT_ITEMS + 502 item]; 503 } 504 #endif /* CONFIG_NUMA */ 505 506 static inline const char *node_stat_name(enum node_stat_item item) 507 { 508 return vmstat_text[NR_VM_ZONE_STAT_ITEMS + 509 NR_VM_NUMA_EVENT_ITEMS + 510 item]; 511 } 512 513 static inline const char *lru_list_name(enum lru_list lru) 514 { 515 return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" 516 } 517 518 #if defined(CONFIG_VM_EVENT_COUNTERS) || defined(CONFIG_MEMCG) 519 static inline const char *vm_event_name(enum vm_event_item item) 520 { 521 return vmstat_text[NR_VM_ZONE_STAT_ITEMS + 522 NR_VM_NUMA_EVENT_ITEMS + 523 NR_VM_NODE_STAT_ITEMS + 524 NR_VM_STAT_ITEMS + 525 item]; 526 } 527 #endif /* CONFIG_VM_EVENT_COUNTERS || CONFIG_MEMCG */ 528 529 #ifdef CONFIG_MEMCG 530 531 void __mod_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx, 532 int val); 533 534 static inline void mod_lruvec_state(struct lruvec *lruvec, 535 enum node_stat_item idx, int val) 536 { 537 unsigned long flags; 538 539 local_irq_save(flags); 540 __mod_lruvec_state(lruvec, idx, val); 541 local_irq_restore(flags); 542 } 543 544 void __lruvec_stat_mod_folio(struct folio *folio, 545 enum node_stat_item idx, int val); 546 547 static inline void lruvec_stat_mod_folio(struct folio *folio, 548 enum node_stat_item idx, int val) 549 { 550 unsigned long flags; 551 552 local_irq_save(flags); 553 __lruvec_stat_mod_folio(folio, idx, val); 554 local_irq_restore(flags); 555 } 556 557 static inline void mod_lruvec_page_state(struct page *page, 558 enum node_stat_item idx, int val) 559 { 560 lruvec_stat_mod_folio(page_folio(page), idx, val); 561 } 562 563 #else 564 565 static inline void __mod_lruvec_state(struct lruvec *lruvec, 566 enum node_stat_item idx, int val) 567 { 568 __mod_node_page_state(lruvec_pgdat(lruvec), idx, val); 569 } 570 571 static inline void mod_lruvec_state(struct lruvec *lruvec, 572 enum node_stat_item idx, int val) 573 { 574 mod_node_page_state(lruvec_pgdat(lruvec), idx, val); 575 } 576 577 static inline void __lruvec_stat_mod_folio(struct folio *folio, 578 enum node_stat_item idx, int val) 579 { 580 __mod_node_page_state(folio_pgdat(folio), idx, val); 581 } 582 583 static inline void lruvec_stat_mod_folio(struct folio *folio, 584 enum node_stat_item idx, int val) 585 { 586 mod_node_page_state(folio_pgdat(folio), idx, val); 587 } 588 589 static inline void mod_lruvec_page_state(struct page *page, 590 enum node_stat_item idx, int val) 591 { 592 mod_node_page_state(page_pgdat(page), idx, val); 593 } 594 595 #endif /* CONFIG_MEMCG */ 596 597 static inline void __lruvec_stat_add_folio(struct folio *folio, 598 enum node_stat_item idx) 599 { 600 __lruvec_stat_mod_folio(folio, idx, folio_nr_pages(folio)); 601 } 602 603 static inline void __lruvec_stat_sub_folio(struct folio *folio, 604 enum node_stat_item idx) 605 { 606 __lruvec_stat_mod_folio(folio, idx, -folio_nr_pages(folio)); 607 } 608 609 static inline void lruvec_stat_add_folio(struct folio *folio, 610 enum node_stat_item idx) 611 { 612 lruvec_stat_mod_folio(folio, idx, folio_nr_pages(folio)); 613 } 614 615 static inline void lruvec_stat_sub_folio(struct folio *folio, 616 enum node_stat_item idx) 617 { 618 lruvec_stat_mod_folio(folio, idx, -folio_nr_pages(folio)); 619 } 620 621 void __meminit mod_node_early_perpage_metadata(int nid, long delta); 622 void __meminit store_early_perpage_metadata(void); 623 624 #endif /* _LINUX_VMSTAT_H */ 625