All of lore.kernel.org
 help / color / mirror / Atom feed
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.