Feature #3232
open
043: Using a blocking memory allocation when spinlock is held
Added by Evgeny Novikov over 12 years ago.
Updated about 10 years ago.
Description
(copied almost as is from kernel-rules/rules/DRVRULES_en.trl)
Summary¶
You should use GFP_ATOMIC flag when calling memory allocation functions when spinlock is held.
Description¶
A
sleeping memory allocations should be forbidden when spinlock is held. Sleeping memory allocation may cause context switch to the other process if the allocation system (e.g. SLAB) can't allocate memory right now. This erroneous behavior can result in:
- General decrease of system productivity. The other system processes (including real-time processes) that use locked resource will depend on memory allocation.
- OS corruption in embedded systems (those without MMU and address pages), because an implicit deadlock happens if memory allocation is impossible at the moment.
Therefore, having a spinlock acquired, you should use GFP_ATOMIC flag when calling memory allocation functions, such as `kmalloc`, `vmalloc`, `get_free_pages` etc.
Links¶
Sample bugfix in drivers/net/wireless/orinoco/wext.c
Corresponding models 43_1 (old aspect model) and 43_1a (new aspect model) were already implemented. In fixing #453 and related issues old aspect model was completely removed and test sets were fixed respectively (43_1a id is used instead of 43_1). There is such the difference for the medium test set:
-driver=kbdrivers--0043-2.6.31.6--test-0043-2.6.31.6-verdict-unsafe-drivers--char--hvc_console.c.tar.bz2;origin=external;kernel=linux-2.6.31.6;model=43_1a;module=drivers/kbdrivers/0043-2.6.31.6/test-0043-2.6.31.6-verdict-unsafe-drivers--char--hvc_console.c/hvc_console.ko;main=ldv_main0_sequence_infinite_withcheck_stateful;verdict=unsafe
-driver=kbdrivers--0043-2.6.31.6--test-0043-2.6.31.6-verdict-unsafe-drivers--char--n_r3964.c.tar.bz2;origin=external;kernel=linux-2.6.31.6;model=43_1a;module=drivers/kbdrivers/0043-2.6.31.6/test-0043-2.6.31.6-verdict-unsafe-drivers--char--n_r3964.c/n_r3964.ko;main=ldv_main0_sequence_infinite_withcheck_stateful;verdict=unsafe
-driver=kbdrivers--0043-2.6.31.6--test-0043-2.6.31.6-verdict-unsafe-drivers--net--hamradio--6pack.c.tar.bz2;origin=external;kernel=linux-2.6.31.6;model=43_1a;module=drivers/kbdrivers/0043-2.6.31.6/test-0043-2.6.31.6-verdict-unsafe-drivers--net--hamradio--6pack.c/6pack.ko;main=ldv_main0_sequence_infinite_withcheck_stateful;verdict=unsafe
+driver=kbdrivers--0043-2.6.31.6--test-0043-2.6.31.6-verdict-unsafe-drivers--char--hvc_console.c.tar.bz2;origin=external;kernel=linux-2.6.31.6;model=43_1a;module=drivers/kbdrivers/0043-2.6.31.6/test-0043-2.6.31.6-verdict-unsafe-drivers--char--hvc_console.c/hvc_console.ko;main=ldv_main0_sequence_infinite_withcheck_stateful;verdict=safe
+driver=kbdrivers--0043-2.6.31.6--test-0043-2.6.31.6-verdict-unsafe-drivers--char--n_r3964.c.tar.bz2;origin=external;kernel=linux-2.6.31.6;model=43_1a;module=drivers/kbdrivers/0043-2.6.31.6/test-0043-2.6.31.6-verdict-unsafe-drivers--char--n_r3964.c/n_r3964.ko;main=ldv_main0_sequence_infinite_withcheck_stateful;verdict=safe
+driver=kbdrivers--0043-2.6.31.6--test-0043-2.6.31.6-verdict-unsafe-drivers--net--hamradio--6pack.c.tar.bz2;origin=external;kernel=linux-2.6.31.6;model=43_1a;module=drivers/kbdrivers/0043-2.6.31.6/test-0043-2.6.31.6-verdict-unsafe-drivers--net--hamradio--6pack.c/6pack.ko;main=ldv_main0_sequence_infinite_withcheck_stateful;verdict=safe
-driver=test-0043-drivers-net-wireless-orinoco-wext-safe.tar.bz2;origin=external;kernel=linux-2.6.32.15;model=43_1a;module=drivers/test-0043-drivers-net-wireless-orinoco-wext-safe/wext.ko;main=ldv_main0_sequence_infinite_withcheck_stateful;verdict=unsafe
+driver=test-0043-drivers-net-wireless-orinoco-wext-safe.tar.bz2;origin=external;kernel=linux-2.6.32.15;model=43_1a;module=drivers/test-0043-drivers-net-wireless-orinoco-wext-safe/wext.ko;main=ldv_main0_sequence_infinite_withcheck_stateful;verdict=safe
One should investigate what has happened and may be tune 43_1a model or/and tests.
Commit 1f558ed of the master branch has changed corresponding verdicts temporary to pass night tests.
Commits which fix this type of errors in linux-stable repository
2636e65
- Status changed from New to Open
- Assignee set to Ilya Shchepetkov
Please, use ability to refer to function argument by its name specified in aspect file (implemented in #3802).
- Status changed from Open to Resolved
The ability to refer to function argument by its name specified in aspect file was added in the commit b4b7331 of master branch.
Tests passed.
- Subject changed from 43_1: Using a blocking memory allocation when spinlock is held to 043_1: Using a blocking memory allocation when spinlock is held
More correct statement:
Having a spinlock acquired, you should use GFP_ATOMIC or GFP_NOWAIT flag when calling memory allocation functions.
GFP_NOWAIT is similar to GFP_ATOMIC, but it asks to not use emergency pool if there is no regular memory found.
Even more correct statement (bit-level):
Having a spinlock acquired, you should call memory allocation functions with __GFP_WAIT flag unset.
- Subject changed from 043_1: Using a blocking memory allocation when spinlock is held to 043: Using a blocking memory allocation when spinlock is held
Some functions in "before: ALLOC", "around: ALLOC_AROUND" and "before: ALLOC_WITHOUT" (for example, static inline void *kmalloc(.., gfp_t flags, ..) and static inline void *kzalloc(.., gfp_t flags, ..)) will always return 0, which makes some pathes in program infeasible.
- Status changed from Resolved to Open
- Assignee changed from Ilya Shchepetkov to Vitaly Mordan
Also available in: Atom
PDF