• Ilya Dryomov's avatar
    libceph: avoid a __vmalloc() deadlock in ceph_kvmalloc() · 10c12851
    Ilya Dryomov authored
    The vmalloc allocator doesn't fully respect the specified gfp mask:
    while the actual pages are allocated as requested, the page table pages
    are always allocated with GFP_KERNEL.  ceph_kvmalloc() may be called
    with GFP_NOFS and GFP_NOIO (for ceph and rbd respectively), so this may
    result in a deadlock.
    
    There is no real reason for the current PAGE_ALLOC_COSTLY_ORDER logic,
    it's just something that seemed sensible at the time (ceph_kvmalloc()
    predates kvmalloc()).  kvmalloc() is smarter: in an attempt to reduce
    long term fragmentation, it first tries to kmalloc non-disruptively.
    
    Switch to kvmalloc() and set the respective PF_MEMALLOC_* flag using
    the scope API to avoid the deadlock.  Note that kvmalloc() needs to be
    passed GFP_KERNEL to enable the fallback.
    Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
    Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
    10c12851
ceph_common.c 20.8 KB