swap: make cluster allocation per-cpu
Subsystems (2)
PATCH v5 4/4 swap: make cluster allocation per-cpu
swap cluster allocation is to get better request merge to improve performance. But the cluster is shared globally, if multiple tasks are doing swap, this will cause interleave disk access. While multiple tasks swap is quite common, for example, each numa node has a kswapd thread doing swap or multiple threads/processes do direct page reclaim.
We makes the cluster allocation per-cpu here. The interleave disk access issue goes away. All tasks will do sequential swap.
If one CPU can't get its per-cpu cluster (for example, there is no free cluster anymore in the swap), it will fallback to scan swap_map. The CPU can still continue swap. We don't need recycle free swap entries of other CPUs.
In my test (swap to a 2-disk raid0 partition), this improves around 10% swapout throughput, and request size is increased significantly.
How does this impact swap readahead is uncertain though. On one side, page reclaim always isolates and swaps several adjancent pages, this will make page reclaim write the pages sequentially and benefit readahead. On the other side, several CPU write pages interleave means the pages don't live _sequentially_ but relatively _near_. In the per-cpu allocation case, if adjancent pages are written by different cpus, they will live relatively _far_. So how this impacts swap readahead depends on how many pages page reclaim isolates and swaps one time. If the number is big, this patch will benefit swap readahead. Of course, this is about sequential access pattern. The patch has no impact for random access pattern, because the new cluster allocation algorithm is just for SSD.
--- include/linux/swap.h | 6 ++ mm/swapfile.c | 116 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 93 insertions(+), 29 deletions(-)
include/linux/swap.h +6 -0
@@ -186,6 +186,11 @@ struct swap_cluster_info {#define CLUSTER_FLAG_FREE 1/* This cluster is free */ #define CLUSTER_FLAG_NEXT_NULL 2/* This cluster has no next cluster */ +struct percpu_cluster { +struct swap_cluster_info index;/* Current cluster index */ +unsigned int next;/* Likely next allocation offset */ +}; +/* * The in-memory structure used to track swap areas. */
@@ -205,6 +210,7 @@ struct swap_info_struct {unsigned int inuse_pages;/* number of those currently in use */ unsigned int cluster_next;/* likely index for next allocation */ unsigned int cluster_nr;/* countdown to next cluster search */ +struct percpu_cluster __percpu *percpu_cluster;struct swap_extent *curr_swap_extent;struct swap_extent first_swap_extent;struct block_device *bdev;/* swap device or bdev of swap file */
mm/swapfile.c +87 -29
162 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>