Skip to content

Commit

Permalink
fs/ext4: fix a lockup when writing blocks into ext4 rootfs
Browse files Browse the repository at this point in the history
Writing blocks or syncing on ext4 rootfs has caused a lockup with
the following call trace. Fix that by converting the original segment
traversal into a page-based iteration in ext4_finish_bio():

[  480.751901] INFO: task sync:4424 blocked for more than 120 seconds.
[  480.753064]       Not tainted 3.18.0-00025-g46c8231 torvalds#39
[  480.753720] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message.
[  480.754737] sync            D ffff88001fc11180     0  4424   4338
0x00000000
[  480.755719]  ffff88001cdfbc98 0000000000000086 ffff88001cdfbba8
ffff880014adefc0
[  480.756810]  0000000000011180 0000000000004000 ffffffff81813460
ffff880014adefc0
[  480.758102]  ffff88001cdfbbc8 ffffffff812f08be ffff88001cdfbc18
ffff880014adf028
[  480.759454] Call Trace:
[  480.759852]  [<ffffffff812f08be>] ? debug_smp_processor_id+0x17/0x19
[  480.760609]  [<ffffffff8106093e>] ? __enqueue_entity+0x69/0x6b
[  480.761318]  [<ffffffff8106017e>] ? __dequeue_entity+0x33/0x38
[  480.762026]  [<ffffffff810601ab>] ? set_next_entity+0x28/0x7d
[  480.762739]  [<ffffffff8105a4fb>] ? get_parent_ip+0xf/0x3f
[  480.763425]  [<ffffffff8108562b>] ? ktime_get+0x50/0x8f
[  480.763848]  [<ffffffff8148abdb>] ? bit_wait_timeout+0x60/0x60
[  480.764555]  [<ffffffff8148a6be>] schedule+0x6a/0x6c
[  480.765186]  [<ffffffff8148a74f>] io_schedule+0x8f/0xcd
[  480.765841]  [<ffffffff8148ac19>] bit_wait_io+0x3e/0x42
[  480.766493]  [<ffffffff8148ae80>] __wait_on_bit+0x4d/0x86
[  480.767183]  [<ffffffff810d4302>] ? find_get_pages_tag+0x106/0x133
[  480.767847]  [<ffffffff810d4a63>] wait_on_page_bit+0x76/0x78
[  480.768532]  [<ffffffff8106ab59>] ? wake_atomic_t_function+0x2d/0x2d
[  480.769262]  [<ffffffff810d511f>] filemap_fdatawait_range+0x7e/0x11d
[  480.769992]  [<ffffffff8148a639>] ? preempt_schedule+0x36/0x51
[  480.770677]  [<ffffffff8105a4fb>] ? get_parent_ip+0xf/0x3f
[  480.771848]  [<ffffffff810d51df>] filemap_fdatawait+0x21/0x23
[  480.772530]  [<ffffffff811458ce>] sync_inodes_sb+0x158/0x1aa
[  480.773201]  [<ffffffff81480303>] ? br_mdb_dump+0x225/0x495
[  480.773885]  [<ffffffff81149ad8>] ? fdatawrite_one_bdev+0x18/0x18
[  480.774592]  [<ffffffff81149aec>] sync_inodes_one_sb+0x14/0x16
[  480.775278]  [<ffffffff81125937>] iterate_supers+0x6f/0xc4
[  480.775847]  [<ffffffff81149bf4>] sys_sync+0x35/0x83
[  480.776460]  [<ffffffff8148da52>] system_call_fastpath+0x12/0x17

Reported-by: Ming Lin <mlin@minggr.net>
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
  • Loading branch information
Kent Overstreet authored and Dongsu Park committed Dec 29, 2014
1 parent 1fefb13 commit 7708786
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions fs/ext4/page-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ static void buffer_io_error(struct buffer_head *bh)

static void ext4_finish_bio(struct bio *bio)
{
int i;
int error = !test_bit(BIO_UPTODATE, &bio->bi_flags);
struct bio_vec *bvec;
struct bio_vec bvec;
struct bvec_iter iter;

bio_for_each_segment_all(bvec, bio, i) {
struct page *page = bvec->bv_page;
bio_for_each_page_all(bvec, bio, iter) {
struct page *page = bvec.bv_page;
struct buffer_head *bh, *head;
unsigned bio_start = bvec->bv_offset;
unsigned bio_end = bio_start + bvec->bv_len;
unsigned bio_start = bvec.bv_offset;
unsigned bio_end = bio_start + bvec.bv_len;
unsigned under_io = 0;
unsigned long flags;

Expand Down

0 comments on commit 7708786

Please sign in to comment.