Skip to content
  • Vlastimil Babka's avatar
    mm, frontswap: make sure allocated frontswap map is assigned · 5e322bee
    Vlastimil Babka authored
    Christian Borntraeger reports:
    
    With commit 8ea1d2a1 ("mm, frontswap: convert frontswap_enabled to
    static key") kmemleak complains about a memory leak in swapon
    
        unreferenced object 0x3e09ba56000 (size 32112640):
          comm "swapon", pid 7852, jiffies 4294968787 (age 1490.770s)
          hex dump (first 32 bytes):
            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
            00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
          backtrace:
             __vmalloc_node_range+0x194/0x2d8
             vzalloc+0x58/0x68
             SyS_swapon+0xd60/0x12f8
             system_call+0xd6/0x270
    
    Turns out kmemleak is right.  We now allocate the frontswap map
    depending on the kernel config (and no longer on the enablement)
    
      swapfile.c:
      [...]
          if (IS_ENABLED(CONFIG_FRONTSWAP))
                    frontswap_map = vzalloc(BITS_TO_LONGS(maxpages) * sizeof(long));
    
    but later on this is passed along
      --> enable_swap_info(p, prio, swap_map, cluster_info, frontswap_map);
    
    and ignored if frontswap is disabled
      --> frontswap_init(p->type, frontswap_map);
    
      static inline void frontswap_init(unsigned type, unsigned long *map)
      {
            if (frontswap_enabled())
                    __frontswap_init(type, map);
      }
    
    Thing is, that frontswap map is never freed.
    
    The leakage is relatively not that bad, because swapon is an infrequent
    and privileged operation.  However, if the first frontswap backend is
    registered after a swap type has been already enabled, it will WARN_ON
    in frontswap_register_ops() and frontswap will not be available for the
    swap type.
    
    Fix this by making sure the map is assigned by frontswap_init() as long
    as CONFIG_FRONTSWAP is enabled.
    
    Fixes: 8ea1d2a1 ("mm, frontswap: convert frontswap_enabled to static key")
    Link: http://lkml.kernel.org/r/20161026134220.2566-1-vbabka@suse.cz
    
    
    Signed-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
    Reported-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
    Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
    Cc: David Vrabel <david.vrabel@citrix.com>
    Cc: Juergen Gross <jgross@suse.com>
    Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    5e322bee