- 论坛徽章:
- 0
|
本帖最后由 chenyu105 于 2014-06-10 10:30 编辑
内核版本 2.6.32
cpu 架构 mips64
复现方法是大IO下,不停的插拔usb
异常现场如下:
- CPU 1 Unable to handle kernel paging request at virtual address 6b6b6b6b6b6b6b9b, epc == ffffffffc07127c4, ra == ffffffffc071271c
- [<ffffffffc0638b1c>] die+0xa4/0x130
- [<ffffffffc06491a0>] do_page_fault+0x2e8/0x3b8
- [<ffffffffc0601024>] ret_from_exception+0x0/0x10
- [<ffffffffc07127c4>] __mark_inode_dirty+0x124/0x1f8
- [<ffffffffc0776c30>] ext3_put_super+0xb8/0x2c8
- [<ffffffffc06ec454>] generic_shutdown_super+0x7c/0x130
- [<ffffffffc06ec52c>] kill_block_super+0x24/0x50
- [<ffffffffc06ed57c>] deactivate_super+0x94/0xc0
- [<ffffffffc070b438>] SyS_umount+0xb8/0x4e8
- [<ffffffffc06038c4>] handle_sys64+0x44/0x60
复制代码 出错的C代码位置是下面的bdi_cap_writeback_dirty(bdi),即尝试访问bdi->bdi->capabilities时,
由于bdi为6b6b6b6b6b6b6b6b,导致出错。- void __mark_inode_dirty(struct inode *inode, int flags)
- {
- struct super_block *sb = inode->i_sb;
- if (!was_dirty) {
- struct bdi_writeback *wb = &inode_to_bdi(inode)->wb;
- struct backing_dev_info *bdi = wb->bdi;
- if (bdi_cap_writeback_dirty(bdi)
复制代码 错误位置,大概是inode_to_bdi 返回的backing_dev_info结构体内的bdi_writeback成员,
其bdi的值有问题。 根据错误地址6b6b6b6b6b6b6b9b
可以知道,这个bdi_writeback成员指向的bdi的值,已经被slab释放了。- #define POISON_FREE 0x6b /* for use-after-free poisoning */
复制代码 我查了下目前内核对inode_to_bdi的补丁,感觉下面这个补丁修改了inode_to_bdi实现,
但感觉和这个故障没太大联系。大家看看这个是不是什么新的bug?- diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
- index 5581122..ab38fef 100644
- --- a/fs/fs-writeback.c
- +++ b/fs/fs-writeback.c
- @@ -72,22 +72,11 @@ int writeback_in_progress(struct backing_dev_info *bdi)
- static inline struct backing_dev_info *inode_to_bdi(struct inode *inode)
- {
- struct super_block *sb = inode->i_sb;
- - struct backing_dev_info *bdi = inode->i_mapping->backing_dev_info;
- - /*
- - * For inodes on standard filesystems, we use superblock's bdi. For
- - * inodes on virtual filesystems, we want to use inode mapping's bdi
- - * because they can possibly point to something useful (think about
- - * block_dev filesystem).
- - */
- - if (sb->s_bdi && sb->s_bdi != &noop_backing_dev_info) {
- - /* Some device inodes could play dirty tricks. Catch them... */
- - WARN(bdi != sb->s_bdi && bdi_cap_writeback_dirty(bdi),
- - "Dirtiable inode bdi %s != sb bdi %s\n",
- - bdi->name, sb->s_bdi->name);
- - return sb->s_bdi;
- - }
- - return bdi;
- + if (strcmp(sb->s_type->name, "bdev") == 0)
- + return inode->i_mapping->backing_dev_info;
- +
- + return sb->s_bdi;
- }
复制代码 |
|