1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #undef TRACE_SYSTEM 3 #define TRACE_SYSTEM vmscan 4 5 #if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) 6 #define _TRACE_VMSCAN_H 7 8 #include <linux/types.h> 9 #include <linux/tracepoint.h> 10 #include <linux/mm.h> 11 #include <linux/memcontrol.h> 12 #include <trace/events/mmflags.h> 13 14 #define RECLAIM_WB_ANON 0x0001u 15 #define RECLAIM_WB_FILE 0x0002u 16 #define RECLAIM_WB_MIXED 0x0010u 17 #define RECLAIM_WB_SYNC 0x0004u /* Unused, all reclaim async */ 18 #define RECLAIM_WB_ASYNC 0x0008u 19 #define RECLAIM_WB_LRU (RECLAIM_WB_ANON|RECLAIM_WB_FILE) 20 21 #define show_reclaim_flags(flags) \ 22 (flags) ? __print_flags(flags, "|", \ 23 {RECLAIM_WB_ANON, "RECLAIM_WB_ANON"}, \ 24 {RECLAIM_WB_FILE, "RECLAIM_WB_FILE"}, \ 25 {RECLAIM_WB_MIXED, "RECLAIM_WB_MIXED"}, \ 26 {RECLAIM_WB_SYNC, "RECLAIM_WB_SYNC"}, \ 27 {RECLAIM_WB_ASYNC, "RECLAIM_WB_ASYNC"} \ 28 ) : "RECLAIM_WB_NONE" 29 30 #define _VMSCAN_THROTTLE_WRITEBACK (1 << VMSCAN_THROTTLE_WRITEBACK) 31 #define _VMSCAN_THROTTLE_ISOLATED (1 << VMSCAN_THROTTLE_ISOLATED) 32 #define _VMSCAN_THROTTLE_NOPROGRESS (1 << VMSCAN_THROTTLE_NOPROGRESS) 33 #define _VMSCAN_THROTTLE_CONGESTED (1 << VMSCAN_THROTTLE_CONGESTED) 34 35 #define show_throttle_flags(flags) \ 36 (flags) ? __print_flags(flags, "|", \ 37 {_VMSCAN_THROTTLE_WRITEBACK, "VMSCAN_THROTTLE_WRITEBACK"}, \ 38 {_VMSCAN_THROTTLE_ISOLATED, "VMSCAN_THROTTLE_ISOLATED"}, \ 39 {_VMSCAN_THROTTLE_NOPROGRESS, "VMSCAN_THROTTLE_NOPROGRESS"}, \ 40 {_VMSCAN_THROTTLE_CONGESTED, "VMSCAN_THROTTLE_CONGESTED"} \ 41 ) : "VMSCAN_THROTTLE_NONE" 42 43 TRACE_DEFINE_ENUM(KSWAPD_CLEAR_HOPELESS_OTHER); 44 TRACE_DEFINE_ENUM(KSWAPD_CLEAR_HOPELESS_KSWAPD); 45 TRACE_DEFINE_ENUM(KSWAPD_CLEAR_HOPELESS_DIRECT); 46 TRACE_DEFINE_ENUM(KSWAPD_CLEAR_HOPELESS_PCP); 47 48 #define kswapd_clear_hopeless_reason_ops \ 49 {KSWAPD_CLEAR_HOPELESS_KSWAPD, "KSWAPD"}, \ 50 {KSWAPD_CLEAR_HOPELESS_DIRECT, "DIRECT"}, \ 51 {KSWAPD_CLEAR_HOPELESS_PCP, "PCP"}, \ 52 {KSWAPD_CLEAR_HOPELESS_OTHER, "OTHER"} 53 54 #define trace_reclaim_flags(file) ( \ 55 (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ 56 (RECLAIM_WB_ASYNC) \ 57 ) 58 59 TRACE_EVENT(mm_vmscan_kswapd_sleep, 60 61 TP_PROTO(int nid), 62 63 TP_ARGS(nid), 64 65 TP_STRUCT__entry( 66 __field( int, nid ) 67 ), 68 69 TP_fast_assign( 70 __entry->nid = nid; 71 ), 72 73 TP_printk("nid=%d", __entry->nid) 74 ); 75 76 TRACE_EVENT(mm_vmscan_kswapd_wake, 77 78 TP_PROTO(int nid, int zid, int order), 79 80 TP_ARGS(nid, zid, order), 81 82 TP_STRUCT__entry( 83 __field( int, nid ) 84 __field( int, zid ) 85 __field( int, order ) 86 ), 87 88 TP_fast_assign( 89 __entry->nid = nid; 90 __entry->zid = zid; 91 __entry->order = order; 92 ), 93 94 TP_printk("nid=%d order=%d", 95 __entry->nid, 96 __entry->order) 97 ); 98 99 TRACE_EVENT(mm_vmscan_wakeup_kswapd, 100 101 TP_PROTO(int nid, int zid, int order, gfp_t gfp_flags), 102 103 TP_ARGS(nid, zid, order, gfp_flags), 104 105 TP_STRUCT__entry( 106 __field( int, nid ) 107 __field( int, zid ) 108 __field( int, order ) 109 __field( unsigned long, gfp_flags ) 110 ), 111 112 TP_fast_assign( 113 __entry->nid = nid; 114 __entry->zid = zid; 115 __entry->order = order; 116 __entry->gfp_flags = (__force unsigned long)gfp_flags; 117 ), 118 119 TP_printk("nid=%d order=%d gfp_flags=%s", 120 __entry->nid, 121 __entry->order, 122 show_gfp_flags(__entry->gfp_flags)) 123 ); 124 125 DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, 126 127 TP_PROTO(int order, gfp_t gfp_flags), 128 129 TP_ARGS(order, gfp_flags), 130 131 TP_STRUCT__entry( 132 __field( int, order ) 133 __field( unsigned long, gfp_flags ) 134 ), 135 136 TP_fast_assign( 137 __entry->order = order; 138 __entry->gfp_flags = (__force unsigned long)gfp_flags; 139 ), 140 141 TP_printk("order=%d gfp_flags=%s", 142 __entry->order, 143 show_gfp_flags(__entry->gfp_flags)) 144 ); 145 146 DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin, 147 148 TP_PROTO(int order, gfp_t gfp_flags), 149 150 TP_ARGS(order, gfp_flags) 151 ); 152 153 #ifdef CONFIG_MEMCG 154 DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin, 155 156 TP_PROTO(int order, gfp_t gfp_flags), 157 158 TP_ARGS(order, gfp_flags) 159 ); 160 161 DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin, 162 163 TP_PROTO(int order, gfp_t gfp_flags), 164 165 TP_ARGS(order, gfp_flags) 166 ); 167 #endif /* CONFIG_MEMCG */ 168 169 DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, 170 171 TP_PROTO(unsigned long nr_reclaimed), 172 173 TP_ARGS(nr_reclaimed), 174 175 TP_STRUCT__entry( 176 __field( unsigned long, nr_reclaimed ) 177 ), 178 179 TP_fast_assign( 180 __entry->nr_reclaimed = nr_reclaimed; 181 ), 182 183 TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) 184 ); 185 186 DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_direct_reclaim_end, 187 188 TP_PROTO(unsigned long nr_reclaimed), 189 190 TP_ARGS(nr_reclaimed) 191 ); 192 193 #ifdef CONFIG_MEMCG 194 DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end, 195 196 TP_PROTO(unsigned long nr_reclaimed), 197 198 TP_ARGS(nr_reclaimed) 199 ); 200 201 DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end, 202 203 TP_PROTO(unsigned long nr_reclaimed), 204 205 TP_ARGS(nr_reclaimed) 206 ); 207 #endif /* CONFIG_MEMCG */ 208 209 TRACE_EVENT(mm_shrink_slab_start, 210 TP_PROTO(struct shrinker *shr, struct shrink_control *sc, 211 long nr_objects_to_shrink, unsigned long cache_items, 212 unsigned long long delta, unsigned long total_scan, 213 int priority), 214 215 TP_ARGS(shr, sc, nr_objects_to_shrink, cache_items, delta, total_scan, 216 priority), 217 218 TP_STRUCT__entry( 219 __field(struct shrinker *, shr) 220 __field(void *, shrink) 221 __field(int, nid) 222 __field(long, nr_objects_to_shrink) 223 __field(unsigned long, gfp_flags) 224 __field(unsigned long, cache_items) 225 __field(unsigned long long, delta) 226 __field(unsigned long, total_scan) 227 __field(int, priority) 228 ), 229 230 TP_fast_assign( 231 __entry->shr = shr; 232 __entry->shrink = shr->scan_objects; 233 __entry->nid = sc->nid; 234 __entry->nr_objects_to_shrink = nr_objects_to_shrink; 235 __entry->gfp_flags = (__force unsigned long)sc->gfp_mask; 236 __entry->cache_items = cache_items; 237 __entry->delta = delta; 238 __entry->total_scan = total_scan; 239 __entry->priority = priority; 240 ), 241 242 TP_printk("%pS %p: nid: %d objects to shrink %ld gfp_flags %s cache items %ld delta %lld total_scan %ld priority %d", 243 __entry->shrink, 244 __entry->shr, 245 __entry->nid, 246 __entry->nr_objects_to_shrink, 247 show_gfp_flags(__entry->gfp_flags), 248 __entry->cache_items, 249 __entry->delta, 250 __entry->total_scan, 251 __entry->priority) 252 ); 253 254 TRACE_EVENT(mm_shrink_slab_end, 255 TP_PROTO(struct shrinker *shr, int nid, int shrinker_retval, 256 long unused_scan_cnt, long new_scan_cnt, long total_scan), 257 258 TP_ARGS(shr, nid, shrinker_retval, unused_scan_cnt, new_scan_cnt, 259 total_scan), 260 261 TP_STRUCT__entry( 262 __field(struct shrinker *, shr) 263 __field(int, nid) 264 __field(void *, shrink) 265 __field(long, unused_scan) 266 __field(long, new_scan) 267 __field(int, retval) 268 __field(long, total_scan) 269 ), 270 271 TP_fast_assign( 272 __entry->shr = shr; 273 __entry->nid = nid; 274 __entry->shrink = shr->scan_objects; 275 __entry->unused_scan = unused_scan_cnt; 276 __entry->new_scan = new_scan_cnt; 277 __entry->retval = shrinker_retval; 278 __entry->total_scan = total_scan; 279 ), 280 281 TP_printk("%pS %p: nid: %d unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", 282 __entry->shrink, 283 __entry->shr, 284 __entry->nid, 285 __entry->unused_scan, 286 __entry->new_scan, 287 __entry->total_scan, 288 __entry->retval) 289 ); 290 291 TRACE_EVENT(mm_vmscan_lru_isolate, 292 TP_PROTO(int highest_zoneidx, 293 int order, 294 unsigned long nr_requested, 295 unsigned long nr_scanned, 296 unsigned long nr_skipped, 297 unsigned long nr_taken, 298 int lru), 299 300 TP_ARGS(highest_zoneidx, order, nr_requested, nr_scanned, nr_skipped, nr_taken, lru), 301 302 TP_STRUCT__entry( 303 __field(int, highest_zoneidx) 304 __field(int, order) 305 __field(unsigned long, nr_requested) 306 __field(unsigned long, nr_scanned) 307 __field(unsigned long, nr_skipped) 308 __field(unsigned long, nr_taken) 309 __field(int, lru) 310 ), 311 312 TP_fast_assign( 313 __entry->highest_zoneidx = highest_zoneidx; 314 __entry->order = order; 315 __entry->nr_requested = nr_requested; 316 __entry->nr_scanned = nr_scanned; 317 __entry->nr_skipped = nr_skipped; 318 __entry->nr_taken = nr_taken; 319 __entry->lru = lru; 320 ), 321 322 /* 323 * classzone is previous name of the highest_zoneidx. 324 * Reason not to change it is the ABI requirement of the tracepoint. 325 */ 326 TP_printk("classzone=%d order=%d nr_requested=%lu nr_scanned=%lu nr_skipped=%lu nr_taken=%lu lru=%s", 327 __entry->highest_zoneidx, 328 __entry->order, 329 __entry->nr_requested, 330 __entry->nr_scanned, 331 __entry->nr_skipped, 332 __entry->nr_taken, 333 __print_symbolic(__entry->lru, LRU_NAMES)) 334 ); 335 336 TRACE_EVENT(mm_vmscan_write_folio, 337 338 TP_PROTO(struct folio *folio), 339 340 TP_ARGS(folio), 341 342 TP_STRUCT__entry( 343 __field(unsigned long, pfn) 344 __field(int, reclaim_flags) 345 ), 346 347 TP_fast_assign( 348 __entry->pfn = folio_pfn(folio); 349 __entry->reclaim_flags = trace_reclaim_flags( 350 folio_is_file_lru(folio)); 351 ), 352 353 TP_printk("page=%p pfn=0x%lx flags=%s", 354 pfn_to_page(__entry->pfn), 355 __entry->pfn, 356 show_reclaim_flags(__entry->reclaim_flags)) 357 ); 358 359 TRACE_EVENT(mm_vmscan_reclaim_pages, 360 361 TP_PROTO(int nid, 362 unsigned long nr_scanned, unsigned long nr_reclaimed, 363 struct reclaim_stat *stat), 364 365 TP_ARGS(nid, nr_scanned, nr_reclaimed, stat), 366 367 TP_STRUCT__entry( 368 __field(int, nid) 369 __field(unsigned long, nr_scanned) 370 __field(unsigned long, nr_reclaimed) 371 __field(unsigned long, nr_dirty) 372 __field(unsigned long, nr_writeback) 373 __field(unsigned long, nr_congested) 374 __field(unsigned long, nr_immediate) 375 __field(unsigned int, nr_activate0) 376 __field(unsigned int, nr_activate1) 377 __field(unsigned long, nr_ref_keep) 378 __field(unsigned long, nr_unmap_fail) 379 ), 380 381 TP_fast_assign( 382 __entry->nid = nid; 383 __entry->nr_scanned = nr_scanned; 384 __entry->nr_reclaimed = nr_reclaimed; 385 __entry->nr_dirty = stat->nr_dirty; 386 __entry->nr_writeback = stat->nr_writeback; 387 __entry->nr_congested = stat->nr_congested; 388 __entry->nr_immediate = stat->nr_immediate; 389 __entry->nr_activate0 = stat->nr_activate[0]; 390 __entry->nr_activate1 = stat->nr_activate[1]; 391 __entry->nr_ref_keep = stat->nr_ref_keep; 392 __entry->nr_unmap_fail = stat->nr_unmap_fail; 393 ), 394 395 TP_printk("nid=%d nr_scanned=%ld nr_reclaimed=%ld nr_dirty=%ld nr_writeback=%ld nr_congested=%ld nr_immediate=%ld nr_activate_anon=%d nr_activate_file=%d nr_ref_keep=%ld nr_unmap_fail=%ld", 396 __entry->nid, 397 __entry->nr_scanned, __entry->nr_reclaimed, 398 __entry->nr_dirty, __entry->nr_writeback, 399 __entry->nr_congested, __entry->nr_immediate, 400 __entry->nr_activate0, __entry->nr_activate1, 401 __entry->nr_ref_keep, __entry->nr_unmap_fail) 402 ); 403 404 TRACE_EVENT(mm_vmscan_lru_shrink_inactive, 405 406 TP_PROTO(int nid, 407 unsigned long nr_scanned, unsigned long nr_reclaimed, 408 struct reclaim_stat *stat, int priority, int file), 409 410 TP_ARGS(nid, nr_scanned, nr_reclaimed, stat, priority, file), 411 412 TP_STRUCT__entry( 413 __field(int, nid) 414 __field(unsigned long, nr_scanned) 415 __field(unsigned long, nr_reclaimed) 416 __field(unsigned long, nr_dirty) 417 __field(unsigned long, nr_writeback) 418 __field(unsigned long, nr_congested) 419 __field(unsigned long, nr_immediate) 420 __field(unsigned int, nr_activate0) 421 __field(unsigned int, nr_activate1) 422 __field(unsigned long, nr_ref_keep) 423 __field(unsigned long, nr_unmap_fail) 424 __field(int, priority) 425 __field(int, reclaim_flags) 426 ), 427 428 TP_fast_assign( 429 __entry->nid = nid; 430 __entry->nr_scanned = nr_scanned; 431 __entry->nr_reclaimed = nr_reclaimed; 432 __entry->nr_dirty = stat->nr_dirty; 433 __entry->nr_writeback = stat->nr_writeback; 434 __entry->nr_congested = stat->nr_congested; 435 __entry->nr_immediate = stat->nr_immediate; 436 __entry->nr_activate0 = stat->nr_activate[0]; 437 __entry->nr_activate1 = stat->nr_activate[1]; 438 __entry->nr_ref_keep = stat->nr_ref_keep; 439 __entry->nr_unmap_fail = stat->nr_unmap_fail; 440 __entry->priority = priority; 441 __entry->reclaim_flags = trace_reclaim_flags(file); 442 ), 443 444 TP_printk("nid=%d nr_scanned=%ld nr_reclaimed=%ld nr_dirty=%ld nr_writeback=%ld nr_congested=%ld nr_immediate=%ld nr_activate_anon=%d nr_activate_file=%d nr_ref_keep=%ld nr_unmap_fail=%ld priority=%d flags=%s", 445 __entry->nid, 446 __entry->nr_scanned, __entry->nr_reclaimed, 447 __entry->nr_dirty, __entry->nr_writeback, 448 __entry->nr_congested, __entry->nr_immediate, 449 __entry->nr_activate0, __entry->nr_activate1, 450 __entry->nr_ref_keep, __entry->nr_unmap_fail, 451 __entry->priority, 452 show_reclaim_flags(__entry->reclaim_flags)) 453 ); 454 455 TRACE_EVENT(mm_vmscan_lru_shrink_active, 456 457 TP_PROTO(int nid, unsigned long nr_taken, 458 unsigned long nr_active, unsigned long nr_deactivated, 459 unsigned long nr_referenced, int priority, int file), 460 461 TP_ARGS(nid, nr_taken, nr_active, nr_deactivated, nr_referenced, priority, file), 462 463 TP_STRUCT__entry( 464 __field(int, nid) 465 __field(unsigned long, nr_taken) 466 __field(unsigned long, nr_active) 467 __field(unsigned long, nr_deactivated) 468 __field(unsigned long, nr_referenced) 469 __field(int, priority) 470 __field(int, reclaim_flags) 471 ), 472 473 TP_fast_assign( 474 __entry->nid = nid; 475 __entry->nr_taken = nr_taken; 476 __entry->nr_active = nr_active; 477 __entry->nr_deactivated = nr_deactivated; 478 __entry->nr_referenced = nr_referenced; 479 __entry->priority = priority; 480 __entry->reclaim_flags = trace_reclaim_flags(file); 481 ), 482 483 TP_printk("nid=%d nr_taken=%ld nr_active=%ld nr_deactivated=%ld nr_referenced=%ld priority=%d flags=%s", 484 __entry->nid, 485 __entry->nr_taken, 486 __entry->nr_active, __entry->nr_deactivated, __entry->nr_referenced, 487 __entry->priority, 488 show_reclaim_flags(__entry->reclaim_flags)) 489 ); 490 491 TRACE_EVENT(mm_vmscan_node_reclaim_begin, 492 493 TP_PROTO(int nid, int order, gfp_t gfp_flags), 494 495 TP_ARGS(nid, order, gfp_flags), 496 497 TP_STRUCT__entry( 498 __field(int, nid) 499 __field(int, order) 500 __field(unsigned long, gfp_flags) 501 ), 502 503 TP_fast_assign( 504 __entry->nid = nid; 505 __entry->order = order; 506 __entry->gfp_flags = (__force unsigned long)gfp_flags; 507 ), 508 509 TP_printk("nid=%d order=%d gfp_flags=%s", 510 __entry->nid, 511 __entry->order, 512 show_gfp_flags(__entry->gfp_flags)) 513 ); 514 515 DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_node_reclaim_end, 516 517 TP_PROTO(unsigned long nr_reclaimed), 518 519 TP_ARGS(nr_reclaimed) 520 ); 521 522 TRACE_EVENT(mm_vmscan_throttled, 523 524 TP_PROTO(int nid, int usec_timeout, int usec_delayed, int reason), 525 526 TP_ARGS(nid, usec_timeout, usec_delayed, reason), 527 528 TP_STRUCT__entry( 529 __field(int, nid) 530 __field(int, usec_timeout) 531 __field(int, usec_delayed) 532 __field(int, reason) 533 ), 534 535 TP_fast_assign( 536 __entry->nid = nid; 537 __entry->usec_timeout = usec_timeout; 538 __entry->usec_delayed = usec_delayed; 539 __entry->reason = 1U << reason; 540 ), 541 542 TP_printk("nid=%d usec_timeout=%d usect_delayed=%d reason=%s", 543 __entry->nid, 544 __entry->usec_timeout, 545 __entry->usec_delayed, 546 show_throttle_flags(__entry->reason)) 547 ); 548 549 TRACE_EVENT(mm_vmscan_kswapd_reclaim_fail, 550 551 TP_PROTO(int nid, int failures), 552 553 TP_ARGS(nid, failures), 554 555 TP_STRUCT__entry( 556 __field(int, nid) 557 __field(int, failures) 558 ), 559 560 TP_fast_assign( 561 __entry->nid = nid; 562 __entry->failures = failures; 563 ), 564 565 TP_printk("nid=%d failures=%d", 566 __entry->nid, __entry->failures) 567 ); 568 569 TRACE_EVENT(mm_vmscan_kswapd_clear_hopeless, 570 571 TP_PROTO(int nid, int reason), 572 573 TP_ARGS(nid, reason), 574 575 TP_STRUCT__entry( 576 __field(int, nid) 577 __field(int, reason) 578 ), 579 580 TP_fast_assign( 581 __entry->nid = nid; 582 __entry->reason = reason; 583 ), 584 585 TP_printk("nid=%d reason=%s", 586 __entry->nid, 587 __print_symbolic(__entry->reason, kswapd_clear_hopeless_reason_ops)) 588 ); 589 #endif /* _TRACE_VMSCAN_H */ 590 591 /* This part must be outside protection */ 592 #include <trace/define_trace.h> 593