[thisops uV3 09/18] fs: Use this_cpu_xx operations in buffer.c

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Christoph Lameter
Date: Tuesday, November 30, 2010 - 12:07 pm

Optimize various per cpu area operations through the new this cpu
operations. These operations avoid address calculations through the use
of segment prefixes avoid multiple memory references through RMW
instructions etc.

Reduces code size:

Before:

christoph@linux-2.6$ size fs/buffer.o
   text	   data	    bss	    dec	    hex	filename
  19169	     80	     28	  19277	   4b4d	fs/buffer.o

After:

christoph@linux-2.6$ size fs/buffer.o
   text	   data	    bss	    dec	    hex	filename
  19138	     80	     28	  19246	   4b2e	fs/buffer.o

Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christoph Lameter <cl@linux.com>

---
 fs/buffer.c |   37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

Index: linux-2.6/fs/buffer.c
===================================================================
--- linux-2.6.orig/fs/buffer.c	2010-11-30 09:41:30.000000000 -0600
+++ linux-2.6/fs/buffer.c	2010-11-30 09:55:55.000000000 -0600
@@ -1270,12 +1270,10 @@ static inline void check_irqs_on(void)
 static void bh_lru_install(struct buffer_head *bh)
 {
 	struct buffer_head *evictee = NULL;
-	struct bh_lru *lru;
 
 	check_irqs_on();
 	bh_lru_lock();
-	lru = &__get_cpu_var(bh_lrus);
-	if (lru->bhs[0] != bh) {
+	if (__this_cpu_read(bh_lrus.bhs[0]) != bh) {
 		struct buffer_head *bhs[BH_LRU_SIZE];
 		int in;
 		int out = 0;
@@ -1283,7 +1281,8 @@ static void bh_lru_install(struct buffer
 		get_bh(bh);
 		bhs[out++] = bh;
 		for (in = 0; in < BH_LRU_SIZE; in++) {
-			struct buffer_head *bh2 = lru->bhs[in];
+			struct buffer_head *bh2 =
+				__this_cpu_read(bh_lrus.bhs[in]);
 
 			if (bh2 == bh) {
 				__brelse(bh2);
@@ -1298,7 +1297,7 @@ static void bh_lru_install(struct buffer
 		}
 		while (out < BH_LRU_SIZE)
 			bhs[out++] = NULL;
-		memcpy(lru->bhs, bhs, sizeof(bhs));
+		memcpy(__this_cpu_ptr(&bh_lrus.bhs), bhs, sizeof(bhs));
 	}
 	bh_lru_unlock();
 
@@ -1313,23 +1312,22 @@ static struct buffer_head *
 lookup_bh_lru(struct block_device *bdev, sector_t block, unsigned size)
 {
 	struct buffer_head *ret = NULL;
-	struct bh_lru *lru;
 	unsigned int i;
 
 	check_irqs_on();
 	bh_lru_lock();
-	lru = &__get_cpu_var(bh_lrus);
 	for (i = 0; i < BH_LRU_SIZE; i++) {
-		struct buffer_head *bh = lru->bhs[i];
+		struct buffer_head *bh = __this_cpu_read(bh_lrus.bhs[i]);
 
 		if (bh && bh->b_bdev == bdev &&
 				bh->b_blocknr == block && bh->b_size == size) {
 			if (i) {
 				while (i) {
-					lru->bhs[i] = lru->bhs[i - 1];
+					__this_cpu_write(bh_lrus.bhs[i],
+						__this_cpu_read(bh_lrus.bhs[i - 1]));
 					i--;
 				}
-				lru->bhs[0] = bh;
+				__this_cpu_write(bh_lrus.bhs[0], bh);
 			}
 			get_bh(bh);
 			ret = bh;
@@ -3203,22 +3201,23 @@ static void recalc_bh_state(void)
 	int i;
 	int tot = 0;
 
-	if (__get_cpu_var(bh_accounting).ratelimit++ < 4096)
+	if (__this_cpu_inc_return(bh_accounting.ratelimit) < 4096)
 		return;
-	__get_cpu_var(bh_accounting).ratelimit = 0;
+	__this_cpu_write(bh_accounting.ratelimit, 0);
 	for_each_online_cpu(i)
 		tot += per_cpu(bh_accounting, i).nr;
 	buffer_heads_over_limit = (tot > max_buffer_heads);
 }
-	
+
 struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
 {
 	struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags);
 	if (ret) {
 		INIT_LIST_HEAD(&ret->b_assoc_buffers);
-		get_cpu_var(bh_accounting).nr++;
+		preempt_disable();
+		__this_cpu_inc(bh_accounting.nr);
 		recalc_bh_state();
-		put_cpu_var(bh_accounting);
+		preempt_enable();
 	}
 	return ret;
 }
@@ -3228,9 +3227,10 @@ void free_buffer_head(struct buffer_head
 {
 	BUG_ON(!list_empty(&bh->b_assoc_buffers));
 	kmem_cache_free(bh_cachep, bh);
-	get_cpu_var(bh_accounting).nr--;
+	preempt_disable();
+	__this_cpu_dec(bh_accounting.nr);
 	recalc_bh_state();
-	put_cpu_var(bh_accounting);
+	preempt_enable();
 }
 EXPORT_SYMBOL(free_buffer_head);
 
@@ -3243,9 +3243,8 @@ static void buffer_exit_cpu(int cpu)
 		brelse(b->bhs[i]);
 		b->bhs[i] = NULL;
 	}
-	get_cpu_var(bh_accounting).nr += per_cpu(bh_accounting, cpu).nr;
+	this_cpu_add(bh_accounting.nr, per_cpu(bh_accounting, cpu).nr);
 	per_cpu(bh_accounting, cpu).nr = 0;
-	put_cpu_var(bh_accounting);
 }
 
 static int buffer_cpu_notify(struct notifier_block *self,

--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[thisops uV3 00/18] Upgrade of this_cpu_ops V3, Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 01/18] percpucounter: Optimize __percpu_count ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 02/18] vmstat: Optimize zone counter modifica ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 03/18] percpu: Generic support for this_cpu_a ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 04/18] x86: Support for this_cpu_add,sub,dec, ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 05/18] x86: Use this_cpu_inc_return for nmi c ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 06/18] vmstat: Use this_cpu_inc_return for vm ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 07/18] highmem: Use this_cpu_xx_return() oper ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 08/18] Taskstats: Use this_cpu_ops, Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 09/18] fs: Use this_cpu_xx operations in buffer.c, Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 10/18] x86: Use this_cpu_ops to optimize code, Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 11/18] x86: Use this_cpu_ops for current_cpu_ ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 12/18] Core: Replace __get_cpu_var with __thi ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 13/18] drivers: Replace __get_cpu_var with __ ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 14/18] lguest: Use this_cpu_ops, Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 15/18] Xen: Use this_cpu_ops, Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 16/18] kprobes: Use this_cpu_ops, Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 17/18] Connector: Use this_cpu operations, Christoph Lameter, (Tue Nov 30, 12:07 pm)
[thisops uV3 18/18] Fakekey: Simplify speakup_fake_key_pre ..., Christoph Lameter, (Tue Nov 30, 12:07 pm)
Re: [thisops uV3 07/18] highmem: Use this_cpu_xx_return() ..., Christoph Lameter, (Tue Nov 30, 12:26 pm)
Re: [thisops uV3 07/18] highmem: Use this_cpu_xx_return() ..., Christoph Lameter, (Tue Nov 30, 12:53 pm)
[extra] timers: Use this_cpu_read, Christoph Lameter, (Tue Nov 30, 1:05 pm)
Re: [thisops uV3 15/18] Xen: Use this_cpu_ops, Jeremy Fitzhardinge, (Tue Nov 30, 1:53 pm)
Re: [thisops uV3 15/18] Xen: Use this_cpu_ops, Christoph Lameter, (Tue Nov 30, 2:03 pm)
Re: [thisops uV3 08/18] Taskstats: Use this_cpu_ops, Michael Holzheu, (Wed Dec 1, 11:06 am)
Re: [thisops uV3 08/18] Taskstats: Use this_cpu_ops, Christoph Lameter, (Wed Dec 1, 11:13 am)
Re: [thisops uV3 14/18] lguest: Use this_cpu_ops, Rusty Russell, (Mon Dec 6, 12:46 am)
Re: [thisops uV3 08/18] Taskstats: Use this_cpu_ops, Balbir Singh, (Mon Dec 6, 7:32 am)
Re: [thisops uV3 14/18] lguest: Use this_cpu_ops, Christoph Lameter, (Mon Dec 6, 8:54 am)
Re: [thisops uV3 08/18] Taskstats: Use this_cpu_ops, Christoph Lameter, (Tue Dec 7, 7:39 am)
[tip:timers/core] timers: Use this_cpu_read, tip-bot for Christop ..., (Sun Dec 12, 10:41 am)