| 1 |
|
| 2 | #undef TRACE_SYSTEM
|
| 3 | #define TRACE_SYSTEM writeback
|
| 4 |
|
| 5 | #if !defined(_TRACE_WRITEBACK_H) || defined(TRACE_HEADER_MULTI_READ)
|
| 6 | #define _TRACE_WRITEBACK_H
|
| 7 |
|
| 8 | #include <linux/tracepoint.h>
|
| 9 | #include <linux/backing-dev.h>
|
| 10 | #include <linux/writeback.h>
|
| 11 |
|
| 12 | #define show_inode_state(state) \
|
| 13 | __print_flags(state, "|", \
|
| 14 | {I_DIRTY_SYNC, "I_DIRTY_SYNC"}, \
|
| 15 | {I_DIRTY_DATASYNC, "I_DIRTY_DATASYNC"}, \
|
| 16 | {I_DIRTY_PAGES, "I_DIRTY_PAGES"}, \
|
| 17 | {I_NEW, "I_NEW"}, \
|
| 18 | {I_WILL_FREE, "I_WILL_FREE"}, \
|
| 19 | {I_FREEING, "I_FREEING"}, \
|
| 20 | {I_CLEAR, "I_CLEAR"}, \
|
| 21 | {I_SYNC, "I_SYNC"}, \
|
| 22 | {I_DIRTY_TIME, "I_DIRTY_TIME"}, \
|
| 23 | {I_REFERENCED, "I_REFERENCED"}, \
|
| 24 | {I_LINKABLE, "I_LINKABLE"}, \
|
| 25 | {I_WB_SWITCH, "I_WB_SWITCH"}, \
|
| 26 | {I_OVL_INUSE, "I_OVL_INUSE"}, \
|
| 27 | {I_CREATING, "I_CREATING"}, \
|
| 28 | {I_DONTCACHE, "I_DONTCACHE"}, \
|
| 29 | {I_SYNC_QUEUED, "I_SYNC_QUEUED"}, \
|
| 30 | {I_PINNING_NETFS_WB, "I_PINNING_NETFS_WB"}, \
|
| 31 | {I_LRU_ISOLATING, "I_LRU_ISOLATING"} \
|
| 32 | )
|
| 33 |
|
| 34 |
|
| 35 | #undef EM
|
| 36 | #undef EMe
|
| 37 | #define EM(a,b) TRACE_DEFINE_ENUM(a);
|
| 38 | #define EMe(a,b) TRACE_DEFINE_ENUM(a);
|
| 39 |
|
| 40 | #define WB_WORK_REASON \
|
| 41 | EM( WB_REASON_BACKGROUND, "background") \
|
| 42 | EM( WB_REASON_VMSCAN, "vmscan") \
|
| 43 | EM( WB_REASON_SYNC, "sync") \
|
| 44 | EM( WB_REASON_PERIODIC, "periodic") \
|
| 45 | EM( WB_REASON_FS_FREE_SPACE, "fs_free_space") \
|
| 46 | EM( WB_REASON_FORKER_THREAD, "forker_thread") \
|
| 47 | EM( WB_REASON_FOREIGN_FLUSH, "foreign_flush") \
|
| 48 | EMe(WB_REASON_DONTCACHE, "dontcache")
|
| 49 |
|
| 50 | WB_WORK_REASON
|
| 51 |
|
| 52 | |
| 53 | * Now redefine the EM() and EMe() macros to map the enums to the strings
|
| 54 | * that will be printed in the output.
|
| 55 |
|
| 56 | #undef EM
|
| 57 | #undef EMe
|
| 58 | #define EM(a,b) { a, b },
|
| 59 | #define EMe(a,b) { a, b }
|
| 60 |
|
| 61 | struct wb_writeback_work;
|
| 62 |
|
| 63 | DECLARE_EVENT_CLASS(writeback_folio_template,
|
| 64 |
|
| 65 | TP_PROTO(struct folio *folio, struct address_space *mapping),
|
| 66 |
|
| 67 | TP_ARGS(folio, mapping),
|
| 68 |
|
| 69 | TP_STRUCT__entry (
|
| 70 | __array(char, name, 32)
|
| 71 | __field(u64, ino)
|
| 72 | __field(pgoff_t, index)
|
| 73 | ),
|
| 74 |
|
| 75 | TP_fast_assign(
|
| 76 | strscpy_pad(__entry->name,
|
| 77 | bdi_dev_name(mapping ? inode_to_bdi(mapping->host) :
|
| 78 | NULL), 32);
|
| 79 | __entry->ino = (mapping && mapping->host) ? mapping->host->i_ino : 0;
|
| 80 | __entry->index = folio->index;
|
| 81 | ),
|
| 82 |
|
| 83 | TP_printk("bdi %s: ino=%llu index=%lu",
|
| 84 | __entry->name,
|
| 85 | __entry->ino,
|
| 86 | __entry->index
|
| 87 | )
|
| 88 | );
|
| 89 |
|
| 90 | DEFINE_EVENT(writeback_folio_template, writeback_dirty_folio,
|
| 91 |
|
| 92 | TP_PROTO(struct folio *folio, struct address_space *mapping),
|
| 93 |
|
| 94 | TP_ARGS(folio, mapping)
|
| 95 | );
|
| 96 |
|
| 97 | DEFINE_EVENT(writeback_folio_template, folio_wait_writeback,
|
| 98 |
|
| 99 | TP_PROTO(struct folio *folio, struct address_space *mapping),
|
| 100 |
|
| 101 | TP_ARGS(folio, mapping)
|
| 102 | );
|
| 103 |
|
| 104 | DECLARE_EVENT_CLASS(writeback_dirty_inode_template,
|
| 105 |
|
| 106 | TP_PROTO(struct inode *inode, int flags),
|
| 107 |
|
| 108 | TP_ARGS(inode, flags),
|
| 109 |
|
| 110 | TP_STRUCT__entry (
|
| 111 | __array(char, name, 32)
|
| 112 | __field(u64, ino)
|
| 113 | __field(unsigned long, state)
|
| 114 | __field(unsigned long, flags)
|
| 115 | ),
|
| 116 |
|
| 117 | TP_fast_assign(
|
| 118 | struct backing_dev_info *bdi = inode_to_bdi(inode);
|
| 119 |
|
| 120 |
|
| 121 | strscpy_pad(__entry->name, bdi_dev_name(bdi), 32);
|
| 122 | __entry->ino = inode->i_ino;
|
| 123 | __entry->state = inode_state_read_once(inode);
|
| 124 | __entry->flags = flags;
|
| 125 | ),
|
| 126 |
|
| 127 | TP_printk("bdi %s: ino=%llu state=%s flags=%s",
|
| 128 | __entry->name,
|
| 129 | __entry->ino,
|
| 130 | show_inode_state(__entry->state),
|
| 131 | show_inode_state(__entry->flags)
|
| 132 | )
|
| 133 | );
|
| 134 |
|
| 135 | DEFINE_EVENT(writeback_dirty_inode_template, writeback_mark_inode_dirty,
|
| 136 |
|
| 137 | TP_PROTO(struct inode *inode, int flags),
|
| 138 |
|
| 139 | TP_ARGS(inode, flags)
|
| 140 | );
|
| 141 |
|
| 142 | DEFINE_EVENT(writeback_dirty_inode_template, writeback_dirty_inode_start,
|
| 143 |
|
| 144 | TP_PROTO(struct inode *inode, int flags),
|
| 145 |
|
| 146 | TP_ARGS(inode, flags)
|
| 147 | );
|
| 148 |
|
| 149 | DEFINE_EVENT(writeback_dirty_inode_template, writeback_dirty_inode,
|
| 150 |
|
| 151 | TP_PROTO(struct inode *inode, int flags),
|
| 152 |
|
| 153 | TP_ARGS(inode, flags)
|
| 154 | );
|
| 155 |
|
| 156 | #ifdef CREATE_TRACE_POINTS
|
| 157 | #ifdef CONFIG_CGROUP_WRITEBACK
|
| 158 |
|
| 159 | static inline u64 __trace_wb_assign_cgroup(struct bdi_writeback *wb)
|
| 160 | {
|
| 161 | return cgroup_ino(wb->memcg_css->cgroup);
|
| 162 | }
|
| 163 |
|
| 164 | static inline u64 __trace_wbc_assign_cgroup(struct writeback_control *wbc)
|
| 165 | {
|
| 166 | if (wbc->wb)
|
| 167 | return __trace_wb_assign_cgroup(wbc->wb);
|
| 168 | else
|
| 169 | return 1;
|
| 170 | }
|
| 171 | #else
|
| 172 |
|
| 173 | static inline u64 __trace_wb_assign_cgroup(struct bdi_writeback *wb)
|
| 174 | {
|
| 175 | return 1;
|
| 176 | }
|
| 177 |
|
| 178 | static inline u64 __trace_wbc_assign_cgroup(struct writeback_control *wbc)
|
| 179 | {
|
| 180 | return 1;
|
| 181 | }
|
| 182 |
|
| 183 | #endif
|
| 184 | #endif
|
| 185 |
|
| 186 | #ifdef CONFIG_CGROUP_WRITEBACK
|
| 187 | TRACE_EVENT(inode_foreign_history,
|
| 188 |
|
| 189 | TP_PROTO(struct inode *inode, struct writeback_control *wbc,
|
| 190 | unsigned int history),
|
| 191 |
|
| 192 | TP_ARGS(inode, wbc, history),
|
| 193 |
|
| 194 | TP_STRUCT__entry(
|
| 195 | __array(char, name, 32)
|
| 196 | __field(u64, ino)
|
| 197 | __field(u64, cgroup_ino)
|
| 198 | __field(unsigned int, history)
|
| 199 | ),
|
| 200 |
|
| 201 | TP_fast_assign(
|
| 202 | strscpy_pad(__entry->name, bdi_dev_name(inode_to_bdi(inode)), 32);
|
| 203 | __entry->ino = inode->i_ino;
|
| 204 | __entry->cgroup_ino = __trace_wbc_assign_cgroup(wbc);
|
| 205 | __entry->history = history;
|
| 206 | ),
|
| 207 |
|
| 208 | TP_printk("bdi %s: ino=%llu cgroup_ino=%llu history=0x%x",
|
| 209 | __entry->name,
|
| 210 | __entry->ino,
|
| 211 | __entry->cgroup_ino,
|
| 212 | __entry->history
|
| 213 | )
|
| 214 | );
|
| 215 |
|
| 216 | TRACE_EVENT(inode_switch_wbs_queue,
|
| 217 |
|
| 218 | TP_PROTO(struct bdi_writeback *old_wb, struct bdi_writeback *new_wb,
|
| 219 | unsigned int count),
|
| 220 |
|
| 221 | TP_ARGS(old_wb, new_wb, count),
|
| 222 |
|
| 223 | TP_STRUCT__entry(
|
| 224 | __array(char, name, 32)
|
| 225 | __field(u64, old_cgroup_ino)
|
| 226 | __field(u64, new_cgroup_ino)
|
| 227 | __field(unsigned int, count)
|
| 228 | ),
|
| 229 |
|
| 230 | TP_fast_assign(
|
| 231 | strscpy_pad(__entry->name, bdi_dev_name(old_wb->bdi), 32);
|
| 232 | __entry->old_cgroup_ino = __trace_wb_assign_cgroup(old_wb);
|
| 233 | __entry->new_cgroup_ino = __trace_wb_assign_cgroup(new_wb);
|
| 234 | __entry->count = count;
|
| 235 | ),
|
| 236 |
|
| 237 | TP_printk("bdi %s: old_cgroup_ino=%llu new_cgroup_ino=%llu count=%u",
|
| 238 | __entry->name,
|
| 239 | __entry->old_cgroup_ino,
|
| 240 | __entry->new_cgroup_ino,
|
| 241 | __entry->count
|
| 242 | )
|
| 243 | );
|
| 244 |
|
| 245 | TRACE_EVENT(inode_switch_wbs,
|
| 246 |
|
| 247 | TP_PROTO(struct inode *inode, struct bdi_writeback *old_wb,
|
| 248 | struct bdi_writeback *new_wb),
|
| 249 |
|
| 250 | TP_ARGS(inode, old_wb, new_wb),
|
| 251 |
|
| 252 | TP_STRUCT__entry(
|
| 253 | __array(char, name, 32)
|
| 254 | __field(u64, ino)
|
| 255 | __field(u64, old_cgroup_ino)
|
| 256 | __field(u64, new_cgroup_ino)
|
| 257 | ),
|
| 258 |
|
| 259 | TP_fast_assign(
|
| 260 | strscpy_pad(__entry->name, bdi_dev_name(old_wb->bdi), 32);
|
| 261 | __entry->ino = inode->i_ino;
|
| 262 | __entry->old_cgroup_ino = __trace_wb_assign_cgroup(old_wb);
|
| 263 | __entry->new_cgroup_ino = __trace_wb_assign_cgroup(new_wb);
|
| 264 | ),
|
| 265 |
|
| 266 | TP_printk("bdi %s: ino=%llu old_cgroup_ino=%llu new_cgroup_ino=%llu",
|
| 267 | __entry->name,
|
| 268 | __entry->ino,
|
| 269 | __entry->old_cgroup_ino,
|
| 270 | __entry->new_cgroup_ino
|
| 271 | )
|
| 272 | );
|
| 273 |
|
| 274 | TRACE_EVENT(track_foreign_dirty,
|
| 275 |
|
| 276 | TP_PROTO(struct folio *folio, struct bdi_writeback *wb),
|
| 277 |
|
| 278 | TP_ARGS(folio, wb),
|
| 279 |
|
| 280 | TP_STRUCT__entry(
|
| 281 | __array(char, name, 32)
|
| 282 | __field(u64, bdi_id)
|
| 283 | __field(u64, ino)
|
| 284 | __field(u64, cgroup_ino)
|
| 285 | __field(u64, page_cgroup_ino)
|
| 286 | __field(unsigned int, memcg_id)
|
| 287 | ),
|
| 288 |
|
| 289 | TP_fast_assign(
|
| 290 | struct address_space *mapping = folio_mapping(folio);
|
| 291 | struct inode *inode = mapping ? mapping->host : NULL;
|
| 292 |
|
| 293 | strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32);
|
| 294 | __entry->bdi_id = wb->bdi->id;
|
| 295 | __entry->ino = inode ? inode->i_ino : 0;
|
| 296 | __entry->memcg_id = wb->memcg_css->id;
|
| 297 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb);
|
| 298 |
|
| 299 | rcu_read_lock();
|
| 300 | __entry->page_cgroup_ino = cgroup_ino(folio_memcg(folio)->css.cgroup);
|
| 301 | rcu_read_unlock();
|
| 302 | ),
|
| 303 |
|
| 304 | TP_printk("bdi %s[%llu]: ino=%llu memcg_id=%u cgroup_ino=%llu page_cgroup_ino=%llu",
|
| 305 | __entry->name,
|
| 306 | __entry->bdi_id,
|
| 307 | __entry->ino,
|
| 308 | __entry->memcg_id,
|
| 309 | __entry->cgroup_ino,
|
| 310 | __entry->page_cgroup_ino
|
| 311 | )
|
| 312 | );
|
| 313 |
|
| 314 | TRACE_EVENT(flush_foreign,
|
| 315 |
|
| 316 | TP_PROTO(struct bdi_writeback *wb, unsigned int frn_bdi_id,
|
| 317 | unsigned int frn_memcg_id),
|
| 318 |
|
| 319 | TP_ARGS(wb, frn_bdi_id, frn_memcg_id),
|
| 320 |
|
| 321 | TP_STRUCT__entry(
|
| 322 | __array(char, name, 32)
|
| 323 | __field(u64, cgroup_ino)
|
| 324 | __field(unsigned int, frn_bdi_id)
|
| 325 | __field(unsigned int, frn_memcg_id)
|
| 326 | ),
|
| 327 |
|
| 328 | TP_fast_assign(
|
| 329 | strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32);
|
| 330 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb);
|
| 331 | __entry->frn_bdi_id = frn_bdi_id;
|
| 332 | __entry->frn_memcg_id = frn_memcg_id;
|
| 333 | ),
|
| 334 |
|
| 335 | TP_printk("bdi %s: cgroup_ino=%llu frn_bdi_id=%u frn_memcg_id=%u",
|
| 336 | __entry->name,
|
| 337 | __entry->cgroup_ino,
|
| 338 | __entry->frn_bdi_id,
|
| 339 | __entry->frn_memcg_id
|
| 340 | )
|
| 341 | );
|
| 342 | #endif
|
| 343 |
|
| 344 | DECLARE_EVENT_CLASS(writeback_write_inode_template,
|
| 345 |
|
| 346 | TP_PROTO(struct inode *inode, struct writeback_control *wbc),
|
| 347 |
|
| 348 | TP_ARGS(inode, wbc),
|
| 349 |
|
| 350 | TP_STRUCT__entry (
|
| 351 | __array(char, name, 32)
|
| 352 | __field(u64, ino)
|
| 353 | __field(u64, cgroup_ino)
|
| 354 | __field(int, sync_mode)
|
| 355 | ),
|
| 356 |
|
| 357 | TP_fast_assign(
|
| 358 | strscpy_pad(__entry->name,
|
| 359 | bdi_dev_name(inode_to_bdi(inode)), 32);
|
| 360 | __entry->ino = inode->i_ino;
|
| 361 | __entry->sync_mode = wbc->sync_mode;
|
| 362 | __entry->cgroup_ino = __trace_wbc_assign_cgroup(wbc);
|
| 363 | ),
|
| 364 |
|
| 365 | TP_printk("bdi %s: ino=%llu sync_mode=%d cgroup_ino=%llu",
|
| 366 | __entry->name,
|
| 367 | __entry->ino,
|
| 368 | __entry->sync_mode,
|
| 369 | __entry->cgroup_ino
|
| 370 | )
|
| 371 | );
|
| 372 |
|
| 373 | DEFINE_EVENT(writeback_write_inode_template, writeback_write_inode_start,
|
| 374 |
|
| 375 | TP_PROTO(struct inode *inode, struct writeback_control *wbc),
|
| 376 |
|
| 377 | TP_ARGS(inode, wbc)
|
| 378 | );
|
| 379 |
|
| 380 | DEFINE_EVENT(writeback_write_inode_template, writeback_write_inode,
|
| 381 |
|
| 382 | TP_PROTO(struct inode *inode, struct writeback_control *wbc),
|
| 383 |
|
| 384 | TP_ARGS(inode, wbc)
|
| 385 | );
|
| 386 |
|
| 387 | DECLARE_EVENT_CLASS(writeback_work_class,
|
| 388 | TP_PROTO(struct bdi_writeback *wb, struct wb_writeback_work *work),
|
| 389 | TP_ARGS(wb, work),
|
| 390 | TP_STRUCT__entry(
|
| 391 | __array(char, name, 32)
|
| 392 | __field(u64, cgroup_ino)
|
| 393 | __field(long, nr_pages)
|
| 394 | __field(dev_t, sb_dev)
|
| 395 | __field(int, sync_mode)
|
| 396 | __field(int, for_kupdate)
|
| 397 | __field(int, range_cyclic)
|
| 398 | __field(int, for_background)
|
| 399 | __field(int, reason)
|
| 400 | ),
|
| 401 | TP_fast_assign(
|
| 402 | strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32);
|
| 403 | __entry->nr_pages = work->nr_pages;
|
| 404 | __entry->sb_dev = work->sb ? work->sb->s_dev : 0;
|
| 405 | __entry->sync_mode = work->sync_mode;
|
| 406 | __entry->for_kupdate = work->for_kupdate;
|
| 407 | __entry->range_cyclic = work->range_cyclic;
|
| 408 | __entry->for_background = work->for_background;
|
| 409 | __entry->reason = work->reason;
|
| 410 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb);
|
| 411 | ),
|
| 412 | TP_printk("bdi %s: sb_dev %d:%d nr_pages=%ld sync_mode=%d "
|
| 413 | "kupdate=%d range_cyclic=%d background=%d reason=%s cgroup_ino=%llu",
|
| 414 | __entry->name,
|
| 415 | MAJOR(__entry->sb_dev), MINOR(__entry->sb_dev),
|
| 416 | __entry->nr_pages,
|
| 417 | __entry->sync_mode,
|
| 418 | __entry->for_kupdate,
|
| 419 | __entry->range_cyclic,
|
| 420 | __entry->for_background,
|
| 421 | __print_symbolic(__entry->reason, WB_WORK_REASON),
|
| 422 | __entry->cgroup_ino
|
| 423 | )
|
| 424 | );
|
| 425 | #define DEFINE_WRITEBACK_WORK_EVENT(name) \
|
| 426 | DEFINE_EVENT(writeback_work_class, name, \
|
| 427 | TP_PROTO(struct bdi_writeback *wb, struct wb_writeback_work *work), \
|
| 428 | TP_ARGS(wb, work))
|
| 429 | DEFINE_WRITEBACK_WORK_EVENT(writeback_queue);
|
| 430 | DEFINE_WRITEBACK_WORK_EVENT(writeback_exec);
|
| 431 | DEFINE_WRITEBACK_WORK_EVENT(writeback_start);
|
| 432 | DEFINE_WRITEBACK_WORK_EVENT(writeback_written);
|
| 433 | DEFINE_WRITEBACK_WORK_EVENT(writeback_wait);
|
| 434 |
|
| 435 | TRACE_EVENT(writeback_pages_written,
|
| 436 | TP_PROTO(long pages_written),
|
| 437 | TP_ARGS(pages_written),
|
| 438 | TP_STRUCT__entry(
|
| 439 | __field(long, pages)
|
| 440 | ),
|
| 441 | TP_fast_assign(
|
| 442 | __entry->pages = pages_written;
|
| 443 | ),
|
| 444 | TP_printk("%ld", __entry->pages)
|
| 445 | );
|
| 446 |
|
| 447 | DECLARE_EVENT_CLASS(writeback_class,
|
| 448 | TP_PROTO(struct bdi_writeback *wb),
|
| 449 | TP_ARGS(wb),
|
| 450 | TP_STRUCT__entry(
|
| 451 | __array(char, name, 32)
|
| 452 | __field(u64, cgroup_ino)
|
| 453 | ),
|
| 454 | TP_fast_assign(
|
| 455 | strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32);
|
| 456 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb);
|
| 457 | ),
|
| 458 | TP_printk("bdi %s: cgroup_ino=%llu",
|
| 459 | __entry->name,
|
| 460 | __entry->cgroup_ino
|
| 461 | )
|
| 462 | );
|
| 463 | #define DEFINE_WRITEBACK_EVENT(name) \
|
| 464 | DEFINE_EVENT(writeback_class, name, \
|
| 465 | TP_PROTO(struct bdi_writeback *wb), \
|
| 466 | TP_ARGS(wb))
|
| 467 |
|
| 468 | DEFINE_WRITEBACK_EVENT(writeback_wake_background);
|
| 469 |
|
| 470 | TRACE_EVENT(writeback_bdi_register,
|
| 471 | TP_PROTO(struct backing_dev_info *bdi),
|
| 472 | TP_ARGS(bdi),
|
| 473 | TP_STRUCT__entry(
|
| 474 | __array(char, name, 32)
|
| 475 | ),
|
| 476 | TP_fast_assign(
|
| 477 | strscpy_pad(__entry->name, bdi_dev_name(bdi), 32);
|
| 478 | ),
|
| 479 | TP_printk("bdi %s",
|
| 480 | __entry->name
|
| 481 | )
|
| 482 | );
|
| 483 |
|
| 484 | DECLARE_EVENT_CLASS(wbc_class,
|
| 485 | TP_PROTO(struct writeback_control *wbc, struct backing_dev_info *bdi),
|
| 486 | TP_ARGS(wbc, bdi),
|
| 487 | TP_STRUCT__entry(
|
| 488 | __array(char, name, 32)
|
| 489 | __field(u64, cgroup_ino)
|
| 490 | __field(long, nr_to_write)
|
| 491 | __field(long, pages_skipped)
|
| 492 | __field(long, range_start)
|
| 493 | __field(long, range_end)
|
| 494 | __field(int, sync_mode)
|
| 495 | __field(int, for_kupdate)
|
| 496 | __field(int, for_background)
|
| 497 | __field(int, range_cyclic)
|
| 498 | ),
|
| 499 |
|
| 500 | TP_fast_assign(
|
| 501 | strscpy_pad(__entry->name, bdi_dev_name(bdi), 32);
|
| 502 | __entry->nr_to_write = wbc->nr_to_write;
|
| 503 | __entry->pages_skipped = wbc->pages_skipped;
|
| 504 | __entry->sync_mode = wbc->sync_mode;
|
| 505 | __entry->for_kupdate = wbc->for_kupdate;
|
| 506 | __entry->for_background = wbc->for_background;
|
| 507 | __entry->range_cyclic = wbc->range_cyclic;
|
| 508 | __entry->range_start = (long)wbc->range_start;
|
| 509 | __entry->range_end = (long)wbc->range_end;
|
| 510 | __entry->cgroup_ino = __trace_wbc_assign_cgroup(wbc);
|
| 511 | ),
|
| 512 |
|
| 513 | TP_printk("bdi %s: towrt=%ld skip=%ld mode=%d kupd=%d bgrd=%d "
|
| 514 | "cyclic=%d start=0x%lx end=0x%lx cgroup_ino=%llu",
|
| 515 | __entry->name,
|
| 516 | __entry->nr_to_write,
|
| 517 | __entry->pages_skipped,
|
| 518 | __entry->sync_mode,
|
| 519 | __entry->for_kupdate,
|
| 520 | __entry->for_background,
|
| 521 | __entry->range_cyclic,
|
| 522 | __entry->range_start,
|
| 523 | __entry->range_end,
|
| 524 | __entry->cgroup_ino
|
| 525 | )
|
| 526 | )
|
| 527 |
|
| 528 | #define DEFINE_WBC_EVENT(name) \
|
| 529 | DEFINE_EVENT(wbc_class, name, \
|
| 530 | TP_PROTO(struct writeback_control *wbc, struct backing_dev_info *bdi), \
|
| 531 | TP_ARGS(wbc, bdi))
|
| 532 | DEFINE_WBC_EVENT(wbc_writepage);
|
| 533 |
|
| 534 | TRACE_EVENT(writeback_queue_io,
|
| 535 | TP_PROTO(struct bdi_writeback *wb,
|
| 536 | struct wb_writeback_work *work,
|
| 537 | unsigned long dirtied_before,
|
| 538 | int moved),
|
| 539 | TP_ARGS(wb, work, dirtied_before, moved),
|
| 540 | TP_STRUCT__entry(
|
| 541 | __array(char, name, 32)
|
| 542 | __field(u64, cgroup_ino)
|
| 543 | __field(unsigned long, older)
|
| 544 | __field(long, age)
|
| 545 | __field(int, moved)
|
| 546 | __field(int, reason)
|
| 547 | ),
|
| 548 | TP_fast_assign(
|
| 549 | strscpy_pad(__entry->name, bdi_dev_name(wb->bdi), 32);
|
| 550 | __entry->older = dirtied_before;
|
| 551 | __entry->age = (jiffies - dirtied_before) * 1000 / HZ;
|
| 552 | __entry->moved = moved;
|
| 553 | __entry->reason = work->reason;
|
| 554 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb);
|
| 555 | ),
|
| 556 | TP_printk("bdi %s: older=%lu age=%ld enqueue=%d reason=%s cgroup_ino=%llu",
|
| 557 | __entry->name,
|
| 558 | __entry->older,
|
| 559 | __entry->age,
|
| 560 | __entry->moved,
|
| 561 | __print_symbolic(__entry->reason, WB_WORK_REASON),
|
| 562 | __entry->cgroup_ino
|
| 563 | )
|
| 564 | );
|
| 565 |
|
| 566 | TRACE_EVENT(global_dirty_state,
|
| 567 |
|
| 568 | TP_PROTO(unsigned long background_thresh,
|
| 569 | unsigned long dirty_thresh
|
| 570 | ),
|
| 571 |
|
| 572 | TP_ARGS(background_thresh,
|
| 573 | dirty_thresh
|
| 574 | ),
|
| 575 |
|
| 576 | TP_STRUCT__entry(
|
| 577 | __field(unsigned long, nr_dirty)
|
| 578 | __field(unsigned long, nr_writeback)
|
| 579 | __field(unsigned long, background_thresh)
|
| 580 | __field(unsigned long, dirty_thresh)
|
| 581 | __field(unsigned long, dirty_limit)
|
| 582 | __field(unsigned long, nr_dirtied)
|
| 583 | __field(unsigned long, nr_written)
|
| 584 | ),
|
| 585 |
|
| 586 | TP_fast_assign(
|
| 587 | __entry->nr_dirty = global_node_page_state(NR_FILE_DIRTY);
|
| 588 | __entry->nr_writeback = global_node_page_state(NR_WRITEBACK);
|
| 589 | __entry->nr_dirtied = global_node_page_state(NR_DIRTIED);
|
| 590 | __entry->nr_written = global_node_page_state(NR_WRITTEN);
|
| 591 | __entry->background_thresh = background_thresh;
|
| 592 | __entry->dirty_thresh = dirty_thresh;
|
| 593 | __entry->dirty_limit = global_wb_domain.dirty_limit;
|
| 594 | ),
|
| 595 |
|
| 596 | TP_printk("dirty=%lu writeback=%lu "
|
| 597 | "bg_thresh=%lu thresh=%lu limit=%lu "
|
| 598 | "dirtied=%lu written=%lu",
|
| 599 | __entry->nr_dirty,
|
| 600 | __entry->nr_writeback,
|
| 601 | __entry->background_thresh,
|
| 602 | __entry->dirty_thresh,
|
| 603 | __entry->dirty_limit,
|
| 604 | __entry->nr_dirtied,
|
| 605 | __entry->nr_written
|
| 606 | )
|
| 607 | );
|
| 608 |
|
| 609 | #define KBps(x) ((x) << (PAGE_SHIFT - 10))
|
| 610 |
|
| 611 | TRACE_EVENT(bdi_dirty_ratelimit,
|
| 612 |
|
| 613 | TP_PROTO(struct bdi_writeback *wb,
|
| 614 | unsigned long dirty_rate,
|
| 615 | unsigned long task_ratelimit),
|
| 616 |
|
| 617 | TP_ARGS(wb, dirty_rate, task_ratelimit),
|
| 618 |
|
| 619 | TP_STRUCT__entry(
|
| 620 | __array(char, bdi, 32)
|
| 621 | __field(u64, cgroup_ino)
|
| 622 | __field(unsigned long, write_bw)
|
| 623 | __field(unsigned long, avg_write_bw)
|
| 624 | __field(unsigned long, dirty_rate)
|
| 625 | __field(unsigned long, dirty_ratelimit)
|
| 626 | __field(unsigned long, task_ratelimit)
|
| 627 | __field(unsigned long, balanced_dirty_ratelimit)
|
| 628 | ),
|
| 629 |
|
| 630 | TP_fast_assign(
|
| 631 | strscpy_pad(__entry->bdi, bdi_dev_name(wb->bdi), 32);
|
| 632 | __entry->write_bw = KBps(wb->write_bandwidth);
|
| 633 | __entry->avg_write_bw = KBps(wb->avg_write_bandwidth);
|
| 634 | __entry->dirty_rate = KBps(dirty_rate);
|
| 635 | __entry->dirty_ratelimit = KBps(wb->dirty_ratelimit);
|
| 636 | __entry->task_ratelimit = KBps(task_ratelimit);
|
| 637 | __entry->balanced_dirty_ratelimit =
|
| 638 | KBps(wb->balanced_dirty_ratelimit);
|
| 639 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb);
|
| 640 | ),
|
| 641 |
|
| 642 | TP_printk("bdi %s: "
|
| 643 | "write_bw=%lu awrite_bw=%lu dirty_rate=%lu "
|
| 644 | "dirty_ratelimit=%lu task_ratelimit=%lu "
|
| 645 | "balanced_dirty_ratelimit=%lu cgroup_ino=%llu",
|
| 646 | __entry->bdi,
|
| 647 | __entry->write_bw,
|
| 648 | __entry->avg_write_bw,
|
| 649 | __entry->dirty_rate,
|
| 650 | __entry->dirty_ratelimit,
|
| 651 | __entry->task_ratelimit,
|
| 652 | __entry->balanced_dirty_ratelimit,
|
| 653 | __entry->cgroup_ino
|
| 654 | )
|
| 655 | );
|
| 656 |
|
| 657 | TRACE_EVENT(balance_dirty_pages,
|
| 658 |
|
| 659 | TP_PROTO(struct bdi_writeback *wb,
|
| 660 | struct dirty_throttle_control *dtc,
|
| 661 | unsigned long dirty_ratelimit,
|
| 662 | unsigned long task_ratelimit,
|
| 663 | unsigned long dirtied,
|
| 664 | unsigned long period,
|
| 665 | long pause,
|
| 666 | unsigned long start_time),
|
| 667 |
|
| 668 | TP_ARGS(wb, dtc,
|
| 669 | dirty_ratelimit, task_ratelimit,
|
| 670 | dirtied, period, pause, start_time),
|
| 671 |
|
| 672 | TP_STRUCT__entry(
|
| 673 | __array( char, bdi, 32)
|
| 674 | __field(u64, cgroup_ino)
|
| 675 | __field(unsigned long, limit)
|
| 676 | __field(unsigned long, setpoint)
|
| 677 | __field(unsigned long, dirty)
|
| 678 | __field(unsigned long, wb_setpoint)
|
| 679 | __field(unsigned long, wb_dirty)
|
| 680 | __field(unsigned long, dirty_ratelimit)
|
| 681 | __field(unsigned long, task_ratelimit)
|
| 682 | __field(unsigned long, paused)
|
| 683 | __field( long, pause)
|
| 684 | __field(unsigned long, period)
|
| 685 | __field( long, think)
|
| 686 | __field(unsigned int, dirtied)
|
| 687 | __field(unsigned int, dirtied_pause)
|
| 688 | ),
|
| 689 |
|
| 690 | TP_fast_assign(
|
| 691 | unsigned long freerun = (dtc->thresh + dtc->bg_thresh) / 2;
|
| 692 | strscpy_pad(__entry->bdi, bdi_dev_name(wb->bdi), 32);
|
| 693 |
|
| 694 | __entry->limit = dtc->limit;
|
| 695 | __entry->setpoint = (dtc->limit + freerun) / 2;
|
| 696 | __entry->dirty = dtc->dirty;
|
| 697 | __entry->wb_setpoint = __entry->setpoint *
|
| 698 | dtc->wb_thresh / (dtc->thresh + 1);
|
| 699 | __entry->wb_dirty = dtc->wb_dirty;
|
| 700 | __entry->dirty_ratelimit = KBps(dirty_ratelimit);
|
| 701 | __entry->task_ratelimit = KBps(task_ratelimit);
|
| 702 | __entry->dirtied = dirtied;
|
| 703 | __entry->dirtied_pause = current->nr_dirtied_pause;
|
| 704 | __entry->think = current->dirty_paused_when == 0 ? 0 :
|
| 705 | (long)(jiffies - current->dirty_paused_when) * 1000/HZ;
|
| 706 | __entry->period = period * 1000 / HZ;
|
| 707 | __entry->pause = pause * 1000 / HZ;
|
| 708 | __entry->paused = (jiffies - start_time) * 1000 / HZ;
|
| 709 | __entry->cgroup_ino = __trace_wb_assign_cgroup(wb);
|
| 710 | ),
|
| 711 |
|
| 712 |
|
| 713 | TP_printk("bdi %s: "
|
| 714 | "limit=%lu setpoint=%lu dirty=%lu "
|
| 715 | "wb_setpoint=%lu wb_dirty=%lu "
|
| 716 | "dirty_ratelimit=%lu task_ratelimit=%lu "
|
| 717 | "dirtied=%u dirtied_pause=%u "
|
| 718 | "paused=%lu pause=%ld period=%lu think=%ld cgroup_ino=%llu",
|
| 719 | __entry->bdi,
|
| 720 | __entry->limit,
|
| 721 | __entry->setpoint,
|
| 722 | __entry->dirty,
|
| 723 | __entry->wb_setpoint,
|
| 724 | __entry->wb_dirty,
|
| 725 | __entry->dirty_ratelimit,
|
| 726 | __entry->task_ratelimit,
|
| 727 | __entry->dirtied,
|
| 728 | __entry->dirtied_pause,
|
| 729 | __entry->paused,
|
| 730 | __entry->pause,
|
| 731 | __entry->period,
|
| 732 | __entry->think,
|
| 733 | __entry->cgroup_ino
|
| 734 | )
|
| 735 | );
|
| 736 |
|
| 737 | TRACE_EVENT(writeback_sb_inodes_requeue,
|
| 738 |
|
| 739 | TP_PROTO(struct inode *inode),
|
| 740 | TP_ARGS(inode),
|
| 741 |
|
| 742 | TP_STRUCT__entry(
|
| 743 | __array(char, name, 32)
|
| 744 | __field(u64, ino)
|
| 745 | __field(u64, cgroup_ino)
|
| 746 | __field(unsigned long, state)
|
| 747 | __field(unsigned long, dirtied_when)
|
| 748 | ),
|
| 749 |
|
| 750 | TP_fast_assign(
|
| 751 | strscpy_pad(__entry->name,
|
| 752 | bdi_dev_name(inode_to_bdi(inode)), 32);
|
| 753 | __entry->ino = inode->i_ino;
|
| 754 | __entry->state = inode_state_read_once(inode);
|
| 755 | __entry->dirtied_when = inode->dirtied_when;
|
| 756 | __entry->cgroup_ino = __trace_wb_assign_cgroup(inode_to_wb(inode));
|
| 757 | ),
|
| 758 |
|
| 759 | TP_printk("bdi %s: ino=%llu state=%s dirtied_when=%lu age=%lu cgroup_ino=%llu",
|
| 760 | __entry->name,
|
| 761 | __entry->ino,
|
| 762 | show_inode_state(__entry->state),
|
| 763 | __entry->dirtied_when,
|
| 764 | (jiffies - __entry->dirtied_when) / HZ,
|
| 765 | __entry->cgroup_ino
|
| 766 | )
|
| 767 | );
|
| 768 |
|
| 769 | DECLARE_EVENT_CLASS(writeback_single_inode_template,
|
| 770 |
|
| 771 | TP_PROTO(struct inode *inode,
|
| 772 | struct writeback_control *wbc,
|
| 773 | unsigned long nr_to_write
|
| 774 | ),
|
| 775 |
|
| 776 | TP_ARGS(inode, wbc, nr_to_write),
|
| 777 |
|
| 778 | TP_STRUCT__entry(
|
| 779 | __array(char, name, 32)
|
| 780 | __field(u64, ino)
|
| 781 | __field(u64, cgroup_ino)
|
| 782 | __field(unsigned long, state)
|
| 783 | __field(unsigned long, dirtied_when)
|
| 784 | __field(unsigned long, writeback_index)
|
| 785 | __field(unsigned long, wrote)
|
| 786 | __field(long, nr_to_write)
|
| 787 | ),
|
| 788 |
|
| 789 | TP_fast_assign(
|
| 790 | strscpy_pad(__entry->name,
|
| 791 | bdi_dev_name(inode_to_bdi(inode)), 32);
|
| 792 | __entry->ino = inode->i_ino;
|
| 793 | __entry->state = inode_state_read_once(inode);
|
| 794 | __entry->dirtied_when = inode->dirtied_when;
|
| 795 | __entry->writeback_index = inode->i_mapping->writeback_index;
|
| 796 | __entry->nr_to_write = nr_to_write;
|
| 797 | __entry->wrote = nr_to_write - wbc->nr_to_write;
|
| 798 | __entry->cgroup_ino = __trace_wbc_assign_cgroup(wbc);
|
| 799 | ),
|
| 800 |
|
| 801 | TP_printk("bdi %s: ino=%llu state=%s dirtied_when=%lu age=%lu "
|
| 802 | "index=%lu to_write=%ld wrote=%lu cgroup_ino=%llu",
|
| 803 | __entry->name,
|
| 804 | __entry->ino,
|
| 805 | show_inode_state(__entry->state),
|
| 806 | __entry->dirtied_when,
|
| 807 | (jiffies - __entry->dirtied_when) / HZ,
|
| 808 | __entry->writeback_index,
|
| 809 | __entry->nr_to_write,
|
| 810 | __entry->wrote,
|
| 811 | __entry->cgroup_ino
|
| 812 | )
|
| 813 | );
|
| 814 |
|
| 815 | DEFINE_EVENT(writeback_single_inode_template, writeback_single_inode_start,
|
| 816 | TP_PROTO(struct inode *inode,
|
| 817 | struct writeback_control *wbc,
|
| 818 | unsigned long nr_to_write),
|
| 819 | TP_ARGS(inode, wbc, nr_to_write)
|
| 820 | );
|
| 821 |
|
| 822 | DEFINE_EVENT(writeback_single_inode_template, writeback_single_inode,
|
| 823 | TP_PROTO(struct inode *inode,
|
| 824 | struct writeback_control *wbc,
|
| 825 | unsigned long nr_to_write),
|
| 826 | TP_ARGS(inode, wbc, nr_to_write)
|
| 827 | );
|
| 828 |
|
| 829 | DECLARE_EVENT_CLASS(writeback_inode_template,
|
| 830 | TP_PROTO(struct inode *inode),
|
| 831 |
|
| 832 | TP_ARGS(inode),
|
| 833 |
|
| 834 | TP_STRUCT__entry(
|
| 835 | __field( u64, ino )
|
| 836 | __field(unsigned long, state )
|
| 837 | __field(unsigned long, dirtied_when )
|
| 838 | __field( dev_t, dev )
|
| 839 | __field( __u16, mode )
|
| 840 | ),
|
| 841 |
|
| 842 | TP_fast_assign(
|
| 843 | __entry->dev = inode->i_sb->s_dev;
|
| 844 | __entry->ino = inode->i_ino;
|
| 845 | __entry->state = inode_state_read_once(inode);
|
| 846 | __entry->mode = inode->i_mode;
|
| 847 | __entry->dirtied_when = inode->dirtied_when;
|
| 848 | ),
|
| 849 |
|
| 850 | TP_printk("dev %d,%d ino %llu dirtied %lu state %s mode 0%o",
|
| 851 | MAJOR(__entry->dev), MINOR(__entry->dev),
|
| 852 | __entry->ino, __entry->dirtied_when,
|
| 853 | show_inode_state(__entry->state), __entry->mode)
|
| 854 | );
|
| 855 |
|
| 856 | DEFINE_EVENT(writeback_inode_template, writeback_lazytime,
|
| 857 | TP_PROTO(struct inode *inode),
|
| 858 |
|
| 859 | TP_ARGS(inode)
|
| 860 | );
|
| 861 |
|
| 862 | DEFINE_EVENT(writeback_inode_template, writeback_dirty_inode_enqueue,
|
| 863 |
|
| 864 | TP_PROTO(struct inode *inode),
|
| 865 |
|
| 866 | TP_ARGS(inode)
|
| 867 | );
|
| 868 |
|
| 869 | |
| 870 | * Inode writeback list tracking.
|
| 871 |
|
| 872 |
|
| 873 | DEFINE_EVENT(writeback_inode_template, sb_mark_inode_writeback,
|
| 874 | TP_PROTO(struct inode *inode),
|
| 875 | TP_ARGS(inode)
|
| 876 | );
|
| 877 |
|
| 878 | DEFINE_EVENT(writeback_inode_template, sb_clear_inode_writeback,
|
| 879 | TP_PROTO(struct inode *inode),
|
| 880 | TP_ARGS(inode)
|
| 881 | );
|
| 882 |
|
| 883 | #endif
|
| 884 |
|
| 885 |
|
| 886 | #include <trace/define_trace.h>
|