是否有 linux header 用于带有 spinlock-protected 个桶的哈希表?
Is there a linux header for hashtable with spinlock-protected buckets?
我写的代码很少 creates/removes object 秒(最多几千)但经常在软 IRQ 上下文中修改它们。这些 object 也很少从任务上下文中读取(并且可能也很少被修改)(通过 procfs: file per object)。目前我的代码包含全局 per-CPU 数据块,每个数据块都由自旋锁保护。这样的块包含用于 object 存储的 fixed-sized 哈希表。
显然当前的设计不是最优的,尤其是当有非常高的 object 更新负载时:从 procfs 读取 objects 会导致更新软 IRQ 时的数据丢失。我需要重写同步方案以摆脱全局锁。最明显的选择——为每个哈希表桶设置一个自旋锁——它应该可以很好地扩展。问题是我可能需要使用我自己的哈希表实现或至少重新实现几个 top-level 宏(在 linux/hashtable.h 中没有找到 spinlock-protected 桶)。我还应该看看 RCU-enabled 哈希表吗(但我对这种同步方法还没有充分的了解)?
在 header linux/list_bl.h 中声明了带锁保护的桶。他们使用头指针的最低位作为锁定位。
RCU-protected 对存储桶的访问是使用 header linux/hashtable.h 中的其他散列 table 函数定义的(它们具有 _rcu
后缀)。
锁和 RCU 之间的选择由您决定。请注意,RCU 本身无法解决 modify-modify 冲突。它主要对 frequently-read 数据有帮助,这似乎不是你的情况。
因为只有一个锁定函数 - hlist_bl_lock
- 被声明为 struct hlist_bl_head
,并且这个函数对于 irq 是未知的,所以当 hash table 可以用于irq 或 bottom halves:
spin_lock_irqsave:
local_irq_save(flags);
hlist_bl_lock(...);
spin_unlock_irqrestore:
hlist_bl_unlock(...);
local_irq_restore(flags);
spin_lock_bh:
local_bh_disable();
hlist_bl_lock(...);
spin_unlock_bh:
hlist_bl_unlock(...);
local_bh_enable();
我写的代码很少 creates/removes object 秒(最多几千)但经常在软 IRQ 上下文中修改它们。这些 object 也很少从任务上下文中读取(并且可能也很少被修改)(通过 procfs: file per object)。目前我的代码包含全局 per-CPU 数据块,每个数据块都由自旋锁保护。这样的块包含用于 object 存储的 fixed-sized 哈希表。
显然当前的设计不是最优的,尤其是当有非常高的 object 更新负载时:从 procfs 读取 objects 会导致更新软 IRQ 时的数据丢失。我需要重写同步方案以摆脱全局锁。最明显的选择——为每个哈希表桶设置一个自旋锁——它应该可以很好地扩展。问题是我可能需要使用我自己的哈希表实现或至少重新实现几个 top-level 宏(在 linux/hashtable.h 中没有找到 spinlock-protected 桶)。我还应该看看 RCU-enabled 哈希表吗(但我对这种同步方法还没有充分的了解)?
在 header linux/list_bl.h 中声明了带锁保护的桶。他们使用头指针的最低位作为锁定位。
RCU-protected 对存储桶的访问是使用 header linux/hashtable.h 中的其他散列 table 函数定义的(它们具有 _rcu
后缀)。
锁和 RCU 之间的选择由您决定。请注意,RCU 本身无法解决 modify-modify 冲突。它主要对 frequently-read 数据有帮助,这似乎不是你的情况。
因为只有一个锁定函数 - hlist_bl_lock
- 被声明为 struct hlist_bl_head
,并且这个函数对于 irq 是未知的,所以当 hash table 可以用于irq 或 bottom halves:
spin_lock_irqsave:
local_irq_save(flags); hlist_bl_lock(...);
spin_unlock_irqrestore:
hlist_bl_unlock(...); local_irq_restore(flags);
spin_lock_bh:
local_bh_disable(); hlist_bl_lock(...);
spin_unlock_bh:
hlist_bl_unlock(...); local_bh_enable();