diff options
author | Xiao Ni <xni@redhat.com> | 2023-02-03 06:13:44 +0100 |
---|---|---|
committer | Song Liu <song@kernel.org> | 2023-02-09 00:46:57 +0100 |
commit | 76fed01420bb8b0e282745a4945925b25751d42b (patch) | |
tree | cfd8694bedd41a4a5cb6a3a9c7899704182fcfe4 /drivers/md/md.h | |
parent | block: ublk: improve handling device deletion (diff) | |
download | linux-76fed01420bb8b0e282745a4945925b25751d42b.tar.xz linux-76fed01420bb8b0e282745a4945925b25751d42b.zip |
md: account io_acct_set usage with active_io
io_acct_set was enabled for raid0/raid5 io accounting. bios that contain
md_io_acct are allocated in the i/o path. There isn't a good method to
monitor if these bios are all finished and freed. In the takeover process,
io_acct_set (which is used for bios with md_io_acct) need to be freed.
However, if some bios finish after io_acct_set is freed, it may trigger
the following panic:
[ 6973.767999] RIP: 0010:mempool_free+0x52/0x80
[ 6973.786098] Call Trace:
[ 6973.786549] md_end_io_acct+0x31/0x40
[ 6973.787227] blk_update_request+0x224/0x380
[ 6973.787994] blk_mq_end_request+0x1a/0x130
[ 6973.788739] blk_complete_reqs+0x35/0x50
[ 6973.789456] __do_softirq+0xd7/0x2c8
[ 6973.790114] ? sort_range+0x20/0x20
[ 6973.790763] run_ksoftirqd+0x2a/0x40
[ 6973.791400] smpboot_thread_fn+0xb5/0x150
[ 6973.792114] kthread+0x10b/0x130
[ 6973.792724] ? set_kthread_struct+0x50/0x50
[ 6973.793491] ret_from_fork+0x1f/0x40
Fix this by increasing and decreasing active_io for each bio with
md_io_acct so that mddev_suspend() will wait until all bios from
io_acct_set finish before freeing io_acct_set.
Reported-by: Fine Fan <ffan@redhat.com>
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Song Liu <song@kernel.org>
Diffstat (limited to '')
-rw-r--r-- | drivers/md/md.h | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/md/md.h b/drivers/md/md.h index 6335cb86e52e..e148e3c83b0d 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -710,9 +710,10 @@ struct md_thread { }; struct md_io_acct { - struct bio *orig_bio; - unsigned long start_time; - struct bio bio_clone; + struct mddev *mddev; + struct bio *orig_bio; + unsigned long start_time; + struct bio bio_clone; }; #define THREAD_WAKEUP 0 |