summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2006-03-24 03:15:47 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-24 07:33:20 -0800
commit36f574135e36b86bb6ae794bf1d0fce3efa5601f (patch)
tree9dd55b2244d2ac9f7e05098e7236aa8cf6cd6d60 /kernel
parent3cf64b933c90ba701cfdc7188431104c646d7c9e (diff)
downloadlwn-36f574135e36b86bb6ae794bf1d0fce3efa5601f.tar.gz
lwn-36f574135e36b86bb6ae794bf1d0fce3efa5601f.zip
[PATCH] free_uid() locking improvement
Reduce lock hold times in free_uid(). Cc: Ingo Molnar <mingo@elte.hu> Cc: "Paul E. McKenney" <paulmck@us.ibm.com> Cc: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/user.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/kernel/user.c b/kernel/user.c
index d9deae43a9ab..2116642f42c6 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -105,15 +105,19 @@ void free_uid(struct user_struct *up)
{
unsigned long flags;
+ if (!up)
+ return;
+
local_irq_save(flags);
- if (up && atomic_dec_and_lock(&up->__count, &uidhash_lock)) {
+ if (atomic_dec_and_lock(&up->__count, &uidhash_lock)) {
uid_hash_remove(up);
+ spin_unlock_irqrestore(&uidhash_lock, flags);
key_put(up->uid_keyring);
key_put(up->session_keyring);
kmem_cache_free(uid_cachep, up);
- spin_unlock(&uidhash_lock);
+ } else {
+ local_irq_restore(flags);
}
- local_irq_restore(flags);
}
struct user_struct * alloc_uid(uid_t uid)