Messages in this thread Patch in this message | | | Date | Tue, 20 Aug 2002 10:50:55 -0700 | From | mingming cao <> | Subject | Re: [PATCH] Breaking down the global IPC locks - 2.5.31 |
| |
mingming cao wrote: > > This patch breaks the three global IPC locks into one lock per IPC ID. > By doing so it could reduce possible lock contention in workloads which > make heavy use of IPC semaphores, message queues and Shared > memories...etc.
Here is the patch again. Fixed a typo. *_^diff -urN -X ../dontdiff ../base/linux-2.5.31/include/linux/ipc.h 2.5.31-ipc/include/linux/ipc.h --- ../base/linux-2.5.31/include/linux/ipc.h Sat Aug 10 18:41:16 2002 +++ 2.5.31-ipc/include/linux/ipc.h Tue Aug 13 10:23:59 2002 @@ -56,6 +56,7 @@ /* used by in-kernel data structures */ struct kern_ipc_perm { + spinlock_t lock; key_t key; uid_t uid; gid_t gid; diff -urN -X ../dontdiff ../base/linux-2.5.31/ipc/util.c 2.5.31-ipc/ipc/util.c --- ../base/linux-2.5.31/ipc/util.c Sat Aug 10 18:41:27 2002 +++ 2.5.31-ipc/ipc/util.c Wed Aug 14 15:59:19 2002 @@ -74,7 +74,7 @@ printk(KERN_ERR "ipc_init_ids() failed, ipc service disabled.\n"); ids->size = 0; } - ids->ary = SPIN_LOCK_UNLOCKED; + ids->ary =RW_LOCK_UNLOCKED; for(i=0;i<ids->size;i++) ids->entries[i].p = NULL; } @@ -120,13 +120,13 @@ for(i=ids->size;i<newsize;i++) { new[i].p = NULL; } - spin_lock(&ids->ary); + write_lock(&ids->ary); old = ids->entries; ids->entries = new; i = ids->size; ids->size = newsize; - spin_unlock(&ids->ary); + write_unlock(&ids->ary); ipc_free(old, sizeof(struct ipc_id)*i); return ids->size; } @@ -165,7 +165,9 @@ if(ids->seq > ids->seq_max) ids->seq = 0; - spin_lock(&ids->ary); + new->lock = SPIN_LOCK_UNLOCKED; + read_lock(&ids->ary); + spin_lock(&new->lock); ids->entries[id].p = new; return id; } diff -urN -X ../dontdiff ../base/linux-2.5.31/ipc/util.h 2.5.31-ipc/ipc/util.h --- ../base/linux-2.5.31/ipc/util.h Sat Aug 10 18:41:40 2002 +++ 2.5.31-ipc/ipc/util.h Wed Aug 14 17:05:22 2002 @@ -19,7 +19,7 @@ unsigned short seq; unsigned short seq_max; struct semaphore sem; - spinlock_t ary; + rwlock_t ary; struct ipc_id* entries; }; @@ -47,7 +47,7 @@ extern inline void ipc_lockall(struct ipc_ids* ids) { - spin_lock(&ids->ary); + write_lock(&ids->ary); } extern inline struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id) @@ -63,7 +63,7 @@ extern inline void ipc_unlockall(struct ipc_ids* ids) { - spin_unlock(&ids->ary); + write_unlock(&ids->ary); } extern inline struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id) { @@ -72,16 +72,29 @@ if(lid >= ids->size) return NULL; - spin_lock(&ids->ary); + read_lock(&ids->ary); out = ids->entries[lid].p; - if(out==NULL) - spin_unlock(&ids->ary); + if(out==NULL) { + read_unlock(&ids->ary); + return NULL; + } + spin_lock(&out->lock); return out; } extern inline void ipc_unlock(struct ipc_ids* ids, int id) { - spin_unlock(&ids->ary); + int lid = id % SEQ_MULTIPLIER; + struct kern_ipc_perm* out; + + if(lid >= ids->size) + return; + out = ids->entries[lid].p; + if (out == NULL) + return; + + spin_unlock(&out->lock); + read_unlock(&ids->ary); } extern inline int ipc_buildid(struct ipc_ids* ids, int id, int seq) | |