ACPI: DPTF: Add PCH FIVR participant driver
[linux-2.6-microblaze.git] / mm / swapfile.c
index 6c26916..12f59e6 100644 (file)
@@ -672,7 +672,7 @@ static void swap_range_alloc(struct swap_info_struct *si, unsigned long offset,
        if (offset == si->lowest_bit)
                si->lowest_bit += nr_entries;
        if (end == si->highest_bit)
-               si->highest_bit -= nr_entries;
+               WRITE_ONCE(si->highest_bit, si->highest_bit - nr_entries);
        si->inuse_pages += nr_entries;
        if (si->inuse_pages == si->pages) {
                si->lowest_bit = si->max;
@@ -696,6 +696,7 @@ static void add_to_avail_list(struct swap_info_struct *p)
 static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
                            unsigned int nr_entries)
 {
+       unsigned long begin = offset;
        unsigned long end = offset + nr_entries - 1;
        void (*swap_slot_free_notify)(struct block_device *, unsigned long);
 
@@ -704,7 +705,7 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
        if (end > si->highest_bit) {
                bool was_full = !si->highest_bit;
 
-               si->highest_bit = end;
+               WRITE_ONCE(si->highest_bit, end);
                if (was_full && (si->flags & SWP_WRITEOK))
                        add_to_avail_list(si);
        }
@@ -721,6 +722,7 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
                        swap_slot_free_notify(si->bdev, offset);
                offset++;
        }
+       clear_shadow_from_swap_cache(si->type, begin, end);
 }
 
 static void set_cluster_next(struct swap_info_struct *si, unsigned long next)
@@ -868,7 +870,7 @@ checks:
                else
                        goto done;
        }
-       si->swap_map[offset] = usage;
+       WRITE_ONCE(si->swap_map[offset], usage);
        inc_cluster_info_page(si, si->cluster_info, offset);
        unlock_cluster(ci);
 
@@ -927,12 +929,13 @@ done:
 
 scan:
        spin_unlock(&si->lock);
-       while (++offset <= si->highest_bit) {
-               if (!si->swap_map[offset]) {
+       while (++offset <= READ_ONCE(si->highest_bit)) {
+               if (data_race(!si->swap_map[offset])) {
                        spin_lock(&si->lock);
                        goto checks;
                }
-               if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
+               if (vm_swap_full() &&
+                   READ_ONCE(si->swap_map[offset]) == SWAP_HAS_CACHE) {
                        spin_lock(&si->lock);
                        goto checks;
                }
@@ -944,11 +947,12 @@ scan:
        }
        offset = si->lowest_bit;
        while (offset < scan_base) {
-               if (!si->swap_map[offset]) {
+               if (data_race(!si->swap_map[offset])) {
                        spin_lock(&si->lock);
                        goto checks;
                }
-               if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
+               if (vm_swap_full() &&
+                   READ_ONCE(si->swap_map[offset]) == SWAP_HAS_CACHE) {
                        spin_lock(&si->lock);
                        goto checks;
                }
@@ -1147,7 +1151,7 @@ static struct swap_info_struct *__swap_info_get(swp_entry_t entry)
        p = swp_swap_info(entry);
        if (!p)
                goto bad_nofile;
-       if (!(p->flags & SWP_USED))
+       if (data_race(!(p->flags & SWP_USED)))
                goto bad_device;
        offset = swp_offset(entry);
        if (offset >= p->max)
@@ -1173,7 +1177,7 @@ static struct swap_info_struct *_swap_info_get(swp_entry_t entry)
        p = __swap_info_get(entry);
        if (!p)
                goto out;
-       if (!p->swap_map[swp_offset(entry)])
+       if (data_race(!p->swap_map[swp_offset(entry)]))
                goto bad_free;
        return p;
 
@@ -1242,7 +1246,10 @@ static unsigned char __swap_entry_free_locked(struct swap_info_struct *p,
        }
 
        usage = count | has_cache;
-       p->swap_map[offset] = usage ? : SWAP_HAS_CACHE;
+       if (usage)
+               WRITE_ONCE(p->swap_map[offset], usage);
+       else
+               WRITE_ONCE(p->swap_map[offset], SWAP_HAS_CACHE);
 
        return usage;
 }
@@ -1294,7 +1301,7 @@ struct swap_info_struct *get_swap_device(swp_entry_t entry)
                goto bad_nofile;
 
        rcu_read_lock();
-       if (!(si->flags & SWP_VALID))
+       if (data_race(!(si->flags & SWP_VALID)))
                goto unlock_out;
        offset = swp_offset(entry);
        if (offset >= si->max)
@@ -1368,7 +1375,7 @@ void put_swap_page(struct page *page, swp_entry_t entry)
        unsigned char *map;
        unsigned int i, free_entries = 0;
        unsigned char val;
-       int size = swap_entry_size(hpage_nr_pages(page));
+       int size = swap_entry_size(thp_nr_pages(page));
 
        si = _swap_info_get(entry);
        if (!si)
@@ -1915,7 +1922,7 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
                page_add_anon_rmap(page, vma, addr, false);
        } else { /* ksm created a completely new copy */
                page_add_new_anon_rmap(page, vma, addr, false);
-               lru_cache_add_active_or_unevictable(page, vma);
+               lru_cache_add_inactive_or_unevictable(page, vma);
        }
        swap_free(entry);
        /*
@@ -3482,7 +3489,7 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage)
        } else
                err = -ENOENT;                  /* unused swap entry */
 
-       p->swap_map[offset] = count | has_cache;
+       WRITE_ONCE(p->swap_map[offset], count | has_cache);
 
 unlock_out:
        unlock_cluster_or_swap_info(p, ci);