Re: Character device synchronization with network interface
Re: Character device synchronization with network interface
- Subject: Re: Character device synchronization with network interface
- From: Quinn <email@hidden>
- Date: Wed, 3 Nov 2004 23:22:42 +0000
At 12:11 -0800 3/11/04, Jamie Wood wrote:
I have a network interface driver that passes information to user
space via a character device file in /dev. I need to provide some
sort of synchronization between the code which services the
read/write system calls and the code that accepts and sends network
packets from the IP stack.
I've been poking around in the Apple documentation, but am still a
little confused. In the syscall service code, do I simply need to
use thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL) and vice
versa to keep the networking code from accessing the driver's shared
data structures? Based on what
http://www.usenix.org/publications/library/proceedings/bsdcon02/full_papers/gerbarg/gerbarg_html/
says, this doesn't sound like it will be enough, and only helps in
SMP situations. However, that seems to be what other drivers are
doing (namely, the PPP driver).
Do I need to use a mutex in addition to thread_funnel_switch()?
Performance is critical to me, so I would like to avoid using any
unnecessary locks.
Any clarification would be greatly appreciated.
It depends on what version of the OS you're targetting. The BSD
portions of 10.3.x and earlier are funnelled. The networking stack
runs under the network funnel, everything else (including character
devices) under the kernel funnel. If you hold the funnel, you are
assured that no other thread will run in that part of the kernel
until you either block or release the funnel. If your code has data
that it wants to protect, you can do this in two ways.
1. use the funnels -- Decide which funnel you want to access the data
under, and then always make sure you're running under that funnel
when you access the data. For example, if you want to protect the
data under the network funnel, the network part of your driver will
be already protected but the character device part of your driver
will have to drop the kernel funnel and acquire the network funnel.
Also, the code that works on the data will have to be careful when it
blocks; it can't assume that the data didn't change across the block.
2. ignore the funnels -- Protect your data with a lock and then drop
all funnels before accessing it.
Generally option 1 is easier to implement.
btw Funnels are important even on single processor machines. The BSD
portitions of the kernel are preemptible and I/O Kit delivers
'interrupts' to BSD on work loop threads. These two facts make it
possible for a thread within BSD to be stepped on by another thread
trying to enter BSD. The funnels are what prevents this.
* * *
If you're targetting Tiger, you have to deal with fine grained
locking. The fine grained locking in the BSD portions of Tiger works
as follows.
o all objects have a reference count
o the kernel /never/ calls you with any locks held; rather, if the
kernel wants to guarantee that an object you're working on stays
around for the duration of its call to you, it bumps the reference
count before it releases its lock on the object, calls you, then
reacquires the lock or drops the reference (depending on whether it
still needs to work on the object) once you return
o if you want to guarantee that an object you're working on stays
around, you should bump the reference count
o you are responsible for providing locks for your own data structures
S+E
--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Technical Support * Networking, Communications, Hardware
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden