Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Le mar 28/03/2006 à 00:58, Ravikiran G Thirumalai a écrit :
> On Mon, Mar 27, 2006 at 01:10:49PM -0800, Andrew Morton wrote:
> > Mingming Cao <[email protected]> wrote:
> > >
> > > I am wondering if we have (or plan to have) "long long " type of percpu
> > >  counters?  Andrew, Kiran, do you know?  
> > > 
> > >  It seems right now the percpu counters are used mostly by ext2/3 for
> > >  filesystem free blocks accounting. Right now the counter is "long" type,
> > >  which is not enough if we want to extend the filesystem limit from 2**31
> > >  to 2**32 on 32 bit machine.
> > > 
> > >  The patch from Takashi copies the whole percpu_count.h  and create a new
> > >  percpu_llcounter.h to support longlong type percpu counters. I am
> > >  wondering is there any better way for this?
> > > 
> > 
> > I can't immediately think of anything smarter.
> > 
> > One could of course implement a 64-bit percpu counter by simply
> > concatenating two 32-bit counters.  That would be a little less efficient,
> > but would introduce less source code and would mean that we don't need to
> > keep two different implemetations in sync.  But one would need to do a bit
> > of implementation, see how bad it looks.
> 
> Since long long is 64 bits on both 32bit and 64 bit arches, we can just
> change percpu_counter type to long long (or s64) and just have one
> implementation of percpu_counter?  
> But reads and writes on 64 bit counters may not be atomic on all 32 bit arches.
> So the implementation might have to be reviewed for that.

As 64bit per cpu counter is used only by ext3 and needed only on 64bit
architecture and when CONFIG_LBD is set, perhaps we can have only one
implementation, 32bit in the case of 32bit arch and 64bit in the case of
64bit arch + LBD, as I did in my 64bit patches for ext3 ?

Cheers,
Laurent
-- 
Laurent Vivier
Bull, Architect of an Open World (TM)
http://www.bullopensource.org/ext4
Index: linux-2.6.16-lv/include/linux/percpu_counter.h
===================================================================
--- linux-2.6.16-lv.orig/include/linux/percpu_counter.h	2006-03-27 15:47:03.000000000 +0200
+++ linux-2.6.16-lv/include/linux/percpu_counter.h	2006-03-27 15:47:14.000000000 +0200
@@ -16,8 +16,13 @@
 
 struct percpu_counter {
 	spinlock_t lock;
+#ifdef CONFIG_LBD
+	long long count;
+	long long *counters;
+#else
 	long count;
 	long *counters;
+#endif
 };
 
 #if NR_CPUS >= 16
@@ -30,7 +35,11 @@ static inline void percpu_counter_init(s
 {
 	spin_lock_init(&fbc->lock);
 	fbc->count = 0;
+#ifdef CONFIG_LBD
+	fbc->counters = alloc_percpu(long long);
+#else
 	fbc->counters = alloc_percpu(long);
+#endif
 }
 
 static inline void percpu_counter_destroy(struct percpu_counter *fbc)
@@ -38,10 +47,17 @@ static inline void percpu_counter_destro
 	free_percpu(fbc->counters);
 }
 
+#ifdef CONFIG_LBD
+void percpu_counter_mod(struct percpu_counter *fbc, long long amount);
+long long percpu_counter_sum(struct percpu_counter *fbc);
+
+static inline long long percpu_counter_read(struct percpu_counter *fbc)
+#else
 void percpu_counter_mod(struct percpu_counter *fbc, long amount);
 long percpu_counter_sum(struct percpu_counter *fbc);
 
 static inline long percpu_counter_read(struct percpu_counter *fbc)
+#endif
 {
 	return fbc->count;
 }
