• Hugh Dickins's avatar
    tmpfs: radix_tree_preloading · b409f9fc
    Hugh Dickins authored
    Nick has observed that shmem.c still uses GFP_ATOMIC when adding to page cache
    or swap cache, without any radix tree preload: so tending to deplete emergency
    reserves of memory.
    
    GFP_ATOMIC remains appropriate in shmem_writepage's add_to_swap_cache: it's
    being called under memory pressure, so must not wait for more memory to become
    available.  But shmem_unuse_inode now has a window in which it can and should
    preload with GFP_KERNEL, and say GFP_NOWAIT instead of GFP_ATOMIC in its
    add_to_page_cache.
    
    shmem_getpage is not so straightforward: its filepage/swappage integrity
    relies upon exchanging between caches under spinlock, and it would need a lot
    of restructuring to place the preloads correctly.  Instead, follow its pattern
    of retrying on races: use GFP_NOWAIT instead of GFP_ATOMIC in
    add_to_page_cache, and begin each circuit of the repeat loop with a sleeping
    radix_tree_preload, followed immediately by radix_tree_preload_end - that
    won't guarantee success in the next add_to_page_cache, but doesn't need to.
    
    And we can then remove that bothersome congestion_wait: when needed, it'll
    automatically get done in the course of the radix_tree_preload.
    Signed-off-by: default avatarHugh Dickins <hugh@veritas.com>
    Looks-good-to: Nick Piggin <npiggin@suse.de>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    b409f9fc
shmem.c 64.2 KB