All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bart Van Assche <bvanassche@acm.org>
To: Jens Axboe <axboe@kernel.dk>, Khazhy Kumykov <khazhy@google.com>,
	John Garry <john.garry@huawei.com>
Cc: linux-block@vger.kernel.org, Christoph Hellwig <hch@lst.de>,
	"Martin K . Petersen" <martin.petersen@oracle.com>,
	Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>,
	Ming Lei <ming.lei@redhat.com>, Hannes Reinecke <hare@suse.de>,
	Johannes Thumshirn <johannes.thumshirn@wdc.com>
Subject: Re: [PATCH v5 3/3] blk-mq: Fix a race between iterating over requests and freeing requests
Date: Mon, 5 Apr 2021 18:06:25 -0700	[thread overview]
Message-ID: <2e8e4954-5e28-5f04-52c0-5f48424b4532@acm.org> (raw)
In-Reply-To: <54474b65-ffa4-9335-f7a2-5b49ccf169d4@kernel.dk>

On 4/5/21 2:34 PM, Jens Axboe wrote:
> For something out of left field, we can check if the page that the rq
> belongs to is still part of the tag set. If it isn't, then don't
> deref it.
> 
> Totally untested.
> 
> diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
> index e5bfecf2940d..6209c465e884 100644
> --- a/block/blk-mq-tag.c
> +++ b/block/blk-mq-tag.c
> @@ -196,9 +196,35 @@ struct bt_iter_data {
>  	struct blk_mq_hw_ctx *hctx;
>  	busy_iter_fn *fn;
>  	void *data;
> +	struct page *last_lookup;
>  	bool reserved;
>  };
>  
> +static bool rq_from_queue(struct bt_iter_data *iter_data, struct request *rq)
> +{
> +	struct blk_mq_hw_ctx *hctx = iter_data->hctx;
> +	struct page *rq_page, *page;
> +
> +	/*
> +	 * We can hit rq == NULL here, because the tagging functions
> +	 * test and set the bit before assigning ->rqs[].
> +	 */
> +	if (!rq)
> +		return false;
> +	rq_page = virt_to_page(rq);
> +	if (rq_page == iter_data->last_lookup)
> +		goto check_queue;
> +	list_for_each_entry(page, &hctx->tags->page_list, lru) {
> +		if (page == rq_page) {
> +			iter_data->last_lookup = page;
> +			goto check_queue;
> +		}
> +	}
> +	return false;
> +check_queue:
> +	return rq->q == hctx->queue && rq->mq_hctx == hctx;
> +}
> +
>  static bool bt_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
>  {
>  	struct bt_iter_data *iter_data = data;
> @@ -211,11 +237,7 @@ static bool bt_iter(struct sbitmap *bitmap, unsigned int bitnr, void *data)
>  		bitnr += tags->nr_reserved_tags;
>  	rq = tags->rqs[bitnr];
>  
> -	/*
> -	 * We can hit rq == NULL here, because the tagging functions
> -	 * test and set the bit before assigning ->rqs[].
> -	 */
> -	if (rq && rq->q == hctx->queue && rq->mq_hctx == hctx)
> +	if (rq_from_queue(iter_data, rq))
>  		return iter_data->fn(hctx, rq, iter_data->data, reserved);
>  	return true;
>  }

Hi Jens,

That's a very interesting suggestion. However, it seems to me that Khazhy's
suggestion will result in shorter and faster code?

Khazhy pointed out another race to me off-list, namely a race between updating
the number of hardware queues and iterating over the tags in a tag set. I'm
currently analyzing how to fix that race too.

Thanks,

Bart.



  reply	other threads:[~2021-04-06  1:06 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-05  0:28 [PATCH v5 0/3] blk-mq: Fix a race between iterating over requests and freeing requests Bart Van Assche
2021-04-05  0:28 ` [PATCH v5 1/3] blk-mq: Move the elevator_exit() definition Bart Van Assche
2021-04-05  0:28 ` [PATCH v5 2/3] blk-mq: Introduce atomic variants of the tag iteration functions Bart Van Assche
2021-04-05  0:28 ` [PATCH v5 3/3] blk-mq: Fix a race between iterating over requests and freeing requests Bart Van Assche
2021-04-05 18:08   ` Khazhy Kumykov
2021-04-05 21:34     ` Bart Van Assche
2021-04-06  0:24       ` Khazhy Kumykov
2021-04-05 21:34     ` Jens Axboe
2021-04-06  1:06       ` Bart Van Assche [this message]
2021-04-06  8:00 ` [PATCH v5 0/3] " John Garry
2021-04-06 17:49   ` Bart Van Assche
2021-04-07 15:12     ` John Garry

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2e8e4954-5e28-5f04-52c0-5f48424b4532@acm.org \
    --to=bvanassche@acm.org \
    --cc=axboe@kernel.dk \
    --cc=hare@suse.de \
    --cc=hch@lst.de \
    --cc=johannes.thumshirn@wdc.com \
    --cc=john.garry@huawei.com \
    --cc=khazhy@google.com \
    --cc=linux-block@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=ming.lei@redhat.com \
    --cc=shinichiro.kawasaki@wdc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.