Linux kernel 对于具有自旋锁保护的存储桶的哈希表,是否有linux头?

Linux kernel 对于具有自旋锁保护的存储桶的哈希表,是否有linux头?,linux-kernel,synchronization,hashtable,rcu,softirq,Linux Kernel,Synchronization,Hashtable,Rcu,Softirq,我写的代码很少创建/删除对象(最多几千个),但在软IRQ环境中经常修改它们。这些对象也很少从任务上下文读取(可能也很少修改)(通过procfs:file per object)。目前,我的代码包含每个CPU的全局数据块,每个数据块都由一个自旋锁保护。这样的块包含用于对象存储的固定大小的哈希表 显然,当前的设计不是最优的,特别是在对象更新负载非常高的情况下:从procfs读取对象将导致更新软irq时的数据丢失。我需要重写同步方案以摆脱全局锁。最明显的选择是——为每个哈希表存储桶设置一个自旋锁——它

我写的代码很少创建/删除对象(最多几千个),但在软IRQ环境中经常修改它们。这些对象也很少从任务上下文读取(可能也很少修改)(通过procfs:file per object)。目前,我的代码包含每个CPU的全局数据块,每个数据块都由一个自旋锁保护。这样的块包含用于对象存储的固定大小的哈希表


显然,当前的设计不是最优的,特别是在对象更新负载非常高的情况下:从procfs读取对象将导致更新软irq时的数据丢失。我需要重写同步方案以摆脱全局锁。最明显的选择是——为每个哈希表存储桶设置一个自旋锁——它应该具有良好的伸缩性。问题是,我可能需要使用自己的哈希表实现,或者至少要重新实现几个顶级宏(在linux/hashtable.h中没有找到受自旋锁保护的bucket的宏)。我是否也应该关注支持RCU的哈希表(但我对这种同步方法没有深入的了解)?

具有锁保护的存储桶在标题中声明。它们使用头指针的最低位作为锁定位

对bucket的受RCU保护的访问是通过标头中的其他哈希表函数定义的(它们具有
\u RCU
后缀)

锁和RCU之间的选择取决于您。请注意,RCU本身无法解决修改冲突。而且它主要对频繁读取的数据有帮助,这似乎不是你的情况


由于只为
结构hlist\u bl\u head
声明了一个锁定函数-
hlist\u bl\u lock
,并且该函数对irq不知道,因此当哈希表可用于irq或下半部分时,应执行其他操作:

  • 旋转锁定保存:

    local_irq_save(flags);
    hlist_bl_lock(...);
    
  • 旋转\u解锁\u irqrestore:

    hlist_bl_unlock(...);
    local_irq_restore(flags);
    
  • 旋转锁定:

    local_bh_disable();
    hlist_bl_lock(...);
    
  • 旋转解锁按钮:

    hlist_bl_unlock(...);
    local_bh_enable();
    

与普通的位自旋锁相比,使用位自旋锁时的性能下降有多大?也许我更喜欢普通的旋转锁,因为我不需要太多的桶?据我所知,你不会降低性能。与此相反,您可以提高性能,因为在访问存储桶时,缓存占用空间会减少。使用单个位作为锁将丢失一些锁调试功能。至少,锁映射不知道您的锁:它需要锁对象中的额外字节。但是,只要您正确地实现了锁定,调试您的锁就不会困扰您。总结:除非您以非常不寻常的方式使用锁,否则位锁在性能和代码可读性方面都是不错的选择。我希望使用位锁在软IRQ和内核线程之间共享数据是安全的(因为没有
bit\u spin\u lock\u bh
)?很好的捕获!您可以在IRQ中使用位锁,但需要调用其他函数。我已经编辑了这篇文章的答案。