Skip to content

Commit 225311a

Browse files
yhuang-inteltorvalds
authored andcommitted
mm: test code to write THP to swap device as a whole
To support delay splitting THP (Transparent Huge Page) after swapped out, we need to enhance swap writing code to support to write a THP as a whole. This will improve swap write IO performance. As Ming Lei <[email protected]> pointed out, this should be based on multipage bvec support, which hasn't been merged yet. So this patch is only for testing the functionality of the other patches in the series. And will be reimplemented after multipage bvec support is merged. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: "Huang, Ying" <[email protected]> Cc: "Kirill A . Shutemov" <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: Dan Williams <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Minchan Kim <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Ross Zwisler <[email protected]> [for brd.c, zram_drv.c, pmem.c] Cc: Shaohua Li <[email protected]> Cc: Vishal L Verma <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 98cc093 commit 225311a

File tree

5 files changed

+28
-7
lines changed

5 files changed

+28
-7
lines changed

include/linux/bio.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,15 @@
3838
#define BIO_BUG_ON
3939
#endif
4040

41+
#ifdef CONFIG_THP_SWAP
42+
#if HPAGE_PMD_NR > 256
43+
#define BIO_MAX_PAGES HPAGE_PMD_NR
44+
#else
4145
#define BIO_MAX_PAGES 256
46+
#endif
47+
#else
48+
#define BIO_MAX_PAGES 256
49+
#endif
4250

4351
#define bio_prio(bio) (bio)->bi_ioprio
4452
#define bio_set_prio(bio, prio) ((bio)->bi_ioprio = prio)

include/linux/page-flags.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,8 @@ PAGEFLAG(OwnerPriv1, owner_priv_1, PF_ANY)
303303
* Only test-and-set exist for PG_writeback. The unconditional operators are
304304
* risky: they bypass page accounting.
305305
*/
306-
TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND)
307-
TESTSCFLAG(Writeback, writeback, PF_NO_COMPOUND)
306+
TESTPAGEFLAG(Writeback, writeback, PF_NO_TAIL)
307+
TESTSCFLAG(Writeback, writeback, PF_NO_TAIL)
308308
PAGEFLAG(MappedToDisk, mappedtodisk, PF_NO_TAIL)
309309

310310
/* PG_readahead is only used for reads; PG_reclaim is only for writes */

include/linux/vm_event_item.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
8585
#endif
8686
THP_ZERO_PAGE_ALLOC,
8787
THP_ZERO_PAGE_ALLOC_FAILED,
88+
THP_SWPOUT,
8889
#endif
8990
#ifdef CONFIG_MEMORY_BALLOON
9091
BALLOON_INFLATE,

mm/page_io.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,18 @@
2828
static struct bio *get_swap_bio(gfp_t gfp_flags,
2929
struct page *page, bio_end_io_t end_io)
3030
{
31+
int i, nr = hpage_nr_pages(page);
3132
struct bio *bio;
3233

33-
bio = bio_alloc(gfp_flags, 1);
34+
bio = bio_alloc(gfp_flags, nr);
3435
if (bio) {
3536
bio->bi_iter.bi_sector = map_swap_page(page, &bio->bi_bdev);
3637
bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9;
3738
bio->bi_end_io = end_io;
3839

39-
bio_add_page(bio, page, PAGE_SIZE, 0);
40-
BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE);
40+
for (i = 0; i < nr; i++)
41+
bio_add_page(bio, page + i, PAGE_SIZE, 0);
42+
VM_BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE * nr);
4143
}
4244
return bio;
4345
}
@@ -262,6 +264,15 @@ static sector_t swap_page_sector(struct page *page)
262264
return (sector_t)__page_file_index(page) << (PAGE_SHIFT - 9);
263265
}
264266

267+
static inline void count_swpout_vm_event(struct page *page)
268+
{
269+
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
270+
if (unlikely(PageTransHuge(page)))
271+
count_vm_event(THP_SWPOUT);
272+
#endif
273+
count_vm_events(PSWPOUT, hpage_nr_pages(page));
274+
}
275+
265276
int __swap_writepage(struct page *page, struct writeback_control *wbc,
266277
bio_end_io_t end_write_func)
267278
{
@@ -313,7 +324,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
313324

314325
ret = bdev_write_page(sis->bdev, swap_page_sector(page), page, wbc);
315326
if (!ret) {
316-
count_vm_event(PSWPOUT);
327+
count_swpout_vm_event(page);
317328
return 0;
318329
}
319330

@@ -326,7 +337,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
326337
goto out;
327338
}
328339
bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc);
329-
count_vm_event(PSWPOUT);
340+
count_swpout_vm_event(page);
330341
set_page_writeback(page);
331342
unlock_page(page);
332343
submit_bio(bio);

mm/vmstat.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,7 @@ const char * const vmstat_text[] = {
10711071
#endif
10721072
"thp_zero_page_alloc",
10731073
"thp_zero_page_alloc_failed",
1074+
"thp_swpout",
10741075
#endif
10751076
#ifdef CONFIG_MEMORY_BALLOON
10761077
"balloon_inflate",

0 commit comments

Comments
 (0)