Блокировка внутри системных вызовов с использованием модулей ядра

Я заменил системный вызов 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) может пролить свет здесь.

Другие вопросы по тегам