writeback.h 23 KB

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