fix: memcg: fix a crash in wb_workfn when a device disappears (5.6)
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 10 Feb 2021 16:45:42 +0000 (11:45 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 10 Feb 2021 17:26:11 +0000 (12:26 -0500)
See upstream commit:

commit 68f23b89067fdf187763e75a56087550624fdbee
("memcg: fix a crash in wb_workfn when a device disappears")

It is currently backported into stable branches 5.4 and 5.5, but appears
to be missing from the 4.4, 4.9, 4.14, 4.19 LTS branches.

Implement our own lttng_bdi_dev_name wrapper to provide this fix on
builds against stable kernels which do not have this fix.

There is one user-visible change with this commit: for builds against
kernels < 4.4.0, the writeback_work_class events did use the
default_backing_dev_info to handle cases where the device is NULL,
writing "default" into the trace. This behavior is now aligned to
match what is done in kernels >= 4.4.0, which is to write "(unknown)"
into the name field.

Link: https://lore.kernel.org/r/537870616.15400.1612973059419.JavaMail.zimbra@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I0823643aa2f9d4c2b9f2005748a2adfd4457979a

include/instrumentation/events/writeback.h

index 3d5df91f916465a6a9840646157cceacdccccc0f..f24237b296f507283c1a3c46bcfbf372764c64fe 100644 (file)
 #ifndef _TRACE_WRITEBACK_DEF_
 #define _TRACE_WRITEBACK_DEF_
 
+#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,6,0) ||        \
+       LTTNG_KERNEL_RANGE(5,5,3, 5,6,0) ||                     \
+       LTTNG_KERNEL_RANGE(5,4,19, 5,5,0))
+static inline const char *lttng_bdi_dev_name(struct backing_dev_info *bdi)
+{
+       return bdi_dev_name(bdi);
+}
+#else
+static inline const char *lttng_bdi_dev_name(struct backing_dev_info *bdi)
+{
+       if (!bdi || !bdi->dev)
+               return "(unknown)";
+       return dev_name(bdi->dev);
+}
+#endif
+
 /*
  * Vanilla kernels before 4.0 do not implement inode_to_bdi
  * RHEL kernels before 3.10.0-327.10.1 do not implement inode_to_bdi
@@ -96,8 +112,7 @@ LTTNG_TRACEPOINT_EVENT(writeback_dirty_page,
        TP_PROTO(struct page *page, struct address_space *mapping),
        TP_ARGS(page, mapping),
        TP_FIELDS(
-               ctf_string(name,
-                       mapping ? dev_name(lttng_inode_to_bdi(mapping->host)->dev) : "(unknown)")
+               ctf_string(name, lttng_bdi_dev_name(mapping ? lttng_inode_to_bdi(mapping->host) : NULL))
                ctf_integer(unsigned long, ino, mapping ? mapping->host->i_ino : 0)
                ctf_integer(pgoff_t, index, page->index)
        )
@@ -108,9 +123,7 @@ LTTNG_TRACEPOINT_EVENT_CLASS(writeback_dirty_inode_template,
        TP_ARGS(inode, flags),
        TP_FIELDS(
                /* may be called for files on pseudo FSes w/ unregistered bdi */
-               ctf_string(name,
-                       lttng_inode_to_bdi(inode)->dev ?
-                               dev_name(lttng_inode_to_bdi(inode)->dev) : "(unknown)")
+               ctf_string(name, lttng_bdi_dev_name(lttng_inode_to_bdi(inode)))
                ctf_integer(unsigned long, ino, inode->i_ino)
                ctf_integer(unsigned long, state, inode->i_state)
                ctf_integer(unsigned long, flags, flags)
@@ -128,8 +141,7 @@ LTTNG_TRACEPOINT_EVENT_CLASS(writeback_write_inode_template,
        TP_PROTO(struct inode *inode, struct writeback_control *wbc),
        TP_ARGS(inode, wbc),
        TP_FIELDS(
-               ctf_string(name,
-                       dev_name(lttng_inode_to_bdi(inode)->dev))
+               ctf_string(name, lttng_bdi_dev_name(lttng_inode_to_bdi(inode)))
                ctf_integer(unsigned long, ino, inode->i_ino)
                ctf_integer(int, sync_mode, wbc->sync_mode)
        )
@@ -148,8 +160,7 @@ LTTNG_TRACEPOINT_EVENT(writeback_dirty_page,
        TP_PROTO(struct page *page, struct address_space *mapping),
        TP_ARGS(page, mapping),
        TP_FIELDS(
-               ctf_string(name,
-                       mapping ? dev_name(mapping->backing_dev_info->dev) : "(unknown)")
+               ctf_string(name, lttng_bdi_dev_name(mapping ? mapping->backing_dev_info : NULL))
                ctf_integer(unsigned long, ino, mapping ? mapping->host->i_ino : 0)
                ctf_integer(pgoff_t, index, page->index)
        )
@@ -160,10 +171,7 @@ LTTNG_TRACEPOINT_EVENT_CLASS(writeback_dirty_inode_template,
        TP_ARGS(inode, flags),
        TP_FIELDS(
                /* may be called for files on pseudo FSes w/ unregistered bdi */
-               ctf_string(name,
-                       inode->i_mapping->backing_dev_info->dev ?
-                               dev_name(inode->i_mapping->backing_dev_info->dev)
-                               : "(unknown)")
+               ctf_string(name, lttng_bdi_dev_name(inode->i_mapping->backing_dev_info))
                ctf_integer(unsigned long, ino, inode->i_ino)
                ctf_integer(unsigned long, flags, flags)
        )
@@ -179,8 +187,7 @@ LTTNG_TRACEPOINT_EVENT_CLASS(writeback_write_inode_template,
        TP_PROTO(struct inode *inode, struct writeback_control *wbc),
        TP_ARGS(inode, wbc),
        TP_FIELDS(
-               ctf_string(name,
-                       dev_name(inode->i_mapping->backing_dev_info->dev))
+               ctf_string(name, lttng_bdi_dev_name(inode->i_mapping->backing_dev_info))
                ctf_integer(unsigned long, ino, inode->i_ino)
                ctf_integer(int, sync_mode, wbc->sync_mode)
        )
@@ -201,35 +208,21 @@ LTTNG_TRACEPOINT_EVENT_CLASS(writeback_work_class,
        TP_PROTO(struct bdi_writeback *wb, struct wb_writeback_work *work),
        TP_ARGS(wb, work),
        TP_FIELDS(
-               ctf_string(name, wb->bdi->dev ? dev_name(wb->bdi->dev) :
-                               "(unknown)")
+               ctf_string(name, lttng_bdi_dev_name(wb->bdi))
        )
 )
 
-#elif (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,0,0))
-
-LTTNG_TRACEPOINT_EVENT_CLASS(writeback_work_class,
-       TP_PROTO(struct backing_dev_info *bdi, struct wb_writeback_work *work),
-       TP_ARGS(bdi, work),
-       TP_FIELDS(
-               ctf_string(name, bdi->dev ? dev_name(bdi->dev) :
-                               "(unknown)")
-       )
-)
-
-#else /* #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,0,0)) */
+#else
 
 LTTNG_TRACEPOINT_EVENT_CLASS(writeback_work_class,
        TP_PROTO(struct backing_dev_info *bdi, struct wb_writeback_work *work),
        TP_ARGS(bdi, work),
        TP_FIELDS(
-               ctf_string(name,
-                       dev_name(bdi->dev ? bdi->dev :
-                               default_backing_dev_info.dev))
+               ctf_string(name, lttng_bdi_dev_name(bdi))
        )
 )
 
-#endif /* #else #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,0,0)) */
+#endif /* #else if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,3,0)) */
 
 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,3,0))
 
@@ -270,8 +263,7 @@ LTTNG_TRACEPOINT_EVENT_CLASS(writeback_class,
        TP_PROTO(struct bdi_writeback *wb),
        TP_ARGS(wb),
        TP_FIELDS(
-               ctf_string(name,
-                       dev_name(wb->bdi->dev))
+               ctf_string(name, lttng_bdi_dev_name(wb->bdi))
        )
 )
 
@@ -290,8 +282,7 @@ LTTNG_TRACEPOINT_EVENT(writeback_bdi_register,
        TP_PROTO(struct backing_dev_info *bdi),
        TP_ARGS(bdi),
        TP_FIELDS(
-               ctf_string(name,
-                       dev_name(bdi->dev))
+               ctf_string(name, lttng_bdi_dev_name(bdi))
        )
 )
 
@@ -301,8 +292,7 @@ LTTNG_TRACEPOINT_EVENT_CLASS(writeback_class,
        TP_PROTO(struct backing_dev_info *bdi),
        TP_ARGS(bdi),
        TP_FIELDS(
-               ctf_string(name,
-                       dev_name(bdi->dev))
+               ctf_string(name, lttng_bdi_dev_name(bdi))
        )
 )
 
@@ -341,7 +331,7 @@ LTTNG_TRACEPOINT_EVENT_MAP(balance_dirty_written,
        TP_ARGS(bdi, written),
 
        TP_FIELDS(
-               ctf_string(name, dev_name(bdi->dev))
+               ctf_string(name, lttng_bdi_dev_name(bdi))
                ctf_integer(int, written, written)
        )
 )
@@ -351,7 +341,7 @@ LTTNG_TRACEPOINT_EVENT_CLASS(writeback_wbc_class,
        TP_PROTO(struct writeback_control *wbc, struct backing_dev_info *bdi),
        TP_ARGS(wbc, bdi),
        TP_FIELDS(
-               ctf_string(name, dev_name(bdi->dev))
+               ctf_string(name, lttng_bdi_dev_name(bdi))
                ctf_integer(long, nr_to_write, wbc->nr_to_write)
                ctf_integer(long, pages_skipped, wbc->pages_skipped)
                ctf_integer(int, sync_mode, wbc->sync_mode)
@@ -399,7 +389,7 @@ LTTNG_TRACEPOINT_EVENT(writeback_queue_io,
                 int moved),
        TP_ARGS(wb, work, dirtied_before, moved),
        TP_FIELDS(
-               ctf_string(name, dev_name(wb->bdi->dev))
+               ctf_string(name, lttng_bdi_dev_name(wb->bdi))
                ctf_integer(unsigned long, older, dirtied_before)
                ctf_integer(int, moved, moved)
        )
@@ -411,7 +401,7 @@ LTTNG_TRACEPOINT_EVENT(writeback_queue_io,
                 int moved),
        TP_ARGS(wb, work, moved),
        TP_FIELDS(
-               ctf_string(name, dev_name(wb->bdi->dev))
+               ctf_string(name, lttng_bdi_dev_name(wb->bdi))
                ctf_integer(int, moved, moved)
        )
 )
@@ -422,7 +412,7 @@ LTTNG_TRACEPOINT_EVENT(writeback_queue_io,
                 int moved),
        TP_ARGS(wb, older_than_this, moved),
        TP_FIELDS(
-               ctf_string(name, dev_name(wb->bdi->dev))
+               ctf_string(name, lttng_bdi_dev_name(wb->bdi))
                ctf_integer(unsigned long, older,
                        older_than_this ? *older_than_this : 0)
                ctf_integer(long, age,
@@ -524,7 +514,7 @@ LTTNG_TRACEPOINT_EVENT_MAP(bdi_dirty_ratelimit,
        TP_ARGS(wb, dirty_rate, task_ratelimit),
 
        TP_FIELDS(
-               ctf_string(bdi, dev_name(wb->bdi->dev))
+               ctf_string(bdi, lttng_bdi_dev_name(wb->bdi))
                ctf_integer(unsigned long, write_bw, KBps(wb->bdi->wb.write_bandwidth))
                ctf_integer(unsigned long, avg_write_bw, KBps(wb->bdi->wb.avg_write_bandwidth))
                ctf_integer(unsigned long, dirty_rate, KBps(dirty_rate))
@@ -548,7 +538,7 @@ LTTNG_TRACEPOINT_EVENT_MAP(bdi_dirty_ratelimit,
        TP_ARGS(bdi, dirty_rate, task_ratelimit),
 
        TP_FIELDS(
-               ctf_string(bdi, dev_name(bdi->dev))
+               ctf_string(bdi, lttng_bdi_dev_name(bdi))
                ctf_integer(unsigned long, write_bw, KBps(bdi->wb.write_bandwidth))
                ctf_integer(unsigned long, avg_write_bw, KBps(bdi->wb.avg_write_bandwidth))
                ctf_integer(unsigned long, dirty_rate, KBps(dirty_rate))
@@ -572,7 +562,7 @@ LTTNG_TRACEPOINT_EVENT_MAP(bdi_dirty_ratelimit,
        TP_ARGS(bdi, dirty_rate, task_ratelimit),
 
        TP_FIELDS(
-               ctf_string(bdi, dev_name(bdi->dev))
+               ctf_string(bdi, lttng_bdi_dev_name(bdi))
                ctf_integer(unsigned long, write_bw, KBps(bdi->write_bandwidth))
                ctf_integer(unsigned long, avg_write_bw, KBps(bdi->avg_write_bandwidth))
                ctf_integer(unsigned long, dirty_rate, KBps(dirty_rate))
@@ -610,7 +600,7 @@ LTTNG_TRACEPOINT_EVENT_MAP(balance_dirty_pages,
        ),
 
        TP_FIELDS(
-               ctf_string(bdi, dev_name(wb->bdi->dev))
+               ctf_string(bdi, lttng_bdi_dev_name(wb->bdi))
                ctf_integer(unsigned long, limit, global_dirty_limit)
                ctf_integer(unsigned long, setpoint,
                        (global_dirty_limit + (thresh + bg_thresh) / 2) / 2)
@@ -668,7 +658,7 @@ LTTNG_TRACEPOINT_EVENT_MAP(balance_dirty_pages,
        ),
 
        TP_FIELDS(
-               ctf_string(bdi, dev_name(bdi->dev))
+               ctf_string(bdi, lttng_bdi_dev_name(bdi))
                ctf_integer(unsigned long, limit, global_dirty_limit)
                ctf_integer(unsigned long, setpoint,
                        (global_dirty_limit + (thresh + bg_thresh) / 2) / 2)
@@ -707,8 +697,7 @@ LTTNG_TRACEPOINT_EVENT(writeback_sb_inodes_requeue,
        TP_ARGS(inode),
 
        TP_FIELDS(
-               ctf_string(name,
-                       dev_name(lttng_inode_to_bdi(inode)->dev))
+               ctf_string(name, lttng_bdi_dev_name(lttng_inode_to_bdi(inode)))
                ctf_integer(unsigned long, ino, inode->i_ino)
                ctf_integer(unsigned long, state, inode->i_state)
                ctf_integer(unsigned long, dirtied_when, inode->dirtied_when)
@@ -753,8 +742,7 @@ LTTNG_TRACEPOINT_EVENT_CLASS(writeback_single_inode_template,
        TP_ARGS(inode, wbc, nr_to_write),
 
        TP_FIELDS(
-               ctf_string(name,
-                       dev_name(lttng_inode_to_bdi(inode)->dev))
+               ctf_string(name, lttng_bdi_dev_name(lttng_inode_to_bdi(inode)))
                ctf_integer(unsigned long, ino, inode->i_ino)
                ctf_integer(unsigned long, state, inode->i_state)
                ctf_integer(unsigned long, dirtied_when, inode->dirtied_when)
This page took 0.029767 seconds and 4 git commands to generate.