Merge branch 'net-mctp-usb-minor-fixes-for-mctp-over-usb-transport-driver'
Jeremy Kerr says: ==================== net: mctp: usb: minor fixes for MCTP over USB transport driver This series adds a couple of fixes in the ndo_open / ndo_stop path for the MCTP over USB transport, where we are incorrectly sequencing two error cases. Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au> ==================== Link: https://patch.msgid.link/20260608-dev-mctp-usb-rx-requeue-v2-0-29a3aa507609@codeconstruct.com.au Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
0aa05daef7
1 changed files with 18 additions and 10 deletions
|
|
@ -22,7 +22,6 @@
|
|||
struct mctp_usb {
|
||||
struct usb_device *usbdev;
|
||||
struct usb_interface *intf;
|
||||
bool stopped;
|
||||
|
||||
struct net_device *netdev;
|
||||
|
||||
|
|
@ -32,6 +31,9 @@ struct mctp_usb {
|
|||
struct urb *tx_urb;
|
||||
struct urb *rx_urb;
|
||||
|
||||
/* enforces atomic access to rx_stopped and requeuing the retry work */
|
||||
spinlock_t rx_lock;
|
||||
bool rx_stopped;
|
||||
struct delayed_work rx_retry_work;
|
||||
};
|
||||
|
||||
|
|
@ -122,6 +124,7 @@ static const unsigned long RX_RETRY_DELAY = HZ / 4;
|
|||
|
||||
static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct sk_buff *skb;
|
||||
int rc;
|
||||
|
||||
|
|
@ -147,8 +150,11 @@ static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp)
|
|||
return rc;
|
||||
|
||||
err_retry:
|
||||
schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY);
|
||||
return rc;
|
||||
spin_lock_irqsave(&mctp_usb->rx_lock, flags);
|
||||
if (!mctp_usb->rx_stopped)
|
||||
schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY);
|
||||
spin_unlock_irqrestore(&mctp_usb->rx_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mctp_usb_in_complete(struct urb *urb)
|
||||
|
|
@ -248,9 +254,6 @@ static void mctp_usb_rx_retry_work(struct work_struct *work)
|
|||
struct mctp_usb *mctp_usb = container_of(work, struct mctp_usb,
|
||||
rx_retry_work.work);
|
||||
|
||||
if (READ_ONCE(mctp_usb->stopped))
|
||||
return;
|
||||
|
||||
mctp_usb_rx_queue(mctp_usb, GFP_KERNEL);
|
||||
}
|
||||
|
||||
|
|
@ -258,7 +261,7 @@ static int mctp_usb_open(struct net_device *dev)
|
|||
{
|
||||
struct mctp_usb *mctp_usb = netdev_priv(dev);
|
||||
|
||||
WRITE_ONCE(mctp_usb->stopped, false);
|
||||
WRITE_ONCE(mctp_usb->rx_stopped, false);
|
||||
|
||||
netif_start_queue(dev);
|
||||
|
||||
|
|
@ -268,17 +271,21 @@ 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);
|
||||
unsigned long flags;
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
/* prevent RX submission retry */
|
||||
WRITE_ONCE(mctp_usb->stopped, true);
|
||||
spin_lock_irqsave(&mctp_usb->rx_lock, flags);
|
||||
mctp_usb->rx_stopped = true;
|
||||
cancel_delayed_work(&mctp_usb->rx_retry_work);
|
||||
spin_unlock_irqrestore(&mctp_usb->rx_lock, flags);
|
||||
|
||||
flush_delayed_work(&mctp_usb->rx_retry_work);
|
||||
|
||||
usb_kill_urb(mctp_usb->rx_urb);
|
||||
usb_kill_urb(mctp_usb->tx_urb);
|
||||
|
||||
cancel_delayed_work_sync(&mctp_usb->rx_retry_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -331,6 +338,7 @@ static int mctp_usb_probe(struct usb_interface *intf,
|
|||
dev->netdev = netdev;
|
||||
dev->usbdev = interface_to_usbdev(intf);
|
||||
dev->intf = intf;
|
||||
spin_lock_init(&dev->rx_lock);
|
||||
usb_set_intfdata(intf, dev);
|
||||
|
||||
dev->ep_in = ep_in->bEndpointAddress;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue