Writing a plain text file to disk from kernel space

Lawrence Stewart lstewart at room52.net
Wed May 23 01:24:37 UTC 2007


Comments inline...

Dag-Erling Smørgrav wrote:
> Lawrence Stewart <lstewart at room52.net> writes:
>   
>> After further investigation, it turns out that the pfil input hook I'm
>> using, which catches packets as they traverse up the network stack,
>> has no problems, and will happily write to the file using the
>> kio_write function. However, in the pfil output hook, a call to
>> kio_write causes a hard reset, with the following text shown on tty0:
>>
>> Sleeping thread (tid 100069, pid 613) owns a non-sleepable lock
>> panic: sleeping thread
>>     
>
> This is a panic, not a hard reset.
>
> Since you are writing kernel code, I assume you have KDB/DDB in your
> kernel and know how to use it.
>   

I don't know how to use them really. Thus far I haven't had a need for 
really low level debugging tools... seems that may have changed though! 
Any good tutorials/pointers on how to get started with kernel debugging?

>   
>> If I comment out the kio_write code and put a printf instead, there
>> are no such problems, so it seems the kio_write function is doing
>> something that is upsetting the kernel, but only when called from a
>> function that is acting as a pfil output hook? Strikes me as odd
>> behaviour. I don't understand which thread the error is in relation
>> to, why that thread is sleeping or which lock it is referring to.
>>     
>
> kio_write probably blocks waiting for the write to complete.  You can't
> do that while holding a non-sleepable lock.
>   

So this is where my knowledge/understanding gets very hazy...

When a thread blocks waiting for some operation to complete or event to 
happen, the thread effectively goes to sleep, correct?

Looking at the kio_write code in subr_kernio.c, I'm guessing the lock 
that is causing the trouble is related to the "vn_lock" function call?

I don't understand though why the vnode lock would be set up in such a 
way that when the write blocks whilst waiting for the underlying 
filesystem to signal everything is ok, it causes the kernel to panic!

How do I make the lock "sleepable" or make sure the thread doesn't try 
go to sleep whilst holding the lock?

>   
>> I tried wrapping the call to kio_write in a mutex, in case there was a
>> race condition caused by multiple threads trying to write to the file
>> at the one time, but that hasn't made a difference at all.
>>     
>
> It complains about sleeping with a non-sleepable lock held, and your
> solution is to add another non-sleepable lock?
>   

I didn't realise and don't understand why a mutex is considered a 
non-sleepable lock? Reading the mutex man page, it seems clear that 
creation of a standard mutex can indeed allow an interrupt or other 
kernel event to preempt the current thread holding the mutex, and 
therefore allow the thread to sleep whilst the higher priority event is 
handled? Doesn't sound like it's non-sleepable to me, but I could very 
well be misunderstanding the terminology.


All of that aside, why don't I get a "sleeping thread" panic when only 
the pfil input hook is put in place? If I was getting the panic when 
either an input or output hook was set, I wouldn't be so perplexed. But 
the fact that I only see this panic behaviour when the output hook 
(catching packets travelling down the network stack) is installed 
doesn't seem to add up. Any ideas?

Cheers,
Lawrence


More information about the freebsd-hackers mailing list