Workqueue and kernel panic on device disconnect
Hi,
I'm trying to use a workqueue in a usb driver for polling the states of the device buttons.
That works fine, but when I disconnect the device, the kernel sometimes explodes.
The machine turns off immediately, without saving a backtrace (I will try to make a photo tomorrow)
The code:
static struct delayed_work poll_work;
static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x1234, 0x5678)},
{}
};static void poll(struct work_struct *work)
{
schedule_delayed_work(&poll_work,
msecs_to_jiffies(100));
}MODULE_DEVICE_TABLE(usb, device_table);
static int test_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
INIT_DELAYED_WORK(&poll_work, poll);
schedule_delayed_work(&poll_work,
msecs_to_jiffies(100));
return 0;
}static void test_disconnect(struct usb_interface *intf)
{
cancel_delayed_work_sync(&poll_work);
}static struct usb_driver test_driver = {
.name = MODULE_NAME,
.id_table = device_table,
.probe = test_probe, .disconnect = test_disconnect,
};
static int __init test_mod_init(void)
{
return usb_register(&test_driver);
}static void __exit test_mod_exit(void)
{
usb_deregister(&test_driver);
}module_init(test_mod_init);module_exit(test_mod_exit);
What am I doing wrong ?
Is there anything else I have to do in addition to calling cancel_delayed_work_sync() in the disconnect fcn ?
Thanks,
Frank Schaefer
Am 25.10.2011 23:29, schrieb Frank Sch?fer:
Quoted 63 lines
Hi,
I'm trying to use a workqueue in a usb driver for polling the states of the device buttons.
That works fine, but when I disconnect the device, the kernel sometimes explodes.
The machine turns off immediately, without saving a backtrace (I will try to make a photo tomorrow)The code:
static struct
delayed_workpoll_work;static const struct usb_device_id device_table[] = { {USB_DEVICE(0x1234, 0x5678)}, {} };static void
poll(struct work_struct *work){ schedule_delayed_work(&poll_work, msecs_to_jiffies(100)); }
MODULE_DEVICE_TABLE(usb, device_table);static int test_probe(struct
usb_interface*intf,
const structusb_device_id*id){ INIT_DELAYED_WORK(&poll_work, poll); schedule_delayed_work(&poll_work, msecs_to_jiffies(100)); return 0; }static void
test_disconnect(struct usb_interface *intf){ cancel_delayed_work_sync(&poll_work); }static struct
usb_drivertest_driver= {.name = MODULE_NAME, .id_table = device_table, .probe = test_probe,.disconnect =
test_disconnect,
};static int
__inittest_mod_init(void){ return usb_register(&test_driver); }static void
__exittest_mod_exit(void){ usb_deregister(&test_driver); }
module_init(test_mod_init);module_exit(test_mod_exit);
Quoted 7 lines
What am I doing wrong ?
Is there anything else I have to do in addition to callingcancel_delayed_work_sync()in the disconnect fcn ?Thanks,
Frank Schaefer
I've managed to make a photo of the backtrace:
http://imageshack.us/photo/my-images/823/img075gv.jpg
Could this be a kernel bug ?
Regards,
Frank