forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a set of primitives to do reference counting for objects that are looked up without locks using RCU. Signed-off-by: Ravikiran Thirumalai <[email protected]> Signed-off-by: Dipankar Sarma <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
- v4.15
- v4.15-rc9
- v4.15-rc8
- v4.15-rc7
- v4.15-rc6
- v4.15-rc5
- v4.15-rc4
- v4.15-rc3
- v4.15-rc2
- v4.15-rc1
- v4.14
- v4.14-rc8
- v4.14-rc7
- v4.14-rc6
- v4.14-rc5
- v4.14-rc4
- v4.14-rc3
- v4.14-rc2
- v4.14-rc1
- v4.13
- v4.13-rc7
- v4.13-rc6
- v4.13-rc5
- v4.13-rc4
- v4.13-rc3
- v4.13-rc2
- v4.13-rc1
- v4.12
- v4.12-rc7
- v4.12-rc6
- v4.12-rc5
- v4.12-rc4
- v4.12-rc3
- v4.12-rc2
- v4.12-rc1
- v4.11
- v4.11-rc8
- v4.11-rc7
- v4.11-rc6
- v4.11-rc5
- v4.11-rc4
- v4.11-rc3
- v4.11-rc2
- v4.11-rc1
- v4.10
- v4.10-rc8
- v4.10-rc7
- v4.10-rc6
- v4.10-rc5
- v4.10-rc4
- v4.10-rc3
- v4.10-rc2
- v4.10-rc1
- v4.9
- v4.9-rc8
- v4.9-rc7
- v4.9-rc6
- v4.9-rc5
- v4.9-rc4
- v4.9-rc3
- v4.9-rc2
- v4.9-rc1
- v4.8
- v4.8-rc8
- v4.8-rc7
- v4.8-rc6
- v4.8-rc5
- v4.8-rc4
- v4.8-rc3
- v4.8-rc2
- v4.8-rc1
- v4.7
- v4.7-rc7
- v4.7-rc6
- v4.7-rc5
- v4.7-rc4
- v4.7-rc3
- v4.7-rc2
- v4.7-rc1
- v4.6
- v4.6-rc7
- v4.6-rc6
- v4.6-rc5
- v4.6-rc4
- v4.6-rc3
- v4.6-rc2
- v4.6-rc1
- v4.5
- v4.5-rc7
- v4.5-rc6
- v4.5-rc5
- v4.5-rc4
- v4.5-rc3
- v4.5-rc2
- v4.5-rc1
- v4.4
- v4.4-rc8
- v4.4-rc7
- v4.4-rc6
- v4.4-rc5
- v4.4-rc4
- v4.4-rc3
- v4.4-rc2
- v4.4-rc1
- v4.3
- v4.3-rc7
- v4.3-rc6
- v4.3-rc5
- v4.3-rc4
- v4.3-rc3
- v4.3-rc2
- v4.3-rc1
- v4.2
- v4.2-rc8
- v4.2-rc7
- v4.2-rc6
- v4.2-rc5
- v4.2-rc4
- v4.2-rc3
- v4.2-rc2
- v4.2-rc1
- v4.1
- v4.1-rc8
- v4.1-rc7
- v4.1-rc6
- v4.1-rc5
- v4.1-rc4
- v4.1-rc3
- v4.1-rc2
- v4.1-rc1
- v4.0
- v4.0-rc7
- v4.0-rc6
- v4.0-rc5
- v4.0-rc4
- v4.0-rc3
- v4.0-rc2
- v4.0-rc1
- v3.19
- v3.19-rc7
- v3.19-rc6
- v3.19-rc5
- v3.19-rc4
- v3.19-rc3
- v3.19-rc2
- v3.19-rc1
- v3.18
- v3.18-rc7
- v3.18-rc6
- v3.18-rc5
- v3.18-rc4
- v3.18-rc3
- v3.18-rc2
- v3.18-rc1
- v3.17
- v3.17-rc7
- v3.17-rc6
- v3.17-rc5
- v3.17-rc4
- v3.17-rc3
- v3.17-rc2
- v3.17-rc1
- v3.16
- v3.16-rc7
- v3.16-rc6
- v3.16-rc5
- v3.16-rc4
- v3.16-rc3
- v3.16-rc2
- v3.16-rc1
- v3.15
- v3.15-rc8
- v3.15-rc7
- v3.15-rc6
- v3.15-rc5
- v3.15-rc4
- v3.15-rc3
- v3.15-rc2
- v3.15-rc1
- v3.14
- v3.14-rc8
- v3.14-rc7
- v3.14-rc6
- v3.14-rc5
- v3.14-rc4
- v3.14-rc3
- v3.14-rc2
- v3.14-rc1
- v3.13
- v3.13-rc8
- v3.13-rc7
- v3.13-rc6
- v3.13-rc5
- v3.13-rc4
- v3.13-rc3
- v3.13-rc2
- v3.13-rc1
- v3.12
- v3.12-rc7
- v3.12-rc6
- v3.12-rc5
- v3.12-rc4
- v3.12-rc3
- v3.12-rc2
- v3.12-rc1
- v3.11
- v3.11-rc7
- v3.11-rc6
- v3.11-rc5
- v3.11-rc4
- v3.11-rc3
- v3.11-rc2
- v3.11-rc1
- v3.10
- v3.10-rc7
- v3.10-rc6
- v3.10-rc5
- v3.10-rc4
- v3.10-rc3
- v3.10-rc2
- v3.10-rc1
- v3.9
- v3.9-rc8
- v3.9-rc7
- v3.9-rc6
- v3.9-rc5
- v3.9-rc4
- v3.9-rc3
- v3.9-rc2
- v3.9-rc1
- v3.8
- v3.8-rc7
- v3.8-rc6
- v3.8-rc5
- v3.8-rc4
- v3.8-rc3
- v3.8-rc2
- v3.8-rc1
- v3.7
- v3.7-rc8
- v3.7-rc7
- v3.7-rc6
- v3.7-rc5
- v3.7-rc4
- v3.7-rc3
- v3.7-rc2
- v3.7-rc1
- v3.6
- v3.6-rc7
- v3.6-rc6
- v3.6-rc5
- v3.6-rc4
- v3.6-rc3
- v3.6-rc2
- v3.6-rc1
- v3.5
- v3.5-rc7
- v3.5-rc6
- v3.5-rc5
- v3.5-rc4
- v3.5-rc3
- v3.5-rc2
- v3.5-rc1
- v3.4
- v3.4-rc7
- v3.4-rc6
- v3.4-rc5
- v3.4-rc4
- v3.4-rc3
- v3.4-rc2
- v3.4-rc1
- v3.3
- v3.3-rc7
- v3.3-rc6
- v3.3-rc5
- v3.3-rc4
- v3.3-rc3
- v3.3-rc2
- v3.3-rc1
- v3.2
- v3.2-rc7
- v3.2-rc6
- v3.2-rc5
- v3.2-rc4
- v3.2-rc3
- v3.2-rc2
- v3.2-rc1
- v3.1
- v3.1-rc10
- v3.1-rc9
- v3.1-rc8
- v3.1-rc7
- v3.1-rc6
- v3.1-rc5
- v3.1-rc4
- v3.1-rc3
- v3.1-rc2
- v3.1-rc1
- v3.0
- v3.0-rc7
- v3.0-rc6
- v3.0-rc5
- v3.0-rc4
- v3.0-rc3
- v3.0-rc2
- v3.0-rc1
- v2.6.39
- v2.6.39-rc7
- v2.6.39-rc6
- v2.6.39-rc5
- v2.6.39-rc4
- v2.6.39-rc3
- v2.6.39-rc2
- v2.6.39-rc1
- v2.6.38
- v2.6.38-rc8
- v2.6.38-rc7
- v2.6.38-rc6
- v2.6.38-rc5
- v2.6.38-rc4
- v2.6.38-rc3
- v2.6.38-rc2
- v2.6.38-rc1
- v2.6.37
- v2.6.37-rc8
- v2.6.37-rc7
- v2.6.37-rc6
- v2.6.37-rc5
- v2.6.37-rc4
- v2.6.37-rc3
- v2.6.37-rc2
- v2.6.37-rc1
- v2.6.36
- v2.6.36-rc8
- v2.6.36-rc7
- v2.6.36-rc6
- v2.6.36-rc5
- v2.6.36-rc4
- v2.6.36-rc3
- v2.6.36-rc2
- v2.6.36-rc1
- v2.6.35
- v2.6.35-rc6
- v2.6.35-rc5
- v2.6.35-rc4
- v2.6.35-rc3
- v2.6.35-rc2
- v2.6.35-rc1
- v2.6.34
- v2.6.34-rc7
- v2.6.34-rc6
- v2.6.34-rc5
- v2.6.34-rc4
- v2.6.34-rc3
- v2.6.34-rc2
- v2.6.34-rc1
- v2.6.33
- v2.6.33-rc8
- v2.6.33-rc7
- v2.6.33-rc6
- v2.6.33-rc5
- v2.6.33-rc4
- v2.6.33-rc3
- v2.6.33-rc2
- v2.6.33-rc1
- v2.6.32
- v2.6.32-rc8
- v2.6.32-rc7
- v2.6.32-rc6
- v2.6.32-rc5
- v2.6.32-rc4
- v2.6.32-rc3
- v2.6.32-rc2
- v2.6.32-rc1
- v2.6.31
- v2.6.31-rc9
- v2.6.31-rc8
- v2.6.31-rc7
- v2.6.31-rc6
- v2.6.31-rc5
- v2.6.31-rc4
- v2.6.31-rc3
- v2.6.31-rc2
- v2.6.31-rc1
- v2.6.30
- v2.6.30-rc8
- v2.6.30-rc7
- v2.6.30-rc6
- v2.6.30-rc5
- v2.6.30-rc4
- v2.6.30-rc3
- v2.6.30-rc2
- v2.6.30-rc1
- v2.6.29
- v2.6.29-rc8
- v2.6.29-rc7
- v2.6.29-rc6
- v2.6.29-rc5
- v2.6.29-rc4
- v2.6.29-rc3
- v2.6.29-rc2
- v2.6.29-rc1
- v2.6.28
- v2.6.28-rc9
- v2.6.28-rc8
- v2.6.28-rc7
- v2.6.28-rc6
- v2.6.28-rc5
- v2.6.28-rc4
- v2.6.28-rc3
- v2.6.28-rc2
- v2.6.28-rc1
- v2.6.27
- v2.6.27-rc9
- v2.6.27-rc8
- v2.6.27-rc7
- v2.6.27-rc6
- v2.6.27-rc5
- v2.6.27-rc4
- v2.6.27-rc3
- v2.6.27-rc2
- v2.6.27-rc1
- v2.6.26
- v2.6.26-rc9
- v2.6.26-rc8
- v2.6.26-rc7
- v2.6.26-rc6
- v2.6.26-rc5
- v2.6.26-rc4
- v2.6.26-rc3
- v2.6.26-rc2
- v2.6.26-rc1
- v2.6.25
- v2.6.25-rc9
- v2.6.25-rc8
- v2.6.25-rc7
- v2.6.25-rc6
- v2.6.25-rc5
- v2.6.25-rc4
- v2.6.25-rc3
- v2.6.25-rc2
- v2.6.25-rc1
- v2.6.24
- v2.6.24-rc8
- v2.6.24-rc7
- v2.6.24-rc6
- v2.6.24-rc5
- v2.6.24-rc4
- v2.6.24-rc3
- v2.6.24-rc2
- v2.6.24-rc1
- v2.6.23
- v2.6.23-rc9
- v2.6.23-rc8
- v2.6.23-rc7
- v2.6.23-rc6
- v2.6.23-rc5
- v2.6.23-rc4
- v2.6.23-rc3
- v2.6.23-rc2
- v2.6.23-rc1
- v2.6.22
- v2.6.22-rc7
- v2.6.22-rc6
- v2.6.22-rc5
- v2.6.22-rc4
- v2.6.22-rc3
- v2.6.22-rc2
- v2.6.22-rc1
- v2.6.21
- v2.6.21-rc7
- v2.6.21-rc6
- v2.6.21-rc5
- v2.6.21-rc4
- v2.6.21-rc3
- v2.6.21-rc2
- v2.6.21-rc1
- v2.6.20
- v2.6.20-rc7
- v2.6.20-rc6
- v2.6.20-rc5
- v2.6.20-rc4
- v2.6.20-rc3
- v2.6.20-rc2
- v2.6.20-rc1
- v2.6.19
- v2.6.19-rc6
- v2.6.19-rc5
- v2.6.19-rc4
- v2.6.19-rc3
- v2.6.19-rc2
- v2.6.19-rc1
- v2.6.18
- v2.6.18-rc7
- v2.6.18-rc6
- v2.6.18-rc5
- v2.6.18-rc4
- v2.6.18-rc3
- v2.6.18-rc2
- v2.6.18-rc1
- v2.6.17
- v2.6.17-rc6
- v2.6.17-rc5
- v2.6.17-rc4
- v2.6.17-rc3
- v2.6.17-rc2
- v2.6.17-rc1
- v2.6.16
- v2.6.16-rc6
- v2.6.16-rc5
- v2.6.16-rc4
- v2.6.16-rc3
- v2.6.16-rc2
- v2.6.16-rc1
- v2.6.15
- v2.6.15-rc7
- v2.6.15-rc6
- v2.6.15-rc5
- v2.6.15-rc4
- v2.6.15-rc3
- v2.6.15-rc2
- v2.6.15-rc1
- v2.6.14
- v2.6.14-rc5
- v2.6.14-rc4
- v2.6.14-rc3
- v2.6.14-rc2
- v2.6.14-rc1
1 parent
8b6490e
commit c0dfb29
Showing
3 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
Refcounter framework for elements of lists/arrays protected by | ||
RCU. | ||
|
||
Refcounting on elements of lists which are protected by traditional | ||
reader/writer spinlocks or semaphores are straight forward as in: | ||
|
||
1. 2. | ||
add() search_and_reference() | ||
{ { | ||
alloc_object read_lock(&list_lock); | ||
... search_for_element | ||
atomic_set(&el->rc, 1); atomic_inc(&el->rc); | ||
write_lock(&list_lock); ... | ||
add_element read_unlock(&list_lock); | ||
... ... | ||
write_unlock(&list_lock); } | ||
} | ||
|
||
3. 4. | ||
release_referenced() delete() | ||
{ { | ||
... write_lock(&list_lock); | ||
atomic_dec(&el->rc, relfunc) ... | ||
... delete_element | ||
} write_unlock(&list_lock); | ||
... | ||
if (atomic_dec_and_test(&el->rc)) | ||
kfree(el); | ||
... | ||
} | ||
|
||
If this list/array is made lock free using rcu as in changing the | ||
write_lock in add() and delete() to spin_lock and changing read_lock | ||
in search_and_reference to rcu_read_lock(), the rcuref_get in | ||
search_and_reference could potentially hold reference to an element which | ||
has already been deleted from the list/array. rcuref_lf_get_rcu takes | ||
care of this scenario. search_and_reference should look as; | ||
|
||
1. 2. | ||
add() search_and_reference() | ||
{ { | ||
alloc_object rcu_read_lock(); | ||
... search_for_element | ||
atomic_set(&el->rc, 1); if (rcuref_inc_lf(&el->rc)) { | ||
write_lock(&list_lock); rcu_read_unlock(); | ||
return FAIL; | ||
add_element } | ||
... ... | ||
write_unlock(&list_lock); rcu_read_unlock(); | ||
} } | ||
3. 4. | ||
release_referenced() delete() | ||
{ { | ||
... write_lock(&list_lock); | ||
rcuref_dec(&el->rc, relfunc) ... | ||
... delete_element | ||
} write_unlock(&list_lock); | ||
... | ||
if (rcuref_dec_and_test(&el->rc)) | ||
call_rcu(&el->head, el_free); | ||
... | ||
} | ||
|
||
Sometimes, reference to the element need to be obtained in the | ||
update (write) stream. In such cases, rcuref_inc_lf might be an overkill | ||
since the spinlock serialising list updates are held. rcuref_inc | ||
is to be used in such cases. | ||
For arches which do not have cmpxchg rcuref_inc_lf | ||
api uses a hashed spinlock implementation and the same hashed spinlock | ||
is acquired in all rcuref_xxx primitives to preserve atomicity. | ||
Note: Use rcuref_inc api only if you need to use rcuref_inc_lf on the | ||
refcounter atleast at one place. Mixing rcuref_inc and atomic_xxx api | ||
might lead to races. rcuref_inc_lf() must be used in lockfree | ||
RCU critical sections only. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
/* | ||
* 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 <[email protected]> | ||
* Ravikiran Thirumalai <[email protected]> | ||
* | ||
* 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_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters