提交 13014827 编写于 作者: D Di Wang 提交者: Yang Yingliang

nvme: fix nvme_stop_queues cost long time error

driver inclusion
category: bugfix
bugzilla: NA
Link: https://gitee.com/openeuler/kernel/issues/I1WGZE

--------------------------------

It will cost a lot of time when synchronize_rcu() is called for every
namspace in nvme_stop_queues().
Reviewed-by: NChao Leng <lengchao@huawei.com>
Reviewed-by: NJike Cheng <chengjike.cheng@huawei.com>
Signed-off-by: NDi Wang <wangdi44@huawei.com>
Signed-off-by: NLijie <lijie34@huawei.com>
Acked-by: NHanjun Guo <guohanjun@huawei.com>
Reviewed-by: NHou Tao <houtao1@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 fecfff95
...@@ -242,6 +242,24 @@ void blk_mq_quiesce_queue(struct request_queue *q) ...@@ -242,6 +242,24 @@ void blk_mq_quiesce_queue(struct request_queue *q)
} }
EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue); EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue);
bool blk_mq_quiesce_queue_without_rcu(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;
}
return rcu;
}
EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue_without_rcu);
/* /*
* blk_mq_unquiesce_queue() - counterpart of blk_mq_quiesce_queue() * blk_mq_unquiesce_queue() - counterpart of blk_mq_quiesce_queue()
* @q: request queue. * @q: request queue.
......
...@@ -3904,11 +3904,15 @@ EXPORT_SYMBOL_GPL(nvme_start_freeze); ...@@ -3904,11 +3904,15 @@ EXPORT_SYMBOL_GPL(nvme_start_freeze);
void nvme_stop_queues(struct nvme_ctrl *ctrl) void nvme_stop_queues(struct nvme_ctrl *ctrl)
{ {
struct nvme_ns *ns; struct nvme_ns *ns;
bool rcu = false;
down_read(&ctrl->namespaces_rwsem); down_read(&ctrl->namespaces_rwsem);
list_for_each_entry(ns, &ctrl->namespaces, list) list_for_each_entry(ns, &ctrl->namespaces, list)
blk_mq_quiesce_queue(ns->queue); rcu = (blk_mq_quiesce_queue_without_rcu(ns->queue) || rcu);
up_read(&ctrl->namespaces_rwsem); up_read(&ctrl->namespaces_rwsem);
if (rcu)
synchronize_rcu();
} }
EXPORT_SYMBOL_GPL(nvme_stop_queues); EXPORT_SYMBOL_GPL(nvme_stop_queues);
......
...@@ -309,6 +309,7 @@ void blk_mq_start_hw_queues(struct request_queue *q); ...@@ -309,6 +309,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_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_start_stopped_hw_queues(struct request_queue *q, bool async);
void blk_mq_quiesce_queue(struct request_queue *q); void blk_mq_quiesce_queue(struct request_queue *q);
bool blk_mq_quiesce_queue_without_rcu(struct request_queue *q);
void blk_mq_unquiesce_queue(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_delay_run_hw_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs);
bool blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async); bool blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册