Я пишу модуль ядра, который использует потоки ядра и семафоры.
Я вызываю up(...)
функцию для семафора из обработчика прерываний, и затем мой kthread начинает выполняться.
static int interrupt_handler_thread(void *data)
{
/* duty cycle */
while (!kthread_should_stop()) {
/*
* If semaphore has been uped in the interrupt, we will
* acquire it here, else thread will go to sleep.
*/
if (!down_interruptible(mysem)) {
/* proccess gpio interrupt */
dev_info(dev, "gpio interrupt detected\n");
}
}
do_exit(0);
return 0;
}
Семафор и нить инициализируются в функции module_init. Проверка ошибок была пропущена.
...
sema_init(mysem, 0);
thread = kthread_create(interrupt_handler_thread,client,"my_int_handler");
wake_up_process(thread);
...
И во время выгрузки модуля семафор и нить удаляются:
/*
* After this call kthread_should_stop() in the thread will return TRUE.
* See https://lwn.net/Articles/118935/
*/
kthread_stop(thread);
/*
* Release the semaphore to return
* from down_interruptible() function
*/
up(mysem);
Когда я пытаюсь выгрузить мой модуль, он замирает в нить в down_interruptible()
функция, потому что она ждет, пока семафор поднимается в обработчике прерываний. И мой код никогда не возвращается из kthread_stop()
.
Кажется, мне нужно отключить прерывание от моего gpio, поднять семафор вручную и вызвать функцию kthread_stop()
. Но это потенциальная ошибка, потому что после того, как семафор восстановлен вручную, поток начинает выполняться и после его рабочего цикла можно снова down_interruptible()
.
Может кто-нибудь помочь мне, пожалуйста?
PS: я знаю про этот вопрос , но, похоже, это не мой случай.