Messages in this thread | | | Date | Fri, 6 May 2011 08:54:12 -0600 | From | "Jim Schutt" <> | Subject | Re: [patch 04/38] [SCSI] put stricter guards on queue dead checks |
| |
Hi Greg,
Greg KH wrote: > 2.6.38-stable review patch. If anyone has any objections, please let us know.
You probably don't want to add this patch to stable kernels until commit c055f5b2614b4f from git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6 shows up in Linus' tree.
See details in http://www.spinics.net/lists/kernel/msg1181665.html.
-- Jim
> > ------------------ > > From: James Bottomley <James.Bottomley@suse.de> > > commit 86cbfb5607d4b81b1a993ff689bbd2addd5d3a9b upstream. > > SCSI uses request_queue->queuedata == NULL as a signal that the queue > is dying. We set this state in the sdev release function. However, > this allows a small window where we release the last reference but > haven't quite got to this stage yet and so something will try to take > a reference in scsi_request_fn and oops. It's very rare, but we had a > report here, so we're pushing this as a bug fix > > The actual fix is to set request_queue->queuedata to NULL in > scsi_remove_device() before we drop the reference. This causes > correct automatic rejects from scsi_request_fn as people who hold > additional references try to submit work and prevents anything from > getting a new reference to the sdev that way. > > Signed-off-by: James Bottomley <James.Bottomley@suse.de> > Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> > > --- > drivers/scsi/scsi_sysfs.c | 16 ++++++++-------- > 1 file changed, 8 insertions(+), 8 deletions(-) > > --- a/drivers/scsi/scsi_sysfs.c > +++ b/drivers/scsi/scsi_sysfs.c > @@ -322,14 +322,8 @@ static void scsi_device_dev_release_user > kfree(evt); > } > > - if (sdev->request_queue) { > - sdev->request_queue->queuedata = NULL; > - /* user context needed to free queue */ > - scsi_free_queue(sdev->request_queue); > - /* temporary expedient, try to catch use of queue lock > - * after free of sdev */ > - sdev->request_queue = NULL; > - } > + /* NULL queue means the device can't be used */ > + sdev->request_queue = NULL; > > scsi_target_reap(scsi_target(sdev)); > > @@ -937,6 +931,12 @@ void __scsi_remove_device(struct scsi_de > if (sdev->host->hostt->slave_destroy) > sdev->host->hostt->slave_destroy(sdev); > transport_destroy_device(dev); > + > + /* cause the request function to reject all I/O requests */ > + sdev->request_queue->queuedata = NULL; > + > + /* Freeing the queue signals to block that we're done */ > + scsi_free_queue(sdev->request_queue); > put_device(dev); > } > > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > > >
| |