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?=
- Follow-Ups:
- Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)
- From: Mingming Cao <[email protected]>
- Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)
- From: Ravikiran G Thirumalai <[email protected]>
- Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)
- References:
- Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)
- From: [email protected]
- Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)
- From: Mingming Cao <[email protected]>
- Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)
- From: Andrew Morton <[email protected]>
- Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)
- From: Ravikiran G Thirumalai <[email protected]>
- Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)
- Prev by Date: Re: 2.6.16-mm1 leaks in dvb playback
- Next by Date: Re: 2.6.16-mm1 leaks in dvb playback
- Previous by thread: Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)
- Next by thread: Re: [Ext2-devel] [PATCH 2/2] ext2/3: Support2^32-1blocks(e2fsprogs)
- Index(es):