Double-lock with GobiSerial driver on certain kernels

Hi all,

I think there may be a problem with the GobiSerial driver (S2.9) on certain versions of the Linux kernel. The symptom is when slqssdk tries to run and hangs with a message similar to this:

INFO: task slqssdk:618 blocked for more than 120 seconds.
slqssdk         D c0325c48     0   618      1 0x00000000
Backtrace: 
[<c0325968>] (__schedule+0x0/0x320) from [<c0325fd0>] (schedule+0x84/0x88)
[<c0325f4c>] (schedule+0x0/0x88) from [<c0326134>] (schedule_preempt_disabled+0x10/0x14)
[<c0326124>] (schedule_preempt_disabled+0x0/0x14) from [<c03251bc>] (__mutex_lock_slowpath+0x70/0x9c)
[<c032514c>] (__mutex_lock_slowpath+0x0/0x9c) from [<c0325224>] (mutex_lock+0x3c/0x40)
[<c03251e8>] (mutex_lock+0x0/0x40) from [<bf050058>] (Gobi_dtr_rts+0x58/0x108 [GobiSerial])
[<bf050000>] (Gobi_dtr_rts+0x0/0x108 [GobiSerial]) from [<bf0176e8>] (serial_dtr_rts+0x50/0x5c [usbserial])
[<bf017698>] (serial_dtr_rts+0x0/0x5c [usbserial]) from [<c0153914>] (tty_port_raise_dtr_rts+0x24/0x28)
...(remainder truncated)...

The Gobi_dtr_rts() function attempts to lock serial->disc_mutex … which is proper behavior for kernels prior to commit b2ca699076573c94fee9a73cb0d8645383b602a0. However, after this commit, the function which calls Gobi_dtr_rts() locks disc_mutex prior to the call. This results in Gobi_dtr_rts() attempting to double-lock the mutex, hanging the whole process.

I think that this affects the following kernels:

Note: I fully acknowledge that some distributions patch their kernels, and that this error may not affect your particular system. This analysis assumes a vanilla Linux kernel – no patches – available from kernel.org.

If you are running one of these kernels, you will need to remove the lock/unlock calls for disc_mutex in Gobi_dtr_rts().

Hope this helps,
Chris

Heads up for anyone using Ubuntu 12.04 or 12.10 …

Canonical just released a new kernel, 3.5.0-27.46, which incorporates the usbserial driver change that causes this double-lock to appear. A full changelog on the kernel patches can be found here: launchpad.net/ubuntu/+source/linux/3.5.0-27.46.

This means, however, that simply patching for the previously mentioned kernels isn’t an option. You’ll have to deep dive into your particular kernel to under its patch level.

Chris