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