@@ -50,9 +66,15 @@ static inline long percpu_counter_read(s
  * It is possible for the percpu_counter_read() to return a small negative
  * number for some counter which should never be negative.
  */
+#ifdef CONFIG_LBD
+static inline long long percpu_counter_read_positive(struct percpu_counter *fbc)
+{
+	long long ret = fbc->count;
+#else
 static inline long percpu_counter_read_positive(struct percpu_counter *fbc)
 {
 	long ret = fbc->count;
+#endif
 
 	barrier();		/* Prevent reloads of fbc->count */
 	if (ret > 0)
@@ -63,7 +85,11 @@ static inline long percpu_counter_read_p
 #else
 
 struct percpu_counter {
+#ifdef CONFIG_LBD
+	long long count;
+#else
 	long count;
+#endif
 };
 
 static inline void percpu_counter_init(struct percpu_counter *fbc)
@@ -76,24 +102,40 @@ static inline void percpu_counter_destro
 }
 
 static inline void
+#ifdef CONFIG_LBD
+percpu_counter_mod(struct percpu_counter *fbc, long long amount)
+#else
 percpu_counter_mod(struct percpu_counter *fbc, long amount)
+#endif
 {
 	preempt_disable();
 	fbc->count += amount;
 	preempt_enable();
 }
 
+#ifdef CONFIG_LBD
+static inline long long percpu_counter_read(struct percpu_counter *fbc)
+#else
 static inline long percpu_counter_read(struct percpu_counter *fbc)
+#endif
 {
 	return fbc->count;
 }
 
+#ifdef CONFIG_LBD
+static inline long long percpu_counter_read_positive(struct percpu_counter *fbc)
+#else
 static inline long percpu_counter_read_positive(struct percpu_counter *fbc)
+#endif
 {
 	return fbc->count;
 }
 
+#ifdef CONFIG_LBD
+static inline long long percpu_counter_sum(struct percpu_counter *fbc)
+#else
 static inline long percpu_counter_sum(struct percpu_counter *fbc)
+#endif
 {
 	return percpu_counter_read_positive(fbc);
 }
Index: linux-2.6.16-lv/mm/swap.c
===================================================================
--- linux-2.6.16-lv.orig/mm/swap.c	2006-03-27 15:47:03.000000000 +0200
+++ linux-2.6.16-lv/mm/swap.c	2006-03-27 15:47:14.000000000 +0200
@@ -479,10 +479,17 @@ static int cpu_swap_callback(struct noti
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_SMP
+#ifdef CONFIG_LBD
+void percpu_counter_mod(struct percpu_counter *fbc, long long amount)
+{
+	long long count;
+	long long *pcount;
+#else
 void percpu_counter_mod(struct percpu_counter *fbc, long amount)
 {
 	long count;
 	long *pcount;
+#endif
 	int cpu = get_cpu();
 
 	pcount = per_cpu_ptr(fbc->counters, cpu);
@@ -503,15 +510,26 @@ EXPORT_SYMBOL(percpu_counter_mod);
  * Add up all the per-cpu counts, return the result.  This is a more accurate
  * but much slower version of percpu_counter_read_positive()
  */
+#ifdef CONFIG_LBD
+long long percpu_counter_sum(struct percpu_counter *fbc)
+{
+	long long ret;
+#else
 long percpu_counter_sum(struct percpu_counter *fbc)
 {
 	long ret;
+#endif
 	int cpu;
 
 	spin_lock(&fbc->lock);
 	ret = fbc->count;
 	for_each_cpu(cpu) {
-		long *pcount = per_cpu_ptr(fbc->counters, cpu);
+#ifdef CONFIG_LBD
+		long long *pcount;
+#else
+		long *pcount;
+#endif
+		pcount = per_cpu_ptr(fbc->counters, cpu);
 		ret += *pcount;
 	}
 	spin_unlock(&fbc->lock);

Attachment: signature.asc
Description: Ceci est une partie de message =?ISO-8859-1?Q?num=E9riquement?= =?ISO-8859-1?Q?_sign=E9e=2E?=


[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux