Re: crossing user-kernel boundary (using copyin/copyout or mmap?)
Re: crossing user-kernel boundary (using copyin/copyout or mmap?)
- Subject: Re: crossing user-kernel boundary (using copyin/copyout or mmap?)
- From: Jim Magee <email@hidden>
- Date: Mon, 1 Sep 2003 09:30:09 -0400
On Sep 1, 2003, at 12:06 AM, Nathan Lim wrote:
So I have attempted the following to get information from the kernel
to the
user-space client (I will also want to send information the other
direction):
A) allocate memory in the user space using malloc()
B) pass the allocated user space void * ptr to the NKE via sysctl of
an int
C) in the NKE, call copyout() like this:
ret = copyout(k_addr, u_addr, shareSize);
This results in the copyout returning EFAULT (bad address). I checked
the
pointers and believe I am dereferencing all the addresses correctly,
but it
still doesn't work.
The copyout() function only works when you are guaranteed to be running
in the context of a thread within the target process. Since NKEs
typically run in many random thread contexts (all the user-level
threads from all applications that are pushing data through the network
stack as well as the kernel-bound threads that drive data upward from
the devices), very rarely will you be in the right context for the
copyout(). In fact, the EFAULT cases are the least of your worries.
On many of the cases where you didn't get EFAULT, you might have been
corrupting some innocent task's memory.
My questions are:
1) Are the copyout() and copyin() functions the best way to do this
(i.e.
share memory across the user-kernel boundary)?
Not for NKEs to "push" data to user-space, typically.
2) Should I be using mmap() or something else instead?
3) What do I need to do to get the copyout() working?
4) Do I need to wire the memory to get the copyout() to work?
Do you really need to use a "push" model for moving data from the
kernel to the user-space? Can you keep the data pooled in the kernel
and then call a special ioctl() to actively pull the data out from the
user-level thread context? If so (and I recommend this), then you can
use copyout() because you will always be in the right thread context.
If you must "push" the data out of the kernel (from whatever random
context you may executing in within your NKE), you probably want to use
a prepare()'ed and map()'ed IOKit memory descriptor. The only trick
(and it is a big one) is correctly detecting that your "special"
user-level process (the one that has the memory that you are copying
out to) has gone away in order to clean that up and release the hold on
the memory (otherwise you will likely keep the process lingering a
sort-of-zombie state waiting for the IOKit memory descriptor prepare()
to be complete()'ed).
--Jim
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.