aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/ref.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-01-13 01:06:28 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-01-13 01:06:28 -0500
commitf43dc23d5ea91fca257be02138a255f02d98e806 (patch)
treeb29722f6e965316e90ac97abf79923ced250dc21 /net/tipc/ref.c
parentf8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff)
parent4162cf64973df51fc885825bc9ca4d055891c49f (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework
Conflicts: arch/sh/kernel/cpu/sh2/setup-sh7619.c arch/sh/kernel/cpu/sh2a/setup-mxg.c arch/sh/kernel/cpu/sh2a/setup-sh7201.c arch/sh/kernel/cpu/sh2a/setup-sh7203.c arch/sh/kernel/cpu/sh2a/setup-sh7206.c arch/sh/kernel/cpu/sh3/setup-sh7705.c arch/sh/kernel/cpu/sh3/setup-sh770x.c arch/sh/kernel/cpu/sh3/setup-sh7710.c arch/sh/kernel/cpu/sh3/setup-sh7720.c arch/sh/kernel/cpu/sh4/setup-sh4-202.c arch/sh/kernel/cpu/sh4/setup-sh7750.c arch/sh/kernel/cpu/sh4/setup-sh7760.c arch/sh/kernel/cpu/sh4a/setup-sh7343.c arch/sh/kernel/cpu/sh4a/setup-sh7366.c arch/sh/kernel/cpu/sh4a/setup-sh7722.c arch/sh/kernel/cpu/sh4a/setup-sh7723.c arch/sh/kernel/cpu/sh4a/setup-sh7724.c arch/sh/kernel/cpu/sh4a/setup-sh7763.c arch/sh/kernel/cpu/sh4a/setup-sh7770.c arch/sh/kernel/cpu/sh4a/setup-sh7780.c arch/sh/kernel/cpu/sh4a/setup-sh7785.c arch/sh/kernel/cpu/sh4a/setup-sh7786.c arch/sh/kernel/cpu/sh4a/setup-shx3.c arch/sh/kernel/cpu/sh5/setup-sh5.c drivers/serial/sh-sci.c drivers/serial/sh-sci.h include/linux/serial_sci.h
Diffstat (limited to 'net/tipc/ref.c')
-rw-r--r--net/tipc/ref.c49
1 files changed, 18 insertions, 31 deletions
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 414fc34b8bea..83116892528b 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -89,7 +89,7 @@ struct ref_table {
89 * have a reference value of 0 (although this is unlikely). 89 * have a reference value of 0 (although this is unlikely).
90 */ 90 */
91 91
92static struct ref_table tipc_ref_table = { NULL }; 92static struct ref_table tipc_ref_table;
93 93
94static DEFINE_RWLOCK(ref_table_lock); 94static DEFINE_RWLOCK(ref_table_lock);
95 95
@@ -153,11 +153,11 @@ void tipc_ref_table_stop(void)
153 153
154u32 tipc_ref_acquire(void *object, spinlock_t **lock) 154u32 tipc_ref_acquire(void *object, spinlock_t **lock)
155{ 155{
156 struct reference *entry;
157 u32 index; 156 u32 index;
158 u32 index_mask; 157 u32 index_mask;
159 u32 next_plus_upper; 158 u32 next_plus_upper;
160 u32 ref; 159 u32 ref;
160 struct reference *entry = NULL;
161 161
162 if (!object) { 162 if (!object) {
163 err("Attempt to acquire reference to non-existent object\n"); 163 err("Attempt to acquire reference to non-existent object\n");
@@ -175,29 +175,33 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
175 index = tipc_ref_table.first_free; 175 index = tipc_ref_table.first_free;
176 entry = &(tipc_ref_table.entries[index]); 176 entry = &(tipc_ref_table.entries[index]);
177 index_mask = tipc_ref_table.index_mask; 177 index_mask = tipc_ref_table.index_mask;
178 /* take lock in case a previous user of entry still holds it */
179 spin_lock_bh(&entry->lock);
180 next_plus_upper = entry->ref; 178 next_plus_upper = entry->ref;
181 tipc_ref_table.first_free = next_plus_upper & index_mask; 179 tipc_ref_table.first_free = next_plus_upper & index_mask;
182 ref = (next_plus_upper & ~index_mask) + index; 180 ref = (next_plus_upper & ~index_mask) + index;
183 entry->ref = ref; 181 } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
184 entry->object = object;
185 *lock = &entry->lock;
186 }
187 else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
188 index = tipc_ref_table.init_point++; 182 index = tipc_ref_table.init_point++;
189 entry = &(tipc_ref_table.entries[index]); 183 entry = &(tipc_ref_table.entries[index]);
190 spin_lock_init(&entry->lock); 184 spin_lock_init(&entry->lock);
191 spin_lock_bh(&entry->lock);
192 ref = tipc_ref_table.start_mask + index; 185 ref = tipc_ref_table.start_mask + index;
186 } else {
187 ref = 0;
188 }
189 write_unlock_bh(&ref_table_lock);
190
191 /*
192 * Grab the lock so no one else can modify this entry
193 * While we assign its ref value & object pointer
194 */
195 if (entry) {
196 spin_lock_bh(&entry->lock);
193 entry->ref = ref; 197 entry->ref = ref;
194 entry->object = object; 198 entry->object = object;
195 *lock = &entry->lock; 199 *lock = &entry->lock;
200 /*
201 * keep it locked, the caller is responsible
202 * for unlocking this when they're done with it
203 */
196 } 204 }
197 else {
198 ref = 0;
199 }
200 write_unlock_bh(&ref_table_lock);
201 205
202 return ref; 206 return ref;
203} 207}
@@ -276,23 +280,6 @@ void *tipc_ref_lock(u32 ref)
276 return NULL; 280 return NULL;
277} 281}
278 282
279/**
280 * tipc_ref_unlock - unlock referenced object
281 */
282
283void tipc_ref_unlock(u32 ref)
284{
285 if (likely(tipc_ref_table.entries)) {
286 struct reference *entry;
287
288 entry = &tipc_ref_table.entries[ref &
289 tipc_ref_table.index_mask];
290 if (likely((entry->ref == ref) && (entry->object)))
291 spin_unlock_bh(&entry->lock);
292 else
293 err("Attempt to unlock non-existent reference\n");
294 }
295}
296 283
297/** 284/**
298 * tipc_ref_deref - return pointer referenced object (without locking it) 285 * tipc_ref_deref - return pointer referenced object (without locking it)