x86/smpboot: Init apic mapping before usage
[cascardo/linux.git] / mm / swapfile.c
index 2657acc..2210de2 100644 (file)
@@ -105,7 +105,7 @@ __try_to_reclaim_swap(struct swap_info_struct *si, unsigned long offset)
        struct page *page;
        int ret = 0;
 
-       page = find_get_page(swap_address_space(entry), entry.val);
+       page = find_get_page(swap_address_space(entry), swp_offset(entry));
        if (!page)
                return 0;
        /*
@@ -257,6 +257,53 @@ static inline void cluster_set_null(struct swap_cluster_info *info)
        info->data = 0;
 }
 
+static inline bool cluster_list_empty(struct swap_cluster_list *list)
+{
+       return cluster_is_null(&list->head);
+}
+
+static inline unsigned int cluster_list_first(struct swap_cluster_list *list)
+{
+       return cluster_next(&list->head);
+}
+
+static void cluster_list_init(struct swap_cluster_list *list)
+{
+       cluster_set_null(&list->head);
+       cluster_set_null(&list->tail);
+}
+
+static void cluster_list_add_tail(struct swap_cluster_list *list,
+                                 struct swap_cluster_info *ci,
+                                 unsigned int idx)
+{
+       if (cluster_list_empty(list)) {
+               cluster_set_next_flag(&list->head, idx, 0);
+               cluster_set_next_flag(&list->tail, idx, 0);
+       } else {
+               unsigned int tail = cluster_next(&list->tail);
+
+               cluster_set_next(&ci[tail], idx);
+               cluster_set_next_flag(&list->tail, idx, 0);
+       }
+}
+
+static unsigned int cluster_list_del_first(struct swap_cluster_list *list,
+                                          struct swap_cluster_info *ci)
+{
+       unsigned int idx;
+
+       idx = cluster_next(&list->head);
+       if (cluster_next(&list->tail) == idx) {
+               cluster_set_null(&list->head);
+               cluster_set_null(&list->tail);
+       } else
+               cluster_set_next_flag(&list->head,
+                                     cluster_next(&ci[idx]), 0);
+
+       return idx;
+}
+
 /* Add a cluster to discard list and schedule it to do discard */
 static void swap_cluster_schedule_discard(struct swap_info_struct *si,
                unsigned int idx)
@@ -270,17 +317,7 @@ static void swap_cluster_schedule_discard(struct swap_info_struct *si,
        memset(si->swap_map + idx * SWAPFILE_CLUSTER,
                        SWAP_MAP_BAD, SWAPFILE_CLUSTER);
 
-       if (cluster_is_null(&si->discard_cluster_head)) {
-               cluster_set_next_flag(&si->discard_cluster_head,
-                                               idx, 0);
-               cluster_set_next_flag(&si->discard_cluster_tail,
-                                               idx, 0);
-       } else {
-               unsigned int tail = cluster_next(&si->discard_cluster_tail);
-               cluster_set_next(&si->cluster_info[tail], idx);
-               cluster_set_next_flag(&si->discard_cluster_tail,
-                                               idx, 0);
-       }
+       cluster_list_add_tail(&si->discard_clusters, si->cluster_info, idx);
 
        schedule_work(&si->discard_work);
 }
@@ -296,15 +333,8 @@ static void swap_do_scheduled_discard(struct swap_info_struct *si)
 
        info = si->cluster_info;
 
-       while (!cluster_is_null(&si->discard_cluster_head)) {
-               idx = cluster_next(&si->discard_cluster_head);
-
-               cluster_set_next_flag(&si->discard_cluster_head,
-                                               cluster_next(&info[idx]), 0);
-               if (cluster_next(&si->discard_cluster_tail) == idx) {
-                       cluster_set_null(&si->discard_cluster_head);
-                       cluster_set_null(&si->discard_cluster_tail);
-               }
+       while (!cluster_list_empty(&si->discard_clusters)) {
+               idx = cluster_list_del_first(&si->discard_clusters, info);
                spin_unlock(&si->lock);
 
                discard_swap_cluster(si, idx * SWAPFILE_CLUSTER,
@@ -312,19 +342,7 @@ static void swap_do_scheduled_discard(struct swap_info_struct *si)
 
                spin_lock(&si->lock);
                cluster_set_flag(&info[idx], CLUSTER_FLAG_FREE);
-               if (cluster_is_null(&si->free_cluster_head)) {
-                       cluster_set_next_flag(&si->free_cluster_head,
-                                               idx, 0);
-                       cluster_set_next_flag(&si->free_cluster_tail,
-                                               idx, 0);
-               } else {
-                       unsigned int tail;
-
-                       tail = cluster_next(&si->free_cluster_tail);
-                       cluster_set_next(&info[tail], idx);
-                       cluster_set_next_flag(&si->free_cluster_tail,
-                                               idx, 0);
-               }
+               cluster_list_add_tail(&si->free_clusters, info, idx);
                memset(si->swap_map + idx * SWAPFILE_CLUSTER,
                                0, SWAPFILE_CLUSTER);
        }
@@ -353,13 +371,8 @@ static void inc_cluster_info_page(struct swap_info_struct *p,
        if (!cluster_info)
                return;
        if (cluster_is_free(&cluster_info[idx])) {
-               VM_BUG_ON(cluster_next(&p->free_cluster_head) != idx);
-               cluster_set_next_flag(&p->free_cluster_head,
-                       cluster_next(&cluster_info[idx]), 0);
-               if (cluster_next(&p->free_cluster_tail) == idx) {
-                       cluster_set_null(&p->free_cluster_tail);
-                       cluster_set_null(&p->free_cluster_head);
-               }
+               VM_BUG_ON(cluster_list_first(&p->free_clusters) != idx);
+               cluster_list_del_first(&p->free_clusters, cluster_info);
                cluster_set_count_flag(&cluster_info[idx], 0, 0);
        }
 
@@ -398,14 +411,7 @@ static void dec_cluster_info_page(struct swap_info_struct *p,
                }
 
                cluster_set_flag(&cluster_info[idx], CLUSTER_FLAG_FREE);
-               if (cluster_is_null(&p->free_cluster_head)) {
-                       cluster_set_next_flag(&p->free_cluster_head, idx, 0);
-                       cluster_set_next_flag(&p->free_cluster_tail, idx, 0);
-               } else {
-                       unsigned int tail = cluster_next(&p->free_cluster_tail);
-                       cluster_set_next(&cluster_info[tail], idx);
-                       cluster_set_next_flag(&p->free_cluster_tail, idx, 0);
-               }
+               cluster_list_add_tail(&p->free_clusters, cluster_info, idx);
        }
 }
 
@@ -421,8 +427,8 @@ scan_swap_map_ssd_cluster_conflict(struct swap_info_struct *si,
        bool conflict;
 
        offset /= SWAPFILE_CLUSTER;
-       conflict = !cluster_is_null(&si->free_cluster_head) &&
-               offset != cluster_next(&si->free_cluster_head) &&
+       conflict = !cluster_list_empty(&si->free_clusters) &&
+               offset != cluster_list_first(&si->free_clusters) &&
                cluster_is_free(&si->cluster_info[offset]);
 
        if (!conflict)
@@ -447,11 +453,11 @@ static void scan_swap_map_try_ssd_cluster(struct swap_info_struct *si,
 new_cluster:
        cluster = this_cpu_ptr(si->percpu_cluster);
        if (cluster_is_null(&cluster->index)) {
-               if (!cluster_is_null(&si->free_cluster_head)) {
-                       cluster->index = si->free_cluster_head;
+               if (!cluster_list_empty(&si->free_clusters)) {
+                       cluster->index = si->free_clusters.head;
                        cluster->next = cluster_next(&cluster->index) *
                                        SWAPFILE_CLUSTER;
-               } else if (!cluster_is_null(&si->discard_cluster_head)) {
+               } else if (!cluster_list_empty(&si->discard_clusters)) {
                        /*
                         * we don't have free cluster but have some clusters in
                         * discarding, do discard now and reclaim them
@@ -999,7 +1005,7 @@ int free_swap_and_cache(swp_entry_t entry)
        if (p) {
                if (swap_entry_free(p, entry, 1) == SWAP_HAS_CACHE) {
                        page = find_get_page(swap_address_space(entry),
-                                               entry.val);
+                                            swp_offset(entry));
                        if (page && !trylock_page(page)) {
                                put_page(page);
                                page = NULL;
@@ -2292,10 +2298,8 @@ static int setup_swap_map_and_extents(struct swap_info_struct *p,
 
        nr_good_pages = maxpages - 1;   /* omit header page */
 
-       cluster_set_null(&p->free_cluster_head);
-       cluster_set_null(&p->free_cluster_tail);
-       cluster_set_null(&p->discard_cluster_head);
-       cluster_set_null(&p->discard_cluster_tail);
+       cluster_list_init(&p->free_clusters);
+       cluster_list_init(&p->discard_clusters);
 
        for (i = 0; i < swap_header->info.nr_badpages; i++) {
                unsigned int page_nr = swap_header->info.badpages[i];
@@ -2341,19 +2345,8 @@ static int setup_swap_map_and_extents(struct swap_info_struct *p,
        for (i = 0; i < nr_clusters; i++) {
                if (!cluster_count(&cluster_info[idx])) {
                        cluster_set_flag(&cluster_info[idx], CLUSTER_FLAG_FREE);
-                       if (cluster_is_null(&p->free_cluster_head)) {
-                               cluster_set_next_flag(&p->free_cluster_head,
-                                                               idx, 0);
-                               cluster_set_next_flag(&p->free_cluster_tail,
-                                                               idx, 0);
-                       } else {
-                               unsigned int tail;
-
-                               tail = cluster_next(&p->free_cluster_tail);
-                               cluster_set_next(&cluster_info[tail], idx);
-                               cluster_set_next_flag(&p->free_cluster_tail,
-                                                               idx, 0);
-                       }
+                       cluster_list_add_tail(&p->free_clusters, cluster_info,
+                                             idx);
                }
                idx++;
                if (idx == nr_clusters)