mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
blk-mq: add one API for waiting until quiesce is done
Some drivers(NVMe, SCSI) need to call quiesce and unquiesce in pair, but it is hard to switch to this style, so these drivers need one atomic flag for helping to balance quiesce and unquiesce. When quiesce is in-progress, the driver still needs to wait until the quiesce is done, so add API of blk_mq_wait_quiesce_done() for these drivers. Signed-off-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Link: https://lore.kernel.org/r/20211109071144.181581-2-ming.lei@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
a846a8e6c9
commit
9ef4d0209c
@ -250,6 +250,30 @@ void blk_mq_quiesce_queue_nowait(struct request_queue *q)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue_nowait);
|
||||
|
||||
/**
|
||||
* blk_mq_wait_quiesce_done() - wait until in-progress quiesce is done
|
||||
* @q: request queue.
|
||||
*
|
||||
* Note: it is driver's responsibility for making sure that quiesce has
|
||||
* been started.
|
||||
*/
|
||||
void blk_mq_wait_quiesce_done(struct request_queue *q)
|
||||
{
|
||||
struct blk_mq_hw_ctx *hctx;
|
||||
unsigned int i;
|
||||
bool rcu = false;
|
||||
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
if (hctx->flags & BLK_MQ_F_BLOCKING)
|
||||
synchronize_srcu(hctx->srcu);
|
||||
else
|
||||
rcu = true;
|
||||
}
|
||||
if (rcu)
|
||||
synchronize_rcu();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_mq_wait_quiesce_done);
|
||||
|
||||
/**
|
||||
* blk_mq_quiesce_queue() - wait until all ongoing dispatches have finished
|
||||
* @q: request queue.
|
||||
@ -261,20 +285,8 @@ EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue_nowait);
|
||||
*/
|
||||
void blk_mq_quiesce_queue(struct request_queue *q)
|
||||
{
|
||||
struct blk_mq_hw_ctx *hctx;
|
||||
unsigned int i;
|
||||
bool rcu = false;
|
||||
|
||||
blk_mq_quiesce_queue_nowait(q);
|
||||
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
if (hctx->flags & BLK_MQ_F_BLOCKING)
|
||||
synchronize_srcu(hctx->srcu);
|
||||
else
|
||||
rcu = true;
|
||||
}
|
||||
if (rcu)
|
||||
synchronize_rcu();
|
||||
blk_mq_wait_quiesce_done(q);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue);
|
||||
|
||||
|
@ -803,6 +803,7 @@ void blk_mq_start_hw_queues(struct request_queue *q);
|
||||
void blk_mq_start_stopped_hw_queue(struct blk_mq_hw_ctx *hctx, bool async);
|
||||
void blk_mq_start_stopped_hw_queues(struct request_queue *q, bool async);
|
||||
void blk_mq_quiesce_queue(struct request_queue *q);
|
||||
void blk_mq_wait_quiesce_done(struct request_queue *q);
|
||||
void blk_mq_unquiesce_queue(struct request_queue *q);
|
||||
void blk_mq_delay_run_hw_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs);
|
||||
void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async);
|
||||
|
Loading…
Reference in New Issue
Block a user