Messages in this thread Patch in this message | | | Date | Sat, 28 Aug 2004 15:19:18 +0200 | From | Andi Kleen <> | Subject | Re: page fault scalability patch final : i386 tested, x86_64 support added |
| |
On Fri, 27 Aug 2004 22:39:54 -0700 Andrew Morton <akpm@osdl.org> wrote:
> Christoph Lameter <clameter@sgi.com> wrote: > > > > On Fri, 27 Aug 2004, Andrew Morton wrote: > > > > > Christoph Lameter <clameter@sgi.com> wrote: > > > > > > > > So I think the move to atomic for rss acceptable? > > > > > > Short-term, yes. Longer term (within 12 months), no - 50-bit addresses on > > > power5 will cause it to overflow. > > > > I would expect the page size to rise as well. On IA64 we already have > > 16KB-64KB pages corresponding to 256TB - 1PB. Having to manage a couple of > > billion pages could be a significant performance impact. Better increase > > the page size. > > I don't know if that's an option on the power architecture.
On x86-64 it isn't an option.
> > And we need larger atomic types _anyway_ for page->_count. An unprivileged > app can mmap the same page 4G times and can then munmap it once. Do it on > purpose and it's a security hole. Due it by accident and it's a crash. > > > I still would also like to see atomic64_t. I think there was a patch > > posted to linux-ia64 a couple of months back introducing atomic64_t but it > > was rejected since it would not be supportable on other arches. > > atomic64_t already appears to be implemented on alpha, ia64, mips, s390 and > sparc64.
Here's a patch to add it to x86-64:
-Andi
-------------------------------------------------------------------------------------
Add atomic64_t type to x86-64
diff -u linux-2.6.8-work/include/asm-x86_64/atomic.h-o linux-2.6.8-work/include/asm-x86_64/atomic.h --- linux-2.6.8-work/include/asm-x86_64/atomic.h-o 2004-03-21 21:11:54.000000000 +0100 +++ linux-2.6.8-work/include/asm-x86_64/atomic.h 2004-08-28 15:15:46.000000000 +0200 @@ -178,6 +178,166 @@ return c; } +/* An 64bit atomic type */ + +typedef struct { volatile long counter; } atomic64_t; + +#define ATOMIC64_INIT(i) { (i) } + +/** + * atomic64_read - read atomic64 variable + * @v: pointer of type atomic64_t + * + * Atomically reads the value of @v. + * Doesn't imply a read memory barrier. + */ +#define atomic64_read(v) ((v)->counter) + +/** + * atomic64_set - set atomic64 variable + * @v: pointer to type atomic64_t + * @i: required value + * + * Atomically sets the value of @v to @i. + */ +#define atomic64_set(v,i) (((v)->counter) = (i)) + +/** + * atomic64_add - add integer to atomic64 variable + * @i: integer value to add + * @v: pointer to type atomic64_t + * + * Atomically adds @i to @v. + */ +static __inline__ void atomic64_add(long i, atomic64_t *v) +{ + __asm__ __volatile__( + LOCK "addq %1,%0" + :"=m" (v->counter) + :"ir" (i), "m" (v->counter)); +} + +/** + * atomic64_sub - subtract the atomic64 variable + * @i: integer value to subtract + * @v: pointer to type atomic64_t + * + * Atomically subtracts @i from @v. + */ +static __inline__ void atomic64_sub(long i, atomic64_t *v) +{ + __asm__ __volatile__( + LOCK "subq %1,%0" + :"=m" (v->counter) + :"ir" (i), "m" (v->counter)); +} + +/** + * atomic64_sub_and_test - subtract value from variable and test result + * @i: integer value to subtract + * @v: pointer to type atomic64_t + * + * Atomically subtracts @i from @v and returns + * true if the result is zero, or false for all + * other cases. + */ +static __inline__ int atomic64_sub_and_test(long i, atomic64_t *v) +{ + unsigned char c; + + __asm__ __volatile__( + LOCK "subq %2,%0; sete %1" + :"=m" (v->counter), "=qm" (c) + :"ir" (i), "m" (v->counter) : "memory"); + return c; +} + +/** + * atomic64_inc - increment atomic64 variable + * @v: pointer to type atomic64_t + * + * Atomically increments @v by 1. + */ +static __inline__ void atomic64_inc(atomic64_t *v) +{ + __asm__ __volatile__( + LOCK "incq %0" + :"=m" (v->counter) + :"m" (v->counter)); +} + +/** + * atomic64_dec - decrement atomic64 variable + * @v: pointer to type atomic64_t + * + * Atomically decrements @v by 1. + */ +static __inline__ void atomic64_dec(atomic64_t *v) +{ + __asm__ __volatile__( + LOCK "decq %0" + :"=m" (v->counter) + :"m" (v->counter)); +} + +/** + * atomic64_dec_and_test - decrement and test + * @v: pointer to type atomic64_t + * + * Atomically decrements @v by 1 and + * returns true if the result is 0, or false for all other + * cases. + */ +static __inline__ int atomic64_dec_and_test(atomic64_t *v) +{ + unsigned char c; + + __asm__ __volatile__( + LOCK "decq %0; sete %1" + :"=m" (v->counter), "=qm" (c) + :"m" (v->counter) : "memory"); + return c != 0; +} + +/** + * atomic64_inc_and_test - increment and test + * @v: pointer to type atomic64_t + * + * Atomically increments @v by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +static __inline__ int atomic64_inc_and_test(atomic64_t *v) +{ + unsigned char c; + + __asm__ __volatile__( + LOCK "incq %0; sete %1" + :"=m" (v->counter), "=qm" (c) + :"m" (v->counter) : "memory"); + return c != 0; +} + +/** + * atomic64_add_negative - add and test if negative + * @v: pointer to atomic64_t + * @i: integer value to add + * + * Atomically adds @i to @v and returns true + * if the result is negative, or false when + * result is greater than or equal to zero. + */ +static __inline__ long atomic64_add_negative(long i, atomic64_t *v) +{ + unsigned char c; + + __asm__ __volatile__( + LOCK "addq %2,%0; sets %1" + :"=m" (v->counter), "=qm" (c) + :"ir" (i), "m" (v->counter) : "memory"); + return c; +} + /* These are x86-specific, used by some header files */ #define atomic_clear_mask(mask, addr) \ __asm__ __volatile__(LOCK "andl %0,%1" \ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |