mirror of https://github.com/torvalds/linux.git
usb: gadget: f_fs: Remove unnecessary spinlocks.
Commit 24729b307e ("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>
This commit is contained in:
parent
6693750a6f
commit
b581e472d9
|
|
@ -854,7 +854,6 @@ static void ffs_user_copy_worker(struct work_struct *work)
|
||||||
work);
|
work);
|
||||||
int ret = io_data->status;
|
int ret = io_data->status;
|
||||||
bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
|
bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (io_data->read && ret > 0) {
|
if (io_data->read && ret > 0) {
|
||||||
kthread_use_mm(io_data->mm);
|
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)
|
if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd)
|
||||||
eventfd_signal(io_data->ffs->ffs_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);
|
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)
|
if (io_data->read)
|
||||||
kfree(io_data->to_free);
|
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)
|
static int ffs_aio_cancel(struct kiocb *kiocb)
|
||||||
{
|
{
|
||||||
struct ffs_io_data *io_data = kiocb->private;
|
struct ffs_io_data *io_data = kiocb->private;
|
||||||
struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
|
|
||||||
unsigned long flags;
|
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
spin_lock_irqsave(&epfile->ffs->eps_lock, flags);
|
|
||||||
|
|
||||||
if (io_data && io_data->ep && io_data->req)
|
if (io_data && io_data->ep && io_data->req)
|
||||||
value = usb_ep_dequeue(io_data->ep, io_data->req);
|
value = usb_ep_dequeue(io_data->ep, io_data->req);
|
||||||
else
|
else
|
||||||
value = -EINVAL;
|
value = -EINVAL;
|
||||||
|
|
||||||
spin_unlock_irqrestore(&epfile->ffs->eps_lock, flags);
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue