From: wenxiong@linux.vnet.ibm.com
To: Brian King <brking@linux.vnet.ibm.com>
Cc: James.Bottomley@hansenpartnership.com, hch@infradead.org,
linuxppc-dev@lists.ozlabs.org, stable@vger.kernel.org,
linux-scsi@vger.kernel.org
Subject: Re: [PATCH 3/3] ipr: Wait for aborted command responses
Date: Fri, 31 Oct 2014 11:23:44 -0400 [thread overview]
Message-ID: <20141031112344.Horde.Fuk4T1EKF6UM103RSt8Z-Q1@ltc.linux.ibm.com> (raw)
In-Reply-To: <54539294.7010209@linux.vnet.ibm.com>
I have reviewed the patch and it fixed the issue we saw in our
environment recently.
Thanks,
Wendy
Quoting Brian King <brking@linux.vnet.ibm.com>:
> Adding Wendy...
>
> On 10/30/2014 05:27 PM, Brian King wrote:
>> Fixes a race condition in abort handling that was injected
>> when multiple interrupt support was added. When only a single
>> interrupt is present, the adapter guarantees it will send
>> responses for aborted commands prior to the response for the
>> abort command itself. With multiple interrupts, these responses
>> generally come back on different interrupts, so we need to
>> ensure the abort thread waits until the aborted command is
>> complete so we don't perform a double completion. This race
>> condition was being hit frequently in environments which
>> were triggering command timeouts, which was resulting in
>> a double completion causing a kernel oops.
>>
>> Cc: <stable@vger.kernel.org>
>> Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
>> ---
>>
>> drivers/scsi/ipr.c | 92
>> +++++++++++++++++++++++++++++++++++++++++++++++++++++
>> drivers/scsi/ipr.h | 1
>> 2 files changed, 93 insertions(+)
>>
>> diff -puN drivers/scsi/ipr.c~ipr_eh_wait drivers/scsi/ipr.c
>> --- scsi-queue/drivers/scsi/ipr.c~ipr_eh_wait 2014-10-30
>> 17:15:37.302753120 -0500
>> +++ scsi-queue-bjking1/drivers/scsi/ipr.c 2014-10-30
>> 17:15:37.311753039 -0500
>> @@ -683,6 +683,7 @@ static void ipr_init_ipr_cmnd(struct ipr
>> ipr_reinit_ipr_cmnd(ipr_cmd);
>> ipr_cmd->u.scratch = 0;
>> ipr_cmd->sibling = NULL;
>> + ipr_cmd->eh_comp = NULL;
>> ipr_cmd->fast_done = fast_done;
>> init_timer(&ipr_cmd->timer);
>> }
>> @@ -848,6 +849,8 @@ static void ipr_scsi_eh_done(struct ipr_
>>
>> scsi_dma_unmap(ipr_cmd->scsi_cmd);
>> scsi_cmd->scsi_done(scsi_cmd);
>> + if (ipr_cmd->eh_comp)
>> + complete(ipr_cmd->eh_comp);
>> list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
>> }
>>
>> @@ -4854,6 +4857,84 @@ static int ipr_slave_alloc(struct scsi_d
>> return rc;
>> }
>>
>> +/**
>> + * ipr_match_lun - Match function for specified LUN
>> + * @ipr_cmd: ipr command struct
>> + * @device: device to match (sdev)
>> + *
>> + * Returns:
>> + * 1 if command matches sdev / 0 if command does not match sdev
>> + **/
>> +static int ipr_match_lun(struct ipr_cmnd *ipr_cmd, void *device)
>> +{
>> + if (ipr_cmd->scsi_cmd && ipr_cmd->scsi_cmd->device == device)
>> + return 1;
>> + return 0;
>> +}
>> +
>> +/**
>> + * ipr_wait_for_ops - Wait for matching commands to complete
>> + * @ipr_cmd: ipr command struct
>> + * @device: device to match (sdev)
>> + * @match: match function to use
>> + *
>> + * Returns:
>> + * SUCCESS / FAILED
>> + **/
>> +static int ipr_wait_for_ops(struct ipr_ioa_cfg *ioa_cfg, void *device,
>> + int (*match)(struct ipr_cmnd *, void *))
>> +{
>> + struct ipr_cmnd *ipr_cmd;
>> + int wait;
>> + unsigned long flags;
>> + struct ipr_hrr_queue *hrrq;
>> + signed long timeout = IPR_ABORT_TASK_TIMEOUT;
>> + DECLARE_COMPLETION_ONSTACK(comp);
>> +
>> + ENTER;
>> + do {
>> + wait = 0;
>> +
>> + for_each_hrrq(hrrq, ioa_cfg) {
>> + spin_lock_irqsave(hrrq->lock, flags);
>> + list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) {
>> + if (match(ipr_cmd, device)) {
>> + ipr_cmd->eh_comp = ∁
>> + wait++;
>> + }
>> + }
>> + spin_unlock_irqrestore(hrrq->lock, flags);
>> + }
>> +
>> + if (wait) {
>> + timeout = wait_for_completion_timeout(&comp, timeout);
>> +
>> + if (!timeout) {
>> + wait = 0;
>> +
>> + for_each_hrrq(hrrq, ioa_cfg) {
>> + spin_lock_irqsave(hrrq->lock, flags);
>> + list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) {
>> + if (match(ipr_cmd, device)) {
>> + ipr_cmd->eh_comp = NULL;
>> + wait++;
>> + }
>> + }
>> + spin_unlock_irqrestore(hrrq->lock, flags);
>> + }
>> +
>> + if (wait)
>> + dev_err(&ioa_cfg->pdev->dev, "Timed out waiting for aborted
>> commands\n");
>> + LEAVE;
>> + return wait ? FAILED : SUCCESS;
>> + }
>> + }
>> + } while (wait);
>> +
>> + LEAVE;
>> + return SUCCESS;
>> +}
>> +
>> static int ipr_eh_host_reset(struct scsi_cmnd *cmd)
>> {
>> struct ipr_ioa_cfg *ioa_cfg;
>> @@ -5073,11 +5154,17 @@ static int __ipr_eh_dev_reset(struct scs
>> static int ipr_eh_dev_reset(struct scsi_cmnd *cmd)
>> {
>> int rc;
>> + struct ipr_ioa_cfg *ioa_cfg;
>> +
>> + ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata;
>>
>> spin_lock_irq(cmd->device->host->host_lock);
>> rc = __ipr_eh_dev_reset(cmd);
>> spin_unlock_irq(cmd->device->host->host_lock);
>>
>> + if (rc == SUCCESS)
>> + rc = ipr_wait_for_ops(ioa_cfg, cmd->device, ipr_match_lun);
>> +
>> return rc;
>> }
>>
>> @@ -5255,13 +5342,18 @@ static int ipr_eh_abort(struct scsi_cmnd
>> {
>> unsigned long flags;
>> int rc;
>> + struct ipr_ioa_cfg *ioa_cfg;
>>
>> ENTER;
>>
>> + ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
>> +
>> spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags);
>> rc = ipr_cancel_op(scsi_cmd);
>> spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags);
>>
>> + if (rc == SUCCESS)
>> + rc = ipr_wait_for_ops(ioa_cfg, scsi_cmd->device, ipr_match_lun);
>> LEAVE;
>> return rc;
>> }
>> diff -puN drivers/scsi/ipr.h~ipr_eh_wait drivers/scsi/ipr.h
>> --- scsi-queue/drivers/scsi/ipr.h~ipr_eh_wait 2014-10-30
>> 17:15:37.305753093 -0500
>> +++ scsi-queue-bjking1/drivers/scsi/ipr.h 2014-10-30
>> 17:15:37.315753003 -0500
>> @@ -1608,6 +1608,7 @@ struct ipr_cmnd {
>> struct scsi_device *sdev;
>> } u;
>>
>> + struct completion *eh_comp;
>> struct ipr_hrr_queue *hrrq;
>> struct ipr_ioa_cfg *ioa_cfg;
>> };
>> _
>>
>
>
> --
> Brian King
> Power Linux I/O
> IBM Linux Technology Center
prev parent reply other threads:[~2014-10-31 15:23 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-30 22:27 [PATCH 3/3] ipr: Wait for aborted command responses Brian King
2014-10-31 13:45 ` Brian King
2014-10-31 15:23 ` wenxiong [this message]
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=20141031112344.Horde.Fuk4T1EKF6UM103RSt8Z-Q1@ltc.linux.ibm.com \
--to=wenxiong@linux.vnet.ibm.com \
--cc=James.Bottomley@hansenpartnership.com \
--cc=brking@linux.vnet.ibm.com \
--cc=hch@infradead.org \
--cc=linux-scsi@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=stable@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox