[SSI] openssi/kernel/cluster/ssi/ipc ipcmsg_svr.c, 1.7, 1.8 ipcsem_svr.c, 1.7, 1.8 ipcshm_svr.c, 1.17, 1.18 namesvr_clnt.c, 1.7, 1.8 namesvr_func.c, 1.16, 1.17 namesvr_svr.c, 1.6, 1.7 rmtunix.c, 1.27, 1.28 unixnm.c, 1.15, 1.16

Roger Tsang <[email protected]>
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/ipc
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv16224/kernel/cluster/ssi/ipc

Modified Files:
      Tag: OPENSSI-FC
	ipcmsg_svr.c ipcsem_svr.c ipcshm_svr.c namesvr_clnt.c 
	namesvr_func.c namesvr_svr.c rmtunix.c unixnm.c 
Log Message:
Bug fixes and enhancements. See ChangeLog.


Index: ipcmsg_svr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/ipc/ipcmsg_svr.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- ipcmsg_svr.c	13 Feb 2005 07:53:20 -0000	1.7
+++ ipcmsg_svr.c	27 Oct 2009 03:18:29 -0000	1.8
@@ -102,7 +102,7 @@
 	status = RIPC_MSG_GET_MSG_QUEUE(node_num, &rval, msgid, &pstate, msq, &len);
 	if (!status)
 		status = rval;
-	return rval;
+	return status;
 }
 
 int
@@ -178,11 +178,11 @@
 				GFP_KERNEL);
 		if (segs == NULL) {
 			*rval = -ENOMEM;
-			temp = msgp->next;
-			while (temp != NULL) {
-				segs = temp;
+			segs = msgp->next;
+			while (segs != NULL) {
 				temp = segs->next;
 				kfree(segs);
+				segs = temp;
 			}
 			return *rval;
 		}

Index: ipcsem_svr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/ipc/ipcsem_svr.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- ipcsem_svr.c	13 Feb 2005 07:53:20 -0000	1.7
+++ ipcsem_svr.c	27 Oct 2009 03:18:29 -0000	1.8
@@ -91,7 +91,7 @@
 	status = RIPC_SEM_GET_SEM_ARRAY(node_num, &rval, semid, &pstate, sema, &len);
 	if (!status)
 		status = rval;
-	return rval;
+	return status;
 }
 
 int

Index: namesvr_func.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/ipc/namesvr_func.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- namesvr_func.c	28 Mar 2009 23:44:16 -0000	1.16
+++ namesvr_func.c	27 Oct 2009 03:18:29 -0000	1.17
@@ -406,14 +406,10 @@
 {
 	ipc_perm_t *perm;
 
-	/* need to alloc a kern_ipc_perm structure */
-	perm = kzmalloc(sizeof(*perm), GFP_KERNEL);
-	if (perm < 0) {
-		*ipcpp = NULL;
-	} else {
+	/* alloc a kern_ipc_perm structure */
+	*ipcpp = perm = kzmalloc(sizeof(*perm), GFP_KERNEL);
+	if (perm)
 		spin_lock_init(&perm->lock);
-		*ipcpp = perm;
-	}
 }
 
 
@@ -644,22 +640,22 @@
 	ipc_obj_db_t *odbp;
 	int error;
 
-	odbp = &nsc_name_odb[service];
-	NSC_IPC_WRLOCK(odbp);
-
-	error = nsc_ipcremove(odbp, glid);
-
-	NSC_IPC_WRUNLOCK(odbp);
 	switch(service) {
 		case NAME_SERVICE_SHM:
 		case NAME_SERVICE_MSG:
 		case NAME_SERVICE_SEM:
+			odbp = &nsc_name_odb[service];
+			NSC_IPC_WRLOCK(odbp);
+
+			error = nsc_ipcremove(odbp, glid);
+			NSC_IPC_WRUNLOCK(odbp);
+			if (error == 1)
+				error = 0;
 			break;
 		default:
-			break;
+			return -EINVAL;
 	}
-
-	return ((error == 1) ? 0 : error);
+	return error;
 }
 
 int

Index: ipcshm_svr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/ipc/ipcshm_svr.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- ipcshm_svr.c	24 Feb 2009 01:51:47 -0000	1.17
+++ ipcshm_svr.c	27 Oct 2009 03:18:29 -0000	1.18
@@ -45,6 +45,8 @@
 #include <cluster/gen/ics_ipc_macros_gen.h>
 #include <cluster/gen/ics_ipc_protos_gen.h>
 
