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:50 +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

instrumentation/events/lttng-module/writeback.h

index d973007efc72353a8904eba08c94a582e9cb1b0c..4c2a757236a01b3f2586704a8490392396f8df58 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
@@ -81,8 +97,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)
        )
@@ -93,9 +108,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)
@@ -113,8 +126,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)
        )
@@ -133,8 +145,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)
        )
@@ -145,10 +156,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)
        )
@@ -164,8 +172,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)
        )
@@ -186,35 +193,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)")
-       )
-)
-
-#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)")
+               ctf_string(name, lttng_bdi_dev_name(wb->bdi))
        )
 )
 
-#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))
 
@@ -255,8 +248,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))
        )
 )
 
@@ -275,8 +267,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))
        )
 )
 
@@ -286,8 +277,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))
        )
 )
 
@@ -328,7 +318,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)
        )
 )
@@ -338,7 +328,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)
@@ -386,7 +376,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)
        )
@@ -398,7 +388,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)
        )
 )
@@ -409,7 +399,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,
@@ -488,7 +478,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))
@@ -512,7 +502,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))
@@ -536,7 +526,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))
@@ -574,7 +564,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)
@@ -632,7 +622,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)
@@ -671,8 +661,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)
@@ -719,8 +708,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.029752 seconds and 4 git commands to generate.