laforge has submitted this change. ( https://gerrit.osmocom.org/c/dahdi-linux/+/27492 )
Change subject: icE1usb: avoid system hang if USB transfer submission fails ......................................................................
icE1usb: avoid system hang if USB transfer submission fails
If one of the isochronous or the interrupt EP URB cannot be submitted, we should clean-up properly and avoid hanging the dahdi_cfg process at 100% CPU itilization in an un-killable state.
Closes: OS#5477 (https://osmocom.org/issues/5477) Change-Id: Ie6f7f11a64fae0d8c2b7c8ae90df886f2eb8f0c2 --- M drivers/dahdi/icE1usb/icE1usb.c 1 file changed, 15 insertions(+), 12 deletions(-)
Approvals: Jenkins Builder: Verified manawyrm: Looks good to me, but someone else must approve; Verified laforge: Looks good to me, approved
diff --git a/drivers/dahdi/icE1usb/icE1usb.c b/drivers/dahdi/icE1usb/icE1usb.c index 4ce29c6..e829b2d 100644 --- a/drivers/dahdi/icE1usb/icE1usb.c +++ b/drivers/dahdi/icE1usb/icE1usb.c @@ -35,7 +35,7 @@
#include "ice1usb_proto.h"
-#define VERSION "0.1" +#define VERSION "0.2"
/* number of isochronous frames per URB */ #define ICE1USB_MAX_ISOC_FRAMES 4 @@ -756,19 +756,19 @@ iso_in_complete, GFP_KERNEL); if (rc) { ieu_err(ieu, "error submitting IN ep URB %u (%d)", i, rc); - goto err_isoc; + goto err_isoc_in; } rc = ice1usb_submit_isoc_urb(ieu, ieu->ep.iso_fb, &ieu->anchor.iso_fb, iso_fb_complete, GFP_KERNEL); if (rc) { ieu_err(ieu, "error submitting FB ep URB %u (%d)", i, rc); - goto err_isoc; + goto err_isoc_fb; } rc = ice1usb_submit_isoc_urb(ieu, ieu->ep.iso_out, &ieu->anchor.iso_out, iso_out_complete, GFP_KERNEL); if (rc) { ieu_err(ieu, "error submitting OUT ep URB %u (%d)", i, rc); - goto err_isoc; + goto err_isoc_out; } } } @@ -792,10 +792,12 @@ err_irq: usb_kill_anchored_urbs(&ieu->anchor.irq); clear_bit(ICE1USB_IRQ_RUNNING, &ieu->flags); -err_isoc: - usb_kill_anchored_urbs(&ieu->anchor.iso_in); usb_kill_anchored_urbs(&ieu->anchor.iso_out); +err_isoc_out: usb_kill_anchored_urbs(&ieu->anchor.iso_fb); +err_isoc_fb: + usb_kill_anchored_urbs(&ieu->anchor.iso_in); +err_isoc_in: clear_bit(ICE1USB_ISOC_RUNNING, &ieu->flags); ice1usb_set_altif(ieu, false); err: @@ -813,13 +815,14 @@
ieu_dbg(ieu, "entering %s", __FUNCTION__);
- clear_bit(ICE1USB_ISOC_RUNNING, &ieu->flags); - clear_bit(ICE1USB_IRQ_RUNNING, &ieu->flags); + if (test_and_clear_bit(ICE1USB_ISOC_RUNNING, &ieu->flags)) { + usb_kill_anchored_urbs(&ieu->anchor.iso_in); + usb_kill_anchored_urbs(&ieu->anchor.iso_out); + usb_kill_anchored_urbs(&ieu->anchor.iso_fb); + }
- usb_kill_anchored_urbs(&ieu->anchor.iso_in); - usb_kill_anchored_urbs(&ieu->anchor.iso_out); - usb_kill_anchored_urbs(&ieu->anchor.iso_fb); - usb_kill_anchored_urbs(&ieu->anchor.irq); + if (test_and_clear_bit(ICE1USB_IRQ_RUNNING, &ieu->flags)) + usb_kill_anchored_urbs(&ieu->anchor.irq);
/* guard against devices unplugged (see ice1usb_disconnect) */ if (ieu->present) {