usb: dwc2: gadget: Fix kill_all_requests race
authorJohn Keeping <john@metanate.com>
Mon, 5 Aug 2019 16:01:21 +0000 (17:01 +0100)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Fri, 9 Aug 2019 05:28:29 +0000 (08:28 +0300)
commit37bea42fec575203c1b49d64322f717c29e82b90
tree01b4da426a3b2153f0fd6c7065c218476d15c667
parent27125cf8b5aee9f62dd108051203ccbd2e426b51
usb: dwc2: gadget: Fix kill_all_requests race

When a gadget is disabled, kill_all_requests() can be called
simultaneously from both a user process via dwc2_hsotg_pullup() and from
the interrupt handler if the hardware detects disconnection.

Since we drop the lock in dwc2_hsotg_complete_request() in order to call
the completion handler, this means that the list is modified
concurrently and leads to an infinite loop in kill_all_requests().

Replace the foreach loop with a while-not-empty loop in order to remove
the danger of this concurrent modification.

Note: I observed this with threadirqs, I'm not sure if it can be
triggered without threaded interrupts.

Signed-off-by: John Keeping <john@metanate.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/dwc2/gadget.c