• Aaron Lu's avatar
    mm/swap: use nr_node_ids for avail_lists in swap_info_struct · 4fb12a08
    Aaron Lu authored
    [ Upstream commit 66f71da9dd38af17dc17209cdde7987d4679a699 ]
    Since a2468cc9 ("swap: choose swap device according to numa node"),
    avail_lists field of swap_info_struct is changed to an array with
    MAX_NUMNODES elements.  This made swap_info_struct size increased to 40KiB
    and needs an order-4 page to hold it.
    This is not optimal in that:
    1 Most systems have way less than MAX_NUMNODES(1024) nodes so it
      is a waste of memory;
    2 It could cause swapon failure if the swap device is swapped on
      after system has been running for a while, due to no order-4
      page is available as pointed out by Vasily Averin.
    Solve the above two issues by using nr_node_ids(which is the actual
    possible node number the running system has) for avail_lists instead of
    nr_node_ids is unknown at compile time so can't be directly used when
    declaring this array.  What I did here is to declare avail_lists as zero
    element array and allocate space for it when allocating space for
    swap_info_struct.  The reason why keep using array but not pointer is
    plist_for_each_entry needs the field to be part of the struct, so pointer
    will not work.
    This patch is on top of Vasily Averin's fix commit.  I think the use of
    kvzalloc for swap_info_struct is still needed in case nr_node_ids is
    really big on some systems.
    Link: http://lkml.kernel.org/r/20181115083847.GA11129@intel.comSigned-off-by: 's avatarAaron Lu <aaron.lu@intel.com>
    Reviewed-by: 's avatarAndrew Morton <akpm@linux-foundation.org>
    Acked-by: 's avatarMichal Hocko <mhocko@suse.com>
    Cc: Vasily Averin <vvs@virtuozzo.com>
    Cc: Huang Ying <ying.huang@intel.com>
    Signed-off-by: 's avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: 's avatarLinus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: 's avatarSasha Levin <sashal@kernel.org>