All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bart Van Assche <bvanassche@acm.org>
To: Hannes Reinecke <hare@suse.de>,
	Keith Busch <keith.busch@intel.com>,
	linux-scsi@vger.kernel.org, linux-block@vger.kernel.org
Cc: Jens Axboe <axboe@kernel.dk>,
	Martin Petersen <martin.petersen@oracle.com>
Subject: Re: [PATCHv3 2/3] scsi: Do not rely on blk-mq for double completions
Date: Fri, 16 Nov 2018 06:46:40 -0800	[thread overview]
Message-ID: <1542379600.100259.38.camel@acm.org> (raw)
In-Reply-To: <05c4ea6a-9beb-063c-a91c-aca5826cc5b5@suse.de>

On Fri, 2018-11-16 at 10:53 +0100, Hannes Reinecke wrote:
> On 11/15/18 6:58 PM, Keith Busch wrote:
> > The scsi timeout error handling had been directly updating the block
> > layer's request state to prevent a error handling and a natural completion
> > from completing the same request twice. Fix this layering violation
> > by having scsi control the fate of its commands with scsi owned flags
> > rather than use blk-mq's.
> > 
> > Signed-off-by: Keith Busch <keith.busch@intel.com>
> > ---
> >   drivers/scsi/scsi_error.c | 22 +++++++++++-----------
> >   drivers/scsi/scsi_lib.c   |  6 +++++-
> >   include/scsi/scsi_cmnd.h  |  5 ++++-
> >   3 files changed, 20 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
> > index dd338a8cd275..e92e088f636f 100644
> > --- a/drivers/scsi/scsi_error.c
> > +++ b/drivers/scsi/scsi_error.c
> > @@ -297,19 +297,19 @@ enum blk_eh_timer_return scsi_times_out(struct request *req)
> >   
> >   	if (rtn == BLK_EH_DONE) {
> >   		/*
> > -		 * For blk-mq, we must set the request state to complete now
> > -		 * before sending the request to the scsi error handler. This
> > -		 * will prevent a use-after-free in the event the LLD manages
> > -		 * to complete the request before the error handler finishes
> > -		 * processing this timed out request.
> > +		 * Set the command to complete first in order to prevent a real
> > +		 * completion from releasing the command while error handling
> > +		 * is using it. If the command was already completed, then the
> > +		 * lower level driver beat the timeout handler, and it is safe
> > +		 * to return without escalating error recovery.
> >   		 *
> > -		 * If the request was already completed, then the LLD beat the
> > -		 * time out handler from transferring the request to the scsi
> > -		 * error handler. In that case we can return immediately as no
> > -		 * further action is required.
> > +		 * If timeout handling lost the race to a real completion, the
> > +		 * block layer may ignore that due to a fake timeout injection,
> > +		 * so return RESET_TIMER to allow error handling another shot
> > +		 * at this command.
> >   		 */
> > -		if (!blk_mq_mark_complete(req))
> > -			return rtn;
> > +		if (test_and_set_bit(__SCMD_COMPLETE, &scmd->flags))
> > +			return BLK_EH_RESET_TIMER;
> >   		if (scsi_abort_command(scmd) != SUCCESS) {
> >   			set_host_byte(scmd, DID_TIME_OUT);
> >   			scsi_eh_scmd_add(scmd);
> > diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> > index 5d83a162d03b..c1d5e4e36125 100644
> > --- a/drivers/scsi/scsi_lib.c
> > +++ b/drivers/scsi/scsi_lib.c
> > @@ -1635,8 +1635,11 @@ static blk_status_t scsi_mq_prep_fn(struct request *req)
> >   
> >   static void scsi_mq_done(struct scsi_cmnd *cmd)
> >   {
> > +	if (unlikely(test_and_set_bit(__SCMD_COMPLETE, &cmd->flags)))
> > +		return;
> >   	trace_scsi_dispatch_cmd_done(cmd);
> > -	blk_mq_complete_request(cmd->request);
> > +	if (unlikely(!blk_mq_complete_request(cmd->request)))
> > +		clear_bit(__SCMD_COMPLETE, &cmd->flags);
> >   }
> >   
> >   static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx)
> > @@ -1701,6 +1704,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
> >   			goto out_dec_host_busy;
> >   		req->rq_flags |= RQF_DONTPREP;
> >   	} else {
> > +		cmd->flags &= ~SCMD_COMPLETE;
> >   		blk_mq_start_request(req);
> >   	}
> >   
> 
> Why do you use a normal assignment here (and not a clear_bit() as in the 
> above hunk)?
> 
> And shouldn't you add a barrier here to broadcast the state change to 
> other cores?

Although I don't like it that request state information is being moved from 
the block layer core into the SCSI core, I think that this patch is fine.
scsi_queue_rq() is only called after a request structure has been recycled
so I don't think that there can be any kind of race between the code paths
that use atomic instructions to manipulate the __SCMD_COMPLETE bit and
scsi_queue_rq().

Bart.

  reply	other threads:[~2018-11-16 14:46 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-15 17:58 [PATCHv3 0/3] scsi timeout handling updates Keith Busch
2018-11-15 17:58 ` [PATCHv3 1/3] blk-mq: Return true if request was completed Keith Busch
2018-11-19  8:31   ` Christoph Hellwig
2018-11-15 17:58 ` [PATCHv3 2/3] scsi: Do not rely on blk-mq for double completions Keith Busch
2018-11-16  9:53   ` Hannes Reinecke
2018-11-16 14:46     ` Bart Van Assche [this message]
2018-11-19  8:58   ` Christoph Hellwig
2018-11-19 15:17     ` Jens Axboe
2018-11-19 15:19     ` Keith Busch
2018-11-21 13:12       ` Christoph Hellwig
2018-11-26 15:32         ` Jens Axboe
2018-11-26 15:31           ` Keith Busch
2018-11-15 17:58 ` [PATCHv3 3/3] blk-mq: Simplify request completion state Keith Busch
2018-11-19  8:58   ` Christoph Hellwig
2018-11-15 19:53 ` [PATCHv3 0/3] scsi timeout handling updates Jens Axboe

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=1542379600.100259.38.camel@acm.org \
    --to=bvanassche@acm.org \
    --cc=axboe@kernel.dk \
    --cc=hare@suse.de \
    --cc=keith.busch@intel.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.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.