+#define shm_flags	shm_perm.mode
+
 extern struct super_block *cfs_shm_sb;
 extern int shm_tot;
 extern struct ipc_ids shm_ids;
@@ -53,6 +55,9 @@
 extern int cli_ipcname_rmid(int, global_id_t);
 extern void ipc_rcu_putref(void *ptr);
 extern void ipc_drop_locks(int, struct kern_ipc_perm *, struct ipc_ids *, int);
+#ifdef IPC_SHM_LOCK_DEST_FIX
+void ipc_lock_dest_id(struct ipc_ids *ids, int id);
+#endif
 extern struct kern_ipc_perm * ipc_get_locks(int, struct ipc_ids *, int);
 extern int shm_get_segsize(struct shmid_kernel *);
 extern int shm_get_cpid(struct shmid_kernel *);
@@ -106,7 +111,7 @@
 	if (!status)
 		status = rval;
 
-	return rval;
+	return status;
 }
 
 int
@@ -168,14 +173,18 @@
 
 	if (dest) {
 		shp->shm_perm.key = IPC_PRIVATE;
-		shp->shm_perm.mode |= SHM_DEST;
+		shp->shm_flags |= SHM_DEST;
 	}
 	*nattch = shp->shm_nattch;
         *rval = 0;
 	if (dest != 2)
 		ipc_drop_locks(shmid, (struct kern_ipc_perm *)shp, &shm_ids, 1);
 	else {
-		shp->shm_perm.mode |= SHM_LOCK_DEST;
+#ifdef IPC_SHM_LOCK_DEST_FIX
+		ipc_lock_dest_id(&shm_ids, shmid);
+#else
+		shp->shm_flags |= SHM_LOCK_DEST;
+#endif
 		ipc_drop_locks(shmid, (struct kern_ipc_perm *)shp, &shm_ids, 0);
 		/* shm_ids.sem held */
 	}
@@ -191,7 +200,7 @@
 	shp = (struct shmid_kernel *)shm_cli_get(shmid);
 	if (!shp)
         	return;
-	shp->shm_perm.mode |= SHM_DEST;
+	shp->shm_flags |= SHM_DEST;
 }
 
 int
@@ -244,8 +253,12 @@
 	ipc_get_locks(0, &shm_ids_svr, 1);
 #endif
 	svp = (struct shmid_kernel_svr *)shm_svr_get(id);
-	if (!svp)
+	if (!svp) {
+#ifdef IPC_SHM_RACE_FIX
+		ipc_drop_locks(0, NULL, &shm_ids_svr, 1);
+#endif
 		return -EIDRM;
+	}
 
 #ifdef IPC_SHM_RACE_FIX
 	nl = NSC_NODELIST_COPY(svp->shm_nodelist);
@@ -266,6 +279,9 @@
 
 		/* if error should get cleaned up by nodedown */
 		if (ret) {
+#ifdef IPC_SHM_RACE_FIX
+			NSC_NODELIST_FREE(nl);
+#endif
 			idelay(HZ);
 			goto try_again;
 		}
@@ -273,6 +289,9 @@
 		if (!rval && nattch)
 			cnt = cnt + nattch;
 	}
+#ifdef IPC_SHM_RACE_FIX
+	NSC_NODELIST_FREE(nl);
+#endif
 
 	return cnt;
 }
@@ -331,7 +350,7 @@
 		RIPC_INFORM_CLIENTS_MSG(node, SHM_DEST, IPC_PRIVATE);
 #endif
 	}
-	return;
+	NSC_NODELIST_FREE(nl);
 }
 
 int
@@ -425,7 +444,11 @@
 	}
 	shm_rmid(id);
 
-	shp->shm_perm.mode &= ~SHM_LOCK_DEST; 
+#ifdef IPC_SHM_LOCK_DEST_FIX
+	ipc_lock_dest_id(&shm_ids, -1);
+#else
+	shp->shm_flags &= ~SHM_LOCK_DEST;
+#endif
 	/* Drop the locks acquired above */
 	ipc_drop_locks(id, (struct kern_ipc_perm *)shp, &shm_ids, 1);
 
