【问题标题】:list_empty returns 1 (non zero) if the list is not empty如果列表不为空,list_empty 返回 1(非零)
【发布时间】:2015-08-18 10:09:17
【问题描述】:

我正在编写 Linux 设备驱动程序代码。我无法透露此代码的确切用途。我会尽力解释我的情况。当我们收到一个 USB 中断表明有一些来自 USB 的数据时,下面的代码将在中断上下文中执行。数据将作为 URB 到达,我们会将它们转换为块,将它们添加到 Linux 循环双向链表中以进行进一步处理。

     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));

我再说一遍,这段代码在中断上下文中执行。我将此代码用作嵌入式系统的一部分,它永远显示音频和视频(AV)。

大约 12 小时后,AV 被冻结,当我分析时,我看到返回的 list_empty(&demod->ChunkRefList.full) 的值永远是 0x1。通常在 AV 播放正常的情况下,其值为 0x0,表示列表不为空。

如您所见,当执行上述代码时,它首先将一个节点添加到完整列表并检查完整列表是否为空。理想情况下,该值应始终为 0x0。为什么它的值为0x1

我正在使用不会在中断上下文中引入任何开销的 timedoctor 应用程序监视 list_empty(&demod->ChunkRefList.full) 的值。我在上面使用了 printk 来让你明白我正在打印它的值。

【问题讨论】:

    标签: linux list usb drivers


    【解决方案1】:

    最后,我能够找出问题所在。

    由于代码是在中断上下文中实现的,因此使用 list_del 后跟 list_add_tail 会导致问题。

    所以,我删除了这两个宏并引入了 list_move_tail 宏来解决这个问题。

    通过使用list_move_tail,我们不需要删除节点并将其添加到新列表中。内核会处理这两个操作。

    因此,总而言之,最好在中断上下文中尽可能减少 Linux 链表操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-11
      • 2016-08-23
      • 1970-01-01
      • 2014-01-13
      • 2017-05-31
      • 2019-10-02
      • 1970-01-01
      • 2020-09-28
      相关资源
      最近更新 更多