HomeFreeBSD

kmem_alloc(KM_SLEEP) should use kvmalloc()

Description

kmem_alloc(KM_SLEEP) should use kvmalloc()

kmem_alloc(size>PAGESIZE, KM_SLEEP) is backed by kmalloc(), which
finds contiguous physical memory. If there isn't enough contiguous
physical memory available (e.g. due to physical page fragmentation), the
OOM killer will be invoked to make more memory available. This is not
ideal because processes may be killed when there is still plenty of free
memory (it just happens to be in individual pages, not contiguous runs
of pages). We have observed this when allocating the ~13KB zfs_cmd_t,
for example in zfsdev_ioctl().

This commit changes the behavior of
kmem_alloc(size>PAGESIZE, KM_SLEEP) when there are insufficient
contiguous free pages. In this case we will find individual pages and
stitch them together using virtual memory. This is accomplished by
using kvmalloc(), which implements the described behavior by trying
kmalloc(__GFP_NORETRY) and falling back on vmalloc().

The behavior of kmem_alloc(KM_NOSLEEP) is not changed; it continues to
use kmalloc(GPF_ATOMIC | __GFP_NORETRY). This is because vmalloc()
may sleep.

Reviewed-by: Tony Nguyen <tony.nguyen@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: George Wilson <gwilson@delphix.com>
Signed-off-by: Matthew Ahrens <mahrens@delphix.com>
Closes #11461

Details

Provenance
mahrensAuthored on Apr 6 2021, 7:44 PM
GitHub <noreply@github.com>Committed on Apr 6 2021, 7:44 PM
Parents
rG57a1214e3aa2: zpool-features.5: remove "booting not possible with this feature"s
Branches
Unknown
Tags
Unknown