]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
usb: gadget: f_fs: Remove unnecessary spinlocks.
authorIngo Rohloff <ingo.rohloff@lauterbach.com>
Tue, 1 Jul 2025 11:36:02 +0000 (13:36 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Jul 2025 09:05:21 +0000 (11:05 +0200)
Commit 24729b307eefc ("usb: gadget: f_fs: Fix race between aio_cancel()
and AIO request complete") moved the call to usb_ep_free_request() from
ffs_epfile_async_io_complete() to ffs_user_copy_worker().

In ffs_user_copy_worker(), ki_complete() is called before
usb_ep_free_request().  Once ki_complete() returns, ffs_aio_cancel() can
no longer be invoked for the completed kiocb, as ki_complete() removes it
from the &ctx->active_reqs list in aio.c.  ffs_aio_cancel() only applies
to kiocb instances still present on this list.

The potential race between ki_complete() and ffs_aio_cancel() is already
guarded by the &ctx->ctx_lock spinlock in aio.c.

As a result, there is no race condition between the usb_ep_dequeue() call
in ffs_aio_cancel() and the usb_ep_free_request() call in
ffs_user_copy_worker().  Consequently, the spin lock/unlock operations on
&io_data->ffs->eps_lock are no longer necessary.

Signed-off-by: Ingo Rohloff <ingo.rohloff@lauterbach.com>
Link: https://lore.kernel.org/r/20250701113602.33402-2-ingo.rohloff@lauterbach.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/function/f_fs.c

index 67fea7da4652fdec6250957684d0b12355df0fb1..03308a065d5a3aaa0d94cd3b505ea08b3fe47d32 100644 (file)
@@ -854,7 +854,6 @@ static void ffs_user_copy_worker(struct work_struct *work)
                                                   work);
        int ret = io_data->status;
        bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
-       unsigned long flags;
 
        if (io_data->read && ret > 0) {
                kthread_use_mm(io_data->mm);
@@ -867,10 +866,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
        if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd)
                eventfd_signal(io_data->ffs->ffs_eventfd);
 
-       spin_lock_irqsave(&io_data->ffs->eps_lock, flags);
        usb_ep_free_request(io_data->ep, io_data->req);
-       io_data->req = NULL;
-       spin_unlock_irqrestore(&io_data->ffs->eps_lock, flags);
 
        if (io_data->read)
                kfree(io_data->to_free);
@@ -1211,19 +1207,13 @@ ffs_epfile_open(struct inode *inode, struct file *file)
 static int ffs_aio_cancel(struct kiocb *kiocb)
 {
        struct ffs_io_data *io_data = kiocb->private;
-       struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
-       unsigned long flags;
        int value;
 
-       spin_lock_irqsave(&epfile->ffs->eps_lock, flags);
-
        if (io_data && io_data->ep && io_data->req)
                value = usb_ep_dequeue(io_data->ep, io_data->req);
        else
                value = -EINVAL;
 
-       spin_unlock_irqrestore(&epfile->ffs->eps_lock, flags);
-
        return value;
 }