@@ -462,8 +485,13 @@
 
 {
 	struct shmid_kernel *shp = shm_cli_get(id);
+#ifdef IPC_SHM_LOCK_DEST_FIX
 	if (shp)
-		shp->shm_perm.mode &= ~SHM_LOCK_DEST; 
+		ipc_lock_dest_id(&shm_ids, -1);
+#else
+	if (shp)
+		shp->shm_flags &= ~SHM_LOCK_DEST;
+#endif
 	ipc_drop_locks(id, (struct kern_ipc_perm *)shp, &shm_ids, 1); 
 	*rval = 0;
 	return 0;
@@ -512,7 +540,7 @@
 	return 0;
 }
 
-/* Caller holds shm_ids.sem */
+/* Local path called with shm_ids.sem held */
 int
 ssi_shm_cleanup(clusternode_t svrnode, int id, clusternode_t clinode)
 {
@@ -570,12 +598,16 @@
 
 		ipc_get_locks(0, &shm_ids_svr, 1);
 		shm_svr_rmid(id);
+		ipc_drop_locks(0, NULL, &shm_ids_svr, 1);
+#if 0
 		nl = NSC_NODELIST_COPY(svp->shm_nodelist);
 		NSC_NODELIST_FREE(svp->shm_nodelist);
+#endif
+		nl = svp->shm_nodelist;
 		NSC_NODELIST_CLR1(nl, svrnode);
 		shm_svr_cleanup(svp);
 		kfree(svp);
-		ipc_drop_locks(0, NULL, &shm_ids_svr, 1);
+		/* ipc_drop_locks(0, NULL, &shm_ids_svr, 1); */
 
 		cli_ipcname_rmid(NAME_SERVICE_SHM, id);
 		cookie = CLUSTERNODE_INVAL;
@@ -586,7 +618,7 @@
 				NSC_NODELIST_CLR1(svp->shm_nodelist, node);
 
 		}
-		NSC_NODELIST_FREE(nl);
+		NSC_NODELIST_FREE(nl); /* svp->shm_nodelist */
 		if (!do_locks)
 			ipc_drop_locks(0, NULL, &shm_ids, 1);
 	}
@@ -608,10 +640,9 @@
 #endif
 			cli_ipcname_rmid(NAME_SERVICE_SHM, id);
 			ret = ripc_shm_rmid(this_node, &rval, id, 1); 
-#ifndef IPC_SHM_DESTROY_FIX
-			/* SSI_XXX: Reacquire twice? */
+
+			/* ripc_shm_rmid() returns with shm_ids.sem unlocked */
 			ipc_get_locks(0, &shm_ids, 1);
-#endif
 		}
 		if (ret || rval) {
 			if (ret)

Index: unixnm.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/ipc/unixnm.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- unixnm.c	19 Feb 2009 08:01:02 -0000	1.15
+++ unixnm.c	27 Oct 2009 03:18:29 -0000	1.16
@@ -65,7 +65,7 @@
 	unsigned long		sockino;
 };
 static struct list_head unixnm_svr_table[UNIX_HASH_SIZE];
-static DEFINE_RWLOCK(unixnm_svr_lock); 
+static __cacheline_aligned_in_smp DEFINE_RWLOCK(unixnm_svr_lock);
 
 /* rebuild cache */
 struct unixnm_cache_entry {
@@ -76,7 +76,7 @@
 };
 static struct list_head unixnm_cache_list = LIST_HEAD_INIT(unixnm_cache_list);
 static int unixnm_cache_size = 0;
-static DEFINE_SPINLOCK(unixnm_cache_listlock); 
+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(unixnm_cache_listlock);
 
 struct unixnm_rebuild_entry {
 	int hash;
@@ -189,7 +189,9 @@
 		svrent->sockino = rbldent->sockino;
 		svrent->socknode = node;
 
+		write_lock(&unixnm_svr_lock);
 		list_add(&svrent->list, &unixnm_svr_table[rbldent->hash]);
+		write_unlock(&unixnm_svr_lock);
 		++rbldent;
 	}
 }

