mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 07:03:03 +02:00
usb: gadget: functionfs: Wait for fences before enqueueing DMABUF
Instead of bailing when fences have already been installed on the
DMABUF, wait for them (with a timeout) when doing a blocking operation.
This fixes the issue where userspace would submit a DMABUF with fences
already installed, with the (correct) expectation that it would just
work.
Fixes: 7b07a2a7ca ("usb: gadget: functionfs: Add DMABUF import interface")
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Link: https://lore.kernel.org/r/20240402110951.16376-3-paul@crapouillou.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
1500a7b279
commit
862b416560
|
|
@ -46,6 +46,8 @@
|
|||
|
||||
#define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */
|
||||
|
||||
#define DMABUF_ENQUEUE_TIMEOUT_MS 5000
|
||||
|
||||
MODULE_IMPORT_NS(DMA_BUF);
|
||||
|
||||
/* Reference counter handling */
|
||||
|
|
@ -1580,9 +1582,11 @@ static int ffs_dmabuf_transfer(struct file *file,
|
|||
struct usb_request *usb_req;
|
||||
enum dma_resv_usage resv_dir;
|
||||
struct dma_buf *dmabuf;
|
||||
unsigned long timeout;
|
||||
struct ffs_ep *ep;
|
||||
bool cookie;
|
||||
u32 seqno;
|
||||
long retl;
|
||||
int ret;
|
||||
|
||||
if (req->flags & ~USB_FFS_DMABUF_TRANSFER_MASK)
|
||||
|
|
@ -1616,17 +1620,14 @@ static int ffs_dmabuf_transfer(struct file *file,
|
|||
goto err_attachment_put;
|
||||
|
||||
/* Make sure we don't have writers */
|
||||
if (!dma_resv_test_signaled(dmabuf->resv, DMA_RESV_USAGE_WRITE)) {
|
||||
pr_vdebug("FFS WRITE fence is not signaled\n");
|
||||
ret = -EBUSY;
|
||||
goto err_resv_unlock;
|
||||
}
|
||||
|
||||
/* If we're writing to the DMABUF, make sure we don't have readers */
|
||||
if (epfile->in &&
|
||||
!dma_resv_test_signaled(dmabuf->resv, DMA_RESV_USAGE_READ)) {
|
||||
pr_vdebug("FFS READ fence is not signaled\n");
|
||||
ret = -EBUSY;
|
||||
timeout = nonblock ? 0 : msecs_to_jiffies(DMABUF_ENQUEUE_TIMEOUT_MS);
|
||||
retl = dma_resv_wait_timeout(dmabuf->resv,
|
||||
dma_resv_usage_rw(epfile->in),
|
||||
true, timeout);
|
||||
if (retl == 0)
|
||||
retl = -EBUSY;
|
||||
if (retl < 0) {
|
||||
ret = (int)retl;
|
||||
goto err_resv_unlock;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user