mm/sparse.c: fix typo in online_mem_sections
[linux-2.6-microblaze.git] / mm / page_io.c
index 5f61b54..21502d3 100644 (file)
 static struct bio *get_swap_bio(gfp_t gfp_flags,
                                struct page *page, bio_end_io_t end_io)
 {
+       int i, nr = hpage_nr_pages(page);
        struct bio *bio;
 
-       bio = bio_alloc(gfp_flags, 1);
+       bio = bio_alloc(gfp_flags, nr);
        if (bio) {
-               bio->bi_iter.bi_sector = map_swap_page(page, &bio->bi_bdev);
+               struct block_device *bdev;
+
+               bio->bi_iter.bi_sector = map_swap_page(page, &bdev);
+               bio_set_dev(bio, bdev);
                bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9;
                bio->bi_end_io = end_io;
 
-               bio_add_page(bio, page, PAGE_SIZE, 0);
-               BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE);
+               for (i = 0; i < nr; i++)
+                       bio_add_page(bio, page + i, PAGE_SIZE, 0);
+               VM_BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE * nr);
        }
        return bio;
 }
@@ -58,8 +63,7 @@ void end_swap_bio_write(struct bio *bio)
                 */
                set_page_dirty(page);
                pr_alert("Write-error on swap-device (%u:%u:%llu)\n",
-                        imajor(bio->bi_bdev->bd_inode),
-                        iminor(bio->bi_bdev->bd_inode),
+                        MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)),
                         (unsigned long long)bio->bi_iter.bi_sector);
                ClearPageReclaim(page);
        }
@@ -124,8 +128,7 @@ static void end_swap_bio_read(struct bio *bio)
                SetPageError(page);
                ClearPageUptodate(page);
                pr_alert("Read-error on swap-device (%u:%u:%llu)\n",
-                        imajor(bio->bi_bdev->bd_inode),
-                        iminor(bio->bi_bdev->bd_inode),
+                        MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)),
                         (unsigned long long)bio->bi_iter.bi_sector);
                goto out;
        }
@@ -262,6 +265,15 @@ static sector_t swap_page_sector(struct page *page)
        return (sector_t)__page_file_index(page) << (PAGE_SHIFT - 9);
 }
 
+static inline void count_swpout_vm_event(struct page *page)
+{
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+       if (unlikely(PageTransHuge(page)))
+               count_vm_event(THP_SWPOUT);
+#endif
+       count_vm_events(PSWPOUT, hpage_nr_pages(page));
+}
+
 int __swap_writepage(struct page *page, struct writeback_control *wbc,
                bio_end_io_t end_write_func)
 {
@@ -313,7 +325,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
 
        ret = bdev_write_page(sis->bdev, swap_page_sector(page), page, wbc);
        if (!ret) {
-               count_vm_event(PSWPOUT);
+               count_swpout_vm_event(page);
                return 0;
        }
 
@@ -326,7 +338,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
                goto out;
        }
        bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc);
-       count_vm_event(PSWPOUT);
+       count_swpout_vm_event(page);
        set_page_writeback(page);
        unlock_page(page);
        submit_bio(bio);
@@ -340,7 +352,7 @@ int swap_readpage(struct page *page, bool do_poll)
        int ret = 0;
        struct swap_info_struct *sis = page_swap_info(page);
        blk_qc_t qc;
-       struct block_device *bdev;
+       struct gendisk *disk;
 
        VM_BUG_ON_PAGE(!PageSwapCache(page), page);
        VM_BUG_ON_PAGE(!PageLocked(page), page);
@@ -379,7 +391,7 @@ int swap_readpage(struct page *page, bool do_poll)
                ret = -ENOMEM;
                goto out;
        }
-       bdev = bio->bi_bdev;
+       disk = bio->bi_disk;
        /*
         * Keep this task valid during swap readpage because the oom killer may
         * attempt to access it in the page fault retry time check.
@@ -395,7 +407,7 @@ int swap_readpage(struct page *page, bool do_poll)
                if (!READ_ONCE(bio->bi_private))
                        break;
 
-               if (!blk_mq_poll(bdev_get_queue(bdev), qc))
+               if (!blk_mq_poll(disk->queue, qc))
                        break;
        }
        __set_current_state(TASK_RUNNING);