Index: namesvr_clnt.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/ipc/namesvr_clnt.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- namesvr_clnt.c	28 Mar 2009 23:44:16 -0000	1.7
+++ namesvr_clnt.c	27 Oct 2009 03:18:29 -0000	1.8
@@ -188,7 +188,7 @@
 int cli_ipcname_gettotal(int service, struct ssi_nodeid_pair **node_id_pairs, int *sz)
 {
 	clusternode_t	server_node;
-	int		status, rval, len = 0;
+	int rval;
 	extern clms_key_svc_t ipc_key_service;
 again:
 	server_node = name_server_node;
@@ -203,13 +203,12 @@
 		rval = ipcname_gettotal(service, *node_id_pairs, sz);
 	} else {
 		ssi_procstate_t pstate;
+		int status, count = *sz;
 
-		if (*sz > 0)
-			len = *sz * sizeof(struct ssi_nodeid_pair);
 		ssi_procstate_get(&pstate);
 
 		status = RIPC_IPCNAME_GETTOTAL(server_node, &rval, service, &pstate,
-						node_id_pairs, &len, sz);
+						node_id_pairs, &count, sz);
 		if (status == -EAGAIN || status == -EREMOTE) {
 			/* Server is doing failover,dying, or isn't ready yet.*/
 			clms_waitfor_key_service(0);

Index: namesvr_svr.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/ipc/namesvr_svr.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- namesvr_svr.c	28 Mar 2009 23:44:16 -0000	1.6
+++ namesvr_svr.c	27 Oct 2009 03:18:29 -0000	1.7
@@ -88,34 +88,33 @@
  */
 void
 ripc_ipcname_gettotal(clusternode_t *node, int *rval, int service,
-		ssi_procstate_t *pstate, struct ssi_nodeid_pair **node_id_pairs,
-		int *len, int *sz)
+		ssi_procstate_t *pstate,
+		struct ssi_nodeid_pair **node_id_pairs, int *count,
+		int *sz)
 {
 	ssi_procstate_t save_pstate;
-	int count = *sz;
 
 	if (ipcname_failover_flag) {
 		*rval = -EAGAIN;
 		return;
 	}
 
-	*len = 0;
 	ssi_procstate_get(&save_pstate);
 	ssi_procstate_set(pstate);
-	if (count > 0) {
-		*node_id_pairs = kmalloc(count * sizeof(**node_id_pairs), GFP_KERNEL);
-		if (*node_id_pairs == NULL) {
-			*sz = 0;
+	if (*count > 0) {
+		*node_id_pairs = kmalloc((*count) * sizeof(struct ssi_nodeid_pair), GFP_KERNEL);
+		if (!*node_id_pairs) {
+			*count = *sz = 0;
 			goto done;
 		}
 	}
 
 	*rval = ipcname_gettotal(service, *node_id_pairs, sz);
-	if (count > 0) {
-		if (count > *sz)
-			count = *sz;
-		*len = count * sizeof(**node_id_pairs);
-	}
+	if (!*rval) {
+		if (*count && *sz < *count)
+			*count = *sz;
+	} else
+		*count = 0;
 done:
 	ssi_procstate_set(&save_pstate);
 }

Index: rmtunix.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/ipc/rmtunix.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- rmtunix.c	24 Mar 2009 04:26:28 -0000	1.27
+++ rmtunix.c	27 Oct 2009 03:18:29 -0000	1.28
@@ -51,7 +51,7 @@
 #ifdef DEBUG
 int rmtunix_cache_size = 0;
 #endif
-DEFINE_SPINLOCK(rmtunix_cache_listlock); 
+__cacheline_aligned_in_smp DEFINE_SPINLOCK(rmtunix_cache_listlock);
 
 extern int sysctl_unix_max_dgram_qlen;
 extern struct vfsmount *sock_mnt;
@@ -67,10 +67,13 @@
 
 static int __init rmtunix_init(void)
 {
-	rmtunix_socket_info_cachep = kmem_cache_create("rmtunix_socket_info",
+	rmtunix_socket_info_cachep = kmem_cache_create("ssi_rmtunix",
 				sizeof(struct rmtunix_socket_info), 0,
 				SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
 				NULL, NULL);
+	if (!rmtunix_socket_info_cachep)
+		return -ENOMEM;
+
 	return 0;
 }
 
@@ -82,10 +85,8 @@
 void
 rmtunix_free(struct rcu_head *rhead)
 {
-	struct rmtunix_socket_info *info =
-			container_of(rhead, struct rmtunix_socket_info, rhead);
-
-	kmem_cache_free(rmtunix_socket_info_cachep, info);
+	kmem_cache_free(rmtunix_socket_info_cachep,
+			container_of(rhead, struct rmtunix_socket_info, rhead));
 }
 #endif
 
@@ -161,7 +162,11 @@
 static struct sock *
 rmtunixsvr_get_sock_byid(int *rerror, u_long *inop, u_long id)
 {
+#ifdef RCU_RMTUNIX_CACHE
+	struct rmtunix_socket_info *info;
+#else
 	struct list_head *cur;
+#endif
 	struct sock *sk = NULL;
 
 	/* SSI_XXX: this may not be the correct error for all cases */
@@ -171,9 +176,22 @@
 
 #ifdef RCU_RMTUNIX_CACHE
 	rcu_read_lock();
+	list_for_each_entry_rcu(info, &rmtunix_cache_list, list) {
+		if (info->id != id)
+			continue;
+		LOCK_SPIN_LOCK(&info->rsk_spinlock);
+		if (!info->rsk_cached) {
+			UNLOCK_SPIN_LOCK(&info->rsk_spinlock);
+			break;
+		}
+		if ((sk = info->sk))
+			atomic_inc(&info->rsk_refcnt);
+		UNLOCK_SPIN_LOCK(&info->rsk_spinlock);
+		break;
+	}
+	rcu_read_unlock();
 #else
 	spin_lock(&rmtunix_cache_listlock);
-#endif
 	list_for_each(cur, &rmtunix_cache_list) {
 		struct rmtunix_socket_info *info = list_entry(cur,
 				struct rmtunix_socket_info, list);
@@ -182,9 +200,6 @@
 			break;
 		}
 	}
-#ifdef RCU_RMTUNIX_CACHE
-	rcu_read_unlock();
-#else
 	spin_unlock(&rmtunix_cache_listlock);
 #endif
 
@@ -194,6 +209,10 @@
 		*inop = SOCK_INODE(sk->sk_socket)->i_ino;
 
 	sock_hold(sk);
+#ifdef RCU_RMTUNIX_CACHE
+	if (info)
+		__rmtunix_decache_info(info);
+#endif
 	*rerror = 0;
 out:
 	return sk;
@@ -578,29 +597,29 @@
 	}
 #else
 	if (iovlen > 1) {
-		int i;
 		struct iovec *vec = msg->msg_iov;
+		char *__buf;
+		int i;
 
-#ifdef SSI_SKIP
-		if ((int)total_len < 0) {
+		if (total_len > ICS_MAX_OOL_DATA_SIZE) {
 			error = -EMSGSIZE;
 			printk(KERN_ERR "%s: %s: exceeded ics_userbuf "
 					"capacity\n",
 					current->comm, __FUNCTION__);
 			goto out;
 		}
-#endif
 
 		if (!(buf = kmalloc(total_len, GFP_KERNEL))) {
 			error = -ENOMEM;
 			goto out;
 		}
 
+		__buf = buf;
 		buflen = 0;
 		for (i = 0; i < msg->msg_iovlen; i++) {
-			copy_from_user(buf, vec->iov_base, vec->iov_len);
+			copy_from_user(__buf, vec->iov_base, vec->iov_len);
 			buflen += vec->iov_len;
-			buf += vec->iov_len;
+			__buf += vec->iov_len;
 			vec++;
 		}
 	}
@@ -717,7 +736,7 @@
 	info->rmtid = rmtid;
 	info->magic = RMTUNIX_MAGIC;
 
-	set_mb(unix_peer(sk), (struct sock *)info);
+	unix_peer(sk) = (struct sock *)info;
 	rmtunix_cache_info(sk);
 
 	sk->sk_peercred = peercred;
@@ -1153,29 +1172,29 @@
 	}
 #else
 	if (iovlen > 1) {
-		int i;
 		struct iovec *vec = msg->msg_iov;
+		char *__buf;
+		int i;
 
-#ifdef SSI_SKIP
-		if ((int)total_len < 0) {
+		if (total_len > ICS_MAX_OOL_DATA_SIZE) {
 			error = -EMSGSIZE;
 			printk(KERN_ERR "%s: %s: exceeded ics_userbuf "
 					"capacity\n",
 					current->comm, __FUNCTION__);
 			goto out;
 		}
-#endif
 
 		if (!(buf = kmalloc(total_len, GFP_KERNEL))) {
 			error = -ENOMEM;
 			goto out;
 		}
 
+		__buf = buf;
 		buflen = 0;
 		for (i = 0; i < msg->msg_iovlen; i++) {
-			copy_from_user(buf, vec->iov_base, vec->iov_len);
+			copy_from_user(__buf, vec->iov_base, vec->iov_len);
 			buflen += vec->iov_len;
-			buf += vec->iov_len;
+			__buf += vec->iov_len;
 			vec++;
 		}
 	}


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.