Блокировка внутри системных вызовов с использованием модулей ядра
Я заменил системный вызов sys_open в таблице системных вызовов для реализации подсчета системы. Какой замок я должен использовать? Функция spin_lock_irqsave() останавливает систему. Я использую Intel Core i3-4330 в Linux 3.16.0-4-686-pae.
Частичный, но полезный код:
static DEFINE_SPINLOCK(spin);
static int tally = 0;
static asmlinkage long my_sys_open(const char __user *filename, int flags, int mode)
{
unsigned long fl;
spin_lock_irqsave(&spin, fl); // system freeze
tally++;
spin_unlock_irqrestore(&spin, fl);
printk("sys_open used %i times\n", tally);
return old_sys_open(filename, flags, mode);
}
2 ответа
Это не решит вашу проблему с блокировкой напрямую, так как другие заявили в комментарии к вашему вопросу, код выглядит хорошо. Но в качестве альтернативы вы можете использовать atomic_t
введите в качестве счетчика и избегайте спин-блокировки все вместе. Что-то вроде:
atomic_t tally = ATOMIC_INIT(0);
а затем для увеличения значения используйте:
atomic_inc(&tally);
Наконец вы можете использовать atomic_read(&tally)
когда вы хотите, наконец, прочитать значение
Вы можете прочитать больше об атомном здесь.
Что делаешь? Что такое система подсчета? Как вы пришли к выводу, что строка spin_lock_irqsave вызывает проблемы?
Во-первых, в точке входа syscall разрешены прерывания, поэтому вместо этого должно быть spin_lock_irq. Но у этого кода есть 0 причин заботиться об отключении прерываний, поэтому это должно быть spin_lock. За исключением того, что вы только увеличиваете счетчик, что может быть сделано с атомарными операциями, следовательно, блокировка не требуется.
Несмотря на это, код не должен был вызывать проблемы, поэтому что-то еще идет не так. Включение средств отладки в конфигурации ядра и, возможно, получение vmcore (о kdump) может пролить свет здесь.