The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
strange Linux scheduler, !*! Dvorkin, 23-Апр-03, 18:13  [смотреть все]
Здравствуйте!

Предлагаю тему для обсуждения.

Пишу модуль ядра для Linux и столкнулся с одной непонятностью...

после загрузки в ядро модуль создает два файла устройств, один - для чтения, другой - для записи.
Оба фала связаны логически с одним буфером в модуле.
Устройство "виртуальное", типа PIPE'a.

логика такая:
1) программа - ридер открывает 1й файл и пытается читать из него. Тк данных нет в буфере, она блокируется (sleep_on).
2) программа - писатель открывает 2й файл и пишет туда (в буфер) строку. Тк буфер чист, она не блокируется и по
завершении делает wake_up для ридера (чтоб он проснулся и получил данные).

НО! ридер не просыпается. он так и остается в спящем виде до получения прерываения с клавы (Ctrl+C).

Выдержка из кода:

static ssize_t vsp_read( struct file *_file, char *_buff, size_t _len, loff_t *_off) {
/// ...
if ( !(VSP_NONBLOCK( _file))) if ( dev->buff_len < 1) interruptible_sleep_on( &( dev->wqr));
// .. skipped
wake_up_interruptible( &dev->wqw);
// ...
return( readed); } // read end

static ssize_t vsp_write( struct file *_file, const char *_buff, size_t _len, loff_t *_off) {
/// ...
if ( !(VSP_NONBLOCK( _file))) if ( dev->buff_len >= VSP_MAXBUF - 1) interruptible_sleep_on( &( dev->wqw));
// .. skipped
wake_up_interruptible( &dev->wqr);
// ...
return( wrote); } // write end

dev имеет примерно следующую структуру:
struct VSP_DEVICE {
char buff[ VSP_MAXBUF];
unsigned short buff_len;
wait_queue_head_t wqr, wqw;
};

все wait_queue_head_t инициализируются на этапе регистрации девайсов

* я заглядывал в очереди wait_queue_head_t на состояние процессов до и после вызова
wake_up_interruptible, выяснил, что состояние будимого процесса не меняется. Тоесть,
как было 1 (INTERRUPTIBLE), так и осталось.
Самое странное... Если непосредственно до вызова wake_up_interruptible сделать
printk("");
с любой строкой в качестве параметра, хоть "\0", после wake_up_interruptible
состояние читающего процесса меняется, он просыпается и успешно завершается,
возврашая прочитанные данные.

Пытался делать wake_up_sync, wake_up_all и тд... ниче не помогает.
Кто знает где грабли?


gcc 2.96, kernel 2.4.18-6mdk

WBR, Dvorkin

  • strange Linux scheduler, !*! genie, 06:57 , 25-Апр-03 (1)
    A ne deadlock li eto?


    >Здравствуйте!
    >
    >Предлагаю тему для обсуждения.
    >
    >Пишу модуль ядра для Linux и столкнулся с одной непонятностью...
    >
    >после загрузки в ядро модуль создает два файла устройств, один - для
    >чтения, другой - для записи.
    >Оба фала связаны логически с одним буфером в модуле.
    >Устройство "виртуальное", типа PIPE'a.
    >
    >логика такая:
    >1) программа - ридер открывает 1й файл и пытается читать из него.
    >Тк данных нет в буфере, она блокируется (sleep_on).
    >2) программа - писатель открывает 2й файл и пишет туда (в буфер)
    >строку. Тк буфер чист, она не блокируется и по
    >завершении делает wake_up для ридера (чтоб он проснулся и получил данные).
    >
    >НО! ридер не просыпается. он так и остается в спящем виде до
    >получения прерываения с клавы (Ctrl+C).
    >
    >Выдержка из кода:
    >
    >static ssize_t vsp_read( struct file *_file, char *_buff, size_t _len, loff_t *_off)
    >{
    >/// ...
    > if ( !(VSP_NONBLOCK( _file))) if ( dev->buff_len < 1) interruptible_sleep_on( &( dev->wqr));
    >// .. skipped
    > wake_up_interruptible( &dev->wqw);
    >// ...
    > return( readed); } // read end
    >
    >static ssize_t vsp_write( struct file *_file, const char *_buff, size_t _len, loff_t
    >*_off) {
    >/// ...
    > if ( !(VSP_NONBLOCK( _file))) if ( dev->buff_len >= VSP_MAXBUF - 1) interruptible_sleep_on( &( dev->wqw));
    >// .. skipped
    > wake_up_interruptible( &dev->wqr);
    >// ...
    > return( wrote); } // write end
    >
    >dev имеет примерно следующую структуру:
    >struct VSP_DEVICE {
    > char buff[ VSP_MAXBUF];
    > unsigned short buff_len;
    > wait_queue_head_t wqr, wqw;
    >};
    >
    >все wait_queue_head_t инициализируются на этапе регистрации девайсов
    >
    >* я заглядывал в очереди wait_queue_head_t на состояние процессов до и после
    >вызова
    >wake_up_interruptible, выяснил, что состояние будимого процесса не меняется. Тоесть,
    >как было 1 (INTERRUPTIBLE), так и осталось.
    >Самое странное... Если непосредственно до вызова wake_up_interruptible сделать
    >printk("");
    >с любой строкой в качестве параметра, хоть "\0", после wake_up_interruptible
    >состояние читающего процесса меняется, он просыпается и успешно завершается,
    >возврашая прочитанные данные.
    >
    >Пытался делать wake_up_sync, wake_up_all и тд... ниче не помогает.
    >Кто знает где грабли?
    >
    >
    >gcc 2.96, kernel 2.4.18-6mdk
    >
    >WBR, Dvorkin




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру