2015-08-18 2 views
0

Я работаю над кодом драйвера устройства Linux. Я не могу показать, для чего именно этот код используется. Я постараюсь изо всех сил объяснить мою ситуацию. Ниже код будет выполнен в контексте прерывания, когда мы получим прерывание USB, заявив, что есть некоторые данные с USB. Данные будут поступать как URB, и мы преобразуем их в куски, добавим их в Линукс Circular Doubly linked list для дальнейшей обработки.list_empty возвращает 1 (ноль), если список не пуст.

 spin_lock(&demod->demod_lock);   
    /* Delete node from free list */ 
    list_del(&chunk->list_head); 
    /* Add it to full list */ 
    list_add_tail(&chunk->list_head,&demod->ChunkRefList.full); 
    /* Update chunk status */ 
    chunk->status=CHUNKDESC_FULL_LIST;       
    /* Increment the chunks assigned to application */ 
    demod->stats.assigned.c++;       
    spin_unlock(&demod->demod_lock);   

    printk("Value returned by list_empty is %d ",list_empty(&demod->ChunkRefList.full)); 

Повторяю, этот код выполняется в контексте прерывания. Я использую этот код как часть встроенной системы, которая отображает Audio & Video (AV) навсегда.

Спустя примерно 12 часов AV замерзает, и когда я анализирую, я вижу, что значение list_empty (& demod-> ChunkRefList.full), возвращаемое всегда 0x1 навсегда. Обычно в рабочем случае, когда AV играет нормально, его значение будет 0x0, заявив, что список не пуст.

Как вы можете видеть, когда выше код запускается, он сначала добавляет узел в полный список и проверяет, пуст ли полный список. В идеале значение должно быть всегда 0x0. Почему его значение 0x1

Я мониторинг значение list_empty (& demod-> ChunkRefList.full) с использованием timedoctor applicaiton, который не вносит каких-либо накладных расходов в контексте прерывания. Я использовал printk выше, чтобы вы поняли, что я печатаю его значение.

ответ

0

Наконец-то я смог выяснить проблему.

Поскольку код реализован в контексте прерывания, причиной возникновения проблемы является list_del, за которым следует list_add_tail.

Итак, я удалил эти два макроса и представил макрос list_move_tail, который разрешил проблему.

Используя list_move_tail, нам не нужно удалять узел и добавлять его в новый список. Ядро будет выполнять обе операции.

Итак, чтобы сделать вывод, что лучше всего сделать Linux-манипулирование списком максимально минимальным в контексте прерывания.

Смежные вопросы