mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 11:03:07 -04:00
net: mctp: usb: Allow multiple urbs in flight
Currently, we stop tx queues when we have one urb submitted. This means we will immediately hit dev_hard_start_xmit's tx-queues-off -> NETDEV_TX_BUSY case, and revert to the requeue -> gso_skb single-dequeue path, and no longer be able to pack skbs without an xmit_more indication. Instead, allow a few urbs to be in-flight, with a limit of 16kB of data outstanding (after which we will disable queues). With this, the tx path will cause fewer requeues (and therefore non-packed transfers) under normal loads. Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au> Link: https://patch.msgid.link/20260724-dev-mctp-usb-1-1-v5-12-e66bbba0dbdc@codeconstruct.com.au Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
b4a27a474b
commit
88dbfe0d95
@@ -42,6 +42,9 @@ struct mctp_usb {
|
||||
|
||||
struct mctp_usblib_tx tx;
|
||||
struct usb_anchor tx_anchor;
|
||||
/* serialises tx_qmem updates to netdev queue states */
|
||||
spinlock_t tx_qmem_lock;
|
||||
int tx_qmem;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -49,23 +52,41 @@ enum {
|
||||
MCTP_USB_SUBCLASS_SPAN = 0x02,
|
||||
};
|
||||
|
||||
/* We use a total-size limit for outstanding URBs, as the transfer counts
|
||||
* may vary a lot between spanning- and non-spanning modes. In spanning mode,
|
||||
* this will allow for a couple of max-sized transfers to be in flight. In
|
||||
* non-spanning mode, 32.
|
||||
*
|
||||
* We want to avoid disabling the tx queue if possible; doing so will end up
|
||||
* requeueing to gso_skb, and we only dequeue from that one skb at a time,
|
||||
* so can no longer perform transfer packing.
|
||||
*/
|
||||
static const unsigned int TX_QMEM_MAX = 16384;
|
||||
|
||||
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);
|
||||
unsigned int len = urb->transfer_buffer_length;
|
||||
struct net_device *netdev = mctp_usb->netdev;
|
||||
unsigned long flags;
|
||||
|
||||
mctp_usblib_tx_send_complete(tx_ctx, netdev, urb->status == 0);
|
||||
|
||||
usb_free_urb(urb);
|
||||
|
||||
netif_wake_queue(netdev);
|
||||
spin_lock_irqsave(&mctp_usb->tx_qmem_lock, flags);
|
||||
mctp_usb->tx_qmem -= len;
|
||||
if (mctp_usb->tx_qmem < TX_QMEM_MAX && netif_running(netdev))
|
||||
netif_wake_queue(netdev);
|
||||
spin_unlock_irqrestore(&mctp_usb->tx_qmem_lock, flags);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -80,8 +101,6 @@ static int mctp_usb_tx_send(struct mctp_usblib_tx_ctx *tx_ctx,
|
||||
if (mctp_usb->span)
|
||||
urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
|
||||
netif_stop_queue(mctp_usb->netdev);
|
||||
|
||||
usb_anchor_urb(urb, &mctp_usb->tx_anchor);
|
||||
|
||||
rc = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
@@ -89,7 +108,12 @@ static int mctp_usb_tx_send(struct mctp_usblib_tx_ctx *tx_ctx,
|
||||
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);
|
||||
} else {
|
||||
spin_lock_irqsave(&mctp_usb->tx_qmem_lock, flags);
|
||||
mctp_usb->tx_qmem += len;
|
||||
if (mctp_usb->tx_qmem >= TX_QMEM_MAX)
|
||||
netif_stop_queue(mctp_usb->netdev);
|
||||
spin_unlock_irqrestore(&mctp_usb->tx_qmem_lock, flags);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -353,6 +377,7 @@ static int mctp_usb_probe(struct usb_interface *intf,
|
||||
spin_lock_init(&dev->rx_lock);
|
||||
if (dev->span)
|
||||
netdev->max_mtu = MCTP_USB_1_1_MTU_MAX;
|
||||
spin_lock_init(&dev->tx_qmem_lock);
|
||||
usb_set_intfdata(intf, dev);
|
||||
|
||||
rc = mctp_usblib_rx_init(&dev->rx, le16_to_cpu(ep_in->wMaxPacketSize),
|
||||
|
||||
Reference in New Issue
Block a user