linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Lameter <cl@linux.com>
To: akpm@linux-foundation.org
Cc: Michal Hocko <mhocko@kernel.org>, Tejun Heo <htejun@gmail.com>,
	Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
	linux-mm@kvack.org, hannes@cmpxchg.org, mgorman@suse.de
Subject: [patch 1/2] vmstat: Optimize refresh_cpu_vmstat()
Date: Mon, 22 Feb 2016 12:10:41 -0600	[thread overview]
Message-ID: <20160222181049.844884425@linux.com> (raw)
In-Reply-To: <20160222181040.553533936@linux.com>

[-- Attachment #1: vmstat_speed_up --]
[-- Type: text/plain, Size: 3202 bytes --]

Create a new function zone_needs_update() that uses a memchr to check
all diffs for being nonzero first.

If we use this function in refresh_cpu_vm_stat() then we can avoid the
this_cpu_xchg() loop over all differentials. This becomes in particular
important as the number of counters keeps on increasing.

This also avoids modifying the cachelines with the differentials
unnecessarily.

Also add some likely()s to ensure that the icache requirements
are low when we do not have any updates to process.

Signed-off-by: Christoph Lameter <cl@linux.com>

Index: linux/mm/vmstat.c
===================================================================
--- linux.orig/mm/vmstat.c	2016-02-22 11:54:02.179095030 -0600
+++ linux/mm/vmstat.c	2016-02-22 11:54:24.338528277 -0600
@@ -444,6 +444,18 @@ static int fold_diff(int *diff)
 	return changes;
 }
 
+bool zone_needs_update(struct per_cpu_pageset *p)
+{
+
+	BUILD_BUG_ON(sizeof(p->vm_stat_diff[0]) != 1);
+	/*
+	 * The fast way of checking if there are any vmstat diffs.
+	 * This works because the diffs are byte sized items.
+	 */
+	return memchr_inv(p->vm_stat_diff, 0,
+			NR_VM_ZONE_STAT_ITEMS) != NULL;
+}
+
 /*
  * Update the zone counters for the current cpu.
  *
@@ -470,18 +482,20 @@ static int refresh_cpu_vm_stats(bool do_
 	for_each_populated_zone(zone) {
 		struct per_cpu_pageset __percpu *p = zone->pageset;
 
-		for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) {
-			int v;
+		if (unlikely(zone_needs_update(this_cpu_ptr(p)))) {
+			for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) {
+				int v;
 
-			v = this_cpu_xchg(p->vm_stat_diff[i], 0);
-			if (v) {
+				v = this_cpu_xchg(p->vm_stat_diff[i], 0);
+				if (v) {
 
-				atomic_long_add(v, &zone->vm_stat[i]);
-				global_diff[i] += v;
+					atomic_long_add(v, &zone->vm_stat[i]);
+					global_diff[i] += v;
 #ifdef CONFIG_NUMA
-				/* 3 seconds idle till flush */
-				__this_cpu_write(p->expire, 3);
+					/* 3 seconds idle till flush */
+					__this_cpu_write(p->expire, 3);
 #endif
+				}
 			}
 		}
 #ifdef CONFIG_NUMA
@@ -494,8 +508,8 @@ static int refresh_cpu_vm_stats(bool do_
 			 * Check if there are pages remaining in this pageset
 			 * if not then there is nothing to expire.
 			 */
-			if (!__this_cpu_read(p->expire) ||
-			       !__this_cpu_read(p->pcp.count))
+			if (likely(!__this_cpu_read(p->expire) ||
+			       !__this_cpu_read(p->pcp.count)))
 				continue;
 
 			/*
@@ -1440,19 +1454,12 @@ static bool need_update(int cpu)
 	for_each_populated_zone(zone) {
 		struct per_cpu_pageset *p = per_cpu_ptr(zone->pageset, cpu);
 
-		BUILD_BUG_ON(sizeof(p->vm_stat_diff[0]) != 1);
-		/*
-		 * The fast way of checking if there are any vmstat diffs.
-		 * This works because the diffs are byte sized items.
-		 */
-		if (memchr_inv(p->vm_stat_diff, 0, NR_VM_ZONE_STAT_ITEMS))
+		if (zone_needs_update(p))
 			return true;
-
 	}
 	return false;
 }
 
-
 /*
  * Shepherd worker thread that checks the
  * differentials of processors that have their worker

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  reply	other threads:[~2016-02-22 18:10 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-22 18:10 [patch 0/2] vmstat: Speedup and Cleanup Christoph Lameter
2016-02-22 18:10 ` Christoph Lameter [this message]
2016-02-24 17:38   ` [patch 1/2] vmstat: Optimize refresh_cpu_vmstat() Michal Hocko
2016-02-22 18:10 ` [patch 2/2] vmstat: Get rid of the ugly cpu_stat_off variable Christoph Lameter
2016-02-24  0:23   ` Andrew Morton
2016-02-24 10:07     ` Michal Hocko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160222181049.844884425@linux.com \
    --to=cl@linux.com \
    --cc=akpm@linux-foundation.org \
    --cc=hannes@cmpxchg.org \
    --cc=htejun@gmail.com \
    --cc=linux-mm@kvack.org \
    --cc=mgorman@suse.de \
    --cc=mhocko@kernel.org \
    --cc=penguin-kernel@I-love.SAKURA.ne.jp \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox