Hi- I'm trying to write a linux kernel (network) device driver, and
user space library to go with it.

The kernel driver and user space library communicate via the ioctl()
mechanism; the library has to poll the driver (using ioctl()) for
driver-initiated (ie. asynchronous from the library's point of view)
events*. Most events have fixed size data associated with them, for
which the sequence is:

(1) driver: event occurs, added to queue

:

(2) library polls driver: calls ioctl() with a pointer to a user event
data area

(3) driver ioctl handler: gets event off queue and calls
copy_to_user() to copy event data from kernel memory into user memory

(4) library: ioctl() call returns with event data in user event data area.

But some events have variable sized data, and the structures
associated with them contain pointers. So for these the sequence I
want is:

(1) driver: event occurs, kernel memory allocated, added to queue

:

(2) library polls driver: calls ioctl()

(3) driver ioctl handler: gets event off queue, allocates user memory
and sets pointer in ioctl() data pointing to it, copies event data
from kernel into user memory, frees kernel memory

(4) library: ioctl() call returns with pointers to driver-allocated
user memory containing event data.

Is this possible? That is, I don't know how to (or whether I can)
manage user memory in the kernel. I know there is a GFP_USER kmalloc()
flag, but does that return a pointer that can be used as the
destination of a copy_to_user()? (Did a Google but didn't find
appropriate info, apologies if I missed it.)

It would be possible to use fixed size structures between library and
driver, but this would mean changing a published interface and hence
I'm trying to avoid it.

Cheers
John

[*] I know polling isn't ideal, but haven't come up with anything
better. I tried using 2 sockets, one for library to driver traffic and
the other for driver to library events. For the latter, the library
called ioctl() as for polling, but in the device's ioctl handler, it
blocked waiting for an event to be added to the event queue. This
blocking worked, but unfortunately it also blocked the library to
driver traffic on the other socket. I'm not a linux expert, and would
be interested to hear a better way...

Reply via email to