[pvrusb2] pvrusb2 driver lock in 2.6.27: workaround
Mike Isely
isely at isely.net
Sat Oct 18 21:38:05 CDT 2008
On Sat, 18 Oct 2008, Mike Isely wrote:
>
> Finally got a good 2.6.27.2 kernel build here and I tried the included
> pvrusb2 driver. Complete failure, very early in initialization. Same
> problem with the standalone driver, and I'm sure that v4l-dvb resident
> version is going to have the same issue.
>
> I've got a bunch of clues to chase down; stay tuned. Looks like I'll be
> rebooting a lot :-(
Holy crap. This one is very interesting. The good news is that I have
an easy workaround - no code changes needed: Turn off the pvrusb2
module parameter "initusbreset". This is defaulted to on and it's part
of the problem.
Said another way, just do this before you plug in the device for the
first time:
modprobe pvrusb2 initusbreset=0
Alternatively, putting the following into a file anywhere under
/etc/modprobe.d/ should work even better:
options pvrusb2 initusbreset=0
That causes udev to set this parameter for you whenever the driver gets
loaded.
Here is the sequence of events, when the device is plugged in:
1. Driver is called to associate the new device.
2. Driver creates an internal context, and passes it off to its internal
worker thread.
3. Driver worker thread "enters" the new context and starts initializing
the device. Entry into the context causes the instance's mutex to be
entered.
4. Driver notices that initusbreset is true and first kicks a USB reset
to the device.
5. The USB reset action causes the USB core to disconnect the device.
6. The disconnect action triggers another call into the pvrusb2 driver
to disconnect.
7. The disconnect call "enters" that same context - and grabs the
instance's mutex again. *DEADLOCK*
Because the USB core is calling back into the driver right on top of the
reset call into the core, the second grab of the driver's instance mutex
therefore happens in the same thread context and that causes the thread
to deadlock. The deadlocked thread is completely jammed - there's
simply no way out. This stuck thread prevents removal of the pvrusb2.ko
module, which is why a modprobe -r gets stuck. The only escape is a
reboot.
So for now the workaround is easy; set initusbreset to zero; this
prevents the USB reset attempt and avoids the recursive lock. As for
why that initusbreset business is there at all - this dates quite a ways
back when I was doing tricks to better stabilize the hardware. At the
time I found that the reset never "hurt" and that it seem to sometimes
clear any previous jammed condition in the device hardware (if the
device had been jammed mid-transfer from a previous bad hotplug
removal). So omitting the usb reset there is not really a big problem.
I need to go back and study older kernels to see why this wasn't a
problem before 2.6.27. Once I have a better handle on this, I'll
concoct a patch to fix it permanently.
-Mike
--
Mike Isely
isely @ pobox (dot) com
PGP: 03 54 43 4D 75 E5 CC 92 71 16 01 E2 B5 F5 C1 E8
More information about the pvrusb2
mailing list