Re: Kernel Panics & kernel controls
Re: Kernel Panics & kernel controls
- Subject: Re: Kernel Panics & kernel controls
- From: Greg <email@hidden>
- Date: Tue, 23 Jan 2007 12:06:36 -0500
Thanks, I am sending to the same unit number and so I do think that
there probably is a concurrency issue, once I fix it (hopefully) I'll
let you know (I'm definitely not calling ctl_enqueue more than 100
times/sec).
- Greg
On Jan 22, 2007, at 4:31 PM, Matt Darland wrote:
On Jan 21, 2007, at 10:22 PM, Greg wrote:
I thought that your statements might have been the silver bullet
but I don't think that I'm calling anything that implicitly
consumes the mbuf chain before I free it. I think that the
problem is occurring because ctl_enqueue is being called either
too quickly or concurrently, so I will try to work around that (I
was planning on doing it anyway) and see if that stops the kernel
panics.
ctl_enqueuedata() internally does m_allocpacket_internal(M_NOWAIT)
which can fail due to a low free mbuf pool, but it won't panic due
to calling frequency. Concurrency may be an issue if you are
sending data concurrently to the same 'unit number' (not sure about
this; I'm not constrained by this requirement). 'Units' state are
protected such that calling ctl_enqueueXXX() against different
units is no problem.
A possible alternative that I know works in 'high-traffic' usage (>
100 ctl_enqueuembuf() calls/sec and >50Mbits/sec) is to do mbuf
allocation yourself and use ctl_enqueuembuf(). The first mbuf in
your chain MUST be a 'packet header' type mbuf. This isn't
documented, but the darwin source in kern_control.c/ctl_enqueuembuf
() assumes the existence of a packet header. For example:
static
errno_t
send_upbound_data(
u_int32_t sock,
mbuf_t indata )
{
mbuf_t hdr;
mbuf_gethdr( MBUF_WAITOK, MBUF_TYPE_DATA, &hdr );
mbuf_setnext( hdr, indata );
mbuf_pkthdr_setlen( hdr, BYTECOUNT_IN_INDATA_CHAIN );
errno_t error = ctl_enqueuembuf( gKctlRef, sock, hdr,
CTL_DATA_EOR );
if( error != ENOBUFS )
{
/* Mbuf chain consumed. */
if( error )
{
printf( "com.mykext: ctl_enqueuembuf() = %d.\n", error );
}
}
else
{
/* Mbuf chain NOT consumed. Maybe create a timer to retry
send? */
/* ...or delete using mbuf_freem( hdr ); */
}
return( error );
}
----
Matt
On Jan 19, 2007, at 3:46 PM, Matt Darland wrote:
When you get the mbuf from the ctl_send handler your kext owns
the mbuf and is responsible for disposal. However, disposal can
mean things other than directly calling mbuf_freem(), e.g.
ctl_enqueuembuf(), sock_sendmbuf(), or any other routine that
implicitly consumes an mbuf chain.
Also, if you are modifying mbuf payloads, be aware of mbufs with
'external data' (often referred to as mbuf clusters). External
data is payload data that is referenced by multiple mbufs, and
you could be modifying data out from underneath another part of
the OS.
----
Matt
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden