Question

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?

Was it helpful?

Solution 2

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)

OTHER TIPS

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).

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top