[SSI] openssi/kernel/ipc shm.c, 1.28, 1.29 util.c, 1.11, 1.12 util.h, 1.13, 1.14
Roger Tsang <[email protected]> Sun, 07 Mar 2010 05:40:16 +0000
| Newsgroups | gmane.linux.cluster.ssic.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ssic-linux/openssi/kernel/ipc
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv27621/kernel/ipc
Modified Files:
Tag: OPENSSI-FC
shm.c util.c util.h
Log Message:
IPC (#ifdef IPC_SHM_RACE_FIX):
- ipc_shm_nodedown() optimize away ipc_ids->sem lock; acquire lock only if we encounter unattached segments. Restore code to track ID of SHM segment with SHM_DEST_LOCK flag.
- Regression:
- vfsmount struct leak in ipc_shm_nodedown().
cluster/ssi/ipc/ipcshm_svr.c | 8 ++-
ipc/shm.c | 86 ++++++++++-------------------------
ipc/util.c | 14 +++++
ipc/util.h | 5 ++
4 files changed, 53 insertions(+), 60 deletions(-)
Index: util.h
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/ipc/util.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- util.h 5 Mar 2010 06:30:21 -0000 1.13
+++ util.h 7 Mar 2010 05:40:14 -0000 1.14
@@ -34,6 +34,11 @@
int max_id;
unsigned short seq;
unsigned short seq_max;
+#ifdef CONFIG_SSI
+#ifdef IPC_SHM_RACE_FIX
+ int lock_dest_id; /* id of entry holding sem for SHM_LOCK_DEST */
+#endif
+#endif
struct semaphore sem;
struct ipc_id_ary nullentry;
struct ipc_id_ary* entries;
Index: shm.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/ipc/shm.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- shm.c 5 Mar 2010 06:30:21 -0000 1.28
+++ shm.c 7 Mar 2010 05:40:14 -0000 1.29
@@ -1514,41 +1514,37 @@
void
ipc_shm_nodedown(clusternode_t node)
{
+#ifdef IPC_SHM_RACE_FIX
struct ipc_ids *ids = &shm_ids;
struct shmid_kernel *shp;
- int id;
-#ifdef IPC_SHM_RACE_FIX
struct vfsmount *mnt;
- int sem_held;
- int last_id, max_id;
- char retry, use_bitmap, shm_lock_dest;
- DECLARE_BITMAP(retry_bitmap, IPCMNI);
-
- bitmap_zero(retry_bitmap, IPCMNI);
- retry = use_bitmap = shm_lock_dest = 0;
-#endif
+ int id;
+ char sem_held = 0;
icssvr_nodedown_svc_wait(node, cluster_ipc_svc);
-#ifdef IPC_SHM_RACE_FIX
write_lock(&cfs_shm_node_mnts_lock);
- mnt = mntget(cfs_shm_node_mnts[node]);
+ mnt = cfs_shm_node_mnts[node];
cfs_shm_node_mnts[node] = NULL;
write_unlock(&cfs_shm_node_mnts_lock);
mntput(mnt);
- sem_held = !down_trylock(&ids->sem);
- max_id = sem_held ? ids->max_id : shm_ctlmni;
-
- SSI_ASSERT(max_id < IPCMNI);
- last_id = max_id;
-again:
- for (id = 0; id <= max_id; id++) {
- if (use_bitmap && !test_bit(id, retry_bitmap)) {
- id = find_next_bit(retry_bitmap, max_id+1, id+1);
- if (id > max_id)
- break;
+ /* Don't wait for shm_ids.sem since we may deadlock with
+ * a SHM segment with SHM_LOCK_DEST flag.
+ */
+ if (down_trylock(&ids->sem)) {
+ if ((id = ids->lock_dest_id) != -1) {
+ /* segment being destroyed by remote server */
+ shp = shm_lock(id);
+ if (shp && shp->shm_node == node &&
+ (shp->shm_flags & SHM_LOCK_DEST))
+ sem_held = 1;
+ shm_unlock(shp);
}
+ } else
+ sem_held = 1;
+
+ for (id = 0; id <= ids->max_id; id++) {
shp = shm_lock(id);
if (!shp)
continue;
@@ -1561,25 +1557,10 @@
shm_unlock(shp);
continue;
}
- if (!sem_held) {
- /* SSI_XXX: Could be faster if we tracked the ID */
- if (shp->shm_flags & SHM_LOCK_DEST) {
- if (last_id > id)
- last_id = id;
- shm_lock_dest = 1;
- sem_held = 1;
- } else
- sem_held = !down_trylock(&ids->sem);
- }
if (shp->shm_nattch == 0) {
if (!sem_held) {
- if (!(shp->shm_flags & SHM_DEST))
- shp->shm_flags |= SHM_DEST;
- shm_unlock(shp);
- __set_bit(id, retry_bitmap);
- if (!retry)
- retry = 1;
- continue; /* looking for SHM_LOCK_DEST */
+ down(&ids->sem);
+ sem_held = 1;
}
SSI_ASSERT(shp->id == id);
ssi_local_destroy(shp);
@@ -1590,28 +1571,15 @@
shm_unlock(shp);
}
}
- if (retry) {
- retry = 0;
- if (shm_lock_dest) {
- /* SHM_LOCK_DEST flag encountered.
- * ids->sem was held the whole time
- * so our retry_bitmap is accurate.
- */
- SSI_ASSERT(sem_held);
- if (last_id == 0)
- goto out;
- max_id = last_id - 1;
- use_bitmap = 1;
- } else if (!sem_held) {
- down(&ids->sem);
- sem_held = 1;
- }
- goto again;
- }
-out:
if (sem_held)
up(&ids->sem);
#else /* IPC_SHM_RACE_FIX */
+ struct ipc_ids *ids = &shm_ids;
+ struct shmid_kernel *shp;
+ int id;
+
+ icssvr_nodedown_svc_wait(node, cluster_ipc_svc);
+
for (id = 0; id <= ids->max_id; id++) {
if(ids->entries->p[id] == NULL)
continue;
Index: util.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/ipc/util.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- util.c 5 Mar 2010 06:30:21 -0000 1.11
+++ util.c 7 Mar 2010 05:40:14 -0000 1.12
@@ -75,6 +75,11 @@
else
ids->seq_max = seq_limit;
}
+#ifdef CONFIG_SSI
+#ifdef IPC_SHM_RACE_FIX
+ ids->lock_dest_id = -1;
+#endif
+#endif
ids->entries = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*size +
sizeof(struct ipc_id_ary));
@@ -229,6 +234,15 @@
if (table)
up(&ids->sem);
}
+
+#ifdef IPC_SHM_RACE_FIX
+/* Called with ids.sem held */
+void
+ipc_set_lock_dest(struct ipc_ids *ids, int id)
+{
+ ids->lock_dest_id = id; /* entry with SHM_LOCK_DEST flag */
+}
+#endif
#endif /* CONFIG_SSI */
/**
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev