Существует ли заголовок linux для хэш-таблицы с корзинами, защищенными от спин-блокировки?

Я пишу код, который редко создает / удаляет объекты (до нескольких тысяч), но очень часто модифицирует их в контексте мягкого IRQ. Эти объекты также редко читаются (и, вероятно, также редко изменяются) из контекста задачи (через procfs: файл на объект). В настоящее время мой код содержит глобальные блоки данных для каждого процессора, каждый из которых защищен спин-блокировкой. Такой блок содержит хеш-таблицу фиксированного размера для хранения объектов.

Очевидно, что текущий дизайн не является оптимальным, особенно при очень высоких нагрузках на обновление объектов: чтение объектов из procfs приведет к потере данных при обновлении мягких IRQ. Мне нужно переписать схему синхронизации, чтобы избавиться от глобальных блокировок. Самый очевидный выбор - иметь спин-блокировку для каждого хэш-таблицы - он должен хорошо масштабироваться. Проблема в том, что мне, вероятно, понадобится использовать мою собственную реализацию хеш-таблицы или, по крайней мере, переопределить несколько макросов верхнего уровня (не нашло их в linux/hashtable.h для блоков с защитой от спин-блокировки). Должен ли я также взглянуть на хеш-таблицу с поддержкой RCU (но у меня нет четкого понимания этого подхода синхронизации)?

1 ответ

Решение

Контейнеры с защитой от блокировки объявляются в заголовке linux / list_bl.h. Они используют младший бит указателя головы в качестве бита блокировки.

Защищенный RCU доступ к корзине определяется с помощью других функций хеш-таблицы в заголовке linux / hashtable.h (они имеют _rcu суффикс).

Выбор между замками и RCU остается за вами. Обратите внимание, что сам RCU не может разрешить конфликты модификации-модификации. И это помогает в основном для часто читаемых данных, что, кажется, не ваш случай.


Как только одна функция блокировки - hlist_bl_lock - объявлен для struct hlist_bl_headи эта функция не знает о irq, дополнительные действия должны выполняться, когда хеш-таблицу можно использовать в irq или нижних половинах:

  • 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();
    
Другие вопросы по тегам