[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20120115152806.GA32106@debian>
Date: Sun, 15 Jan 2012 20:58:06 +0530
From: Rabin Vincent <rabin@....in>
To: fengguang.wu@...el.com
Cc: linux-kernel@...r.kernel.org
Subject: Crash in writeback:single_inode tracepoint after card removal
I'm testing SD card removal, and with tracing enabled I'm seeing a crash
in the writeback:single_inode event sometimes when a umount is done
after a card is removed with pending io. When the problem occurs,
writeback is begin attempted with the default_backing_dev_info. The
block bdi which was handling this device has been unregistered and it's
bdi->dev is NULL. However it is still referenced by
inode->i_mapping->backing_dev_info, and the trace point does the
following, leading to the oops:
TP_fast_assign(
strncpy(__entry->name,
dev_name(inode->i_mapping->backing_dev_info->dev),
32);
umount-33 0.... 10973110us : writeback_inodes_sb <-__sync_filesystem
umount-33 0.... 10973248us : writeback_inodes_sb_nr <-__sync_filesystem
umount-33 0.... 10973289us : bdi_queue_work <-writeback_inodes_sb_nr
umount-33 0...1 10973336us : writeback_queue: bdi default: sb_dev 179:0 nr_pages=2153 sync_mode=0 kupdate=0 range_cyclic=0 background=0 reason=sync
bdi-defa-14 1.... 10974021us : wb_do_writeback <-bdi_forker_thread
bdi-defa-14 1...1 10974041us : writeback_exec: bdi default: sb_dev 179:0 nr_pages=2153 sync_mode=0 kupdate=0 range_cyclic=0 background=0 reason=sync
bdi-defa-14 1.... 10974053us : wb_writeback <-wb_do_writeback
bdi-defa-14 1...2 10974059us : writeback_start: bdi default: sb_dev 179:0 nr_pages=2153 sync_mode=0 kupdate=0 range_cyclic=0 background=0 reason=sync
bdi-defa-14 1...2 10974093us : writeback_queue_io: bdi default: older=4294939114 age=0 enqueue=2 reason=sync
bdi-defa-14 1...1 10974101us : writeback_sb_inodes <-wb_writeback
bdi-defa-14 1...2 10974166us : writeback_single_inode <-writeback_sb_inodes
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:
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index f855916..424a655 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1057,6 +1057,7 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
* page->mapping->host, so the page-dirtying time is recorded in the internal
* blockdev inode.
*/
+#include <linux/delay.h>
void __mark_inode_dirty(struct inode *inode, int flags)
{
struct super_block *sb = inode->i_sb;
@@ -1131,6 +1132,8 @@ void __mark_inode_dirty(struct inode *inode, int flags)
wakeup_bdi = true;
}
+ trace_printk("bdi %s\n", bdi->name);
+
spin_unlock(&inode->i_lock);
spin_lock(&bdi->wb.list_lock);
inode->dirtied_when = jiffies;
@@ -1139,6 +1142,14 @@ void __mark_inode_dirty(struct inode *inode, int flags)
if (wakeup_bdi)
bdi_wakeup_thread_delayed(bdi);
+
+ if (!strcmp(bdi->name, "block")) {
+ printk("waiting 6s, remove card\n");
+ trace_printk("waiting 6s, remove card\n");
+ msleep(6000);
+ printk("done waiting\n");
+ trace_printk("done waiting\n");
+ }
return;
}
}
View attachment "wblog" of type "text/plain" (38334 bytes)
Powered by blists - more mailing lists