Re: [PATCH] Breaking down the global IPC locks - 2.5.31

From: mingming cao (cmm@us.ibm.com)
Date: Tue Aug 20 2002 - 12:50:55 EST


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)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Aug 23 2002 - 22:00:20 EST