linux driver: wake_up_interruptible from tasklet
Предыдущая тема похоже забыта уже, решил написать ещё раз. Почему не работает wake_up_interruptible() из такслета? (в обработчике прерывания процесс просыпается когда нужно.)
Трассирую запрос, обработчик прерывания и такслет. Единственный процесс делает ioctl запрос с периодом 10 сек. процесс вызывает wait_event_interruptible_timeout(), имитирую прерывание (на входном канале появляется единственный передний фронт сигнала). Вызывается обработчик прерывания, изменяет условие (флаг обнуляется, вижу это через printk()), вызывается такслет (вижу через printk()), такслет вызывает wake_up_interrubtible(), процесс просыпается через 10 секунд (как будто wake_up_... просто игнорируется) значение флага равно 0 !!! (то есть планировщик должен был разбудить поток, но не сделал этого.)
В чём проблема, может чего-то не хватает? (ядро 2.6.35)
Ещё раз код, относящийся к тасклету:
// обработчик для тасклета
static void do_tasklet(unsigned long param)
{
struct daq_device *dev = (struct daq_device*)param;
struct dev_priv *dp = (struct dev_priv*)dev->private;
printk(KERN_INFO "from tasklet\n");
wake_up_interruptible(&dp->wait_queue);
}
// объявление такслета
static DECLARE_TASKLET(dev_tasklet, do_tasklet, 0);
// в коде инициализации устройства
int dev_init(struct daq_device* dev)
{
...
// сохраняю указатель на устройство в структуре тасклета
dev_tasklet.data = (unsigned long)dev;
...
}