In many cases, the precise API (or memory layer) used to perform a memory allocation does not really matter to the caller. So, a pattern of usage that emerged in a lot of in-kernel code paths went something like the following pseudocode:
kptr = kmalloc(n);
if (!kptr) {
kptr = vmalloc(n);
if (unlikely(!kptr))
<... failed, cleanup ...>
}
<ok, continue with kptr>
The cleaner alternative to this kind of code is the kvmalloc() API. Internally, it attempts to allocate the requested n bytes of memory like this: first, via the more efficient kmalloc(); if it succeeds, fine, we have quickly obtained physically contiguous memory and are done; if not, it falls back to allocating the memory via the slower but surer vmalloc() (thus obtaining virtually contiguous memory). Its signature is as follows:
#include <linux/mm.h>
void *kvmalloc(size_t size, gfp_t flags);
(Remember to include the header file.) Note that for...