lkml.org 
[lkml]   [2009]   [Jan]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectPROBLEM: in_atomic() misuse all over the place
From
Date
(resent, non html)

[1.] One line summary of the problem:
in_atomic() is used to select path of execution, most likely to suppress
warning logs when running a preemptive kernel.

[2.] Full description of the problem/report:

The problem is that in_atomic() only works on preemptive kernels...

Result: preemptive kernel warns about a potential deadlock in all kernels,
developer silence with the help of in_atomic()
bug remains in SMP/UP kernels...

[3.] Keywords (i.e., modules, networking, kernel):
in_atomic(), preemptive, sleeping

[4.] Kernel version (from /proc/version):
2.6.28.2 (review)

[5.] Output of Oops..

"sleeping function called from invalid context"

[6.] A small shell script or example program which triggers the
problem (if possible)

Small example of the strange code I found is this

file: include/net/sock.h

static inline gfp_t gfp_any(void)
{
return in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
}

// I can find no comment on why this strange code would be OK.
// An it is in its turn used in several drivers...

If the processor can get to this function while atomic in a preemptive kernel
it will likely be able to get there in other kernels as well, especially SMP.

It returns GFP_ATOMIC when being atomic in a preemptive kernel, allocating
with that flag will not sleep. But calling this with another kernel will
ALWAYS return GFP_KERNEL, and it may cause a sleeping allocate...

Other places that I think misuse of in_atomic is Arch code, USB code, ...

There are 77 uses of in_atomic directly (grep | wc)
36 in ./arch
23 in ./drivers
2 in ./sound/core/seq/seq_virmidi.c
1 in ./include/net/sock.h
The remaining 15 are probably OK (kernel, mm/filemap)

But the sock.h gfp_any() spreads further...
1 in ./Documentation
2 in ./drivers
9 in ./net


Suggestion: should in_atomic() that by default return the safer 1 instead of
the unsafe 0. And add an in_atomic_warn() with default of 0 to use where it is
OK - like when deciding to log a warning.

/RogerL



\
 
 \ /
  Last update: 2009-01-28 00:13    [W:0.677 / U:0.064 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site