diff for duplicates of <20150823081750.GA28349@gmail.com> diff --git a/a/1.txt b/N1/1.txt index 6f775a3..d5d8ced 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -48,3 +48,120 @@ Thanks, Ingo ==============================> +>From f9fd770e75e2edb4143f32ced0b53d7a77969c94 Mon Sep 17 00:00:00 2001 +From: Ingo Molnar <mingo@kernel.org> +Date: Sat, 22 Aug 2015 12:28:01 +0200 +Subject: [PATCH] mm/vmalloc: Cache the vmalloc memory info + +Linus reported that glibc (rather stupidly) reads /proc/meminfo +for every sysinfo() call, which causes the Git build to use +a surprising amount of CPU time, mostly due to the overhead +of get_vmalloc_info() - which walks a long list to do its +statistics. + +Modify Linus's jiffies based patch to use generation counters +to cache the vmalloc info: vmap_unlock() increases the generation +counter, and the get_vmalloc_info() reads it and compares it +against a cached generation counter. + +Also use a seqlock to make sure we always print a consistent +set of vmalloc statistics. + +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Andrew Morton <akpm@linux-foundation.org> +Cc: Rik van Riel <riel@redhat.com> +Cc: linux-mm@kvack.org +Signed-off-by: Ingo Molnar <mingo@kernel.org> +--- + mm/vmalloc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 56 insertions(+), 3 deletions(-) + +diff --git a/mm/vmalloc.c b/mm/vmalloc.c +index 605138083880..d72b23436906 100644 +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -276,7 +276,21 @@ EXPORT_SYMBOL(vmalloc_to_pfn); + #define VM_LAZY_FREEING 0x02 + #define VM_VM_AREA 0x04 + +-static DEFINE_SPINLOCK(vmap_area_lock); ++static __cacheline_aligned_in_smp DEFINE_SPINLOCK(vmap_area_lock); ++ ++#ifdef CONFIG_PROC_FS ++/* ++ * A seqlock and two generation counters for a simple cache of the ++ * vmalloc allocation statistics info printed in /proc/meminfo. ++ * ++ * ( The assumption of the optimization is that it's read frequently, but ++ * modified infrequently. ) ++ */ ++static DEFINE_SEQLOCK(vmap_info_lock); ++static u64 vmap_info_gen; ++static u64 vmap_info_cache_gen; ++static struct vmalloc_info vmap_info_cache; ++#endif + + static inline void vmap_lock(void) + { +@@ -285,6 +299,9 @@ static inline void vmap_lock(void) + + static inline void vmap_unlock(void) + { ++#ifdef CONFIG_PROC_FS ++ WRITE_ONCE(vmap_info_gen, vmap_info_gen+1); ++#endif + spin_unlock(&vmap_area_lock); + } + +@@ -2699,7 +2716,7 @@ static int __init proc_vmalloc_init(void) + } + module_init(proc_vmalloc_init); + +-void get_vmalloc_info(struct vmalloc_info *vmi) ++static void calc_vmalloc_info(struct vmalloc_info *vmi) + { + struct vmap_area *va; + unsigned long free_area_size; +@@ -2746,5 +2763,41 @@ void get_vmalloc_info(struct vmalloc_info *vmi) + out: + rcu_read_unlock(); + } +-#endif + ++/* ++ * Return a consistent snapshot of the current vmalloc allocation ++ * statistics, for /proc/meminfo: ++ */ ++void get_vmalloc_info(struct vmalloc_info *vmi) ++{ ++ u64 gen = READ_ONCE(vmap_info_gen); ++ ++ /* ++ * If the generation counter of the cache matches that of ++ * the vmalloc generation counter then return the cache: ++ */ ++ if (READ_ONCE(vmap_info_cache_gen) == gen) { ++ unsigned int seq; ++ ++ do { ++ seq = read_seqbegin(&vmap_info_lock); ++ *vmi = vmap_info_cache; ++ } while (read_seqretry(&vmap_info_lock, seq)); ++ ++ return; ++ } ++ ++ calc_vmalloc_info(vmi); ++ ++ /* ++ * If are racing with a new vmalloc() then we might write ++ * the old generation counter here - and the next call to ++ * get_vmalloc_info() will fix things up: ++ */ ++ write_seqlock(&vmap_info_lock); ++ vmap_info_cache = *vmi; ++ WRITE_ONCE(vmap_info_cache_gen, gen); ++ write_sequnlock(&vmap_info_lock); ++} ++ ++#endif /* CONFIG_PROC_FS */ diff --git a/a/content_digest b/N1/content_digest index 1999bec..ab27909 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -63,6 +63,123 @@ "\n" "\tIngo\n" "\n" - ==============================> + "==============================>\n" + ">From f9fd770e75e2edb4143f32ced0b53d7a77969c94 Mon Sep 17 00:00:00 2001\n" + "From: Ingo Molnar <mingo@kernel.org>\n" + "Date: Sat, 22 Aug 2015 12:28:01 +0200\n" + "Subject: [PATCH] mm/vmalloc: Cache the vmalloc memory info\n" + "\n" + "Linus reported that glibc (rather stupidly) reads /proc/meminfo\n" + "for every sysinfo() call, which causes the Git build to use\n" + "a surprising amount of CPU time, mostly due to the overhead\n" + "of get_vmalloc_info() - which walks a long list to do its\n" + "statistics.\n" + "\n" + "Modify Linus's jiffies based patch to use generation counters\n" + "to cache the vmalloc info: vmap_unlock() increases the generation\n" + "counter, and the get_vmalloc_info() reads it and compares it\n" + "against a cached generation counter.\n" + "\n" + "Also use a seqlock to make sure we always print a consistent\n" + "set of vmalloc statistics.\n" + "\n" + "Cc: Linus Torvalds <torvalds@linux-foundation.org>\n" + "Cc: Andrew Morton <akpm@linux-foundation.org>\n" + "Cc: Rik van Riel <riel@redhat.com>\n" + "Cc: linux-mm@kvack.org\n" + "Signed-off-by: Ingo Molnar <mingo@kernel.org>\n" + "---\n" + " mm/vmalloc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---\n" + " 1 file changed, 56 insertions(+), 3 deletions(-)\n" + "\n" + "diff --git a/mm/vmalloc.c b/mm/vmalloc.c\n" + "index 605138083880..d72b23436906 100644\n" + "--- a/mm/vmalloc.c\n" + "+++ b/mm/vmalloc.c\n" + "@@ -276,7 +276,21 @@ EXPORT_SYMBOL(vmalloc_to_pfn);\n" + " #define VM_LAZY_FREEING\t0x02\n" + " #define VM_VM_AREA\t0x04\n" + " \n" + "-static DEFINE_SPINLOCK(vmap_area_lock);\n" + "+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(vmap_area_lock);\n" + "+\n" + "+#ifdef CONFIG_PROC_FS\n" + "+/*\n" + "+ * A seqlock and two generation counters for a simple cache of the\n" + "+ * vmalloc allocation statistics info printed in /proc/meminfo.\n" + "+ *\n" + "+ * ( The assumption of the optimization is that it's read frequently, but\n" + "+ * modified infrequently. )\n" + "+ */\n" + "+static DEFINE_SEQLOCK(vmap_info_lock);\n" + "+static u64 vmap_info_gen;\n" + "+static u64 vmap_info_cache_gen;\n" + "+static struct vmalloc_info vmap_info_cache;\n" + "+#endif\n" + " \n" + " static inline void vmap_lock(void)\n" + " {\n" + "@@ -285,6 +299,9 @@ static inline void vmap_lock(void)\n" + " \n" + " static inline void vmap_unlock(void)\n" + " {\n" + "+#ifdef CONFIG_PROC_FS\n" + "+\tWRITE_ONCE(vmap_info_gen, vmap_info_gen+1);\n" + "+#endif\n" + " \tspin_unlock(&vmap_area_lock);\n" + " }\n" + " \n" + "@@ -2699,7 +2716,7 @@ static int __init proc_vmalloc_init(void)\n" + " }\n" + " module_init(proc_vmalloc_init);\n" + " \n" + "-void get_vmalloc_info(struct vmalloc_info *vmi)\n" + "+static void calc_vmalloc_info(struct vmalloc_info *vmi)\n" + " {\n" + " \tstruct vmap_area *va;\n" + " \tunsigned long free_area_size;\n" + "@@ -2746,5 +2763,41 @@ void get_vmalloc_info(struct vmalloc_info *vmi)\n" + " out:\n" + " \trcu_read_unlock();\n" + " }\n" + "-#endif\n" + " \n" + "+/*\n" + "+ * Return a consistent snapshot of the current vmalloc allocation\n" + "+ * statistics, for /proc/meminfo:\n" + "+ */\n" + "+void get_vmalloc_info(struct vmalloc_info *vmi)\n" + "+{\n" + "+\tu64 gen = READ_ONCE(vmap_info_gen);\n" + "+\n" + "+\t/*\n" + "+\t * If the generation counter of the cache matches that of\n" + "+\t * the vmalloc generation counter then return the cache:\n" + "+\t */\n" + "+\tif (READ_ONCE(vmap_info_cache_gen) == gen) {\n" + "+\t\tunsigned int seq;\n" + "+\n" + "+\t\tdo {\n" + "+\t\t\tseq = read_seqbegin(&vmap_info_lock);\n" + "+\t\t\t*vmi = vmap_info_cache;\n" + "+\t\t} while (read_seqretry(&vmap_info_lock, seq));\n" + "+\n" + "+\t\treturn;\n" + "+\t}\n" + "+\n" + "+\tcalc_vmalloc_info(vmi);\n" + "+\n" + "+\t/*\n" + "+\t * If are racing with a new vmalloc() then we might write\n" + "+\t * the old generation counter here - and the next call to\n" + "+\t * get_vmalloc_info() will fix things up:\n" + "+\t */\n" + "+\twrite_seqlock(&vmap_info_lock);\n" + "+\tvmap_info_cache = *vmi;\n" + "+\tWRITE_ONCE(vmap_info_cache_gen, gen);\n" + "+\twrite_sequnlock(&vmap_info_lock);\n" + "+}\n" + "+\n" + +#endif /* CONFIG_PROC_FS */ -a6c79dcb5af5c16b3620c6c2eb062db082c65bb2278691cbc366537c6e6cfda4 +6da897fec33cc4d1d82d1458edd4759712407f97d4fc871e83f809ee2915c836
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.