From: Ingo Rohloff Date: Tue, 1 Jul 2025 11:36:02 +0000 (+0200) Subject: usb: gadget: f_fs: Remove unnecessary spinlocks. X-Git-Tag: v6.17-rc1~175^2~42 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b581e472d95d584d2e30e34f3e055d9754faddb2;p=thirdparty%2Flinux.git usb: gadget: f_fs: Remove unnecessary spinlocks. 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 Link: https://lore.kernel.org/r/20250701113602.33402-2-ingo.rohloff@lauterbach.com Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 67fea7da4652f..03308a065d5a3 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -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; }