return generic_swapfile_activate(sis, swap_file, span);
}
-static void setup_swap_info(struct swap_info_struct *si, int prio,
- unsigned long *zeromap)
-{
- si->prio = prio;
- /*
- * the plist prio is negated because plist ordering is
- * low-to-high, while swap ordering is high-to-low
- */
- si->list.prio = -si->prio;
- si->avail_list.prio = -si->prio;
- si->zeromap = zeromap;
-}
-
static void _enable_swap_info(struct swap_info_struct *si)
{
atomic_long_add(si->pages, &nr_swap_pages);
add_to_avail_list(si, true);
}
-static void enable_swap_info(struct swap_info_struct *si, int prio,
- unsigned long *zeromap)
+/*
+ * Called after the swap device is ready, resurrect its percpu ref, it's now
+ * safe to reference it. Add it to the list to expose it to the allocator.
+ */
+static void enable_swap_info(struct swap_info_struct *si)
{
- spin_lock(&swap_lock);
- spin_lock(&si->lock);
- setup_swap_info(si, prio, zeromap);
- spin_unlock(&si->lock);
- spin_unlock(&swap_lock);
- /*
- * Finished initializing swap device, now it's safe to reference it.
- */
percpu_ref_resurrect(&si->users);
spin_lock(&swap_lock);
spin_lock(&si->lock);
{
spin_lock(&swap_lock);
spin_lock(&si->lock);
- setup_swap_info(si, si->prio, si->zeromap);
_enable_swap_info(si);
spin_unlock(&si->lock);
spin_unlock(&swap_lock);
int nr_extents;
sector_t span;
unsigned long maxpages;
- unsigned long *zeromap = NULL;
struct folio *folio = NULL;
struct inode *inode = NULL;
bool inced_nr_rotate_swap = false;
* Use kvmalloc_array instead of bitmap_zalloc as the allocation order might
* be above MAX_PAGE_ORDER incase of a large swap file.
*/
- zeromap = kvmalloc_array(BITS_TO_LONGS(maxpages), sizeof(long),
- GFP_KERNEL | __GFP_ZERO);
- if (!zeromap) {
+ si->zeromap = kvmalloc_array(BITS_TO_LONGS(maxpages), sizeof(long),
+ GFP_KERNEL | __GFP_ZERO);
+ if (!si->zeromap) {
error = -ENOMEM;
goto bad_swap_unlock_inode;
}
if (swap_flags & SWAP_FLAG_PREFER)
prio = swap_flags & SWAP_FLAG_PRIO_MASK;
+ /*
+ * The plist prio is negated because plist ordering is
+ * low-to-high, while swap ordering is high-to-low
+ */
+ si->prio = prio;
+ si->list.prio = -si->prio;
+ si->avail_list.prio = -si->prio;
si->swap_file = swap_file;
/* Sets SWP_WRITEOK, resurrect the percpu ref, expose the swap device */
- enable_swap_info(si, prio, zeromap);
+ enable_swap_info(si);
pr_info("Adding %uk swap on %s. Priority:%d extents:%d across:%lluk %s%s%s%s\n",
K(si->pages), name->name, si->prio, nr_extents,
si->swap_map = NULL;
free_swap_cluster_info(si->cluster_info, si->max);
si->cluster_info = NULL;
+ kvfree(si->zeromap);
+ si->zeromap = NULL;
/*
* Clear the SWP_USED flag after all resources are freed so
* alloc_swap_info can reuse this si safely.
spin_lock(&swap_lock);
si->flags = 0;
spin_unlock(&swap_lock);
- kvfree(zeromap);
if (inced_nr_rotate_swap)
atomic_dec(&nr_rotate_swap);
if (swap_file)