Re: lock_kernel() & kmalloc - evil together?

From: Jeff V. Merkey (jmerkey@timpanogas.com)
Date: Fri Aug 11 2000 - 13:02:35 EST


Linus Torvalds wrote:
>
> In article <20000811002448.A27012@gruyere.muc.suse.de>,
> Andi Kleen <ak@suse.de> wrote:
> >
> >When you cannot sleep you should use kmalloc(..., GFP_ATOMIC), but it is
> >less reliable than GFP_KERNEL.
>
> Also, you should try to avoid doing these kinds of operations inside a
> spinlock, simply because they are slow (ATOMIC does not imply "fast", it
> only implies that we won't schedule).
>
> Rule of thumb: use GFP_ATOMIC only inside interrupt handlers or bottom
> half routines. In any other case, try to just do the allocation before
> you do the spinlock (or drop the lock and re-start).
>
> It's not positively _wrong_ to do a GFP_ATOMIC inside a spinlock, it's
> just something to be avoided as much as possible. Sometimes it is
> unavoidable (or really ugly to avoid).

Linus,

I am using GFP_ATOMIC inside a spinlock for allocating new cache blocks
inside the NWFS LRU. The source of the deadlocks folks reported last
month were due to using GFP_KERNEL (which could sleep). The reason I
have to do this is that there is a race condition if you unlock whereby
another thread could come in and ask for the same block (which you are
allocating an LRU block for) and you could end up with two blocks
getting created for a single block and I would have to check for this
case and delete one of them if detected). There's also a path where the
disk interrupt could allocate and create an LRU block from the context
of the disk interrupt during callbacks from the buffer_head structure,
so I have to use GFP_ATOMIC with the lock held here.

When NetWare detects someone trying to sleep on an interrupt, it prints
and Abend (panic) and enters the kernel mode debugger rather than just
crash like Linux does. This makes debugging this somewhat harder to
track down since it does not provide any info about who or where in the
code this happened.

Depending on how efficient your kmalloc is (which it looks to have a
fairly short code path on the fall through case) holding a lock over it
on most cases would seem to go pretty quick, but I do agree that this is
less than ideal. NetWare would detect if someone was at interrupt and
also had a method for kernel modules to detect this as well before
attempting any calls that could sleep from an interrupt. They also
allow memory allocs (like kmalloc()) from interrupt and their version of
kmalloc() [AllocateMemory()] detects if it's at interrupt and does not
sleep without requiring the programmer to call separate APIs. I can see
advantages, however, to the model Linux is using since it forces
programmers to identify interrupt code paths in kernel and handle them
properly.

:-)

Jeff

But everybody should be aware of
> the fact that the less you do inside a spinlock, the less contention you
> will have (and this is often a super-linear effect - read some queueing
> theory if you really care about the exact issues).
>
> Linus
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.rutgers.edu
> Please read the FAQ at http://www.tux.org/lkml/

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Aug 15 2000 - 21:00:25 EST