Re: Crash in writeback:single_inode tracepoint after card removal

From: Rabin Vincent
Date: Wed Jan 18 2012 - 15:10:16 EST


On Tue, Jan 17, 2012 at 09:02, Wu Fengguang <fengguang.wu@xxxxxxxxx> wrote:
> On Sun, Jan 15, 2012 at 08:58:06PM +0530, Rabin Vincent wrote:
>>  Unable to handle kernel NULL pointer dereference at virtual address 0000002c
>>  pgd = c0004000
>>  [0000002c] *pgd=00000000
>>  Internal error: Oops: 17 [#1] PREEMPT SMP
>>  PC is at ftrace_raw_event_writeback_single_inode_template+0x60/0xe4
>>  LR is at ftrace_raw_event_writeback_single_inode_template+0x50/0xe4
>>
>> The full trace+log is attached.  My kernel (current linus) has a delay
>> inserted in __mark_inode_dirty, to easily trigger the condition:
>
> Rabin, thanks for showing the helpful details! It should be fixable by
> the use of inode_to_bdi():

Thanks, this fixes that one.

However, I've found one more race condition leading to a crash when
tracing is enabled, this time from the writeback:queue trace point from
bdi_queue_work(). The cause is the same, i.e. bdi->dev is NULL. This
was produced with the help of the following delay patch. trace+log is
attached.

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 424a655..fe9f8f2 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -106,9 +106,21 @@ static void bdi_wakeup_flusher(struct
backing_dev_info *bdi)
}
}

+#include <linux/delay.h>
+
static void bdi_queue_work(struct backing_dev_info *bdi,
struct wb_writeback_work *work)
{
+ if (!strcmp(current->comm, "sync") && work->sb) {
+ trace_printk("waiting 6s\n");
+ printk("%s: waiting 6s, pull out card\n", __func__);
+
+ msleep(6000);
+
+ trace_printk("done waiting\n");
+ printk("%s: done waiting\n", __func__);
+ }
+
trace_writeback_queue(bdi, work);

spin_lock_bh(&bdi->wb_lock);

Attachment: log.gz
Description: GNU Zip compressed data