From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-eopbgr720126.outbound.protection.outlook.com ([40.107.72.126]:5968 "EHLO NAM05-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727728AbeH3WLA (ORCPT ); Thu, 30 Aug 2018 18:11:00 -0400 From: Sasha Levin To: "stable@vger.kernel.org" CC: Jianchao Wang , Jens Axboe , Sasha Levin Subject: [PATCH AUTOSEL 4.18 074/113] blk-mq: count the hctx as active before allocating tag Date: Thu, 30 Aug 2018 18:07:32 +0000 Message-ID: <20180830180714.36167-8-alexander.levin@microsoft.com> References: <20180830180714.36167-1-alexander.levin@microsoft.com> In-Reply-To: <20180830180714.36167-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Jianchao Wang [ Upstream commit d263ed9926823c462f99a7679e18f0c9e5b8550d ] Currently, we count the hctx as active after allocate driver tag successfully. If a previously inactive hctx try to get tag first time, it may fails and need to wait. However, due to the stale tag ->active_queues, the other shared-tags users are still able to occupy all driver tags while there is someone waiting for tag. Consequently, even if the previously inactive hctx is waked up, it still may not be able to get a tag and could be starved. To fix it, we count the hctx as active before try to allocate driver tag, then when it is waiting the tag, the other shared-tag users will reserve budget for it. Reviewed-by: Ming Lei Signed-off-by: Jianchao Wang Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- block/blk-mq-tag.c | 3 +++ block/blk-mq.c | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index 3de0836163c2..d5f2c21d8531 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c @@ -23,6 +23,9 @@ bool blk_mq_has_free_tags(struct blk_mq_tags *tags) =20 /* * If a previously inactive queue goes active, bump the active user count. + * We need to do this before try to allocate driver tag, then even if fail + * to get tag when first time, the other shared-tag users could reserve + * budget for it. */ bool __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx) { diff --git a/block/blk-mq.c b/block/blk-mq.c index 654b0dc7e001..2f9e14361673 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -285,7 +285,7 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq= _alloc_data *data, rq->tag =3D -1; rq->internal_tag =3D tag; } else { - if (blk_mq_tag_busy(data->hctx)) { + if (data->hctx->flags & BLK_MQ_F_TAG_SHARED) { rq_flags =3D RQF_MQ_INFLIGHT; atomic_inc(&data->hctx->nr_active); } @@ -367,6 +367,8 @@ static struct request *blk_mq_get_request(struct reques= t_queue *q, if (!op_is_flush(op) && e->type->ops.mq.limit_depth && !(data->flags & BLK_MQ_REQ_RESERVED)) e->type->ops.mq.limit_depth(op, data); + } else { + blk_mq_tag_busy(data->hctx); } =20 tag =3D blk_mq_get_tag(data); @@ -970,6 +972,7 @@ bool blk_mq_get_driver_tag(struct request *rq, struct b= lk_mq_hw_ctx **hctx, .hctx =3D blk_mq_map_queue(rq->q, rq->mq_ctx->cpu), .flags =3D wait ? 0 : BLK_MQ_REQ_NOWAIT, }; + bool shared; =20 might_sleep_if(wait); =20 @@ -979,9 +982,10 @@ bool blk_mq_get_driver_tag(struct request *rq, struct = blk_mq_hw_ctx **hctx, if (blk_mq_tag_is_reserved(data.hctx->sched_tags, rq->internal_tag)) data.flags |=3D BLK_MQ_REQ_RESERVED; =20 + shared =3D blk_mq_tag_busy(data.hctx); rq->tag =3D blk_mq_get_tag(&data); if (rq->tag >=3D 0) { - if (blk_mq_tag_busy(data.hctx)) { + if (shared) { rq->rq_flags |=3D RQF_MQ_INFLIGHT; atomic_inc(&data.hctx->nr_active); } --=20 2.17.1