Skip to content
  • Nick Piggin's avatar
    mm: pagecache gfp flags fix · 67d58ac4
    Nick Piggin authored
    
    
    Frustratingly, gfp_t is really divided into two classes of flags.  One are
    the context dependent ones (can we sleep?  can we enter filesystem?  block
    subsystem?  should we use some extra reserves, etc.).  The other ones are
    the type of memory required and depend on how the algorithm is implemented
    rather than the point at which the memory is allocated (highmem?  dma
    memory?  etc).
    
    Some of the functions which allocate a page and add it to page cache take
    a gfp_t, but sometimes those functions or their callers aren't really
    doing the right thing: when allocating pagecache page, the memory type
    should be mapping_gfp_mask(mapping).  When allocating radix tree nodes,
    the memory type should be kernel mapped (not highmem) memory.  The gfp_t
    argument should only really be needed for context dependent options.
    
    This patch doesn't really solve that tangle in a nice way, but it does
    attempt to fix a couple of bugs.
    
    - find_or_create_page changes its radix-tree allocation to only include
      the main context dependent flags in order so the pagecache page may be
      allocated from arbitrary types of memory without affecting the
      radix-tree.  In practice, slab allocations don't come from highmem
      anyway, and radix-tree only uses slab allocations.  So there isn't a
      practical change (unless some fs uses GFP_DMA for pages).
    
    - grab_cache_page_nowait() is changed to allocate radix-tree nodes with
      GFP_NOFS, because it is not supposed to reenter the filesystem.  This
      bug could cause lock recursion if a filesystem is not expecting the
      function to reenter the fs (as-per documentation).
    
    Filesystems should be careful about exactly what semantics they want and
    what they get when fiddling with gfp_t masks to allocate pagecache.  One
    should be as liberal as possible with the type of memory that can be used,
    and same for the the context specific flags.
    
    Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    67d58ac4