[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