[PATCH 05/11] net/9p/usbg: only rely on one completion

From: Michael Grzeschik

Date: Thu Mar 19 2026 - 05:46:19 EST


The 9pfs protocol is specified that each request is answered with one
response. Since there is only one pair of tx and rx requests for the usb
stack, the stack complete callback of the tx request can be used to
queue the response.

The current approach is using an extra completion barrier to ensure that
the tx complete callback came back, before enqueuing the rx request.
This all was done in the initial 9p_usbg_request callback of the 9pfs
protocol.

Moving the ep_queue of the rx request removes one extra completion
barrier and is less complex. Other than the complete this call has to be
guarded by the spinlock.

Signed-off-by: Michael Grzeschik <m.grzeschik@xxxxxxxxxxxxxx>
---
net/9p/trans_usbg.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index d6391db6d5d96a1609a3405646f66d82c93d35f1..472f7452794d7ac0f7b1475f0da2f4605a28e062 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -50,7 +50,6 @@ struct f_usb9pfs {
struct usb_ep *out_ep;

struct completion send;
- struct completion received;

unsigned int buflen;

@@ -180,7 +179,7 @@ static void usb9pfs_tx_complete(struct usb_ep *ep, struct usb_request *req)
unlock_complete:
spin_unlock_irqrestore(&usb9pfs->lock, flags);

- complete(&usb9pfs->send);
+ usb9pfs_queue_rx(usb9pfs, usb9pfs->out_req, GFP_ATOMIC);
}

static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs,
@@ -280,7 +279,7 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
out_unlock:
spin_unlock_irqrestore(&usb9pfs->lock, flags);

- complete(&usb9pfs->received);
+ complete(&usb9pfs->send);
}

static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
@@ -442,7 +441,7 @@ static int p9_usbg_create(struct p9_client *client, struct fs_context *fc)

client->trans_mod->maxsize = usb9pfs->buflen;

- complete(&usb9pfs->received);
+ complete(&usb9pfs->send);

return 0;
}
@@ -508,7 +507,7 @@ static int p9_usbg_request(struct p9_client *client, struct p9_req_t *p9_req)
if (client->status != Connected)
return -EBUSY;

- ret = wait_for_completion_killable(&usb9pfs->received);
+ ret = wait_for_completion_killable(&usb9pfs->send);
if (ret)
return ret;

@@ -516,11 +515,8 @@ static int p9_usbg_request(struct p9_client *client, struct p9_req_t *p9_req)
if (ret)
return ret;

- ret = wait_for_completion_killable(&usb9pfs->send);
- if (ret)
- return ret;
+ return 0;

- return usb9pfs_queue_rx(usb9pfs, usb9pfs->out_req, GFP_ATOMIC);
}

static int p9_usbg_cancel(struct p9_client *client, struct p9_req_t *req)
@@ -802,7 +798,6 @@ static struct usb_function *usb9pfs_alloc(struct usb_function_instance *fi)
spin_lock_init(&usb9pfs->lock);

init_completion(&usb9pfs->send);
- init_completion(&usb9pfs->received);

usb9pfs_opts = container_of(fi, struct f_usb9pfs_opts, func_inst);


--
2.47.3