]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: uas: reduce time under spinlock
authorOliver Neukum <oneukum@suse.com>
Wed, 12 Nov 2025 13:55:05 +0000 (14:55 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 21 Nov 2025 14:13:43 +0000 (15:13 +0100)
Drop the lock before freeing memory.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Link: https://patch.msgid.link/20251112135543.31081-1-oneukum@suse.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/storage/uas.c

index 0657f5f7a51fa624875907de4f1af61853a4b140..8f24b81d6c12a0f8491d28b4f5b8817851011844 100644 (file)
@@ -309,18 +309,18 @@ static void uas_stat_cmplt(struct urb *urb)
        int status = urb->status;
        bool success;
 
-       spin_lock_irqsave(&devinfo->lock, flags);
-
-       if (devinfo->resetting)
-               goto out;
-
        if (status) {
                if (status != -ENOENT && status != -ECONNRESET && status != -ESHUTDOWN)
                        dev_err(&urb->dev->dev, "stat urb: status %d\n", status);
-               goto out;
+               goto bail;
        }
 
        idx = be16_to_cpup(&iu->tag) - 1;
+
+       spin_lock_irqsave(&devinfo->lock, flags);
+
+       if (devinfo->resetting)
+               goto out;
        if (idx >= MAX_CMNDS || !devinfo->cmnd[idx]) {
                dev_err(&urb->dev->dev,
                        "stat urb: no pending cmd for uas-tag %d\n", idx + 1);
@@ -375,9 +375,8 @@ static void uas_stat_cmplt(struct urb *urb)
        default:
                uas_log_cmd_state(cmnd, "bogus IU", iu->iu_id);
        }
-out:
-       usb_free_urb(urb);
        spin_unlock_irqrestore(&devinfo->lock, flags);
+       usb_free_urb(urb);
 
        /* Unlinking of data urbs must be done without holding the lock */
        if (data_in_urb) {
@@ -388,6 +387,12 @@ out:
                usb_unlink_urb(data_out_urb);
                usb_put_urb(data_out_urb);
        }
+       return;
+
+out:
+       spin_unlock_irqrestore(&devinfo->lock, flags);
+bail:
+       usb_free_urb(urb);
 }
 
 static void uas_data_cmplt(struct urb *urb)
@@ -429,8 +434,8 @@ static void uas_data_cmplt(struct urb *urb)
        }
        uas_try_complete(cmnd, __func__);
 out:
-       usb_free_urb(urb);
        spin_unlock_irqrestore(&devinfo->lock, flags);
+       usb_free_urb(urb);
 }
 
 static void uas_cmd_cmplt(struct urb *urb)