cdc_wdm driver: infinite loop on -EPROTO error leads to system freeze with SIM7600 module
@AlanStern @gregkh @oneukum
Describe the bug
Hello,
I have encountered a bug in the cdc_wdm driver on a Raspberry Pi running the latest kernel (6.6.51+rpt-rpi-v7). When using a SIM7600 (SIMCom) modem alongside ModemManager and NetworkManager, issuing a reset command (or powering off the modem via hardware pin) results in a flood of -EPROTO errors in the wdm_int_callback() function.
These errors appear in the kernel log with a prefix referencing “qmi_wwan 1-1.4:1.5,” but the code responsible for resubmitting the URB is in cdc_wdm.
This behavior causes the system to freeze, presumably because of an infinite loop in usb_submit_urb() calls.
Steps to reproduce the behaviour
When there is no cellular signal and a reset is issued to the SIM7600, the driver immediately begins logging:
nonzero urb status received: -71
wdm_int_callback - 0 bytes
repeatedly and at a high rate.
The Raspberry Pi becomes unresponsive, eventually freezing.
This does not happen if a LAN cable is connected; the system remains stable in that scenario.
Device (s)
Raspberry Pi 3 Mod. B+
System
System: 32-bit Kernel version: 6.6 Debian version: 12 (bookworm)
Modem: SIMCOM SIM7600, controlled by ModemManager + NetworkManager Drivers involved: cdc_wdm (for control), qmi_wwan (for data)
Logs
No response
Additional context
Relevant Code Snippet
Below is the portion of cdc-wdm.c where the callback is continuously re-submitting the URB (excerpt from the mainline kernel around wdm_int_callback()):
exit:
rv = usb_submit_urb(urb, GFP_ATOMIC);
if (rv)
dev_err(&desc->intf->dev,
"%s - usb_submit_urb failed with result %d\n",
__func__, rv);
If the URB’s status is -EPROTO, the driver still re-submits the URB.
I was in email correspondence with Mr. Bjørn Mork, the author of the qmi_wwan driver, and he brought this bug to my attention.
The wdm_int_callback() function, errors are handled in a switch statement based on urb->status. The error codes -ESHUTDOWN, -ENOENT, and -ECONNRESET are properly handled by returning immediately, and -EPIPE is handled by logging a stall and scheduling work. However, when a -EPROTO error occurs (which corresponds to the -71 error), there is no dedicated case to handle it; instead, it falls into the default case where the error is logged using dev_err_ratelimited(), and execution continues.
Hi there,
I opened this issue a few weeks ago regarding cdc_wdm driver and haven’t received any feedback yet. I wanted to follow up to see if anyone has had a chance to review it or if there is any update on addressing the problem.
If there’s any further information you need from me, or if there’s anything I can do to help, please let me know.
Thank you for your time and effort!
Best regards, Zsolt
[+Oliver, linux-usb]
On Mon, Apr 14, 2025 at 01:31:39AM -0700, sfczsolti wrote:
sfczsolti left a comment (raspberrypi/linux#6746)
Hi there,
I opened this issue a few weeks ago regarding cdc_wdm driver and haven’t received any feedback yet. I wanted to follow up to see if anyone has had a chance to review it or if there is any update on addressing the problem.
If there’s any further information you need from me, or if there’s anything I can do to help, please let me know.
Thank you for your time and effort!
Many USB drivers getting a -EPROTO error immediately give up and treat it as fatal (an indication of a disconnection).
However, I'm not an expert on the cdc-wdm driver, and the people who are may not want to do this.
Alan Stern