Netdev List
 help / color / mirror / Atom feed
From: Jeremy Kerr <jk@codeconstruct.com.au>
To: Matt Johnston <matt@codeconstruct.com.au>,
	 Andrew Lunn <andrew+netdev@lunn.ch>,
	 "David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	 Jakub Kicinski <kuba@kernel.org>,
	Paolo Abeni <pabeni@redhat.com>,
	 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: netdev@vger.kernel.org, linux-usb@vger.kernel.org
Subject: [PATCH net-next v2 05/12] net: mctp: usb: Allow for multiple urb submissions from a packet tx
Date: Fri, 03 Jul 2026 13:47:25 +0800	[thread overview]
Message-ID: <20260703-dev-mctp-usb-1-1-v2-5-60367b861b33@codeconstruct.com.au> (raw)
In-Reply-To: <20260703-dev-mctp-usb-1-1-v2-0-60367b861b33@codeconstruct.com.au>

We currently assume that one packet tx (ie., a mctp_usblib_tx_push())
will result in zero or one calls to the ->send() op, and so zero or one
urb submissions.

However, in order to support multi-packet transfers in future (and later,
packet-spanning mode), we may have up to two: one flushing an existing
transmit (if we could not append to that), and one for the new packet
(if we are not expecting to add more packets to the new transfer).

Remove the assumption that we have a single tx urb in flight, by
tracking the tx urb with a usb_anchor rather than a single urb pointer.

Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
---
v2:
 - adjust tx_anchor handling; the urb is unanchored before completion,
   so we don't need to unanchor explicitly. We can now rely on the
   anchor's own lock for serialisation
---
 drivers/net/mctp/mctp-usb.c | 27 ++++++---------------------
 1 file changed, 6 insertions(+), 21 deletions(-)

diff --git a/drivers/net/mctp/mctp-usb.c b/drivers/net/mctp/mctp-usb.c
index 0eacad18cb73..e26ddeac9c73 100644
--- a/drivers/net/mctp/mctp-usb.c
+++ b/drivers/net/mctp/mctp-usb.c
@@ -37,9 +37,7 @@ struct mctp_usb {
 	struct delayed_work rx_retry_work;
 
 	struct mctp_usblib_tx tx;
-	/* protects tx_urb */
-	spinlock_t tx_lock;
-	struct urb *tx_urb;
+	struct usb_anchor tx_anchor;
 };
 
 static void mctp_usb_out_complete(struct urb *urb)
@@ -47,14 +45,9 @@ static void mctp_usb_out_complete(struct urb *urb)
 	struct mctp_usblib_tx_ctx *tx_ctx = urb->context;
 	struct mctp_usb *mctp_usb = mctp_usblib_tx_ctx_priv(tx_ctx);
 	struct net_device *netdev = mctp_usb->netdev;
-	unsigned long flags;
 
 	mctp_usblib_tx_send_complete(tx_ctx, netdev, urb->status == 0);
 
-	spin_lock_irqsave(&mctp_usb->tx_lock, flags);
-	mctp_usb->tx_urb = NULL;
-	spin_unlock_irqrestore(&mctp_usb->tx_lock, flags);
-
 	usb_free_urb(urb);
 
 	netif_wake_queue(netdev);
