Re: Using ifnet pointers safely
In a nutshell, I have a C++ class whose instances each encapsulate a
network interface of interest. Each has a member that holds its
associated ifnet*. My plan is to put the dlil_attach_interface_filter()
and dlil_detach_filter() calls in the constructor and destructor of
these interface objects.
In looking at the code in xnu it seems that there is a refcount that
will prevent the system from freeing an interface with such an attached
filter. And my hope it that this will make it OK for me to hold onto
the ifnet* for as long as that filter is in place. Can anyone confirm
this?
No. The refcount doesn't count the filters, but count the protocols. If an interface is detached, the detach function of your filter is called, and then interface detachment continues. You have no way to prevent that from a filter.
My second question is how to create these objects safely in the first
place. Again, cribbing from xnu I've come up with a loop like this:
struct ifnet *ifp;
// read through list of devices and build a list of adapters that
we care about
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
... new InterfaceObject( ... ifp ...);
}
During this section of code I have the network funnel. If I understand
correctly, that protects me from any other running thread (even on MP
systems). Again, can someone confirm?
I think walking the list of ifnet is unfortunately the only way to discover the all ifnet. However, if you do an allocation like new InterfaceObject, you can loose the funnel, and potentially the list can be updated by an other code.
My real worry is about my own thread's behavior. I understand that
kernel threads can block and if they do then I loose and regain the
funnel. But since I can avoid making calls that block I can handle
that. But what about preemption? If my thread runs out of its time
quantum might it get preempted (and again loose and regain the funnel)?
And if that happens, couldn't the interface list change while I'm
iterating over it?
That's possible.
And lastly, whatever the solution to that is ("kernel threads can't be
preempted" or "use splnet() / splx()", or something else), what about
paths into my NKE that are really user threads that have called into
the kernel (through the network stack)? (Can that happen or is
everything in the kernel run on a kernel thread with the "call" handled
via a kernel thread blocking on a queue?) If it can happen, do I need
to consider such threads as different from native kernel threads as far
as preemption in my NKE goes?
I hate to ask so many questions but I do want to get this right. Any
hints would be appreciated.
Thanks,
Mike
_______________________________________________ darwin-kernel mailing list | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.
participants (1)
-
Christophe Allie