usb_get_from_anchor() hands over a reference to the URB, which the caller
has to release. atusb_work_urbs() never does, so every URB collected from
the idle anchor keeps an extra reference: the reference count grows on
each retry cycle and the URBs are never freed on disconnect. Drop the
reference after a successful submission, and after the URB has been put
back on the idle anchor when submission failed, as the HCD holds its own
reference while the URB is in flight.
Fixes: 7490b008d123 ("ieee802154: add support for atusb transceiver")
Cc: [email protected]
Signed-off-by: Wentao Liang <[email protected]>
---
drivers/net/ieee802154/atusb.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c
index 5f7fc4ee7a07..3dbb142eccb2 100644
--- a/drivers/net/ieee802154/atusb.c
+++ b/drivers/net/ieee802154/atusb.c
@@ -180,9 +180,15 @@ static void atusb_work_urbs(struct work_struct *work)
if (!urb)
return;
ret = atusb_submit_rx_urb(atusb, urb);
+ if (!ret)
+ usb_put_urb(urb);
} while (!ret);
+ /* The reference obtained above is dropped once the URB is back
+ * on the idle anchor.
+ */
usb_anchor_urb(urb, &atusb->idle_urbs);
+ usb_put_urb(urb);
dev_warn_ratelimited(&usb_dev->dev,
"atusb_in: can't allocate/submit URB (%d)\n", ret);
schedule_delayed_work(&atusb->work,
--
2.34.1