Вы по сути никогда не должны использовать try_module_get (THIS_MODULE); почти все такие применения небезопасны, поскольку, если вы уже находитесь в своем модуле, слишком поздно увеличить счетчик ссылок - всегда будет (маленькое) окно, в котором вы выполняете код в своем модуле, но не увеличивали ссылку сосчитать. Если кто-то удаляет модуль именно в этом окне, то у вас плохая ситуация с запуском кода в незагруженном модуле.
Конкретный пример, который вы связали в LKMPG, где код выполняет try_module_get () в методе open (), будет обработан в современном ядре путем установки поля .owner в struct file_operations:
struct file_operations fops = {
.owner = THIS_MODULE,
.open = device_open,
//...
};
это заставит код VFS принимать ссылку на модуль перед вызовом в него, что исключает небезопасное окно - либо try_module_get () будет успешным перед вызовом .open (), либо try_module_get () потерпит неудачу, и VFS никогда не вызовет модуль. В любом случае мы никогда не запускаем код из модуля, который уже был выгружен.
Единственное хорошее время для использования try_module_get () - это когда вы хотите получить ссылку на другой модуль, прежде чем вызывать его или использовать его каким-либо образом (например, как код открытия файла делает в Пример, который я объяснил выше). Существует несколько вариантов использования try_module_get (THIS_MODULE) в исходном коде ядра, но большинство из них, если не все, являются скрытыми ошибками, которые следует устранить.
Причина, по которой вы не смогли выгрузить пример расписания, заключается в том, что ваш
$ tail /proc/sched -f &
Команда сохраняет / proc / sched открытой, и из-за
Our_Proc_File->owner = THIS_MODULE;
в коде sched.c открытие / proc / sched увеличивает счетчик ссылок модуля sched, который учитывает 1 ссылку, которую показывает ваш lsmod. После быстрой проверки остальной части кода, я думаю, что если вы выпустите / proc / sched, убив команду tail, вы сможете удалить модуль sched.