mm/swap: Regular page swap optimizations
Subsystems (2)
v4 cover mm/swap: Regular page swap optimizations
Change Log:
v4:
1. Fix a bug in unlock cluster in add_swap_count_continuation(). We should use unlock_cluster() instead of unlock_cluser_or_swap_info().
2. During swap off, handle race when swap slot is marked unused but allocated, and not yet placed in swap cache. Wait for swap slot to be placed in swap cache and not abort swap off.
3. Initialize n_ret in get_swap_pages().
v3:
1. Fix bug that didn't check for page already in swap cache before skipping read ahead and return null page.
2. Fix bug that didn't try to allocate from global pool if allocation from swap slot cache did not succeed.
3. Fix memory allocation bug for spaces to store split up 64MB radix tree
4. Fix problems caused by races between get_swap_page, cpu online/offline and swap_on/off
v2:
1. Fix bug in the index limit used in scan_swap_map_try_ssd_cluster when searching for empty slots in cluster.
2. Fix bug in swap off that incorrectly determines if we still have swap devices left.
3. Port patches to mmotm-2016-10-11-15-46 branch
Andrew,
We're updating this patch series with some minor fixes. Please consider this patch series for inclusion to 4.10.
Times have changed. Coming generation of Solid state Block device latencies are getting down to sub 100 usec, which is within an order of magnitude of DRAM, and their performance is orders of magnitude higher than the single- spindle rotational media we've swapped to historically.
This could benefit many usage scenearios. For example cloud providers who overcommit their memory (as VM don't use all the memory provisioned). Having a fast swap will allow them to be more aggressive in memory overcommit and fit more VMs to a platform.
In our testing [see footnote], the median latency that the kernel adds to a page fault is 15 usec, which comes quite close to the amount that will be contributed by the underlying I/O devices.
The software latency comes mostly from contentions on the locks protecting the radix tree of the swap cache and also the locks protecting the individual swap devices. The lock contentions already consumed 35% of cpu cycles in our test. In the very near future, software latency will become the bottleneck to swap performnace as block device I/O latency gets within the shouting distance of DRAM speed.
This patch set, plus a previous patch Ying already posted (commit: f6498b3f) reduced the median page fault latency from 15 usec to 4 usec (375% reduction) for DRAM based pmem block device.
Patch 1 is a clean up patch.
Patch 2 creates a lock per cluster, this gives us a more fine graind lock
that can be used for accessing swap_map, and not lock the whole swap device
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
the rate that we have to contende for the radix tree.
Patch 4 eliminates unnecessary page allocation for read ahead. Patch 5-9 create a per cpu cache of the swap slots, so we don't have
to contend on the swap device to get a swap slot or to release a swap slot. And we allocate and release the swap slots in batches for better efficiency.
Ying Huang & Tim Chen
Footnote:
We tested mmotm-2016-10-11-15-46 kernel with/without optimizations from this patche series plus one additional patch Ying posted earlier on removing radix tree write back tag in swap cache. Eight threads performed random memory access on a 2 socket Haswell using swap mounted on RAM based PMEM block device. This emulated a moderate load and a SWAP device unbounded by I/O speed. The aggregate working set is twice the RAM size. We instrumented the kernel to measure the page fault latency.
Huang Ying (1):
mm/swap: Skip readahead only when swap slot cache is enabled
Huang, Ying (3):
mm/swap: Fix kernel message in swap_info_get()
mm/swap: Add cluster lock
mm/swap: Split swap cache into 64MB trunks
Tim Chen (5):
mm/swap: skip read ahead for unreferenced swap slots mm/swap: Allocate swap slots in batches mm/swap: Free swap slots in batch
mm/swap: Add cache for swap slots allocation mm/swap: Enable swap slots cache usage
include/linux/swap.h | 36 ++- include/linux/swap_slots.h | 30 +++ mm/Makefile | 2 +- mm/swap.c | 6 - mm/swap_slots.c | 364 ++++++++++++++++++++++++++++++ mm/swap_state.c | 80 ++++++- mm/swapfile.c | 542 +++++++++++++++++++++++++++++++++++---------- 7 files changed, 919 insertions(+), 141 deletions(-) create mode 100644 include/linux/swap_slots.h create mode 100644 mm/swap_slots.c
Signature · 7 lines
2.5.5 -- 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>
PATCH v4 1/9 mm/swap: Fix kernel message in swap_info_get()
From: "Huang, Ying" <[email protected]>
swap_info_get() is used not only in swap free code path but also in page_swapcount(), etc. So the original kernel message in swap_info_get() is not correct now. Fix it via replacing "swap_free" to "swap_info_get" in the message.
--- mm/swapfile.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
mm/swapfile.c +4 -4
@@ -753,16 +753,16 @@ static struct swap_info_struct *swap_info_get(swp_entry_t entry)return p; bad_free: -pr_err ("swap_free: %s%08lx\n" , Unused_offset, entry.val); +pr_err ("swap_info_get: %s%08lx\n" , Unused_offset, entry.val); goto out; bad_offset: -pr_err ("swap_free: %s%08lx\n" , Bad_offset, entry.val); +pr_err ("swap_info_get: %s%08lx\n" , Bad_offset, entry.val); goto out; bad_device: -pr_err ("swap_free: %s%08lx\n" , Unused_file, entry.val); +pr_err ("swap_info_get: %s%08lx\n" , Unused_file, entry.val); goto out; bad_nofile: -pr_err ("swap_free: %s%08lx\n" , Bad_file, entry.val); +pr_err ("swap_info_get: %s%08lx\n" , Bad_file, entry.val); out:return NULL ; }
Signature · 7 lines
2.5.5 -- 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>
PATCH v4 2/9 mm/swap: Add cluster lock
In reply to Tim ChenFrom: "Huang, Ying" <[email protected]>
This patch is to reduce the lock contention of swap_info_struct->lock via using a more fine grained lock in swap_cluster_info for some swap operations. swap_info_struct->lock is heavily contended if multiple processes reclaim pages simultaneously. Because there is only one lock for each swap device. While in common configuration, there is only one or several swap devices in the system. The lock protects almost all swap related operations.
In fact, many swap operations only access one element of swap_info_struct->swap_map array. And there is no dependency between different elements of swap_info_struct->swap_map. So a fine grained lock can be used to allow parallel access to the different elements of swap_info_struct->swap_map.
In this patch, one bit of swap_cluster_info is used as the bin spinlock to protect the elements of swap_info_struct->swap_map in the swap cluster and the fields of swap_cluster_info. This reduced locking contention for swap_info_struct->swap_map access greatly.
To use the bin spinlock, the size of swap_cluster_info needs to increase from 4 bytes to 8 bytes on the 64bit system. This will use 4k more memory for every 1G swap space.
Because the size of swap_cluster_info is much smaller than the size of the cache line (8 vs 64 on x86_64 architecture), there may be false cache line sharing between swap_cluster_info bit spinlocks. To avoid the false sharing in the first round of the swap cluster allocation, the order of the swap clusters in the free clusters list is changed. So that, the swap_cluster_info sharing the same cache line will be placed as far as possible. After the first round of allocation, the order of the clusters in free clusters list is expected to be random. So the false sharing should be not noticeable.
--- include/linux/swap.h | 13 ++- mm/swapfile.c | 239 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 194 insertions(+), 58 deletions(-)
include/linux/swap.h +9 -4
@@ -175,11 +175,16 @@ enum {* protected by swap_info_struct.lock. */ struct swap_cluster_info { -unsigned int data:24 ; -unsigned int flags:8 ; +unsigned long data; }; -#define CLUSTER_FLAG_FREE 1/* This cluster is free */ -#define CLUSTER_FLAG_NEXT_NULL 2/* This cluster has no next cluster */ +#define CLUSTER_COUNT_SHIFT 8 +#define CLUSTER_FLAG_MASK ((1UL << CLUSTER_COUNT_SHIFT) - 1) +#define CLUSTER_COUNT_MASK (~CLUSTER_FLAG_MASK) +#define CLUSTER_FLAG_FREE 1/* This cluster is free */ +#define CLUSTER_FLAG_NEXT_NULL 2/* This cluster has no next cluster */ +/* cluster lock, protect cluster_info contents and sis->swap_map */ +#define CLUSTER_FLAG_LOCK_BIT 2 +#define CLUSTER_FLAG_LOCK (1 << CLUSTER_FLAG_LOCK_BIT)/* * We assign a cluster to each CPU, so each CPU can allocate swap entry from
mm/swapfile.c +185 -54
524 lines not on this page · raw message
Signature · 7 lines
2.5.5 -- 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>
PATCH v4 3/9 mm/swap: Split swap cache into 64MB trunks
In reply to Tim ChenFrom: "Huang, Ying" <[email protected]>
The patch is to improve the scalability of the swap out/in via using fine grained locks for the swap cache. In current kernel, one address space will be used for each swap device. And in the common configuration, the number of the swap device is very small (one is typical). This causes the heavy lock contention on the radix tree of the address space if multiple tasks swap out/in concurrently. But in fact, there is no dependency between pages in the swap cache. So that, we can split the one shared address space for each swap device into several address spaces to reduce the lock contention. In the patch, the shared address space is split into 64MB trunks. 64MB is chosen to balance the memory space usage and effect of lock contention reduction.
The size of struct address_space on x86_64 architecture is 408B, so with the patch, 6528B more memory will be used for every 1GB swap space on x86_64 architecture.
One address space is still shared for the swap entries in the same 64M trunks. To avoid lock contention for the first round of swap space allocation, the order of the swap clusters in the initial free clusters list is changed. The swap space distance between the consecutive swap clusters in the free cluster list is at least 64M. After the first round of allocation, the swap clusters are expected to be freed randomly, so the lock contention should be reduced effectively.
--- include/linux/swap.h | 10 ++++++-- mm/swap.c | 6 ----- mm/swap_state.c | 68 ++++++++++++++++++++++++++++++++++++++++++---------- mm/swapfile.c | 16 +++++++++++-- 4 files changed, 78 insertions(+), 22 deletions(-)
include/linux/swap.h +8 -2
@@ -370,8 +370,12 @@ int generic_swapfile_activate(struct swap_info_struct *, struct file *, sector_t *);/* linux/mm/swap_state.c */ -extern struct address_space swapper_spaces[]; -#define swap_address_space (entry) (&swapper_spaces[swp_type(entry)]) +/* One swap address space for each 64M swap space */ +#define SWAP_ADDRESS_SPACE_SHIFT 14 +#define SWAP_ADDRESS_SPACE_PAGES (1 << SWAP_ADDRESS_SPACE_SHIFT) +extern struct address_space * swapper_spaces[]; +#define swap_address_space (entry) \ + (&swapper_spaces[swp_type(entry)][swp_offset(entry) >> SWAP_ADDRESS_SPACE_SHIFT])extern unsigned long total_swapcache_pages (void );extern void show_swap_cache_info (void );extern int add_to_swap (struct page *,struct list_head *list);
@@ -425,6 +429,8 @@ extern struct swap_info_struct *page_swap_info(struct page *);extern bool reuse_swap_page (struct page *,int *);extern int try_to_free_swap (struct page *);struct backing_dev_info ; +extern int init_swap_address_space (unsigned int type,unsigned long nr_pages); +extern void exit_swap_address_space (unsigned int type);#else /* CONFIG_SWAP */
mm/swap.c +0 -6
@@ -969,12 +969,6 @@ EXPORT_SYMBOL(pagevec_lookup_tag);void __init swap_setup (void ) {unsigned long megs = totalram_pages >> (20 -PAGE_SHIFT ); -#ifdef CONFIG_SWAP -int i; - -for (i =0 ; i <MAX_SWAPFILES ; i++) -spin_lock_init (&swapper_spaces[i].tree_lock); -#endif /* Use a smaller cluster for small-memory machines */ if (megs <16 )
mm/swap_state.c +56 -12
91 lines not on this page · raw message
mm/swapfile.c +14 -2
@@ -2076,6 +2076,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)vfree (frontswap_map);/* Destroy swap account information */ swap_cgroup_swapoff (p->type); +exit_swap_address_space (p->type); inode = mapping->host;if (S_ISBLK (inode->i_mode)) {
@@ -2399,8 +2400,12 @@ static unsigned long read_swap_header(struct swap_info_struct *p,return maxpages; } -#define SWAP_CLUSTER_COLS \ +#define SWAP_CLUSTER_INFO_COLS \ DIV_ROUND_UP(L1_CACHE_BYTES, sizeof(struct swap_cluster_info)) +#define SWAP_CLUSTER_SPACE_COLS \ + DIV_ROUND_UP(SWAP_ADDRESS_SPACE_PAGES, SWAPFILE_CLUSTER) +#define SWAP_CLUSTER_COLS \ + max_t(unsigned int, SWAP_CLUSTER_INFO_COLS, SWAP_CLUSTER_SPACE_COLS) static int setup_swap_map_and_extents(struct swap_info_struct *p, union swap_header *swap_header,
@@ -2463,7 +2468,10 @@ static int setup_swap_map_and_extents(struct swap_info_struct *p,return nr_extents; -/* Reduce false cache line sharing between cluster_info */ +/* +* Reduce false cache line sharing between cluster_info and +* sharing same address space. +*/ for (k =0 ; k <SWAP_CLUSTER_COLS ; k++) { j = (k + col) %SWAP_CLUSTER_COLS ;for (i =0 ; i <DIV_ROUND_UP (nr_clusters,SWAP_CLUSTER_COLS ); i++) {
@@ -2644,6 +2652,10 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) } } + error =init_swap_address_space (p->type, maxpages); +if (error) + goto bad_swap; +mutex_lock (&swapon_mutex); prio =-1 ;if (swap_flags &SWAP_FLAG_PREFER )
Signature · 7 lines
2.5.5 -- 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>
PATCH v4 4/9 mm/swap: skip read ahead for unreferenced swap slots
In reply to Tim ChenWe can avoid needlessly allocating page for swap slots that are not used by anyone. No pages have to be read in for these slots.
--- include/linux/swap.h | 6 ++++++ mm/swap_state.c | 4 ++++ mm/swapfile.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 51 insertions(+), 6 deletions(-)
include/linux/swap.h +6 -0
@@ -424,6 +424,7 @@ extern unsigned int count_swap_pages(int, int);extern sector_t map_swap_page (struct page *,struct block_device **);extern sector_t swapdev_block (int ,pgoff_t );extern int page_swapcount (struct page *); +extern int __swp_swapcount (swp_entry_t entry);extern int swp_swapcount (swp_entry_t entry);extern struct swap_info_struct *page_swap_info (struct page *);extern bool reuse_swap_page (struct page *,int *);
@@ -518,6 +519,11 @@ static inline int page_swapcount(struct page *page)return 0 ; } +static inline int __swp_swapcount (swp_entry_t entry) +{ +return 0 ; +} +static inline int swp_swapcount (swp_entry_t entry) {return 0 ;
mm/swap_state.c +4 -0
@@ -323,6 +323,10 @@ struct page *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,if (found_page)break ; +/* Just skip read ahead for unused swap slot */ +if (!__swp_swapcount (entry)) +return NULL ; +/* * Get a new page to read into from swap. */
mm/swapfile.c +41 -6
73 lines not on this page · raw message
Signature · 7 lines
2.5.5 -- 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>
PATCH v4 5/9 mm/swap: Allocate swap slots in batches
In reply to Tim ChenCurrently, the swap slots are allocated one page at a time, causing contention to the swap_info lock protecting the swap partition on every page being swapped.
This patch adds new functions get_swap_pages and scan_swap_map_slots to request multiple swap slots at once. This will reduces the lock contention on the swap_info lock. Also scan_swap_map_slots can operate more efficiently as swap slots often occurs in clusters close to each other on a swap device and it is quicker to allocate them together.
--- include/linux/swap.h | 2 + mm/swapfile.c | 138 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 115 insertions(+), 25 deletions(-)
include/linux/swap.h +2 -0
@@ -27,6 +27,7 @@ struct bio;#define SWAP_FLAGS_VALID (SWAP_FLAG_PRIO_MASK | SWAP_FLAG_PREFER | \ SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_ONCE | \ SWAP_FLAG_DISCARD_PAGES) +#define SWAP_BATCH 64static inline int current_is_kswapd (void ) {
@@ -412,6 +413,7 @@ static inline long get_nr_swap_pages(void)extern void si_swapinfo (struct sysinfo *);extern swp_entry_t get_swap_page (void );extern swp_entry_t get_swap_page_of_type (int ); +extern int get_swap_pages (int n,swp_entry_t swp_entries[]);extern int add_swap_count_continuation (swp_entry_t ,gfp_t );extern void swap_shmem_alloc (swp_entry_t );extern int swap_duplicate (swp_entry_t );
mm/swapfile.c +113 -25
222 lines not on this page · raw message
Signature · 7 lines
2.5.5 -- 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>
PATCH v4 6/9 mm/swap: Free swap slots in batch
In reply to Tim ChenAdd new functions that free unused swap slots in batches without the need to reacquire swap info lock. This improves scalability and reduce lock contention.
--- include/linux/swap.h | 1 + mm/swapfile.c | 155 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 95 insertions(+), 61 deletions(-)
include/linux/swap.h +1 -0
@@ -420,6 +420,7 @@ extern int swap_duplicate(swp_entry_t);extern int swapcache_prepare (swp_entry_t );extern void swap_free (swp_entry_t );extern void swapcache_free (swp_entry_t ); +extern void swapcache_free_entries (swp_entry_t *entries,int n);extern int free_swap_and_cache (swp_entry_t );extern int swap_type_of (dev_t ,sector_t ,struct block_device **);extern unsigned int count_swap_pages (int ,int );
mm/swapfile.c +94 -61
212 lines not on this page · raw message
Signature · 7 lines
2.5.5 -- 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>
PATCH v4 7/9 mm/swap: Add cache for swap slots allocation
In reply to Tim ChenWe add per cpu caches for swap slots that can be allocated and freed quickly without the need to touch the swap info lock.
Two separate caches are maintained for swap slots allocated and swap slots returned. This is to allow the swap slots to be returned to the global pool in a batch so they will have a chance to be coaelesced with other slots in a cluster. We do not reuse the slots that are returned right away, as it may increase fragmentation of the slots.
The swap allocation cache is protected by a mutex as we may sleep when searching for empty slots in cache. The swap free cache is protected by a spin lock as we cannot sleep in the free path.
We refill the swap slots cache when we run out of slots, and we disable the swap slots cache and drain the slots if the global number of slots fall below a low watermark threshold. We re-enable the cache agian when the slots available are above a high watermark.
--- include/linux/swap.h | 4 + include/linux/swap_slots.h | 28 ++++ mm/Makefile | 2 +- mm/swap_slots.c | 364 +++++++++++++++++++++++++++++++++++++++++++++ mm/swap_state.c | 1 + mm/swapfile.c | 26 ++-- 6 files changed, 413 insertions(+), 12 deletions(-) create mode 100644 include/linux/swap_slots.h create mode 100644 mm/swap_slots.c
include/linux/swap.h +4 -0
@@ -398,6 +398,7 @@ extern struct page *swapin_readahead(swp_entry_t, gfp_t,/* linux/mm/swapfile.c */ extern atomic_long_t nr_swap_pages;extern long total_swap_pages; +extern bool has_usable_swap (void );/* Swap 50% full? Release swapcache more aggressively.. */ static inline bool vm_swap_full (void )
@@ -436,6 +437,9 @@ struct backing_dev_info;extern int init_swap_address_space (unsigned int type,unsigned long nr_pages);extern void exit_swap_address_space (unsigned int type); +extern int get_swap_slots (int n,swp_entry_t *slots); +extern void swapcache_free_batch (swp_entry_t *entries,int n); +#else /* CONFIG_SWAP */ #define swap_address_space (entry) (NULL)
include/linux/swap_slots.h new file +28 -0
@@ -0,0 +1,28 @@ +#ifndef _LINUX_SWAP_SLOTS_H +#define _LINUX_SWAP_SLOTS_H + +#include <linux/swap.h> +#include <linux/spinlock.h> +#include <linux/mutex.h> + +#define SWAP_SLOTS_CACHE_SIZE SWAP_BATCH +#define THRESHOLD_ACTIVATE_SWAP_SLOTS_CACHE (5*SWAP_SLOTS_CACHE_SIZE) +#define THRESHOLD_DEACTIVATE_SWAP_SLOTS_CACHE (2*SWAP_SLOTS_CACHE_SIZE) + +struct swap_slots_cache { +bool lock_initialized; +struct mutex alloc_lock; +swp_entry_t *slots; +int nr; +int cur; +spinlock_t free_lock; +swp_entry_t *slots_ret; +int n_ret; +}; + +void disable_swap_slots_cache_lock (void ); +void reenable_swap_slots_cache_unlock (void ); +int enable_swap_slots_cache (void ); +int free_swap_slot (swp_entry_t entry); + +#endif /* _LINUX_SWAP_SLOTS_H */
mm/Makefile +1 -1
@@ -35,7 +35,7 @@ obj-y := filemap.o mempool.o oom_kill.o \ readahead.o swap.o truncate.o vmscan.o shmem.o \ util.o mmzone.o vmstat.o backing-dev.o \ mm_init.o mmu_context.o percpu.o slab_common.o \ - compaction.o vmacache.o \ + compaction.o vmacache.o swap_slots.o \ interval_tree.o list_lru.o workingset.o \ debug.o $(mmu-y)
mm/swap_slots.c new file +364 -0
364 lines not on this page · raw message
mm/swap_state.c +1 -0
@@ -18,6 +18,7 @@#include <linux/pagevec.h> #include <linux/migrate.h> #include <linux/vmalloc.h> +#include <linux/swap_slots.h> #include <asm/pgtable.h>
mm/swapfile.c +15 -11
@@ -34,6 +34,7 @@#include <linux/frontswap.h> #include <linux/swapfile.h> #include <linux/export.h> +#include <linux/swap_slots.h> #include <asm/pgtable.h> #include <asm/tlbflush.h>
@@ -861,14 +862,6 @@ int get_swap_pages(int n_goal, swp_entry_t swp_entries[])return n_ret; } -swp_entry_t get_swap_page (void ) -{ -swp_entry_t entry; - -get_swap_pages (1 , &entry); -return entry; -} -/* The only caller of this function is now suspend routine */ swp_entry_t get_swap_page_of_type (int type) {
@@ -1059,7 +1052,7 @@ void swap_free(swp_entry_t entry) p =_swap_info_get (entry);if (p) {if (!__swap_entry_free (p, entry,1 )) -swapcache_free_entries (&entry,1 ); +free_swap_slot (entry); } }
@@ -1073,7 +1066,7 @@ void swapcache_free(swp_entry_t entry) p =_swap_info_get (entry);if (p) {if (!__swap_entry_free (p, entry,SWAP_HAS_CACHE )) -swapcache_free_entries (&entry,1 ); +free_swap_slot (entry); } }
@@ -1281,7 +1274,7 @@ int free_swap_and_cache(swp_entry_t entry) page =NULL ; } }else if (!count) -swapcache_free_entries (&entry,1 ); +free_swap_slot (entry); }if (page) {/*
@@ -2110,6 +2103,17 @@ static void reinsert_swap_info(struct swap_info_struct *p)spin_unlock (&swap_lock); } +bool has_usable_swap (void ) +{ +bool ret = true; + +spin_lock (&swap_lock); +if (plist_head_empty (&swap_active_head)) + ret = false; +spin_unlock (&swap_lock); +return ret; +} + SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) {struct swap_info_struct *p =NULL ;
Signature · 7 lines
2.5.5 -- 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>
PATCH v4 8/9 mm/swap: Enable swap slots cache usage
In reply to Tim ChenInitialize swap slots cache and enable it on swap on. Drain all swap slots on swap off.
--- mm/swapfile.c | 7 +++++++ 1 file changed, 7 insertions(+)
mm/swapfile.c +7 -0
@@ -2184,6 +2184,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)spin_unlock (&p->lock);spin_unlock (&swap_lock); +disable_swap_slots_cache_lock (); +set_current_oom_origin (); err =try_to_unuse (p->type, false,0 );/* force unuse all pages */ clear_current_oom_origin ();
@@ -2191,9 +2193,12 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)if (err) {/* re-insert swap space back into swap_list */ reinsert_swap_info (p); +reenable_swap_slots_cache_unlock (); goto out_dput; } +reenable_swap_slots_cache_unlock (); +flush_work (&p->discard_work);destroy_swap_extents (p);
@@ -2871,6 +2876,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)putname (name);if (inode &&S_ISREG (inode->i_mode))inode_unlock (inode); +if (!error) +enable_swap_slots_cache ();return error; }
Signature · 7 lines
2.5.5 -- 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>
PATCH v4 9/9 mm/swap: Skip readahead only when swap slot cache is enabled
In reply to Tim ChenFrom: Huang Ying <[email protected]>
Because during swap off, a swap entry may have swap_map[] == SWAP_HAS_CACHE (for example, just allocated). If we return NULL in __read_swap_cache_async(), the swap off will abort. So when swap slot cache is disabled, (for swap off), we will wait for page to be put into swap cache in such race condition. This should not be a problem for swap slot cache, because swap slot cache should be drained after clearing swap_slot_cache_enabled.
--- include/linux/swap_slots.h | 2 ++ mm/swap_slots.c | 2 +- mm/swap_state.c | 11 +++++++++-- 3 files changed, 12 insertions(+), 3 deletions(-)
include/linux/swap_slots.h +2 -0
@@ -25,4 +25,6 @@ void reenable_swap_slots_cache_unlock(void);int enable_swap_slots_cache (void );int free_swap_slot (swp_entry_t entry); +extern bool swap_slot_cache_enabled; +#endif /* _LINUX_SWAP_SLOTS_H */
mm/swap_slots.c +1 -1
@@ -36,7 +36,7 @@ static DEFINE_PER_CPU(struct swap_slots_cache, swp_slots);static bool swap_slot_cache_active; -static bool swap_slot_cache_enabled; +bool swap_slot_cache_enabled;static bool swap_slot_cache_initialized;DEFINE_MUTEX (swap_slots_cache_mutex);/* Serialize swap slots cache enable/disable operations */
mm/swap_state.c +9 -2
@@ -324,8 +324,15 @@ struct page *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,if (found_page)break ; -/* Just skip read ahead for unused swap slot */ -if (!__swp_swapcount (entry)) +/* +* Just skip read ahead for unused swap slot. +* During swap_off when swap_slot_cache is disabled, +* we have to handle the race between putting +* swap entry in swap cache and marking swap slot +* as SWAP_HAS_CACHE. That's done in later part of code or +* else swap_off will be aborted if we return NULL. +*/ +if (!__swp_swapcount (entry) && swap_slot_cache_enabled)return NULL ;/*
Signature · 7 lines
2.5.5 -- 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>
Hi,
Quoted 52 lines · Tim Chen
Change Log:
v4:
1. Fix a bug in unlock cluster inadd_swap_count_continuation(). We should useunlock_cluster()instead ofunlock_cluser_or_swap_info().
2. During swap off, handle race when swap slot is marked unused but allocated, and not yet placed in swap cache. Wait for swap slot to be placed in swap cache and not abort swap off.
3. Initializen_retinget_swap_pages().v3:
1. Fix bug that didn't check for page already in swap cache before skipping read ahead and return null page.
2. Fix bug that didn't try to allocate from global pool if allocation from swap slot cache did not succeed.
3. Fix memory allocation bug for spaces to store split up 64MB radix tree
4. Fix problems caused by races betweenget_swap_page, cpu online/offline and swap_on/offv2:
1. Fix bug in the index limit used inscan_swap_map_try_ssd_clusterwhen searching for empty slots in cluster.
2. Fix bug in swap off that incorrectly determines if we still have swap devices left.
3. Port patches to mmotm-2016-10-11-15-46 branchAndrew,
We're updating this patch series with some minor fixes. Please consider this patch series for inclusion to 4.10.
Times have changed. Coming generation of Solid state Block device latencies are getting down to sub 100 usec, which is within an order of magnitude of DRAM, and their performance is orders of magnitude higher than the single- spindle rotational media we've swapped to historically.
This could benefit many usage scenearios. For example cloud providers who overcommit their memory (as VM don't use all the memory provisioned). Having a fast swap will allow them to be more aggressive in memory overcommit and fit more VMs to a platform.
In our testing [see footnote], the median latency that the kernel adds to a page fault is 15 usec, which comes quite close to the amount that will be contributed by the underlying I/O devices.
The software latency comes mostly from contentions on the locks protecting the radix tree of the swap cache and also the locks protecting the individual swap devices. The lock contentions already consumed 35% of cpu cycles in our test. In the very near future, software latency will become the bottleneck to swap performnace as block device I/O latency gets within the shouting distance of DRAM speed.
Quoted 4 lines
This patch set, plus a previous patch Ying already posted (commit:
f6498b3f) reduced the median page fault latency from 15 usec to 4 usec (375% reduction) for DRAM based pmem block device.
The patchset has used several techniqueus to reduce lock contention, for example, batching alloc/free, fine-grained lock and cluster distribution to avoid cache false-sharing. Each items has different complexity and benefits so could you show the number for each step of pathchset? It would be better to include the nubmer in each description. It helps how the patch is important when we consider complexitiy of the patch.
Quoted 2 lines
Patch 1 is a clean up patch.
Could it be separated patch?
Quoted 3 lines
Patch 2 creates a lock per cluster, this gives us a more fine graind lock
that can be used for accessingswap_map, and not lock the whole swap device
I hope you make three steps to review easier. You can create some functions like swap_map_lock and cluster_lock which are wrapper functions just hold swap_lock. It doesn't change anything performance pov but it clearly shows what kinds of lock we should use in specific context.
Then, you can introduce more fine-graind lock in next patch and apply it into those wrapper functions.
And last patch, you can adjust cluster distribution to avoid false-sharing. And the description should include how it's bad in testing so it's worth.
Frankly speaking, although I'm huge user of bit_spin_lock(zram/zsmalloc have used it heavily), I don't like swap subsystem uses it.
During zram development, it really hurts debugging due to losing lockdep. The reason zram have used it is by size concern of embedded world but server would be not critical so please consider trade-off of spinlock vs. bit_spin_lock.
Quoted 2 lines
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
the rate that we have to contende for the radix tree.
To me, it's rather hacky. I think it might be common problem for page cache so can we think another generalized way like range_lock? Ccing Jan.
Quoted 1 line
Patch 4 eliminates unnecessary page allocation for read ahead.
Could it be separated patch?
Quoted 4 lines
Patch 5-9 create a per cpu cache of the swap slots, so we don't have
to contend on the swap device to get a swap slot or to release a swap slot. And we allocate and release the swap slots in batches for better efficiency.
To me, idea is good although I feel the amount of code is rather huge and messy so it should include the number about the benefit, at least.
And it might make some of patches in this patchset if we put this batching ahead before other patches redundant.
Sorry for vague commenting. In this phase, it's really hard to review.
--
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>
Hi, Minchan,
Quoted 60 lines · Minchan Kim
Hi,
Quoted 52 lines · Tim Chen
Change Log:
v4:
1. Fix a bug in unlock cluster inadd_swap_count_continuation(). We should useunlock_cluster()instead ofunlock_cluser_or_swap_info().
2. During swap off, handle race when swap slot is marked unused but allocated, and not yet placed in swap cache. Wait for swap slot to be placed in swap cache and not abort swap off.
3. Initializen_retinget_swap_pages().v3:
1. Fix bug that didn't check for page already in swap cache before skipping read ahead and return null page.
2. Fix bug that didn't try to allocate from global pool if allocation from swap slot cache did not succeed.
3. Fix memory allocation bug for spaces to store split up 64MB radix tree
4. Fix problems caused by races betweenget_swap_page, cpu online/offline and swap_on/offv2:
1. Fix bug in the index limit used inscan_swap_map_try_ssd_clusterwhen searching for empty slots in cluster.
2. Fix bug in swap off that incorrectly determines if we still have swap devices left.
3. Port patches to mmotm-2016-10-11-15-46 branchAndrew,
We're updating this patch series with some minor fixes. Please consider this patch series for inclusion to 4.10.
Times have changed. Coming generation of Solid state Block device latencies are getting down to sub 100 usec, which is within an order of magnitude of DRAM, and their performance is orders of magnitude higher than the single- spindle rotational media we've swapped to historically.
This could benefit many usage scenearios. For example cloud providers who overcommit their memory (as VM don't use all the memory provisioned). Having a fast swap will allow them to be more aggressive in memory overcommit and fit more VMs to a platform.
In our testing [see footnote], the median latency that the kernel adds to a page fault is 15 usec, which comes quite close to the amount that will be contributed by the underlying I/O devices.
The software latency comes mostly from contentions on the locks protecting the radix tree of the swap cache and also the locks protecting the individual swap devices. The lock contentions already consumed 35% of cpu cycles in our test. In the very near future, software latency will become the bottleneck to swap performnace as block device I/O latency gets within the shouting distance of DRAM speed.
Quoted 4 lines
This patch set, plus a previous patch Ying already posted (commit:
f6498b3f) reduced the median page fault latency from 15 usec to 4 usec (375% reduction) for DRAM based pmem block device.
Quoted 6 lines
The patchset has used several techniqueus to reduce lock contention, for example, batching alloc/free, fine-grained lock and cluster distribution to avoid cache false-sharing. Each items has different complexity and benefits so could you show the number for each step of pathchset? It would be better to include the nubmer in each description. It helps how the patch is important when we consider complexitiy of the patch.
One common problem of scalability optimization is that, after you have optimized one lock, the end result may be not very good, because another lock becomes heavily contended. Similar problem occurs here, there are mainly two locks during swap out/in, one protects swap cache, the other protects swap device. We can achieve good scalability only after having optimized the two locks.
You cannot say that one patch is not important just because the test result for that single patch is not very good. Because without that, the end result of the whole series will be not very good.
Quoted 17 lines
Quoted 2 lines
Patch 1 is a clean up patch.
Could it be separated patch?
Quoted 3 lines
Patch 2 creates a lock per cluster, this gives us a more fine graind lock
that can be used for accessingswap_map, and not lock the whole swap deviceI hope you make three steps to review easier. You can create some functions like
swap_map_lockandcluster_lockwhich are wrapper functions just holdswap_lock. It doesn't change anything performance pov but it clearly shows what kinds of lock we should use in specific context.Then, you can introduce more fine-graind lock in next patch and apply it into those wrapper functions.
Quoted 8 lines
And last patch, you can adjust cluster distribution to avoid false-sharing. And the description should include how it's bad in testing so it's worth.
Frankly speaking, although I'm huge user of
bit_spin_lock(zram/zsmalloc have used it heavily), I don't like swap subsystem uses it.
During zram development, it really hurts debugging due to losing lockdep. The reason zram have used it is by size concern of embedded world but server would be not critical so please consider trade-off of spinlock vs.bit_spin_lock.
There will be one struct swap_cluster_info for every 1MB swap space. So, for example, for 1TB swap space, the number of struct swap_cluster_info will be one million. To reduce the RAM usage, we choose to use bit_spin_lock, otherwise, spinlock is better. The code will be used by embedded, PC and server, so the RAM usage is important.
Best Regards,
Huang, Ying
Quoted 16 lines
Quoted 2 lines
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
the rate that we have to contende for the radix tree.To me, it's rather hacky. I think it might be common problem for page cache so can we think another generalized way like
range_lock? Ccing Jan.Quoted 1 line
Patch 4 eliminates unnecessary page allocation for read ahead.
Could it be separated patch?
Quoted 4 lines
Patch 5-9 create a per cpu cache of the swap slots, so we don't have
to contend on the swap device to get a swap slot or to release a swap slot. And we allocate and release the swap slots in batches for better efficiency.
Quoted 7 lines
To me, idea is good although I feel the amount of code is rather huge and messy so it should include the number about the benefit, at least.
And it might make some of patches in this patchset if we put this batching ahead before other patches redundant.
Sorry for vague commenting. In this phase, it's really hard to review.
--
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>
Hi Huang,
On Wed, Dec 28, 2016 at 09:54:27AM +0800, Huang, Ying wrote:
< snip >
Quoted 7 lines
Quoted 6 lines
The patchset has used several techniqueus to reduce lock contention, for example, batching alloc/free, fine-grained lock and cluster distribution to avoid cache false-sharing. Each items has different complexity and benefits so could you show the number for each step of pathchset? It would be better to include the nubmer in each description. It helps how the patch is important when we consider complexitiy of the patch.
Quoted 6 lines
One common problem of scalability optimization is that, after you have optimized one lock, the end result may be not very good, because another lock becomes heavily contended. Similar problem occurs here, there are mainly two locks during swap out/in, one protects swap cache, the other protects swap device. We can achieve good scalability only after having optimized the two locks.
Yes. You can describe that situation into the description. For example, "with this patch, we can watch less swap_lock contention with perf but overall performance is not good because swap cache lock still is still contended heavily like below data so next patch will solve the problem".
It will make patch's justficiation clear.
Quoted 4 lines
You cannot say that one patch is not important just because the test result for that single patch is not very good. Because without that, the end result of the whole series will be not very good.
I know that but this patchset are lack of number too much to justify each works. You can show just raw number itself of a techniqueue although it is not huge benefit or even worse. You can explain the reason why it was not good, which would be enough motivation for next patch.
Number itself wouldn't be important but justfication is really crucial to review/merge patchset and number will help it a lot in especially MM community.
Quoted 27 lines
Quoted 18 lines
Quoted 3 lines
Patch 1 is a clean up patch.
Could it be separated patch?
Quoted 3 lines
Patch 2 creates a lock per cluster, this gives us a more fine graind lock
that can be used for accessingswap_map, and not lock the whole swap deviceI hope you make three steps to review easier. You can create some functions like
swap_map_lockandcluster_lockwhich are wrapper functions just holdswap_lock. It doesn't change anything performance pov but it clearly shows what kinds of lock we should use in specific context.Then, you can introduce more fine-graind lock in next patch and apply it into those wrapper functions.
Quoted 8 lines
And last patch, you can adjust cluster distribution to avoid false-sharing. And the description should include how it's bad in testing so it's worth.
Frankly speaking, although I'm huge user of
bit_spin_lock(zram/zsmalloc have used it heavily), I don't like swap subsystem uses it.
During zram development, it really hurts debugging due to losing lockdep. The reason zram have used it is by size concern of embedded world but server would be not critical so please consider trade-off of spinlock vs.bit_spin_lock.
Quoted 5 lines
There will be one struct
swap_cluster_infofor every 1MB swap space. So, for example, for 1TB swap space, the number of structswap_cluster_infowill be one million. To reduce the RAM usage, we choose to usebit_spin_lock, otherwise, spinlock is better. The code will be used by embedded, PC and server, so the RAM usage is important.
It seems you already increase swap_cluster_info 4 byte to support bit_spin_lock.
Compared to that, how much memory does spin_lock increase?
--
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>
Quoted 68 lines · Minchan Kim
Hi Huang,
On Wed, Dec 28, 2016 at 09:54:27AM +0800, Huang, Ying wrote:
< snip >
Quoted 7 lines
Quoted 6 lines
The patchset has used several techniqueus to reduce lock contention, for example, batching alloc/free, fine-grained lock and cluster distribution to avoid cache false-sharing. Each items has different complexity and benefits so could you show the number for each step of pathchset? It would be better to include the nubmer in each description. It helps how the patch is important when we consider complexitiy of the patch.
Quoted 6 lines
One common problem of scalability optimization is that, after you have optimized one lock, the end result may be not very good, because another lock becomes heavily contended. Similar problem occurs here, there are mainly two locks during swap out/in, one protects swap cache, the other protects swap device. We can achieve good scalability only after having optimized the two locks.
Yes. You can describe that situation into the description. For example, "with this patch, we can watch less
swap_lockcontention with perf but overall performance is not good because swap cache lock still is still contended heavily like below data so next patch will solve the problem".It will make patch's justficiation clear.
Quoted 4 lines
You cannot say that one patch is not important just because the test result for that single patch is not very good. Because without that, the end result of the whole series will be not very good.
I know that but this patchset are lack of number too much to justify each works. You can show just raw number itself of a techniqueue although it is not huge benefit or even worse. You can explain the reason why it was not good, which would be enough motivation for next patch.
Number itself wouldn't be important but justfication is really crucial to review/merge patchset and number will help it a lot in especially MM community.
Quoted 27 lines
Quoted 26 lines
Quoted 3 lines
Patch 1 is a clean up patch.
Could it be separated patch?
Quoted 3 lines
Patch 2 creates a lock per cluster, this gives us a more fine graind lock
that can be used for accessingswap_map, and not lock the whole swap deviceI hope you make three steps to review easier. You can create some functions like
swap_map_lockandcluster_lockwhich are wrapper functions just holdswap_lock. It doesn't change anything performance pov but it clearly shows what kinds of lock we should use in specific context.Then, you can introduce more fine-graind lock in next patch and apply it into those wrapper functions.
And last patch, you can adjust cluster distribution to avoid false-sharing. And the description should include how it's bad in testing so it's worth.
Frankly speaking, although I'm huge user of
bit_spin_lock(zram/zsmalloc have used it heavily), I don't like swap subsystem uses it.
During zram development, it really hurts debugging due to losing lockdep. The reason zram have used it is by size concern of embedded world but server would be not critical so please consider trade-off of spinlock vs.bit_spin_lock.
Quoted 8 lines
Quoted 5 lines
There will be one struct
swap_cluster_infofor every 1MB swap space. So, for example, for 1TB swap space, the number of structswap_cluster_infowill be one million. To reduce the RAM usage, we choose to usebit_spin_lock, otherwise, spinlock is better. The code will be used by embedded, PC and server, so the RAM usage is important.It seems you already increase
swap_cluster_info4 byte to supportbit_spin_lock.
The increment only occurs on 64bit platform. On 32bit platform, the size is the same as before.
Quoted 1 line
Compared to that, how much memory does
spin_lockincrease?
The size of struct swap_cluster_info will increase from 4 bytes to 16 bytes on 64bit platform. I guess it will increase from 4 bytes to 8 bytes on 32bit platform at least, but I did not test that.
Best Regards,
Huang, Ying
--
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>
Quoted 79 lines · Ying
Quoted 68 lines · Minchan Kim
Hi Huang,
On Wed, Dec 28, 2016 at 09:54:27AM +0800, Huang, Ying wrote:
< snip >
Quoted 7 lines
Quoted 6 lines
The patchset has used several techniqueus to reduce lock contention, for example, batching alloc/free, fine-grained lock and cluster distribution to avoid cache false-sharing. Each items has different complexity and benefits so could you show the number for each step of pathchset? It would be better to include the nubmer in each description. It helps how the patch is important when we consider complexitiy of the patch.
Quoted 6 lines
One common problem of scalability optimization is that, after you have optimized one lock, the end result may be not very good, because another lock becomes heavily contended. Similar problem occurs here, there are mainly two locks during swap out/in, one protects swap cache, the other protects swap device. We can achieve good scalability only after having optimized the two locks.
Yes. You can describe that situation into the description. For example, "with this patch, we can watch less
swap_lockcontention with perf but overall performance is not good because swap cache lock still is still contended heavily like below data so next patch will solve the problem".It will make patch's justficiation clear.
Quoted 4 lines
You cannot say that one patch is not important just because the test result for that single patch is not very good. Because without that, the end result of the whole series will be not very good.
I know that but this patchset are lack of number too much to justify each works. You can show just raw number itself of a techniqueue although it is not huge benefit or even worse. You can explain the reason why it was not good, which would be enough motivation for next patch.
Number itself wouldn't be important but justfication is really crucial to review/merge patchset and number will help it a lot in especially MM community.
Quoted 27 lines
Quoted 26 lines
Quoted 3 lines
Patch 1 is a clean up patch.
Could it be separated patch?
Quoted 3 lines
Patch 2 creates a lock per cluster, this gives us a more fine graind lock
that can be used for accessingswap_map, and not lock the whole swap deviceI hope you make three steps to review easier. You can create some functions like
swap_map_lockandcluster_lockwhich are wrapper functions just holdswap_lock. It doesn't change anything performance pov but it clearly shows what kinds of lock we should use in specific context.Then, you can introduce more fine-graind lock in next patch and apply it into those wrapper functions.
And last patch, you can adjust cluster distribution to avoid false-sharing. And the description should include how it's bad in testing so it's worth.
Frankly speaking, although I'm huge user of
bit_spin_lock(zram/zsmalloc have used it heavily), I don't like swap subsystem uses it.
During zram development, it really hurts debugging due to losing lockdep. The reason zram have used it is by size concern of embedded world but server would be not critical so please consider trade-off of spinlock vs.bit_spin_lock.Quoted 8 lines
Quoted 5 lines
There will be one struct
swap_cluster_infofor every 1MB swap space. So, for example, for 1TB swap space, the number of structswap_cluster_infowill be one million. To reduce the RAM usage, we choose to usebit_spin_lock, otherwise, spinlock is better. The code will be used by embedded, PC and server, so the RAM usage is important.It seems you already increase
swap_cluster_info4 byte to supportbit_spin_lock.
Quoted 8 lines
The increment only occurs on 64bit platform. On 32bit platform, the size is the same as before.
Quoted 1 line
Compared to that, how much memory does
spin_lockincrease?The size of struct
swap_cluster_infowill increase from 4 bytes to 16 bytes on 64bit platform. I guess it will increase from 4 bytes to 8 bytes on 32bit platform at least, but I did not test that.
Sorry, I make a mistake during test. The size of struct swap_cluster_info will increase from 4 bytes to 8 bytes on 64 bit platform. I think it will increase from 4 bytes to 8 bytes on 32 bit platform too (not tested).
Best Regards,
Huang, Ying
--
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>
On Wed, Dec 28, 2016 at 11:31:06AM +0800, Huang, Ying wrote:
< snip >
Quoted 20 lines
Quoted 20 lines
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Frankly speaking, although I'm huge user of
bit_spin_lock(zram/zsmalloc have used it heavily), I don't like swap subsystem uses it.
During zram development, it really hurts debugging due to losing lockdep. The reason zram have used it is by size concern of embedded world but server would be not critical so please consider trade-off of spinlock vs.bit_spin_lock.Quoted 8 lines
Quoted 5 lines
There will be one struct
swap_cluster_infofor every 1MB swap space. So, for example, for 1TB swap space, the number of structswap_cluster_infowill be one million. To reduce the RAM usage, we choose to usebit_spin_lock, otherwise, spinlock is better. The code will be used by embedded, PC and server, so the RAM usage is important.It seems you already increase
swap_cluster_info4 byte to supportbit_spin_lock.The increment only occurs on 64bit platform. On 32bit platform, the size is the same as before.
Quoted 1 line
Compared to that, how much memory does
spin_lockincrease?
Quoted 8 lines
Quoted 3 lines
The size of struct
swap_cluster_infowill increase from 4 bytes to 16 bytes on 64bit platform. I guess it will increase from 4 bytes to 8 bytes on 32bit platform at least, but I did not test that.Sorry, I make a mistake during test. The size of struct
swap_cluster_infowill increase from 4 bytes to 8 bytes on 64 bit platform. I think it will increase from 4 bytes to 8 bytes on 32 bit platform too (not tested).
Thanks for the information.
To me, it's not big when we consider spinlock's usefullness which helps cache-line bouncing, lockdep and happy with RT people.
So, I vote spin_lock but I'm not in charge of deciding on that and your opinion might be different still. If so, let's pass the decision to maintainer.
Instead, please write down above content in description for maintainer to judge it fairly.
Thanks.
--
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>
Quoted 28 lines · Minchan Kim
On Wed, Dec 28, 2016 at 11:31:06AM +0800, Huang, Ying wrote:
< snip >
Quoted 24 lines
Quoted 23 lines
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Frankly speaking, although I'm huge user of
bit_spin_lock(zram/zsmalloc have used it heavily), I don't like swap subsystem uses it.
During zram development, it really hurts debugging due to losing lockdep. The reason zram have used it is by size concern of embedded world but server would be not critical so please consider trade-off of spinlock vs.bit_spin_lock.Quoted 8 lines
Quoted 5 lines
There will be one struct
swap_cluster_infofor every 1MB swap space. So, for example, for 1TB swap space, the number of structswap_cluster_infowill be one million. To reduce the RAM usage, we choose to usebit_spin_lock, otherwise, spinlock is better. The code will be used by embedded, PC and server, so the RAM usage is important.It seems you already increase
swap_cluster_info4 byte to supportbit_spin_lock.The increment only occurs on 64bit platform. On 32bit platform, the size is the same as before.
Quoted 1 line
Compared to that, how much memory does
spin_lockincrease?The size of struct
swap_cluster_infowill increase from 4 bytes to 16 bytes on 64bit platform. I guess it will increase from 4 bytes to 8 bytes on 32bit platform at least, but I did not test that.
Quoted 8 lines
Quoted 4 lines
Sorry, I make a mistake during test. The size of struct
swap_cluster_infowill increase from 4 bytes to 8 bytes on 64 bit platform. I think it will increase from 4 bytes to 8 bytes on 32 bit platform too (not tested).Thanks for the information.
To me, it's not big when we consider spinlock's usefullness which helps cache-line bouncing, lockdep and happy with RT people.
Yes. spinlock helps on lockdep and RT, but I don't think it helps cache-line bouncing.
Quoted 3 lines
So, I vote
spin_lockbut I'm not in charge of deciding on that and your opinion might be different still. If so, let's pass the decision to maintainer.
I have no strong opinion for size change on 32bit platform. But I want to know other people's opinion, especially maintainer's too.
Quoted 2 lines
Instead, please write down above content in description for maintainer to judge it fairly.
Sure.
Best Regards,
Huang, Ying
--
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>
Hi,
Quoted 5 lines · Minchan Kim
Quoted 2 lines
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
the rate that we have to contende for the radix tree.To me, it's rather hacky. I think it might be common problem for page cache so can we think another generalized way like
range_lock? Ccing Jan.
I agree on the hackyness of the patch and that page cache would suffer with the same contention (although the files are usually smaller than swap so it would not be that visible I guess). But I don't see how range lock would help here - we need to serialize modifications of the tree structure itself and that is difficult to achieve with the range lock. So what you would need is either a different data structure for tracking swap cache entries or a finer grained locking of the radix tree.
Honza
Signature · 8 lines
Jan Kara <[email protected]> SUSE Labs, CR -- 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>
Hi Jan,
Quoted 9 lines · Jan Kara
Hi,
Quoted 5 lines · Minchan Kim
Quoted 2 lines
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
the rate that we have to contende for the radix tree.To me, it's rather hacky. I think it might be common problem for page cache so can we think another generalized way like
range_lock? Ccing Jan.
Quoted 7 lines
I agree on the hackyness of the patch and that page cache would suffer with the same contention (although the files are usually smaller than swap so it would not be that visible I guess). But I don't see how range lock would help here - we need to serialize modifications of the tree structure itself and that is difficult to achieve with the range lock. So what you would need is either a different data structure for tracking swap cache entries or a finer grained locking of the radix tree.
Thanks for the comment, Jan.
I think there are more general options. One is to shrink batching pages like Mel and Tim had approached.
https://patchwork.kernel.org/patch/9008421/
https://patchwork.kernel.org/patch/9322793/
Or concurrent page cache by peter.
https://www.kernel.org/doc/ols/2007/ols2007v2-pages-311-318.pdf
Ccing Nick who might have an interest on lockless page cache.
Thanks.
--
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>
Hi, Minchan,
Quoted 20 lines · Minchan Kim
Hi Jan,
Quoted 9 lines · Jan Kara
Hi,
Quoted 5 lines · Minchan Kim
Quoted 2 lines
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
the rate that we have to contende for the radix tree.To me, it's rather hacky. I think it might be common problem for page cache so can we think another generalized way like
range_lock? Ccing Jan.Quoted 7 lines
I agree on the hackyness of the patch and that page cache would suffer with the same contention (although the files are usually smaller than swap so it would not be that visible I guess). But I don't see how range lock would help here - we need to serialize modifications of the tree structure itself and that is difficult to achieve with the range lock. So what you would need is either a different data structure for tracking swap cache entries or a finer grained locking of the radix tree.
Quoted 7 lines
Thanks for the comment, Jan.
I think there are more general options. One is to shrink batching pages like Mel and Tim had approached.
https://patchwork.kernel.org/patch/9008421/
https://patchwork.kernel.org/patch/9322793/
This helps to reduce the lock contention on radix tree of swap cache. But splitting swap cache has much better performance. So we switched from that solution to current solution.
Quoted 3 lines
Or concurrent page cache by peter.
https://www.kernel.org/doc/ols/2007/ols2007v2-pages-311-318.pdf
I think this is good, it helps swap and file cache. But I don't know whether other people want to go this way and how much effort will be needed.
In contrast, splitting swap cache is quite simple, for implementation and review. And the effect is good.
Best Regards,
Huang, Ying
Quoted 3 lines
Ccing Nick who might have an interest on lockless page cache.
Thanks.
--
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>
Hi Huang,
Quoted 38 lines · Ying
Hi, Minchan,
Quoted 20 lines · Minchan Kim
Hi Jan,
Quoted 9 lines · Jan Kara
Hi,
Quoted 5 lines · Minchan Kim
Quoted 2 lines
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
the rate that we have to contende for the radix tree.To me, it's rather hacky. I think it might be common problem for page cache so can we think another generalized way like
range_lock? Ccing Jan.Quoted 7 lines
I agree on the hackyness of the patch and that page cache would suffer with the same contention (although the files are usually smaller than swap so it would not be that visible I guess). But I don't see how range lock would help here - we need to serialize modifications of the tree structure itself and that is difficult to achieve with the range lock. So what you would need is either a different data structure for tracking swap cache entries or a finer grained locking of the radix tree.
Quoted 7 lines
Thanks for the comment, Jan.
I think there are more general options. One is to shrink batching pages like Mel and Tim had approached.
https://patchwork.kernel.org/patch/9008421/
https://patchwork.kernel.org/patch/9322793/This helps to reduce the lock contention on radix tree of swap cache. But splitting swap cache has much better performance. So we switched from that solution to current solution.
Quoted 2 lines
Or concurrent page cache by peter.
Quoted 8 lines
I think this is good, it helps swap and file cache. But I don't know whether other people want to go this way and how much effort will be needed.
In contrast, splitting swap cache is quite simple, for implementation and review. And the effect is good.
I think general approach is better but I don't want to be a a party pooper if every people are okay with this. I just wanted to point out we need to consider more general approach and I did my best.
Decision depends on you guys.
Thanks.
--
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>
Quoted 20 lines · Minchan Kim
Hi Jan,
Quoted 10 lines · Jan Kara
Hi,
Quoted 6 lines · Minchan Kim
Quoted 4 lines
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing A A A A A A A A the rate that we have to contende for the radix tree.
To me, it's rather hacky. I think it might be common problem for page cache so can we think another generalized way like
range_lock? Ccing Jan.Quoted 7 lines
I agree on the hackyness of the patch and that page cache would suffer with the same contention (although the files are usually smaller than swap so it would not be that visible I guess). But I don't see how range lock would help here - we need to serialize modifications of the tree structure itself and that is difficult to achieve with the range lock. So what you would need is either a different data structure for tracking swap cache entries or a finer grained locking of the radix tree.
Quoted 7 lines
Thanks for the comment, Jan.
I think there are more general options. One is to shrink batching pages like Mel and Tim had approached.
https://patchwork.kernel.org/patch/9008421/
https://patchwork.kernel.org/patch/9322793/
The batching of pages is done in this patch series with a page allocation cache and page release cache. A It is done a bit differently than my original patch proposal.
This reduces the contention on the swap_info lock. We uses the splitting of the radix tree to reduce the radix tree lock contention.
In our tests, these two approaches combined are quite effective in reducing the latency on actual fast solid state drives. A So we hope that the patch series can be merged to facilitate the use case of using these drives as secondary memory.
Tim
Quoted 8 lines
Or concurrent page cache by peter.
https://www.kernel.org/doc/ols/2007/ols2007v2-pages-311-318.pdf
Ccing Nick who might have an interest on lockless page cache.
Thanks.
--
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>
Hi, Minchan,
Minchan Kim <[email protected]> writes:
[snip]
Quoted 7 lines
The patchset has used several techniqueus to reduce lock contention, for example, batching alloc/free, fine-grained lock and cluster distribution to avoid cache false-sharing. Each items has different complexity and benefits so could you show the number for each step of pathchset? It would be better to include the nubmer in each description. It helps how the patch is important when we consider complexitiy of the patch.
Here is the test data.
We test the vm-scalability swap-w-seq test case with 32 processes on a Xeon E5 v3 system. The swap device used is a RAM simulated PMEM (persistent memory) device. To test the sequential swapping out, the test case created 32 processes, which sequentially allocate and write to the anonymous pages until the RAM and part of the swap device is used up.
The patchset is rebased on v4.9-rc8. So the baseline performance is as follow,
"vmstat.swap.so": 1428002, "perf-profile.calltrace.cycles-pp._raw_spin_lock_irq.__add_to_swap_cache.add_to_swap_cache.add_to_swap.shrink_page_list": 13.94, "perf-profile.calltrace.cycles-pp._raw_spin_lock_irqsave.__remove_mapping.shrink_page_list.shrink_inactive_list.shrink_node_memcg": 13.75, "perf-profile.calltrace.cycles-pp._raw_spin_lock.swap_info_get.swapcache_free.__remove_mapping.shrink_page_list": 7.05, "perf-profile.calltrace.cycles-pp._raw_spin_lock.swap_info_get.page_swapcount.try_to_free_swap.swap_writepage": 7.03, "perf-profile.calltrace.cycles-pp._raw_spin_lock.__swap_duplicate.swap_duplicate.try_to_unmap_one.rmap_walk_anon": 7.02, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_swap_page.add_to_swap.shrink_page_list.shrink_inactive_list": 6.83, "perf-profile.calltrace.cycles-pp._raw_spin_lock.page_check_address_transhuge.page_referenced_one.rmap_walk_anon.rmap_walk": 0.81,
Quoted 7 lines
Quoted 1 line
Patch 1 is a clean up patch.
Could it be separated patch?
Quoted 3 lines
Patch 2 creates a lock per cluster, this gives us a more fine graind lock
that can be used for accessingswap_map, and not lock the whole swap device
After patch 2, the result is as follow,
"vmstat.swap.so": 1481704, "perf-profile.calltrace.cycles-pp._raw_spin_lock_irq.__add_to_swap_cache.add_to_swap_cache.add_to_swap.shrink_page_list": 27.53, "perf-profile.calltrace.cycles-pp._raw_spin_lock_irqsave.__remove_mapping.shrink_page_list.shrink_inactive_list.shrink_node_memcg": 27.01, "perf-profile.calltrace.cycles-pp._raw_spin_lock.free_pcppages_bulk.drain_pages_zone.drain_pages.drain_local_pages": 1.03,
The swap out throughput is at the same level, but the lock contention on swap_info_struct->lock is eliminated.
Quoted 3 lines
Quoted 2 lines
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
the rate that we have to contende for the radix tree.
After patch 3,
"vmstat.swap.so": 2050097, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_swap_page.add_to_swap.shrink_page_list.shrink_inactive_list": 43.27, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_page_from_freelist.__alloc_pages_nodemask.alloc_pages_vma.handle_mm_fault": 4.84,
The swap out throughput is improved about ~43% compared with baseline. The lock contention on swap cache radix tree lock is eliminated. swap_info_struct->lock in get_swap_page() becomes the most heavy contended lock.
Quoted 9 lines
Quoted 2 lines
Patch 4 eliminates unnecessary page allocation for read ahead.
Could it be separated patch?
Quoted 4 lines
Patch 5-9 create a per cpu cache of the swap slots, so we don't have
to contend on the swap device to get a swap slot or to release a swap slot. And we allocate and release the swap slots in batches for better efficiency.
After patch 9,
"vmstat.swap.so": 4170746, "perf-profile.calltrace.cycles-pp._raw_spin_lock.swapcache_free_entries.free_swap_slot.free_swap_and_cache.unmap_page_range": 13.91, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_page_from_freelist.__alloc_pages_nodemask.alloc_pages_vma.handle_mm_fault": 8.56, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_page_from_freelist.__alloc_pages_slowpath.__alloc_pages_nodemask.alloc_pages_vma": 2.56, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_swap_pages.get_swap_page.add_to_swap.shrink_page_list": 2.47,
The swap out throughput is improved about 192% compared with the baseline. There are still some lock contention for swap_info_struct->lock, but the pressure begins to shift to buddy system now.
Best Regards,
Huang, Ying
--
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>
Hi,
Quoted 5 lines · Ying
Hi, Minchan,
Minchan Kim <[email protected]> writes:
[snip]Quoted 1 line
Quoted 8 lines
Quoted 6 lines
The patchset has used several techniqueus to reduce lock contention, for example, batching alloc/free, fine-grained lock and cluster distribution to avoid cache false-sharing. Each items has different complexity and benefits so could you show the number for each step of pathchset? It would be better to include the nubmer in each description. It helps how the patch is important when we consider complexitiy of the patch.
Here is the test data.
Thanks!
Quoted 8 lines
We test the vm-scalability swap-w-seq test case with 32 processes on a Xeon E5 v3 system. The swap device used is a RAM simulated PMEM (persistent memory) device. To test the sequential swapping out, the test case created 32 processes, which sequentially allocate and write to the anonymous pages until the RAM and part of the swap device is used up.
Quoted 4 lines
The patchset is rebased on v4.9-rc8. So the baseline performance is as follow,
"vmstat.swap.so": 1428002,
What does it mean? vmstat.pswpout?
Quoted 7 lines
"perf-profile.calltrace.cycles-pp._raw_spin_lock_irq.__add_to_swap_cache.add_to_swap_cache.add_to_swap.shrink_page_list": 13.94, "perf-profile.calltrace.cycles-pp._raw_spin_lock_irqsave.__remove_mapping.shrink_page_list.shrink_inactive_list.shrink_node_memcg": 13.75, "perf-profile.calltrace.cycles-pp._raw_spin_lock.swap_info_get.swapcache_free.__remove_mapping.shrink_page_list": 7.05, "perf-profile.calltrace.cycles-pp._raw_spin_lock.swap_info_get.page_swapcount.try_to_free_swap.swap_writepage": 7.03, "perf-profile.calltrace.cycles-pp._raw_spin_lock.__swap_duplicate.swap_duplicate.try_to_unmap_one.rmap_walk_anon": 7.02, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_swap_page.add_to_swap.shrink_page_list.shrink_inactive_list": 6.83, "perf-profile.calltrace.cycles-pp._raw_spin_lock.page_check_address_transhuge.page_referenced_one.rmap_walk_anon.rmap_walk": 0.81,
Numbers mean overhead percentage reported by perf?
Quoted 25 lines
Quoted 8 lines
Quoted 2 lines
Patch 1 is a clean up patch.
Could it be separated patch?
Quoted 3 lines
Patch 2 creates a lock per cluster, this gives us a more fine graind lock
that can be used for accessingswap_map, and not lock the whole swap deviceAfter patch 2, the result is as follow,
"vmstat.swap.so": 1481704, "perf-profile.calltrace.cycles-pp._raw_spin_lock_irq.__add_to_swap_cache.add_to_swap_cache.add_to_swap.shrink_page_list": 27.53, "perf-profile.calltrace.cycles-pp._raw_spin_lock_irqsave.__remove_mapping.shrink_page_list.shrink_inactive_list.shrink_node_memcg": 27.01, "perf-profile.calltrace.cycles-pp._raw_spin_lock.free_pcppages_bulk.drain_pages_zone.drain_pages.drain_local_pages": 1.03,
The swap out throughput is at the same level, but the lock contention on
swap_info_struct->lockis eliminated.Quoted 3 lines
Quoted 2 lines
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
the rate that we have to contende for the radix tree.After patch 3,
Quoted 8 lines
"vmstat.swap.so": 2050097, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_swap_page.add_to_swap.shrink_page_list.shrink_inactive_list": 43.27, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_page_from_freelist.__alloc_pages_nodemask.alloc_pages_vma.handle_mm_fault": 4.84,
The swap out throughput is improved about ~43% compared with baseline. The lock contention on swap cache radix tree lock is eliminated.
swap_info_struct->lockinget_swap_page()becomes the most heavy contended lock.
The numbers are great! Please include those into each patchset. And I ask one more thing I said earlier about patch 2.
""
I hope you make three steps to review easier. You can create some functions like swap_map_lock and cluster_lock which are wrapper functions just hold swap_lock. It doesn't change anything performance pov but it clearly shows what kinds of lock we should use in specific context.
Then, you can introduce more fine-graind lock in next patch and apply it into those wrapper functions.
And last patch, you can adjust cluster distribution to avoid false-sharing. And the description should include how it's bad in testing so it's worth. ""
It makes review more easier, I believe.
Quoted 24 lines
Quoted 10 lines
Quoted 3 lines
Patch 4 eliminates unnecessary page allocation for read ahead.
Could it be separated patch?
Quoted 4 lines
Patch 5-9 create a per cpu cache of the swap slots, so we don't have
to contend on the swap device to get a swap slot or to release a swap slot. And we allocate and release the swap slots in batches for better efficiency.After patch 9,
"vmstat.swap.so": 4170746, "perf-profile.calltrace.cycles-pp._raw_spin_lock.swapcache_free_entries.free_swap_slot.free_swap_and_cache.unmap_page_range": 13.91, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_page_from_freelist.__alloc_pages_nodemask.alloc_pages_vma.handle_mm_fault": 8.56, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_page_from_freelist.__alloc_pages_slowpath.__alloc_pages_nodemask.alloc_pages_vma": 2.56, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_swap_pages.get_swap_page.add_to_swap.shrink_page_list": 2.47,
The swap out throughput is improved about 192% compared with the baseline. There are still some lock contention for
swap_info_struct->lock, but the pressure begins to shift to buddy system now.
Quoted 8 lines
Best Regards,
Huang, Ying--
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>
--
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>
Quoted 27 lines · Minchan Kim
Hi,
Quoted 5 lines · Ying
Hi, Minchan,
Minchan Kim <[email protected]> writes:
[snip]Quoted 1 line
Quoted 8 lines
Quoted 6 lines
The patchset has used several techniqueus to reduce lock contention, for example, batching alloc/free, fine-grained lock and cluster distribution to avoid cache false-sharing. Each items has different complexity and benefits so could you show the number for each step of pathchset? It would be better to include the nubmer in each description. It helps how the patch is important when we consider complexitiy of the patch.
Here is the test data.
Thanks!
Quoted 8 lines
We test the vm-scalability swap-w-seq test case with 32 processes on a Xeon E5 v3 system. The swap device used is a RAM simulated PMEM (persistent memory) device. To test the sequential swapping out, the test case created 32 processes, which sequentially allocate and write to the anonymous pages until the RAM and part of the swap device is used up.
Quoted 6 lines
Quoted 4 lines
The patchset is rebased on v4.9-rc8. So the baseline performance is as follow,
"vmstat.swap.so": 1428002,
What does it mean? vmstat.pswpout?
This is the average of swap.so column of /usr/bin/vmstat output. We run /usr/bin/vmstat with,
/usr/bin/vmstat -n 1
Quoted 10 lines
Quoted 8 lines
"perf-profile.calltrace.cycles-pp._raw_spin_lock_irq.__add_to_swap_cache.add_to_swap_cache.add_to_swap.shrink_page_list": 13.94, "perf-profile.calltrace.cycles-pp._raw_spin_lock_irqsave.__remove_mapping.shrink_page_list.shrink_inactive_list.shrink_node_memcg":
13.75,
"perf-profile.calltrace.cycles-pp._raw_spin_lock.swap_info_get.swapcache_free.__remove_mapping.shrink_page_list": 7.05, "perf-profile.calltrace.cycles-pp._raw_spin_lock.swap_info_get.page_swapcount.try_to_free_swap.swap_writepage": 7.03, "perf-profile.calltrace.cycles-pp._raw_spin_lock.__swap_duplicate.swap_duplicate.try_to_unmap_one.rmap_walk_anon": 7.02, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_swap_page.add_to_swap.shrink_page_list.shrink_inactive_list": 6.83, "perf-profile.calltrace.cycles-pp._raw_spin_lock.page_check_address_transhuge.page_referenced_one.rmap_walk_anon.rmap_walk": 0.81,Numbers mean overhead percentage reported by perf?
Yes.
Quoted 43 lines
Quoted 25 lines
Quoted 7 lines
Quoted 1 line
Patch 1 is a clean up patch.
Could it be separated patch?
Quoted 3 lines
Patch 2 creates a lock per cluster, this gives us a more fine graind lock
that can be used for accessingswap_map, and not lock the whole swap deviceAfter patch 2, the result is as follow,
"vmstat.swap.so": 1481704, "perf-profile.calltrace.cycles-pp._raw_spin_lock_irq.__add_to_swap_cache.add_to_swap_cache.add_to_swap.shrink_page_list": 27.53, "perf-profile.calltrace.cycles-pp._raw_spin_lock_irqsave.__remove_mapping.shrink_page_list.shrink_inactive_list.shrink_node_memcg":
27.01,
"perf-profile.calltrace.cycles-pp._raw_spin_lock.free_pcppages_bulk.drain_pages_zone.drain_pages.drain_local_pages": 1.03,The swap out throughput is at the same level, but the lock contention on
swap_info_struct->lockis eliminated.Quoted 3 lines
Quoted 2 lines
Patch 3 splits the swap cache radix tree into 64MB chunks, reducing
the rate that we have to contende for the radix tree.After patch 3,
Quoted 8 lines
"vmstat.swap.so": 2050097, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_swap_page.add_to_swap.shrink_page_list.shrink_inactive_list": 43.27, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_page_from_freelist.__alloc_pages_nodemask.alloc_pages_vma.handle_mm_fault": 4.84,
The swap out throughput is improved about ~43% compared with baseline. The lock contention on swap cache radix tree lock is eliminated.
swap_info_struct->lockinget_swap_page()becomes the most heavy contended lock.The numbers are great! Please include those into each patchset. And I ask one more thing I said earlier about patch 2.
""
I hope you make three steps to review easier. You can create some functions likeswap_map_lockandcluster_lockwhich are wrapper functions just holdswap_lock. It doesn't change anything performance pov but it clearly shows what kinds of lock we should use in specific context.
Quoted 8 lines
Then, you can introduce more fine-graind lock in next patch and apply it into those wrapper functions.
And last patch, you can adjust cluster distribution to avoid false-sharing. And the description should include how it's bad in testing so it's worth. ""
It makes review more easier, I believe.
Sorry, personally, I don't like this way to organize the patchset. So unless more people have this requirement, I still want to keep the current way.
Best Regards,
Huang, Ying
Quoted 25 lines
Quoted 25 lines
Quoted 10 lines
Quoted 3 lines
Patch 4 eliminates unnecessary page allocation for read ahead.
Could it be separated patch?
Quoted 4 lines
Patch 5-9 create a per cpu cache of the swap slots, so we don't have
to contend on the swap device to get a swap slot or to release a swap slot. And we allocate and release the swap slots in batches for better efficiency.After patch 9,
"vmstat.swap.so": 4170746, "perf-profile.calltrace.cycles-pp._raw_spin_lock.swapcache_free_entries.free_swap_slot.free_swap_and_cache.unmap_page_range": 13.91, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_page_from_freelist.__alloc_pages_nodemask.alloc_pages_vma.handle_mm_fault": 8.56, "perf-profile.calltrace.cycles-pp._raw_spin_lock.get_page_from_freelist.__alloc_pages_slowpath.__alloc_pages_nodemask.alloc_pages_vma":
2.56,
"perf-profile.calltrace.cycles-pp._raw_spin_lock.get_swap_pages.get_swap_page.add_to_swap.shrink_page_list": 2.47,The swap out throughput is improved about 192% compared with the baseline. There are still some lock contention for
swap_info_struct->lock, but the pressure begins to shift to buddy system now.
Quoted 8 lines
Quoted 8 lines
Best Regards,
Huang, Ying--
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>
--
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>