In my driver's file_operations structure, I have:
struct file_operations Fops = {
read: device_read,
write: device_write,
unlocked_ioctl: device_ioctl,
...
};
I.e. there is no ioctl field used. Is this sufficient to avoid Big Kernel Lock and enter into device_ioctl() without any synchronization? Or do I have to change ioctl() calls in userspace part of the code too?
Read this LWN article:
http://lwn.net/Articles/119652/
Also sometime between 2.6.33 and a 2.6.35 rc (use git-diff to find out which commit) the kernel now WARNs when only .ioctl is defined.
This is a move towards more explicit and fine-grained locking. Also note only changing the function signature and pointer will compile but will introduce the possibility of race conditions (two userspace apps doing ioctl calls at same time).
Uhm, I solved this. It is also required to change signature of device_ioctl function. There is no inode parameter, and also the function should return long. Just like in following patch:
-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)
{
(from: http://linux.derkeiler.com/Mailing-Lists/Kernel/2008-01/msg06799.html)
Andi Kleem posted a recipe for a quick-and-dirty conversion of code using ioctl
to unlocked_ioctl
on Linux kernel mailing list:
[JANITOR PROPOSAL] Switch ioctl functions to ->unlocked_ioctl
The recipe explains how to tweak the function's parameters and insert locking and unlocking calls.