]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - mm/swapfile.c
ata: ahci_brcm: Allow using driver or DSL SoCs
[mirror_ubuntu-bionic-kernel.git] / mm / swapfile.c
index 3074b02eaa09e505ae9790d42cdc1e6240556279..1c4b499af7af64d7038e5343c62a0583eedd7911 100644 (file)
@@ -98,6 +98,15 @@ static atomic_t proc_poll_event = ATOMIC_INIT(0);
 
 atomic_t nr_rotate_swap = ATOMIC_INIT(0);
 
+static struct swap_info_struct *swap_type_to_swap_info(int type)
+{
+       if (type >= READ_ONCE(nr_swapfiles))
+               return NULL;
+
+       smp_rmb();      /* Pairs with smp_wmb in alloc_swap_info. */
+       return READ_ONCE(swap_info[type]);
+}
+
 static inline unsigned char swap_count(unsigned char ent)
 {
        return ent & ~SWAP_HAS_CACHE;   /* may include SWAP_HAS_CONT flag */
@@ -1014,12 +1023,14 @@ noswap:
 /* The only caller of this function is now suspend routine */
 swp_entry_t get_swap_page_of_type(int type)
 {
-       struct swap_info_struct *si;
+       struct swap_info_struct *si = swap_type_to_swap_info(type);
        pgoff_t offset;
 
-       si = swap_info[type];
+       if (!si)
+               goto fail;
+
        spin_lock(&si->lock);
-       if (si && (si->flags & SWP_WRITEOK)) {
+       if (si->flags & SWP_WRITEOK) {
                atomic_long_dec(&nr_swap_pages);
                /* This is called for allocating swap entry, not cache */
                offset = scan_swap_map(si, 1);
@@ -1030,6 +1041,7 @@ swp_entry_t get_swap_page_of_type(int type)
                atomic_long_inc(&nr_swap_pages);
        }
        spin_unlock(&si->lock);
+fail:
        return (swp_entry_t) {0};
 }
 
@@ -1041,9 +1053,9 @@ static struct swap_info_struct *__swap_info_get(swp_entry_t entry)
        if (!entry.val)
                goto out;
        type = swp_type(entry);
-       if (type >= nr_swapfiles)
+       p = swap_type_to_swap_info(type);
+       if (!p)
                goto bad_nofile;
-       p = swap_info[type];
        if (!(p->flags & SWP_USED))
                goto bad_device;
        offset = swp_offset(entry);
@@ -1725,10 +1737,9 @@ int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
 sector_t swapdev_block(int type, pgoff_t offset)
 {
        struct block_device *bdev;
+       struct swap_info_struct *si = swap_type_to_swap_info(type);
 
-       if ((unsigned int)type >= nr_swapfiles)
-               return 0;
-       if (!(swap_info[type]->flags & SWP_WRITEOK))
+       if (!si || !(si->flags & SWP_WRITEOK))
                return 0;
        return map_swap_entry(swp_entry(type, offset), &bdev);
 }
@@ -2225,7 +2236,8 @@ int try_to_unuse(unsigned int type, bool frontswap,
                 */
                if (PageSwapCache(page) &&
                    likely(page_private(page) == entry.val) &&
-                   !page_swapped(page))
+                   (!PageTransCompound(page) ||
+                    !swap_page_trans_huge_swapped(si, entry)))
                        delete_from_swap_cache(compound_head(page));
 
                /*
@@ -2285,7 +2297,7 @@ static sector_t map_swap_entry(swp_entry_t entry, struct block_device **bdev)
        struct swap_extent *se;
        pgoff_t offset;
 
-       sis = swap_info[swp_type(entry)];
+       sis = swp_swap_info(entry);
        *bdev = sis->bdev;
 
        offset = swp_offset(entry);
@@ -2723,9 +2735,7 @@ static void *swap_start(struct seq_file *swap, loff_t *pos)
        if (!l)
                return SEQ_START_TOKEN;
 
-       for (type = 0; type < nr_swapfiles; type++) {
-               smp_rmb();      /* read nr_swapfiles before swap_info[type] */
-               si = swap_info[type];
+       for (type = 0; (si = swap_type_to_swap_info(type)); type++) {
                if (!(si->flags & SWP_USED) || !si->swap_map)
                        continue;
                if (!--l)
@@ -2745,9 +2755,7 @@ static void *swap_next(struct seq_file *swap, void *v, loff_t *pos)
        else
                type = si->type + 1;
 
-       for (; type < nr_swapfiles; type++) {
-               smp_rmb();      /* read nr_swapfiles before swap_info[type] */
-               si = swap_info[type];
+       for (; (si = swap_type_to_swap_info(type)); type++) {
                if (!(si->flags & SWP_USED) || !si->swap_map)
                        continue;
                ++*pos;
@@ -2836,8 +2844,9 @@ static struct swap_info_struct *alloc_swap_info(void)
        struct swap_info_struct *p;
        unsigned int type;
        int i;
+       int size = sizeof(*p) + nr_node_ids * sizeof(struct plist_node);
 
-       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       p = kvzalloc(size, GFP_KERNEL);
        if (!p)
                return ERR_PTR(-ENOMEM);
 
@@ -2848,21 +2857,21 @@ static struct swap_info_struct *alloc_swap_info(void)
        }
        if (type >= MAX_SWAPFILES) {
                spin_unlock(&swap_lock);
-               kfree(p);
+               kvfree(p);
                return ERR_PTR(-EPERM);
        }
        if (type >= nr_swapfiles) {
                p->type = type;
-               swap_info[type] = p;
+               WRITE_ONCE(swap_info[type], p);
                /*
                 * Write swap_info[type] before nr_swapfiles, in case a
                 * racing procfs swap_start() or swap_next() is reading them.
                 * (We never shrink nr_swapfiles, we never free this entry.)
                 */
                smp_wmb();
-               nr_swapfiles++;
+               WRITE_ONCE(nr_swapfiles, nr_swapfiles + 1);
        } else {
-               kfree(p);
+               kvfree(p);
                p = swap_info[type];
                /*
                 * Do not memset this entry: a racing procfs swap_next()
@@ -2909,6 +2918,35 @@ static int claim_swapfile(struct swap_info_struct *p, struct inode *inode)
        return 0;
 }
 
+
+/*
+ * Find out how many pages are allowed for a single swap device. There
+ * are two limiting factors:
+ * 1) the number of bits for the swap offset in the swp_entry_t type, and
+ * 2) the number of bits in the swap pte, as defined by the different
+ * architectures.
+ *
+ * In order to find the largest possible bit mask, a swap entry with
+ * swap type 0 and swap offset ~0UL is created, encoded to a swap pte,
+ * decoded to a swp_entry_t again, and finally the swap offset is
+ * extracted.
+ *
+ * This will mask all the bits from the initial ~0UL mask that can't
+ * be encoded in either the swp_entry_t or the architecture definition
+ * of a swap pte.
+ */
+unsigned long generic_max_swapfile_size(void)
+{
+       return swp_offset(pte_to_swp_entry(
+                       swp_entry_to_pte(swp_entry(0, ~0UL)))) + 1;
+}
+
+/* Can be overridden by an architecture for additional checks. */
+__weak unsigned long max_swapfile_size(void)
+{
+       return generic_max_swapfile_size();
+}
+
 static unsigned long read_swap_header(struct swap_info_struct *p,
                                        union swap_header *swap_header,
                                        struct inode *inode)
@@ -2944,23 +2982,12 @@ static unsigned long read_swap_header(struct swap_info_struct *p,
        p->cluster_next = 1;
        p->cluster_nr = 0;
 
-       /*
-        * Find out how many pages are allowed for a single swap
-        * device. There are two limiting factors: 1) the number
-        * of bits for the swap offset in the swp_entry_t type, and
-        * 2) the number of bits in the swap pte as defined by the
-        * different architectures. In order to find the
-        * largest possible bit mask, a swap entry with swap type 0
-        * and swap offset ~0UL is created, encoded to a swap pte,
-        * decoded to a swp_entry_t again, and finally the swap
-        * offset is extracted. This will mask all the bits from
-        * the initial ~0UL mask that can't be encoded in either
-        * the swp_entry_t or the architecture definition of a
-        * swap pte.
-        */
-       maxpages = swp_offset(pte_to_swp_entry(
-                       swp_entry_to_pte(swp_entry(0, ~0UL)))) + 1;
+       maxpages = max_swapfile_size();
        last_page = swap_header->info.last_page;
+       if (!last_page) {
+               pr_warn("Empty swap-file\n");
+               return 0;
+       }
        if (last_page > maxpages) {
                pr_warn("Truncating oversized swap area, only using %luk out of %luk\n",
                        maxpages << (PAGE_SHIFT - 10),
@@ -3356,7 +3383,7 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage)
 {
        struct swap_info_struct *p;
        struct swap_cluster_info *ci;
-       unsigned long offset, type;
+       unsigned long offset;
        unsigned char count;
        unsigned char has_cache;
        int err = -EINVAL;
@@ -3364,10 +3391,10 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage)
        if (non_swap_entry(entry))
                goto out;
 
-       type = swp_type(entry);
-       if (type >= nr_swapfiles)
+       p = swp_swap_info(entry);
+       if (!p)
                goto bad_file;
-       p = swap_info[type];
+
        offset = swp_offset(entry);
        if (unlikely(offset >= p->max))
                goto out;
@@ -3464,7 +3491,7 @@ int swapcache_prepare(swp_entry_t entry)
 
 struct swap_info_struct *swp_swap_info(swp_entry_t entry)
 {
-       return swap_info[swp_type(entry)];
+       return swap_type_to_swap_info(swp_type(entry));
 }
 
 struct swap_info_struct *page_swap_info(struct page *page)