@@ -64,7 +57,6 @@ static int mctp_usb_tx_send(struct mctp_usblib_tx_ctx *tx_ctx,
 			    void *data, size_t len)
 {
 	struct mctp_usb *mctp_usb = mctp_usblib_tx_ctx_priv(tx_ctx);
-	unsigned long flags;
 	struct urb *urb;
 	int rc;
 
@@ -78,14 +70,12 @@ static int mctp_usb_tx_send(struct mctp_usblib_tx_ctx *tx_ctx,
 
 	netif_stop_queue(mctp_usb->netdev);
 
-	spin_lock_irqsave(&mctp_usb->tx_lock, flags);
-	rc = usb_submit_urb(urb, GFP_ATOMIC);
-	if (!rc)
-		mctp_usb->tx_urb = urb;
-	spin_unlock_irqrestore(&mctp_usb->tx_lock, flags);
+	usb_anchor_urb(urb, &mctp_usb->tx_anchor);
 
+	rc = usb_submit_urb(urb, GFP_ATOMIC);
 	if (rc) {
 		netdev_dbg(mctp_usb->netdev, "TX urb submit failed, %d\n", rc);
+		usb_unanchor_urb(urb);
 		usb_free_urb(urb);
 		netif_start_queue(mctp_usb->netdev);
 	}
@@ -207,7 +197,6 @@ static int mctp_usb_open(struct net_device *dev)
 static int mctp_usb_stop(struct net_device *dev)
 {
 	struct mctp_usb *mctp_usb = netdev_priv(dev);
-	struct urb *tx_urb = NULL;
 	unsigned long flags;
 
 	netif_stop_queue(dev);
@@ -222,11 +211,7 @@ static int mctp_usb_stop(struct net_device *dev)
 
 	usb_kill_urb(mctp_usb->rx_urb);
 
-	spin_lock_irqsave(&mctp_usb->tx_lock, flags);
-	swap(mctp_usb->tx_urb, tx_urb);
-	spin_unlock_irqrestore(&mctp_usb->tx_lock, flags);
-
-	usb_kill_urb(tx_urb);
+	usb_kill_anchored_urbs(&mctp_usb->tx_anchor);
 
 	mctp_usblib_tx_cancel(&mctp_usb->tx, dev, SKB_DROP_REASON_DEV_READY);
 
@@ -283,11 +268,11 @@ static int mctp_usb_probe(struct usb_interface *intf,
 	dev->usbdev = interface_to_usbdev(intf);
 	dev->intf = intf;
 	spin_lock_init(&dev->rx_lock);
-	spin_lock_init(&dev->tx_lock);
 	usb_set_intfdata(intf, dev);
 
 	mctp_usblib_rx_init(&dev->rx);
 	mctp_usblib_tx_init(&dev->tx, &tx_ops, dev);
+	init_usb_anchor(&dev->tx_anchor);
 
 	dev->ep_in = ep_in->bEndpointAddress;
 	dev->ep_out = ep_out->bEndpointAddress;

-- 
2.47.3


  parent reply	other threads:[~2026-07-03  5:48 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-03  5:47 [PATCH net-next v2 00/12] net: mctp: usb: Add support for MCTP-over-USB v1.1 Jeremy Kerr
2026-07-03  5:47 ` [PATCH net-next v2 01/12] net: mctp: usb: Include version indicator in max packet size defines Jeremy Kerr
2026-07-03  5:47 ` [PATCH net-next v2 02/12] net: mctp: usb: Use packet-length max for maximum packet-size check Jeremy Kerr
2026-07-03  5:47 ` [PATCH net-next v2 03/12] net: mctp: usblib: Move RX transfer processing to a new mctp-usblib Jeremy Kerr
2026-07-03  5:47 ` [PATCH net-next v2 04/12] net: mctp: usblib: Move TX transfer processing to mctp-usblib Jeremy Kerr
2026-07-03  5:47 ` Jeremy Kerr [this message]
2026-07-03  5:47 ` [PATCH net-next v2 06/12] net: mctp: usblib: Add support for multi-packet transmit Jeremy Kerr
2026-07-03  5:47 ` [PATCH net-next v2 07/12] net: mctp: usb: Accommodate DSP0283 v1.1 header format Jeremy Kerr
2026-07-03  5:47 ` [PATCH net-next v2 08/12] net: mctp: usblib: Implement receive-side packet spanning Jeremy Kerr
2026-07-03  5:47 ` [PATCH net-next v2 09/12] net: mctp: usblib: Implement transmit-side " Jeremy Kerr
2026-07-03  5:47 ` [PATCH net-next v2 10/12] net: mctp: usblib: Add initial kunit tests Jeremy Kerr
2026-07-03  5:47 ` [PATCH net-next v2 11/12] net: mctp: usb: enable v1.1 packet spanning Jeremy Kerr
2026-07-03  5:47 ` [PATCH net-next v2 12/12] net: mctp: usb: Allow multiple urbs in flight Jeremy Kerr

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260703-dev-mctp-usb-1-1-v2-5-60367b861b33@codeconstruct.com.au \
    --to=jk@codeconstruct.com.au \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=kuba@kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=matt@codeconstruct.com.au \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox