|
@@ -28,16 +28,18 @@
|
|
static struct bio *get_swap_bio(gfp_t gfp_flags,
|
|
static struct bio *get_swap_bio(gfp_t gfp_flags,
|
|
struct page *page, bio_end_io_t end_io)
|
|
struct page *page, bio_end_io_t end_io)
|
|
{
|
|
{
|
|
|
|
+ int i, nr = hpage_nr_pages(page);
|
|
struct bio *bio;
|
|
struct bio *bio;
|
|
|
|
|
|
- bio = bio_alloc(gfp_flags, 1);
|
|
|
|
|
|
+ bio = bio_alloc(gfp_flags, nr);
|
|
if (bio) {
|
|
if (bio) {
|
|
bio->bi_iter.bi_sector = map_swap_page(page, &bio->bi_bdev);
|
|
bio->bi_iter.bi_sector = map_swap_page(page, &bio->bi_bdev);
|
|
bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9;
|
|
bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9;
|
|
bio->bi_end_io = end_io;
|
|
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;
|
|
return bio;
|
|
}
|
|
}
|
|
@@ -262,6 +264,15 @@ static sector_t swap_page_sector(struct page *page)
|
|
return (sector_t)__page_file_index(page) << (PAGE_SHIFT - 9);
|
|
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,
|
|
int __swap_writepage(struct page *page, struct writeback_control *wbc,
|
|
bio_end_io_t end_write_func)
|
|
bio_end_io_t end_write_func)
|
|
{
|
|
{
|
|
@@ -313,7 +324,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
|
|
|
|
|
|
ret = bdev_write_page(sis->bdev, swap_page_sector(page), page, wbc);
|
|
ret = bdev_write_page(sis->bdev, swap_page_sector(page), page, wbc);
|
|
if (!ret) {
|
|
if (!ret) {
|
|
- count_vm_event(PSWPOUT);
|
|
|
|
|
|
+ count_swpout_vm_event(page);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -326,7 +337,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc);
|
|
bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc);
|
|
- count_vm_event(PSWPOUT);
|
|
|
|
|
|
+ count_swpout_vm_event(page);
|
|
set_page_writeback(page);
|
|
set_page_writeback(page);
|
|
unlock_page(page);
|
|
unlock_page(page);
|
|
submit_bio(bio);
|
|
submit_bio(bio);
|