Skip to content

Commit 5aa0f92

Browse files
Fengnan ChangMikulas Patocka
authored andcommitted
dm: limit target bio polling to one shot
dm_poll_bio() is the ->poll_bio() callback for a stacked dm device. The caller only knows about the dm queue, so it may decide to do a spinning poll if it thinks a single queue is being polled. Passing those flags unchanged to the mapped clone lets blk_mq_poll() spin on a target queue from inside dm_poll_bio(). With io_uring IOPOLL on a dm-stripe target this can keep a task in dm_poll_bio() -> bio_poll() -> blk_mq_poll() long enough to trigger an RCU CPU stall, before io_uring gets back to io_iopoll_check() and its need_resched() check. Keep dm's ->poll_bio() bounded by forcing one-shot polling for target bios. The caller can invoke dm_poll_bio() again if it wants to keep polling, and it also gets a chance to reap completions or reschedule between passes. Fixes: f22ecf9 ("blk-mq: delete task running check in blk_hctx_poll()") Signed-off-by: Fengnan Chang <changfengnan@bytedance.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
1 parent 457e323 commit 5aa0f92

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

drivers/md/dm.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,8 +2098,17 @@ static bool dm_poll_dm_io(struct dm_io *io, struct io_comp_batch *iob,
20982098
WARN_ON_ONCE(!dm_tio_is_normal(&io->tio));
20992099

21002100
/* don't poll if the mapped io is done */
2101-
if (atomic_read(&io->io_count) > 1)
2102-
bio_poll(&io->tio.clone, iob, flags);
2101+
if (atomic_read(&io->io_count) > 1) {
2102+
/*
2103+
* DM hides the target queues from the upper poller, which may
2104+
* decide it is safe to spin on a single stacked queue. Do not
2105+
* pass that spinning policy down to a target queue: one slow
2106+
* clone could keep the task inside dm_poll_bio() for a long
2107+
* time. Poll target bios once and let the caller decide
2108+
* whether to keep polling, reap completions or reschedule.
2109+
*/
2110+
bio_poll(&io->tio.clone, iob, flags | BLK_POLL_ONESHOT);
2111+
}
21032112

21042113
/* bio_poll holds the last reference */
21052114
return atomic_read(&io->io_count) == 1;

0 commit comments

Comments
 (0)