From: Matthew Wilcox <willy@linux.intel.com>
To: Luben Tuikov <ltuikov@yahoo.com>
Cc: Greg KH <greg@kroah.com>,
linux-usb@vger.kernel.org, linux-scsi@vger.kernel.org
Subject: Re: [PATCH] [USB] UAS: eliminate infinite loop; add debug print
Date: Mon, 8 Nov 2010 06:24:56 -0500 [thread overview]
Message-ID: <20101108112456.GI4173@linux.intel.com> (raw)
In-Reply-To: <106187.30360.qm@web31802.mail.mud.yahoo.com>
On Fri, Oct 29, 2010 at 05:33:19PM -0700, Luben Tuikov wrote:
> Eliminate an infinite loop whereby the SCSI layer
> would reissue a command (which would be failed by
> the driver) ad infinitum. (Invariably due to the
> driver's profuse use of the
> SCSI_MLQUEUE_DEVICE_BUSY returned result in its
> queuecommand() method.)
>
> Also add a debug option and a few debug prints.
Why have you added your own debug scheme instead of using dev_dbg?
You've made a lot of other random whitespace changes too.
I'll pick through this and see what I like in it.
> Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>
> ---
> drivers/usb/storage/Kconfig | 10 ++++
> drivers/usb/storage/Makefile | 4 ++
> drivers/usb/storage/uas.c | 102 +++++++++++++++++++++++++++--------------
> 3 files changed, 81 insertions(+), 35 deletions(-)
>
> diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
> index 49a489e..eb9f6af 100644
> --- a/drivers/usb/storage/Kconfig
> +++ b/drivers/usb/storage/Kconfig
> @@ -185,6 +185,16 @@ config USB_UAS
>
> If you compile this driver as a module, it will be named uas.
>
> +config USB_UAS_DEBUG
> + bool "Compile in debug mode"
> + default n
> + depends on USB_UAS
> + help
> + Compiles the uas driver in debug mode. In debug mode,
> + the driver prints debug messages to the console.
> +
> + If unsure, say 'N'.
> +
> config USB_LIBUSUAL
> bool "The shared table of common (or usual) storage devices"
> depends on USB
> diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
> index fcf14cd..16715ab 100644
> --- a/drivers/usb/storage/Makefile
> +++ b/drivers/usb/storage/Makefile
> @@ -10,6 +10,10 @@ ccflags-y := -Idrivers/scsi
> obj-$(CONFIG_USB_UAS) += uas.o
> obj-$(CONFIG_USB_STORAGE) += usb-storage.o
>
> +ifeq ($(CONFIG_USB_UAS_DEBUG),y)
> + EXTRA_CFLAGS += -DUAS_DEBUG
> +endif
> +
> usb-storage-y := scsiglue.o protocol.o transport.o usb.o
> usb-storage-y += initializers.o sierra_ms.o option_ms.o
>
> diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
> index 48dc2b8..ef6e707 100644
> --- a/drivers/usb/storage/uas.c
> +++ b/drivers/usb/storage/uas.c
> @@ -21,6 +21,14 @@
> #include <scsi/scsi_host.h>
> #include <scsi/scsi_tcq.h>
>
> +#define uas_printk(fmt, ...) printk(KERN_NOTICE "uas: " fmt, ## __VA_ARGS__)
> +
> +#ifdef UAS_DEBUG
> +#define UAS_DPRINTK uas_printk
> +#else
> +#define UAS_DPRINTK(fmt, ...)
> +#endif
> +
> /* Common header for all IUs */
> struct iu {
> __u8 iu_id;
> @@ -128,6 +136,7 @@ static void uas_do_work(struct work_struct *work)
> {
> struct uas_cmd_info *cmdinfo;
> struct list_head list;
> + int res;
>
> spin_lock_irq(&uas_work_lock);
> list_replace_init(&uas_work_list, &list);
> @@ -136,8 +145,10 @@ static void uas_do_work(struct work_struct *work)
> list_for_each_entry(cmdinfo, &list, list) {
> struct scsi_pointer *scp = (void *)cmdinfo;
> struct scsi_cmnd *cmnd = container_of(scp,
> - struct scsi_cmnd, SCp);
> - uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_KERNEL);
> + struct scsi_cmnd, SCp);
> + res = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_KERNEL);
> + UAS_DPRINTK("%s: cmd:%p, res:%d, state:0x%x\n", __FUNCTION__,
> + cmnd, res, cmdinfo->state);
> }
> }
>
> @@ -198,13 +209,15 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
> }
>
> static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
> - unsigned direction)
> + unsigned direction)
> {
> struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
> int err;
>
> cmdinfo->state = direction | SUBMIT_STATUS_URB;
> err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
> + UAS_DPRINTK("%s: cmd:%p, err:%d, state:0x%x\n", __FUNCTION__,
> + cmnd, err, cmdinfo->state);
> if (err) {
> spin_lock(&uas_work_lock);
> list_add_tail(&cmdinfo->list, &uas_work_list);
> @@ -222,7 +235,8 @@ static void uas_stat_cmplt(struct urb *urb)
> u16 tag;
>
> if (urb->status) {
> - dev_err(&urb->dev->dev, "URB BAD STATUS %d\n", urb->status);
> + dev_err(&urb->dev->dev, "%s: URB BAD STATUS %d\n",
> + __FUNCTION__, urb->status);
> usb_free_urb(urb);
> return;
> }
> @@ -259,6 +273,14 @@ static void uas_stat_cmplt(struct urb *urb)
> static void uas_data_cmplt(struct urb *urb)
> {
> struct scsi_data_buffer *sdb = urb->context;
> +
> + if (urb->status) {
> + dev_err(&urb->dev->dev, "%s: URB BAD STATUS %d\n",
> + __FUNCTION__, urb->status);
> + usb_free_urb(urb);
> + return;
> + }
> +
> sdb->resid = sdb->length - urb->actual_length;
> usb_free_urb(urb);
> }
> @@ -339,7 +361,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
> memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len);
>
> usb_fill_bulk_urb(urb, udev, devinfo->cmd_pipe, iu, sizeof(*iu) + len,
> - usb_free_urb, NULL);
> + usb_free_urb, NULL);
> urb->transfer_flags |= URB_FREE_BUFFER;
> out:
> return urb;
> @@ -355,23 +377,26 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
> */
>
> static int uas_submit_urbs(struct scsi_cmnd *cmnd,
> - struct uas_dev_info *devinfo, gfp_t gfp)
> + struct uas_dev_info *devinfo, gfp_t gfp)
> {
> struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
> + int res;
>
> if (cmdinfo->state & ALLOC_STATUS_URB) {
> cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd,
> cmdinfo->stream);
> if (!cmdinfo->status_urb)
> - return SCSI_MLQUEUE_DEVICE_BUSY;
> + return -ENOMEM;
> cmdinfo->state &= ~ALLOC_STATUS_URB;
> }
>
> if (cmdinfo->state & SUBMIT_STATUS_URB) {
> - if (usb_submit_urb(cmdinfo->status_urb, gfp)) {
> + res = usb_submit_urb(cmdinfo->status_urb, gfp);
> + if (res) {
> scmd_printk(KERN_INFO, cmnd,
> - "sense urb submission failure\n");
> - return SCSI_MLQUEUE_DEVICE_BUSY;
> + "sense urb submission failure (%d)\n",
> + res);
> + return res;
> }
> cmdinfo->state &= ~SUBMIT_STATUS_URB;
> }
> @@ -381,15 +406,17 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
> devinfo->data_in_pipe, cmdinfo->stream,
> scsi_in(cmnd), DMA_FROM_DEVICE);
> if (!cmdinfo->data_in_urb)
> - return SCSI_MLQUEUE_DEVICE_BUSY;
> + return -ENOMEM;
> cmdinfo->state &= ~ALLOC_DATA_IN_URB;
> }
>
> if (cmdinfo->state & SUBMIT_DATA_IN_URB) {
> - if (usb_submit_urb(cmdinfo->data_in_urb, gfp)) {
> + res = usb_submit_urb(cmdinfo->data_in_urb, gfp);
> + if (res) {
> scmd_printk(KERN_INFO, cmnd,
> - "data in urb submission failure\n");
> - return SCSI_MLQUEUE_DEVICE_BUSY;
> + "data in urb submission failure (%d)\n",
> + res);
> + return res;
> }
> cmdinfo->state &= ~SUBMIT_DATA_IN_URB;
> }
> @@ -399,15 +426,17 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
> devinfo->data_out_pipe, cmdinfo->stream,
> scsi_out(cmnd), DMA_TO_DEVICE);
> if (!cmdinfo->data_out_urb)
> - return SCSI_MLQUEUE_DEVICE_BUSY;
> + return -ENOMEM;
> cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
> }
>
> if (cmdinfo->state & SUBMIT_DATA_OUT_URB) {
> - if (usb_submit_urb(cmdinfo->data_out_urb, gfp)) {
> + res = usb_submit_urb(cmdinfo->data_out_urb, gfp);
> + if (res) {
> scmd_printk(KERN_INFO, cmnd,
> - "data out urb submission failure\n");
> - return SCSI_MLQUEUE_DEVICE_BUSY;
> + "data out urb submission failure (%d)\n",
> + res);
> + return res;
> }
> cmdinfo->state &= ~SUBMIT_DATA_OUT_URB;
> }
> @@ -416,15 +445,16 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
> cmdinfo->cmd_urb = uas_alloc_cmd_urb(devinfo, gfp, cmnd,
> cmdinfo->stream);
> if (!cmdinfo->cmd_urb)
> - return SCSI_MLQUEUE_DEVICE_BUSY;
> + return -ENOMEM;
> cmdinfo->state &= ~ALLOC_CMD_URB;
> }
>
> if (cmdinfo->state & SUBMIT_CMD_URB) {
> - if (usb_submit_urb(cmdinfo->cmd_urb, gfp)) {
> + res = usb_submit_urb(cmdinfo->cmd_urb, gfp);
> + if (res) {
> scmd_printk(KERN_INFO, cmnd,
> - "cmd urb submission failure\n");
> - return SCSI_MLQUEUE_DEVICE_BUSY;
> + "cmd urb submission failure (%d)\n", res);
> + return res;
> }
> cmdinfo->state &= ~SUBMIT_CMD_URB;
> }
> @@ -433,12 +463,12 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
> }
>
> static int uas_queuecommand(struct scsi_cmnd *cmnd,
> - void (*done)(struct scsi_cmnd *))
> + void (*done)(struct scsi_cmnd *))
> {
> struct scsi_device *sdev = cmnd->device;
> struct uas_dev_info *devinfo = sdev->hostdata;
> struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
> - int err;
> + int res;
>
> BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer));
>
> @@ -474,17 +504,19 @@ static int uas_queuecommand(struct scsi_cmnd *cmnd,
> cmdinfo->stream = 0;
> }
>
> - err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC);
> - if (err) {
> - /* If we did nothing, give up now */
> - if (cmdinfo->state & SUBMIT_STATUS_URB) {
> - usb_free_urb(cmdinfo->status_urb);
> - return SCSI_MLQUEUE_DEVICE_BUSY;
> - }
> - spin_lock(&uas_work_lock);
> - list_add_tail(&cmdinfo->list, &uas_work_list);
> - spin_unlock(&uas_work_lock);
> - schedule_work(&uas_work);
> + res = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC);
> + UAS_DPRINTK("%s: cmd:%p (0x%02x), err:%d, state:0x%x\n", __FUNCTION__,
> + cmnd, cmnd->cmnd[0], res, cmdinfo->state);
> + if (res) {
> + usb_unlink_urb(cmdinfo->status_urb);
> + usb_unlink_urb(cmdinfo->data_in_urb);
> + usb_unlink_urb(cmdinfo->data_out_urb);
> + usb_unlink_urb(cmdinfo->cmd_urb);
> +
> + sdev->current_cmnd = NULL;
> +
> + cmnd->result = DID_NO_CONNECT << 16;
> + done(cmnd);
> }
>
> return 0;
> --
> 1.7.0.1
next prev parent reply other threads:[~2010-11-08 11:24 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-30 0:33 [PATCH] [USB] UAS: eliminate infinite loop; add debug print Luben Tuikov
2010-11-03 16:24 ` Greg KH
2010-11-08 11:24 ` Matthew Wilcox [this message]
2010-11-08 15:55 ` Greg KH
2010-11-08 17:27 ` Luben Tuikov
[not found] ` <272723.33242.qm-5Es2LHxk9sSvuULXzWHTWIglqE1Y4D90QQ4Iyu8u01E@public.gmane.org>
2010-11-08 17:38 ` Greg KH
2010-11-08 17:57 ` Luben Tuikov
2010-11-08 17:40 ` Michał Nazarewicz
-- strict thread matches above, loose matches on Subject: below --
2010-12-10 10:51 Luben Tuikov
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=20101108112456.GI4173@linux.intel.com \
--to=willy@linux.intel.com \
--cc=greg@kroah.com \
--cc=linux-scsi@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=ltuikov@yahoo.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).