unlocked_ioctl против обычного ioctl
-
21-08-2019 - |
Вопрос
В структуре file_operations моего драйвера у меня есть:
struct file_operations Fops = {
read: device_read,
write: device_write,
unlocked_ioctl: device_ioctl,
...
};
Т.е.поле ioctl не используется.Достаточно ли этого, чтобы избежать Big Kernel Lock и войти в device_ioctl() без какой-либо синхронизации?Или мне тоже нужно изменить вызовы ioctl() в части кода пользовательского пространства?
Решение 2
Хм, я решил это.Также необходимо изменить подпись функции device_ioctl.Параметр inode отсутствует, а также функция должна возвращать значение long.Как и в следующем патче:
-static int st_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd_in, unsigned long arg)
+static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
{
(от: http://linux.derkeiler.com/Mailing-Lists/Kernel/2008-01/msg06799.html)
Другие советы
Прочтите эту статью о LWN:http://lwn.net/Articles/119652/
Также где-то между 2.6.33 и 2.6.35 rc (используйте git-diff, чтобы узнать, какой коммит) ядро теперь ПРЕДУПРЕЖДАЕТ, когда определен только .ioctl.
Это шаг к более явной и детальной блокировке.Также обратите внимание, что только изменение сигнатуры функции и указателя будет скомпилировано, но приведет к возникновению условий гонки (два приложения пользовательского пространства одновременно выполняют вызовы ioctl).
Энди Клим опубликовал рецепт быстрого преобразования кода с помощью ioctl
к unlocked_ioctl
в списке рассылки ядра Linux:
[Предложение JANITOR] Переключить функции ioctl на ->unlocked_ioctl
Рецепт объясняет, как настроить параметры функции и вставить вызовы блокировки и разблокировки.