* [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero
@ 2005-09-12 14:51 Nick Piggin
2005-09-12 14:53 ` [PATCH 2/3][RFC] " Nick Piggin
2005-09-12 15:30 ` [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero Dipankar Sarma
0 siblings, 2 replies; 8+ messages in thread
From: Nick Piggin @ 2005-09-12 14:51 UTC (permalink / raw)
To: Dipankar Sarma, linux-arch, Andrew Morton, Linus Torvalds
[-- Attachment #1: Type: text/plain, Size: 992 bytes --]
Hi,
The recent file_table RCU work introduced a new rcuref.h thing,
which is just begging to be atomic.h. Basically it uses atomic_t,
digs into the atomic_t type, and also defines its own table of
spinlocks if the arch doesn't have cmpxchg() thus rendering it
unsafe for any other atomic_xxx operation to be performed on it.
Anyway, as it turns out, my lockless pagecache patches have the
exact same requirement, and so I am proposing to implement two
new atomic_ primitives that should be useful.
Only one is actually needed, atomic_inc_not_zero being the exact
fit for both, however I did atomic_cmpxchg first and it can stay
around because hopefully will be a generally useful primitive.
Now atomic_inc_not_zero is not really anything to do with RCU other
than an RCU protected refcounted structure being an obvious user to
take a reference on the read side where there is nothing to pin it.
1/3 is atomic_cmpxchg, not guaranteed to even compile on most.
--
SUSE Labs, Novell Inc.
[-- Attachment #2: atomic_cmpxchg.patch --]
[-- Type: text/plain, Size: 8240 bytes --]
Introduce an atomic_cmpxchg operation. Implement this for i386 and ppc64.
Signed-off-by: Nick Piggin <npiggin@suse.de>
Index: linux-2.6/include/asm-i386/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-i386/atomic.h
+++ linux-2.6/include/asm-i386/atomic.h
@@ -215,6 +215,8 @@ static __inline__ int atomic_sub_return(
return atomic_add_return(-i,v);
}
+#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+
#define atomic_inc_return(v) (atomic_add_return(1,v))
#define atomic_dec_return(v) (atomic_sub_return(1,v))
Index: linux-2.6/include/asm-ppc64/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-ppc64/atomic.h
+++ linux-2.6/include/asm-ppc64/atomic.h
@@ -162,6 +162,8 @@ static __inline__ int atomic_dec_return(
return t;
}
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0)
Index: linux-2.6/include/asm-ia64/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-ia64/atomic.h
+++ linux-2.6/include/asm-ia64/atomic.h
@@ -88,6 +88,8 @@ ia64_atomic64_sub (__s64 i, atomic64_t *
return new;
}
+#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+
#define atomic_add_return(i,v) \
({ \
int __ia64_aar_i = (i); \
Index: linux-2.6/include/asm-x86_64/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-x86_64/atomic.h
+++ linux-2.6/include/asm-x86_64/atomic.h
@@ -360,6 +360,8 @@ static __inline__ int atomic_sub_return(
return atomic_add_return(-i,v);
}
+#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+
#define atomic_inc_return(v) (atomic_add_return(1,v))
#define atomic_dec_return(v) (atomic_sub_return(1,v))
Index: linux-2.6/Documentation/atomic_ops.txt
===================================================================
--- linux-2.6.orig/Documentation/atomic_ops.txt
+++ linux-2.6/Documentation/atomic_ops.txt
@@ -115,6 +115,21 @@ boolean is return which indicates whethe
is negative. It requires explicit memory barrier semantics around the
operation.
+Finally:
+
+ int atomic_cmpxchg(atomic_t *v, int old, int new);
+
+This performs an atomic compare exchange operation on the atomic value v,
+with the given old and new values. Like all atomic_xxx operations,
+atomic_cmpxchg will only satisfy its atomicity semantics as long as all
+other accesses of *v are performed through atomic_xxx operations.
+
+atomic_cmpxchg requires explicit memory barriers around the operation.
+
+The semantics for atomic_cmpxchg are the same as those defined for 'cas'
+below.
+
+
If a caller requires memory barrier semantics around an atomic_t
operation which does not return a value, a set of interfaces are
defined which accomplish this:
Index: linux-2.6/arch/sparc/lib/atomic32.c
===================================================================
--- linux-2.6.orig/arch/sparc/lib/atomic32.c
+++ linux-2.6/arch/sparc/lib/atomic32.c
@@ -38,6 +38,20 @@ int __atomic_add_return(int i, atomic_t
return ret;
}
+int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ int ret;
+ unsigned long flags;
+ spin_lock_irqsave(ATOMIC_HASH(v), flags);
+
+ ret = v->counter;
+ if (likely(ret == old))
+ v->counter = new;
+
+ spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+ return ret;
+}
+
void atomic_set(atomic_t *v, int i)
{
unsigned long flags;
Index: linux-2.6/include/asm-sparc/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-sparc/atomic.h
+++ linux-2.6/include/asm-sparc/atomic.h
@@ -19,6 +19,7 @@ typedef struct { volatile int counter; }
#define ATOMIC_INIT(i) { (i) }
extern int __atomic_add_return(int, atomic_t *);
+extern int atomic_cmpxchg(atomic_t *, int, int);
extern void atomic_set(atomic_t *, int);
#define atomic_read(v) ((v)->counter)
Index: linux-2.6/include/asm-alpha/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-alpha/atomic.h
+++ linux-2.6/include/asm-alpha/atomic.h
@@ -171,6 +171,8 @@ static __inline__ long atomic64_sub_retu
return result;
}
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
#define atomic_dec_return(v) atomic_sub_return(1,(v))
#define atomic64_dec_return(v) atomic64_sub_return(1,(v))
Index: linux-2.6/include/asm-m68k/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-m68k/atomic.h
+++ linux-2.6/include/asm-m68k/atomic.h
@@ -139,6 +139,8 @@ static inline void atomic_set_mask(unsig
__asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask));
}
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
/* Atomic operations are already serializing */
#define smp_mb__before_atomic_dec() barrier()
#define smp_mb__after_atomic_dec() barrier()
Index: linux-2.6/include/asm-m68knommu/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-m68knommu/atomic.h
+++ linux-2.6/include/asm-m68knommu/atomic.h
@@ -128,6 +128,8 @@ extern __inline__ int atomic_sub_return(
return temp;
}
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
#define atomic_dec_return(v) atomic_sub_return(1,(v))
#define atomic_inc_return(v) atomic_add_return(1,(v))
Index: linux-2.6/include/asm-mips/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-mips/atomic.h
+++ linux-2.6/include/asm-mips/atomic.h
@@ -267,6 +267,8 @@ static __inline__ int atomic_sub_if_posi
return result;
}
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
#define atomic_dec_return(v) atomic_sub_return(1,(v))
#define atomic_inc_return(v) atomic_add_return(1,(v))
Index: linux-2.6/include/asm-parisc/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-parisc/atomic.h
+++ linux-2.6/include/asm-parisc/atomic.h
@@ -164,6 +164,7 @@ static __inline__ int atomic_read(const
}
/* exported interface */
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)i),(v))))
#define atomic_sub(i,v) ((void)(__atomic_add_return(-((int)i),(v))))
Index: linux-2.6/include/asm-ppc/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-ppc/atomic.h
+++ linux-2.6/include/asm-ppc/atomic.h
@@ -177,6 +177,8 @@ static __inline__ int atomic_dec_return(
return t;
}
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0)
Index: linux-2.6/include/asm-s390/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-s390/atomic.h
+++ linux-2.6/include/asm-s390/atomic.h
@@ -198,6 +198,8 @@ atomic_compare_and_swap(int expected_old
return retval;
}
+#define atomic_cmpxchg(v, o, n) (atomic_compare_and_swap((o), (n), &((v)->counter)))
+
#define smp_mb__before_atomic_dec() smp_mb()
#define smp_mb__after_atomic_dec() smp_mb()
#define smp_mb__before_atomic_inc() smp_mb()
Index: linux-2.6/include/asm-sparc64/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-sparc64/atomic.h
+++ linux-2.6/include/asm-sparc64/atomic.h
@@ -70,6 +70,8 @@ extern int atomic64_sub_ret(int, atomic6
#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
#define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
/* Atomic operations are already serializing */
#ifdef CONFIG_SMP
#define smp_mb__before_atomic_dec() membar_storeload_loadload();
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 2/3][RFC] atomic_cmpxchg, atomic_inc_not_zero
2005-09-12 14:51 [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero Nick Piggin
@ 2005-09-12 14:53 ` Nick Piggin
2005-09-12 14:55 ` [PATCH 3/3][RFC] remove rcuref.h Nick Piggin
2005-09-12 15:30 ` [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero Dipankar Sarma
1 sibling, 1 reply; 8+ messages in thread
From: Nick Piggin @ 2005-09-12 14:53 UTC (permalink / raw)
To: Dipankar Sarma, linux-arch, Andrew Morton, Linus Torvalds
[-- Attachment #1: Type: text/plain, Size: 384 bytes --]
2/3 is a sample atomic_inc_not_zero for ppc64 implemented with
atomic_cmpxchg. I couldn't be bothered to go through the motions
without a first round of comments...
Ideally, ppc64 will implement this with ll/sc instructions and
hopefully shave a cycle or so. But anyone who can implement
atomic_cmpxchg can implement atomic_inc_not_zero as demonstrated.
--
SUSE Labs, Novell Inc.
[-- Attachment #2: atomic_inc_not_zero.patch --]
[-- Type: text/plain, Size: 894 bytes --]
Index: linux-2.6/include/asm-ppc64/atomic.h
===================================================================
--- linux-2.6.orig/include/asm-ppc64/atomic.h
+++ linux-2.6/include/asm-ppc64/atomic.h
@@ -164,6 +164,23 @@ static __inline__ int atomic_dec_return(
#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+/**
+ * atomic_inc_not_zero - increment if not zero
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1, so long as it was not 0.
+ * Returns non-zero on successful increment and zero otherwise.
+ */
+#define atomic_inc_not_zero(v) \
+({ \
+ int c, old; \
+ c = atomic_read(v); \
+ while (c && (old = atomic_cmpxchg((v), c, c + 1)) != c) \
+ c = old; \
+ c; \
+})
+
+
#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0)
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 3/3][RFC] remove rcuref.h
2005-09-12 14:53 ` [PATCH 2/3][RFC] " Nick Piggin
@ 2005-09-12 14:55 ` Nick Piggin
2005-09-12 15:34 ` Dipankar Sarma
0 siblings, 1 reply; 8+ messages in thread
From: Nick Piggin @ 2005-09-12 14:55 UTC (permalink / raw)
To: Dipankar Sarma, linux-arch, Andrew Morton, Linus Torvalds
[-- Attachment #1: Type: text/plain, Size: 275 bytes --]
3/3
So this is something like how one would go about removing rcuref.h.
Now I'm not proposing this for inclusion just yet. Obviously it needs
to have the atomic_ primitives supported on all architectures and
be reviewed by Dipankar and lkml...
--
SUSE Labs, Novell Inc.
[-- Attachment #2: rcu-file-use-atomic-primitives.patch --]
[-- Type: text/plain, Size: 9563 bytes --]
Index: linux-2.6/include/linux/rcuref.h
===================================================================
--- linux-2.6.orig/include/linux/rcuref.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * rcuref.h
- *
- * Reference counting for elements of lists/arrays protected by
- * RCU.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2005
- *
- * Author: Dipankar Sarma <dipankar@in.ibm.com>
- * Ravikiran Thirumalai <kiran_th@gmail.com>
- *
- * See Documentation/RCU/rcuref.txt for detailed user guide.
- *
- */
-
-#ifndef _RCUREF_H_
-#define _RCUREF_H_
-
-#ifdef __KERNEL__
-
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-
-/*
- * These APIs work on traditional atomic_t counters used in the
- * kernel for reference counting. Under special circumstances
- * where a lock-free get() operation races with a put() operation
- * these APIs can be used. See Documentation/RCU/rcuref.txt.
- */
-
-#ifdef __HAVE_ARCH_CMPXCHG
-
-/**
- * rcuref_inc - increment refcount for object.
- * @rcuref: reference counter in the object in question.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference
- * in a lock-free reader-side critical section.
- */
-static inline void rcuref_inc(atomic_t *rcuref)
-{
- atomic_inc(rcuref);
-}
-
-/**
- * rcuref_dec - decrement refcount for object.
- * @rcuref: reference counter in the object in question.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference
- * in a lock-free reader-side critical section.
- */
-static inline void rcuref_dec(atomic_t *rcuref)
-{
- atomic_dec(rcuref);
-}
-
-/**
- * rcuref_dec_and_test - decrement refcount for object and test
- * @rcuref: reference counter in the object.
- * @release: pointer to the function that will clean up the object
- * when the last reference to the object is released.
- * This pointer is required.
- *
- * Decrement the refcount, and if 0, return 1. Else return 0.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference
- * in a lock-free reader-side critical section.
- */
-static inline int rcuref_dec_and_test(atomic_t *rcuref)
-{
- return atomic_dec_and_test(rcuref);
-}
-
-/*
- * cmpxchg is needed on UP too, if deletions to the list/array can happen
- * in interrupt context.
- */
-
-/**
- * rcuref_inc_lf - Take reference to an object in a read-side
- * critical section protected by RCU.
- * @rcuref: reference counter in the object in question.
- *
- * Try and increment the refcount by 1. The increment might fail if
- * the reference counter has been through a 1 to 0 transition and
- * is no longer part of the lock-free list.
- * Returns non-zero on successful increment and zero otherwise.
- */
-static inline int rcuref_inc_lf(atomic_t *rcuref)
-{
- int c, old;
- c = atomic_read(rcuref);
- while (c && (old = cmpxchg(&rcuref->counter, c, c + 1)) != c)
- c = old;
- return c;
-}
-
-#else /* !__HAVE_ARCH_CMPXCHG */
-
-extern spinlock_t __rcuref_hash[];
-
-/*
- * Use a hash table of locks to protect the reference count
- * since cmpxchg is not available in this arch.
- */
-#ifdef CONFIG_SMP
-#define RCUREF_HASH_SIZE 4
-#define RCUREF_HASH(k) \
- (&__rcuref_hash[(((unsigned long)k)>>8) & (RCUREF_HASH_SIZE-1)])
-#else
-#define RCUREF_HASH_SIZE 1
-#define RCUREF_HASH(k) &__rcuref_hash[0]
-#endif /* CONFIG_SMP */
-
-/**
- * rcuref_inc - increment refcount for object.
- * @rcuref: reference counter in the object in question.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference in a lock-free
- * reader-side critical section.
- */
-static inline void rcuref_inc(atomic_t *rcuref)
-{
- unsigned long flags;
- spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
- rcuref->counter += 1;
- spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
-}
-
-/**
- * rcuref_dec - decrement refcount for object.
- * @rcuref: reference counter in the object in question.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference in a lock-free
- * reader-side critical section.
- */
-static inline void rcuref_dec(atomic_t *rcuref)
-{
- unsigned long flags;
- spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
- rcuref->counter -= 1;
- spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
-}
-
-/**
- * rcuref_dec_and_test - decrement refcount for object and test
- * @rcuref: reference counter in the object.
- * @release: pointer to the function that will clean up the object
- * when the last reference to the object is released.
- * This pointer is required.
- *
- * Decrement the refcount, and if 0, return 1. Else return 0.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference in a lock-free
- * reader-side critical section.
- */
-static inline int rcuref_dec_and_test(atomic_t *rcuref)
-{
- unsigned long flags;
- spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
- rcuref->counter--;
- if (!rcuref->counter) {
- spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
- return 1;
- } else {
- spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
- return 0;
- }
-}
-
-/**
- * rcuref_inc_lf - Take reference to an object of a lock-free collection
- * by traversing a lock-free list/array.
- * @rcuref: reference counter in the object in question.
- *
- * Try and increment the refcount by 1. The increment might fail if
- * the reference counter has been through a 1 to 0 transition and
- * object is no longer part of the lock-free list.
- * Returns non-zero on successful increment and zero otherwise.
- */
-static inline int rcuref_inc_lf(atomic_t *rcuref)
-{
- int ret;
- unsigned long flags;
- spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
- if (rcuref->counter)
- ret = rcuref->counter++;
- else
- ret = 0;
- spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
- return ret;
-}
-
-
-#endif /* !__HAVE_ARCH_CMPXCHG */
-
-#endif /* __KERNEL__ */
-#endif /* _RCUREF_H_ */
Index: linux-2.6/fs/aio.c
===================================================================
--- linux-2.6.orig/fs/aio.c
+++ linux-2.6/fs/aio.c
@@ -29,7 +29,6 @@
#include <linux/highmem.h>
#include <linux/workqueue.h>
#include <linux/security.h>
-#include <linux/rcuref.h>
#include <asm/kmap_types.h>
#include <asm/uaccess.h>
@@ -500,7 +499,7 @@ static int __aio_put_req(struct kioctx *
/* Must be done under the lock to serialise against cancellation.
* Call this aio_fput as it duplicates fput via the fput_work.
*/
- if (unlikely(rcuref_dec_and_test(&req->ki_filp->f_count))) {
+ if (unlikely(atomic_dec_and_test(&req->ki_filp->f_count))) {
get_ioctx(ctx);
spin_lock(&fput_lock);
list_add(&req->ki_list, &fput_head);
Index: linux-2.6/fs/file_table.c
===================================================================
--- linux-2.6.orig/fs/file_table.c
+++ linux-2.6/fs/file_table.c
@@ -117,7 +117,7 @@ EXPORT_SYMBOL(get_empty_filp);
void fastcall fput(struct file *file)
{
- if (rcuref_dec_and_test(&file->f_count))
+ if (atomic_dec_and_test(&file->f_count))
__fput(file);
}
@@ -166,7 +166,7 @@ struct file fastcall *fget(unsigned int
rcu_read_lock();
file = fcheck_files(files, fd);
if (file) {
- if (!rcuref_inc_lf(&file->f_count)) {
+ if (!atomic_inc_not_zero(&file->f_count)) {
/* File object ref couldn't be taken */
rcu_read_unlock();
return NULL;
@@ -198,7 +198,7 @@ struct file fastcall *fget_light(unsigne
rcu_read_lock();
file = fcheck_files(files, fd);
if (file) {
- if (rcuref_inc_lf(&file->f_count))
+ if (atomic_inc_not_zero(&file->f_count))
*fput_needed = 1;
else
/* Didn't get the reference, someone's freed */
@@ -213,7 +213,7 @@ struct file fastcall *fget_light(unsigne
void put_filp(struct file *file)
{
- if (rcuref_dec_and_test(&file->f_count)) {
+ if (atomic_dec_and_test(&file->f_count)) {
security_file_free(file);
file_kill(file);
file_free(file);
Index: linux-2.6/include/linux/fs.h
===================================================================
--- linux-2.6.orig/include/linux/fs.h
+++ linux-2.6/include/linux/fs.h
@@ -9,7 +9,6 @@
#include <linux/config.h>
#include <linux/limits.h>
#include <linux/ioctl.h>
-#include <linux/rcuref.h>
/*
* It's silly to have NR_OPEN bigger than NR_FILE, but you can change
@@ -604,7 +603,7 @@ extern spinlock_t files_lock;
#define file_list_lock() spin_lock(&files_lock);
#define file_list_unlock() spin_unlock(&files_lock);
-#define get_file(x) rcuref_inc(&(x)->f_count)
+#define get_file(x) atomic_inc(&(x)->f_count)
#define file_count(x) atomic_read(&(x)->f_count)
#define MAX_NON_LFS ((1UL<<31) - 1)
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 3/3][RFC] remove rcuref.h
2005-09-12 14:55 ` [PATCH 3/3][RFC] remove rcuref.h Nick Piggin
@ 2005-09-12 15:34 ` Dipankar Sarma
0 siblings, 0 replies; 8+ messages in thread
From: Dipankar Sarma @ 2005-09-12 15:34 UTC (permalink / raw)
To: Nick Piggin; +Cc: linux-arch, Andrew Morton, Linus Torvalds
On Tue, Sep 13, 2005 at 12:55:38AM +1000, Nick Piggin wrote:
> 3/3
>
> So this is something like how one would go about removing rcuref.h.
>
> Now I'm not proposing this for inclusion just yet. Obviously it needs
> to have the atomic_ primitives supported on all architectures and
> be reviewed by Dipankar and lkml...
The idea looks good. Please publish the full patcheset and we can
work towards merging them.
Thanks
Dipankar
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero
2005-09-12 14:51 [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero Nick Piggin
2005-09-12 14:53 ` [PATCH 2/3][RFC] " Nick Piggin
@ 2005-09-12 15:30 ` Dipankar Sarma
2005-09-12 15:42 ` Nick Piggin
1 sibling, 1 reply; 8+ messages in thread
From: Dipankar Sarma @ 2005-09-12 15:30 UTC (permalink / raw)
To: Nick Piggin; +Cc: linux-arch, Andrew Morton, Linus Torvalds
On Tue, Sep 13, 2005 at 12:51:01AM +1000, Nick Piggin wrote:
> The recent file_table RCU work introduced a new rcuref.h thing,
> which is just begging to be atomic.h. Basically it uses atomic_t,
> digs into the atomic_t type, and also defines its own table of
> spinlocks if the arch doesn't have cmpxchg() thus rendering it
> unsafe for any other atomic_xxx operation to be performed on it.
The rcuref_xxx primitives were for only RCU protected refcounters
and I implemented all the primitives needed for them and use
of them was mandatory.
> Anyway, as it turns out, my lockless pagecache patches have the
> exact same requirement, and so I am proposing to implement two
> new atomic_ primitives that should be useful.
>
> Only one is actually needed, atomic_inc_not_zero being the exact
> fit for both, however I did atomic_cmpxchg first and it can stay
> around because hopefully will be a generally useful primitive.
>
> Now atomic_inc_not_zero is not really anything to do with RCU other
> than an RCU protected refcounted structure being an obvious user to
> take a reference on the read side where there is nothing to pin it.
>
> 1/3 is atomic_cmpxchg, not guaranteed to even compile on most.
This is sooo much better. I would much rather kill rcuref.h
and directly use atomic_inc_not_zero() when necessary.
Please feel free to churn out the whole implementation and I will
test it.
Thanks
Dipankar
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero
2005-09-12 15:30 ` [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero Dipankar Sarma
@ 2005-09-12 15:42 ` Nick Piggin
2005-09-12 16:11 ` Ralf Baechle
2005-09-12 20:46 ` David S. Miller
0 siblings, 2 replies; 8+ messages in thread
From: Nick Piggin @ 2005-09-12 15:42 UTC (permalink / raw)
To: dipankar; +Cc: linux-arch, Andrew Morton, Linus Torvalds
Dipankar Sarma wrote:
> On Tue, Sep 13, 2005 at 12:51:01AM +1000, Nick Piggin wrote:
>
>>The recent file_table RCU work introduced a new rcuref.h thing,
>>which is just begging to be atomic.h. Basically it uses atomic_t,
>>digs into the atomic_t type, and also defines its own table of
>>spinlocks if the arch doesn't have cmpxchg() thus rendering it
>>unsafe for any other atomic_xxx operation to be performed on it.
>
>
> The rcuref_xxx primitives were for only RCU protected refcounters
> and I implemented all the primitives needed for them and use
> of them was mandatory.
>
Oh yes, I realise that and I did not spot a bug in your implementation.
>
>>Anyway, as it turns out, my lockless pagecache patches have the
>>exact same requirement, and so I am proposing to implement two
>>new atomic_ primitives that should be useful.
>>
>>Only one is actually needed, atomic_inc_not_zero being the exact
>>fit for both, however I did atomic_cmpxchg first and it can stay
>>around because hopefully will be a generally useful primitive.
>>
>>Now atomic_inc_not_zero is not really anything to do with RCU other
>>than an RCU protected refcounted structure being an obvious user to
>>take a reference on the read side where there is nothing to pin it.
>>
>>1/3 is atomic_cmpxchg, not guaranteed to even compile on most.
>
>
> This is sooo much better. I would much rather kill rcuref.h
> and directly use atomic_inc_not_zero() when necessary.
> Please feel free to churn out the whole implementation and I will
> test it.
>
OK, once I run it past the arch maintainers I will post a new set to
lkml (and cc you). If you are feeling brave, the atomic_cmpxchg on
ppc64 is working with my lockless pagecache patches, but I simply
haven't tested 3/3.
Anyway, please, arch maintainers: speak now if there is something
really nasty about doing this on your arch. Otherwise, if you can
cook up optimised versions then please send them to me. If not, I'll
try to do the dumb implementations as best I can.
Thanks,
Nick
--
SUSE Labs, Novell Inc.
Send instant messages to your online friends http://au.messenger.yahoo.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero
2005-09-12 15:42 ` Nick Piggin
@ 2005-09-12 16:11 ` Ralf Baechle
2005-09-12 20:46 ` David S. Miller
1 sibling, 0 replies; 8+ messages in thread
From: Ralf Baechle @ 2005-09-12 16:11 UTC (permalink / raw)
To: Nick Piggin; +Cc: dipankar, linux-arch, Andrew Morton, Linus Torvalds
On Tue, Sep 13, 2005 at 01:42:15AM +1000, Nick Piggin wrote:
> OK, once I run it past the arch maintainers I will post a new set to
> lkml (and cc you). If you are feeling brave, the atomic_cmpxchg on
> ppc64 is working with my lockless pagecache patches, but I simply
> haven't tested 3/3.
>
> Anyway, please, arch maintainers: speak now if there is something
> really nasty about doing this on your arch. Otherwise, if you can
> cook up optimised versions then please send them to me. If not, I'll
> try to do the dumb implementations as best I can.
MIPS bits look ok.
Ralf
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero
2005-09-12 15:42 ` Nick Piggin
2005-09-12 16:11 ` Ralf Baechle
@ 2005-09-12 20:46 ` David S. Miller
1 sibling, 0 replies; 8+ messages in thread
From: David S. Miller @ 2005-09-12 20:46 UTC (permalink / raw)
To: nickpiggin; +Cc: dipankar, linux-arch, akpm, torvalds
From: Nick Piggin <nickpiggin@yahoo.com.au>
Date: Tue, 13 Sep 2005 01:42:15 +1000
> Anyway, please, arch maintainers: speak now if there is something
> really nasty about doing this on your arch. Otherwise, if you can
> cook up optimised versions then please send them to me. If not, I'll
> try to do the dumb implementations as best I can.
I'm fine with the Sparc bits.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2005-09-12 20:46 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-12 14:51 [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero Nick Piggin
2005-09-12 14:53 ` [PATCH 2/3][RFC] " Nick Piggin
2005-09-12 14:55 ` [PATCH 3/3][RFC] remove rcuref.h Nick Piggin
2005-09-12 15:34 ` Dipankar Sarma
2005-09-12 15:30 ` [PATCH 1/3][RFC] atomic_cmpxchg, atomic_inc_not_zero Dipankar Sarma
2005-09-12 15:42 ` Nick Piggin
2005-09-12 16:11 ` Ralf Baechle
2005-09-12 20:46 ` David S. Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox