[SSI] openssi/kernel/cluster/ssi/util load_level.c, 1.21, 1.22 rcopy.c, 1.11, 1.12 rmtfb.c, 1.20, 1.21 rmtsock.c, 1.20, 1.21 ssidev.c, 1.23, 1.24 ssidev_ics.c, 1.11, 1.12
Roger Tsang <[email protected]>
| Newsgroups | gmane.linux.cluster.ssic.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv8553/cluster/ssi/util
Modified Files:
Tag: OPENSSI-FC
load_level.c rcopy.c rmtfb.c rmtsock.c ssidev.c ssidev_ics.c
Log Message:
Bug fixes and enhancements. (see ChangeLog)
Index: rmtsock.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/rmtsock.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- rmtsock.c 7 Aug 2007 03:06:09 -0000 1.20
+++ rmtsock.c 3 Feb 2009 06:18:13 -0000 1.21
@@ -47,7 +47,7 @@
#include <cluster/gen/ics_rmtfb_macros_gen.h>
#include <cluster/gen/ics_rmtfb_protos_gen.h>
-struct rmtscm_fp_list;
+//struct rmtscm_fp_list;
/*
@@ -933,8 +933,10 @@
#endif
}
- if (!siocb->scm)
+ if (!siocb->scm) {
siocb->scm = &tmp_scm;
+ memset(&tmp_scm, 0, sizeof(tmp_scm));
+ }
error = scm_send(sock, msg, siocb->scm);
if (error < 0)
#ifndef RMTSOCK_SENDMSG_IOVECS
Index: load_level.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/load_level.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- load_level.c 10 Oct 2008 08:10:32 -0000 1.21
+++ load_level.c 3 Feb 2009 06:18:13 -0000 1.22
@@ -46,7 +46,11 @@
int load_cnt;
/* table used to determine whats loadlevelable */
+#ifdef LOADLEVEL_TABLE_LIST
+LIST_HEAD(loadlevel_table);
+#else
struct inclusion_list *loadlevel_table;
+#endif
extern clusternode_t clms_master_node;
int loadlevel_on;
@@ -71,7 +75,11 @@
#endif /* CONFIG_MOSIX_LL */
extern void exec_balance(void);
+#ifdef LOADLEVEL_TABLE_LIST
+RW_LOCK_T loadlevellist_lock;
+#else
LOCK_T loadlevellist_lock;
+#endif
#define LOADLOG_DEPTH 64
#define LOADLVL_MSGS 11
@@ -459,14 +467,18 @@
struct vm_area_struct * vma;
struct dentry *dentry = NULL;
struct vfsmount *mnt = NULL;
+#ifndef LOADLEVEL_TABLE_LIST
int held;
+#endif
if (!loadlist_lockinit || (p->exit_state >= EXIT_ZOMBIE) ||
!(p->p_vproc) || (p->p_vproc->vp_pid != p->pid))
return 0;
pvp = PVP(p->p_vproc);
+#ifndef LOADLEVEL_TABLE_LIST
held = VPROC_LOCK_EXCL_HELD(p->p_vproc);
+#endif
if (pvp->pvp_loadlevel == -1) {
if (!fname) {
/* Check to see if process has dentry filled in */
@@ -515,6 +527,21 @@
}
+#ifdef LOADLEVEL_TABLE_LIST
+ if (dentry && mnt) {
+ /* check list and set loadlevel field accordingly */
+ LOADLIST_LOCK_SHARED();
+ list_for_each_entry(ent, &loadlevel_table, inc_list) {
+ if (dentry == ent->de && mnt == ent->mnt) {
+ LOADLIST_UNLOCK_SHARED();
+ pvp->pvp_loadlevel = 1;
+ goto out_nolock;
+ }
+ }
+ LOADLIST_UNLOCK_SHARED();
+ }
+ pvp->pvp_loadlevel = 0;
+#else /* !LOADLEVEL_TABLE_LIST */
if (!held)
if (!TRY_VPROC_LOCK_EXCL(p->p_vproc,"is_loadlevelable"))
return 0;
@@ -534,21 +561,26 @@
}
pvp->pvp_loadlevel = 0;
LOADLIST_UNLOCK();
+#endif /* !LOADLEVEL_TABLE_LIST */
}
else if ((pvp->pvp_loadlevel == 0) && fname) {
+#ifndef LOADLEVEL_TABLE_LIST
if (!held)
VPROC_LOCK_EXCL(p->p_vproc,"is_loadlevelable");
+#endif
/* reset so that it can be resolved again since process is
* about to exec
*/
pvp->pvp_loadlevel = -1;
}
+#ifndef LOADLEVEL_TABLE_LIST
else
goto out_nolock;
out:
if (!held)
VPROC_UNLOCK_EXCL(p->p_vproc, "is_loadlevelable");
+#endif
out_nolock:
dput(dentry);
mntput(mnt);
@@ -576,8 +608,13 @@
/* get inclusion list */
str = page;
+#ifdef LOADLEVEL_TABLE_LIST
+ LOADLIST_LOCK_SHARED();
+ list_for_each_entry(ptr, &loadlevel_table, inc_list) {
+#else
LOADLIST_LOCK();
for(ptr = loadlevel_table; ptr != NULL; ptr = ptr->next) {
+#endif
path = d_path(ptr->de, ptr->mnt, tmp, PAGE_SIZE);
len = tmp + PAGE_SIZE - 1 - path;
memcpy(str, path, len);
@@ -586,7 +623,11 @@
*str = '\n';
str++;
}
+#ifdef LOADLEVEL_TABLE_LIST
+ LOADLIST_UNLOCK_SHARED();
+#else
LOADLIST_UNLOCK();
+#endif
read = off - *ppos;
if (read == 0)
goto out;
@@ -653,7 +694,12 @@
ssize_t
do_write_loadlist(int flags, char * buf, size_t count, loff_t *ppos)
{
+#ifdef LOADLEVEL_TABLE_LIST
+ struct inclusion_list *ptr, *ent;
+ LIST_HEAD(oldlist);
+#else
struct inclusion_list *ptr, *ent, *oldlist = NULL;
+#endif
char *line, *str, *tmpbuf;
int len, size;
struct nameidata nd;
@@ -691,8 +737,12 @@
* will be read in again. Free oldlist after setting up new list.
*/
if (!(flags & O_APPEND)) {
+#ifdef LOADLEVEL_TABLE_LIST
+ list_splice_init(&loadlevel_table, &oldlist);
+#else
oldlist = loadlevel_table;
loadlevel_table = NULL;
+#endif
}
line:
for(str = tmpbuf; str && (*str != '\n' && *str != '\0'); str++);
@@ -719,6 +769,11 @@
ent->de = nd.dentry;
ent->mnt = nd.mnt;
+#ifdef LOADLEVEL_TABLE_LIST
+ INIT_LIST_HEAD(&ent->inc_list);
+
+ list_add_tail(&ent->inc_list, &loadlevel_table);
+#else
ent->next = NULL;
ptr = loadlevel_table;
@@ -729,6 +784,7 @@
for(; ptr->next; ptr = ptr->next);
ptr->next = ent;
}
+#endif
}
if (len && write < count)
@@ -746,6 +802,14 @@
kfree(line);
/* Now free oldlist if there is one */
+#ifdef LOADLEVEL_TABLE_LIST
+ list_for_each_entry_safe(ptr, ent, &oldlist, inc_list) {
+ dput(ptr->de);
+ mntput(ptr->mnt);
+ list_del(&ptr->inc_list);
+ kfree(ptr);
+ }
+#else
for(ptr = oldlist; ptr != NULL;) {
ent = ptr->next;
dput(ptr->de);
@@ -753,6 +817,7 @@
kfree(ptr);
ptr = ent;
}
+#endif
return count;
}
Index: rcopy.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/rcopy.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- rcopy.c 10 Oct 2008 08:10:32 -0000 1.11
+++ rcopy.c 3 Feb 2009 06:18:13 -0000 1.12
@@ -105,15 +105,8 @@
SSI_ASSERT(*data_len <= ICS_MAX_OOL_DATA_SIZE);
if (v != NULL) {
pvp = PVP(v);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
- p = PV_IS_ALIVE(pvp) ? pvp->pvp_pproc : NULL;
-#else
p = pvp->pvp_pproc;
-#endif
SSI_ASSERT(p != NULL);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
- VPROC_RELE(v, "rssi_rcopy_from_user(vprocptr v)");
-#endif
}
else
p = NULL;
@@ -136,6 +129,10 @@
*rerror = -ESRCH;
*data_len = 0;
}
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+ if (v)
+ VPROC_RELE(v, "rssi_rcopy_from_user");
+#endif
return 0;
}
@@ -155,15 +152,8 @@
SSI_ASSERT(data_len <= ICS_MAX_OOL_DATA_SIZE);
if (v != NULL) {
pvp = PVP(v);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
- p = PV_IS_ALIVE(pvp) ? pvp->pvp_pproc : NULL;
-#else
p = pvp->pvp_pproc;
-#endif
SSI_ASSERT(p != NULL);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
- VPROC_RELE(v, "rssi_rcopy_to_user(vprocptr v)");
-#endif
}
else
p = NULL;
@@ -178,6 +168,10 @@
*rerror = -ESRCH;
*n = data_len;
}
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+ if (v)
+ VPROC_RELE(v, "rssi_rcopy_to_user");
+#endif
return 0;
}
@@ -196,15 +190,8 @@
SSI_ASSERT(*data_len <= ICS_MAX_OOL_DATA_SIZE);
if (v != NULL) {
pvp = PVP(v);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
- p = PV_IS_ALIVE(pvp) ? pvp->pvp_pproc : NULL;
-#else
p = pvp->pvp_pproc;
-#endif
SSI_ASSERT(p != NULL);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
- VPROC_RELE(v, "rssi_rcopy_strncpy_from_user(vprocptr v)");
-#endif
}
else
p = NULL;
@@ -222,6 +209,10 @@
*rerror = -ESRCH;
*data_len = 0;
}
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+ if (v)
+ VPROC_RELE(v, "rssi_rcopy_strncpy_from_user");
+#endif
return 0;
}
@@ -238,15 +229,8 @@
SSI_ASSERT(*n <= ICS_MAX_OOL_DATA_SIZE);
if (v != NULL) {
pvp = PVP(v);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
- p = PV_IS_ALIVE(pvp) ? pvp->pvp_pproc : NULL;
-#else
p = pvp->pvp_pproc;
-#endif
SSI_ASSERT(p != NULL);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
- VPROC_RELE(v, "rssi_rcopy_strnlen_user(vprocptr v)");
-#endif
}
else
p = NULL;
@@ -256,6 +240,10 @@
*rerror = -ESRCH;
(*n)++;
}
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+ if (v)
+ VPROC_RELE(v, "rssi_rcopy_strnlen_user");
+#endif
return 0;
}
@@ -275,15 +263,8 @@
SSI_ASSERT(*n <= ICS_MAX_OOL_DATA_SIZE);
if (v != NULL) {
pvp = PVP(v);
-#ifdef VPROC_HOLD_ZERO_GET_TASK
- p = PV_IS_ALIVE(pvp) ? pvp->pvp_pproc : NULL;
-#else
p = pvp->pvp_pproc;
-#endif
SSI_ASSERT(p != NULL);
-#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
- VPROC_RELE(v, "rssi_rcopy_clear_user(vprocptr v)");
-#endif
}
else
p = NULL;
@@ -312,6 +293,10 @@
*rerror = -ENOMEM;
} else
*rerror = -ESRCH;
+#ifdef VPROC_RELEASE__REFCNT_RACE_FIX
+ if (v)
+ VPROC_RELE(v, "rssi_rcopy_clear_user");
+#endif
return 0;
}
Index: rmtfb.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/rmtfb.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- rmtfb.c 10 Oct 2008 08:10:32 -0000 1.20
+++ rmtfb.c 3 Feb 2009 06:18:13 -0000 1.21
@@ -703,8 +703,13 @@
struct pathdata *path,
int flags,
unsigned long id,
- clusternode_t svr,
short socket_type)
+#elif defined(REOP_EXPORT_PATH_SVRNODE)
+struct rmtfb_cli *
+rmtfb_getcli_id(
+ struct pathdata *path,
+ int flags,
+ unsigned long id)
#else
struct rmtfb_cli *
rmtfb_getcli_id(
@@ -718,8 +723,13 @@
struct file *file;
struct socket *sock;
int loop = 0;
+#ifdef REOP_EXPORT_PATH_SVRNODE
+ int svr = 0;
+ if (!path || !(svr = path->svrnode) || inval(id,svr)) {
+#else
if (!path || !svr || inval(id,svr)) {
+#endif
printk(KERN_ERR "rmtfb_getcli_id: bad arguments\n");
#ifdef RMTFB_GETCLI_ID__RFB_SERVER_INVAL_FIX
WARN_ON(svr == CLUSTERNODE_INVAL);
@@ -948,8 +958,7 @@
rmtfb_remote_tty_ino(file, svr);
#endif
file->f_op = &ssidev_remote_fops;
- rfb = newrfb;
- file->private_data = rfb;
+ file->private_data = rfb = newrfb;
list_add(&rfb->common.rfb_hash, &rmtfb_clitbl[hash(id)]);
SSI_ASSERT(ftocli(file) == rfb);
UNLOCK_EXCL_RW_LOCK(&rmtfb_clitbl_lock);
Index: ssidev.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/ssidev.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- ssidev.c 10 Oct 2008 08:10:32 -0000 1.23
+++ ssidev.c 3 Feb 2009 06:18:13 -0000 1.24
@@ -63,11 +63,15 @@
char ssidev_inited;
char ssidev_udev_mounted;
static char ssidev_secondary;
-static char ssidev_busy;
static char ssidev_updated;
volatile clusternode_t ssidev_node = CLUSTERNODE_INVAL;
static int ssidev_transid;
+#ifdef SSIDEV_LOCK_MUTEX
+static DECLARE_MUTEX(ssidev_sem);
+#else
+static char ssidev_busy;
static DEFINE_SPINLOCK(ssidev_spinlock);
+#endif
static ssidev_hash_t *ssidev_linux_hash[SSIDEV_HASH_SIZE];
static ssidev_hash_t *ssidev_ssi_hash[SSIDEV_HASH_SIZE];
static ssidev_hash_t *ssidev_last;
@@ -89,6 +93,18 @@
static void ssidev_broadcast_mount_sem(clusternode_t, pid_t, int);
static void ssidev_broadcast_failover(void);
+#ifdef SSIDEV_HASH_KMEM_CACHE
+static kmem_cache_t *ssidev_hash_cachep;
+#endif
+#ifdef SSIDEV_POLL_NODE_KMEM_CACHE
+static kmem_cache_t *ssidev_poll_node_cachep;
+static void ssidev_poll_node_init(void);
+#endif
+#ifdef SSIDEV_POLL_CLI_KMEM_CACHE
+static kmem_cache_t *ssidev_poll_cli_cachep;
+static void ssidev_poll_cli_init(void);
+#endif
+
static inline ssidev_hash_t *
ssidev_search_linuxtossi(clusternode_t devnode, int mode, dev_t linuxdev)
{
@@ -146,6 +162,12 @@
ssidev_ssi_hash[shash] = newp;
}
+#ifdef SSIDEV_LOCK_MUTEX
+#define ssidev_lock() down(&ssidev_sem)
+#define ssidev_lock_busy ssidev_lock
+#define ssidev_lock_makebusy() do { } while(0)
+#define ssidev_unlock() up(&ssidev_sem)
+#else
static void
ssidev_do_locksleep(void)
{
@@ -191,13 +213,6 @@
spin_unlock(&ssidev_spinlock);
}
-static void ssidev_lock_failover(void)
-{
- if (ssidev_node == this_node)
- return;
- ssidev_lock_busy();
-}
-
static void
ssidev_unlock(void)
{
@@ -209,6 +224,24 @@
} else
spin_unlock(&ssidev_spinlock);
}
+#endif /* !SSIDEV_LOCK_MUTEX */
+
+static void ssidev_lock_failover(void)
+{
+ if (ssidev_node == this_node)
+ return;
+ ssidev_lock_busy();
+}
+
+#ifdef SSIDEV_HASH_KMEM_CACHE
+static void ssidev_hash_init(void)
+{
+ ssidev_hash_cachep = kmem_cache_create("ssidev_hash",
+ sizeof(ssidev_hash_t), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
+}
+#endif
static ssidev_hash_t *
ssidev_add_last(ssidev_hash_data_t *dp)
@@ -227,7 +260,11 @@
list_del(&hp->sd_list);
newp = hp;
} else
+#ifdef SSIDEV_HASH_KMEM_CACHE
+ newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
+#else
newp = kmalloc_nofail(sizeof(*newp));
+#endif
ssidev_add(newp, dp->sd_devnode, dp->sd_mode,
dp->sd_linuxdev, dp->sd_ssidev);
} else {
@@ -243,7 +280,11 @@
newp = hp;
newp->sd_data.sd_mode = 0;
} else {
+#ifdef SSIDEV_HASH_KMEM_CACHE
+ newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
+#else
newp = kmalloc_nofail(sizeof(*newp));
+#endif
newp->sd_data = *dp;
}
list_add(&newp->sd_list, &ssidev_unique_list);
@@ -274,8 +315,12 @@
int j;
ssidev_hash_t *newp;
- for (j = 0; j < num; j++) {
+ for (j = 0; j < num; j++, dp++) {
+#ifdef SSIDEV_HASH_KMEM_CACHE
+ newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
+#else
newp = kmalloc_nofail(sizeof(*newp));
+#endif
if (dp->sd_devnode != CLUSTERNODE_INVAL) {
ssidev_add(newp, dp->sd_devnode, dp->sd_mode,
dp->sd_linuxdev, dp->sd_ssidev);
@@ -289,7 +334,6 @@
list_add_tail(&newp->sd_list,
&ssidev_free_list);
}
- dp++;
}
}
@@ -372,7 +416,11 @@
hp = list_entry(ssidev_free_list.next, ssidev_hash_t, sd_list);
list_del(&hp->sd_list);
*ssidevp = hp->sd_data.sd_ssidev;
+#ifdef SSIDEV_HASH_KMEM_CACHE
+ kmem_cache_free(ssidev_hash_cachep, hp);
+#else
kfree(hp);
+#endif
return 0;
}
if (ssidev_current < SSIDEV_LAST) {
@@ -391,7 +439,11 @@
ssidev_hash_t *hp;
(void)to_node;
+#ifdef SSIDEV_HASH_KMEM_CACHE
+ newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL);
+#else
newp = kmalloc(sizeof(*newp), GFP_KERNEL);
+#endif
if (newp == NULL) {
*rerror = -ENOMEM;
return 0;
@@ -421,7 +473,11 @@
ssidev_hash_t *newp;
(void)to_node;
+#ifdef SSIDEV_HASH_KMEM_CACHE
+ newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL);
+#else
newp = kmalloc(sizeof(*newp), GFP_KERNEL);
+#endif
if (newp == NULL) {
*rerror = -ENOMEM;
return 0;
@@ -490,7 +546,11 @@
error = ssidev_new(devnode, mode, linuxdev, &ssidev);
if (error >= 0) {
if (this_node != ssidev_node && !ssidev_secondary) {
+#ifdef SSIDEV_HASH_KMEM_CACHE
+ hp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
+#else
hp = kmalloc_nofail(sizeof(*hp));
+#endif
ssidev_lock();
ssidev_add(hp, devnode, mode & S_IFMT,
linuxdev, ssidev);
@@ -620,7 +680,16 @@
{
/* Wait for the SSI device server if we're not it. */
ssidev_node = clms_get_key_server_node(ssidev_key_service, 1);
- wmb();
+ /* wmb(); */
+#ifdef SSIDEV_HASH_KMEM_CACHE
+ ssidev_hash_init();
+#endif
+#ifdef SSIDEV_POLL_NODE_KMEM_CACHE
+ ssidev_poll_node_init();
+#endif
+#ifdef SSIDEV_POLL_CLI_KMEM_CACHE
+ ssidev_poll_cli_init();
+#endif
if (ssidev_node == this_node) {
ssidev_inited = 1;
clms_set_key_service_ready(ssidev_key_service);
@@ -712,6 +781,19 @@
static inline signed long ssidev_poll_cli_wait(ssidev_poll_cli_t *pcp,
signed long timeout)
{
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+ LOCK_SPIN_LOCK(&pcp->pc_spinlock);
+ if (!pcp->pc_wakeup) {
+ pcp->pc_proc = current;
+ UNLOCK_SPIN_LOCK(&pcp->pc_spinlock);
+ if (!pcp->pc_wakeup)
+ timeout = schedule_timeout(timeout);
+ LOCK_SPIN_LOCK(&pcp->pc_spinlock);
+ pcp->pc_wakeup = 0;
+ pcp->pc_proc = NULL;
+ }
+ UNLOCK_SPIN_LOCK(&pcp->pc_spinlock);
+#else
spin_lock(&ssidev_poll_cli_spinlock);
pcp->pc_proc = current;
spin_unlock(&ssidev_poll_cli_spinlock);
@@ -721,15 +803,33 @@
pcp->pc_proc = NULL;
pcp->pc_wakeup = 0;
spin_unlock(&ssidev_poll_cli_spinlock);
+#endif /* !RCU_SSIDEV_POLL_CLI_LIST */
return timeout;
}
void ssidev_poll_wake_cli(caddr_t cpcp)
{
- struct list_head *ltmp;
ssidev_poll_cli_t *pcp;
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+ rcu_read_lock();
+ list_for_each_entry_rcu(pcp, &ssidev_poll_cli_list, pc_list) {
+ if (pcp == (ssidev_poll_cli_t *)cpcp) {
+ LOCK_SPIN_LOCK(&pcp->pc_spinlock);
+ pcp->pc_wakeup = 1;
+ if (pcp->pc_proc) {
+ wake_up_process(pcp->pc_proc);
+ pcp->pc_proc = NULL; /* avoid race */
+ }
+ UNLOCK_SPIN_LOCK(&pcp->pc_spinlock);
+ break;
+ }
+ }
+ rcu_read_unlock();
+#else
+ struct list_head *ltmp;
+
spin_lock(&ssidev_poll_cli_spinlock);
list_for_each(ltmp, &ssidev_poll_cli_list) {
pcp = list_entry(ltmp, ssidev_poll_cli_t, pc_list);
@@ -741,6 +841,7 @@
}
}
spin_unlock(&ssidev_poll_cli_spinlock);
+#endif /* !RCU_SSIDEV_POLL_CLI_LIST */
}
static int ssidev_poll_return(ssidev_pollfd_t *sfdp)
@@ -781,11 +882,25 @@
return ucount;
}
+#ifdef SSIDEV_POLL_NODE_KMEM_CACHE
+static void ssidev_poll_node_init(void)
+{
+ ssidev_poll_node_cachep = kmem_cache_create("ssidev_poll_node",
+ sizeof(ssidev_poll_node_t), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
+}
+#endif
+
static inline ssidev_poll_node_t *ssidev_poll_node_alloc(void)
{
ssidev_poll_node_t *pnp;
+#ifdef SSIDEV_POLL_NODE_KMEM_CACHE
+ pnp = kmem_cache_alloc(ssidev_poll_node_cachep, GFP_KERNEL);
+#else
pnp = kmalloc(sizeof(*pnp), GFP_KERNEL);
+#endif
if (pnp == NULL)
return NULL;
pnp->pn_waiting = 0;
@@ -800,25 +915,51 @@
if (pnp == NULL)
return;
ics_chunk_free(&pnp->pn_pollfd);
+#ifdef SSIDEV_POLL_NODE_KMEM_CACHE
+ kmem_cache_free(ssidev_poll_node_cachep, pnp);
+#else
kfree(pnp);
+#endif
+}
+
+#ifdef SSIDEV_POLL_CLI_KMEM_CACHE
+static void ssidev_poll_cli_init(void)
+{
+ ssidev_poll_cli_cachep = kmem_cache_create("ssidev_poll_cli",
+ sizeof(ssidev_poll_cli_t), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
}
+#endif
ssidev_poll_cli_t *ssidev_poll_cli_alloc(unsigned int events,
int (*retfunc)(ssidev_pollfd_t *))
{
ssidev_poll_cli_t *pcp;
+#ifdef SSIDEV_POLL_CLI_KMEM_CACHE
+ pcp = kmem_cache_alloc(ssidev_poll_cli_cachep, GFP_KERNEL);
+#else
pcp = kmalloc(sizeof(*pcp), GFP_KERNEL);
+#endif
if (pcp == NULL)
return NULL;
INIT_LIST_HEAD(&pcp->pc_list);
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+ INIT_RCU_HEAD(&pcp->pc_rcu);
+ INIT_SPIN_LOCK(&pcp->pc_spinlock);
+#endif
pcp->pc_proc = NULL;
pcp->pc_events = events;
pcp->pc_wakeup = 0;
pcp->pc_retfunc = retfunc;
memset(pcp->pc_node, 0, sizeof(pcp->pc_node));
spin_lock(&ssidev_poll_cli_spinlock);
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+ list_add_rcu(&pcp->pc_list, &ssidev_poll_cli_list);
+#else
list_add(&pcp->pc_list, &ssidev_poll_cli_list);
+#endif
spin_unlock(&ssidev_poll_cli_spinlock);
return pcp;
@@ -828,11 +969,20 @@
{
ssidev_poll_node_t *pnp;
int i;
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+ extern void ssidev_poll_cli_dealloc(struct rcu_head *);
+#endif
if (pcp == NULL)
return;
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+ SSI_ASSERT(pcp->pc_proc == NULL);
+ spin_lock(&ssidev_poll_cli_spinlock);
+ list_del_rcu(&pcp->pc_list);
+#else
spin_lock(&ssidev_poll_cli_spinlock);
list_del(&pcp->pc_list);
+#endif
spin_unlock(&ssidev_poll_cli_spinlock);
for (i = 0; i < NSC_MAX_NODE_VALUE; i++) {
pnp = pcp->pc_node[i];
@@ -842,7 +992,19 @@
ssidev_rpoll_wake_svr(i + 1, pcp);
ssidev_poll_node_free(pnp);
}
+#ifdef RCU_SSIDEV_POLL_CLI_LIST
+ call_rcu(&pcp->pc_rcu, ssidev_poll_cli_dealloc);
+}
+
+void ssidev_poll_cli_dealloc(struct rcu_head *pc_rcu)
+{
+ ssidev_poll_cli_t *pcp = container_of(pc_rcu, ssidev_poll_cli_t, pc_rcu);
+#endif
+#ifdef SSIDEV_POLL_CLI_KMEM_CACHE
+ kmem_cache_free(ssidev_poll_cli_cachep, pcp);
+#else
kfree(pcp);
+#endif
}
int ssidev_pollfd_add(ssidev_poll_cli_t *pcp, struct pollfd *fdp, void *src)
@@ -1567,11 +1729,17 @@
ics_chan_t ics_ssidev_chan;
clms_key_svc_t ssidev_key_service;
extern int ics_ssidev_svc_init(void);
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+extern void ssidev_poll_svr_init(void);
+#endif
static int __init ci_init_ssidev(void)
{
int ret;
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+ ssidev_poll_svr_init();
+#endif
/* Register SSIDEV ICS channel. */
/* XXX: The ICS channel numbers are hard-coded to ensure consistency
* among cluster nodes. This should go away once dynamic channels
Index: ssidev_ics.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/ssidev_ics.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- ssidev_ics.c 23 Oct 2007 04:08:47 -0000 1.11
+++ ssidev_ics.c 3 Feb 2009 06:18:13 -0000 1.12
@@ -52,6 +52,16 @@
static LIST_HEAD(ssidev_poll_svr_list);
static DEFINE_SPINLOCK(ssidev_poll_svr_spinlock);
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+static kmem_cache_t *ssidev_poll_svr_cachep;
+#endif
+
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+/*
+ * Bits in ssidev_poll_svr_t.ps_state
+ */
+#define ps_wakeup 0x1 /* wake ps_proc */
+#endif
int ssidev_new(clusternode_t devnode, int mode, dev_t linuxdev,
dev_t *ssidevp)
@@ -552,6 +562,16 @@
return error;
}
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+void ssidev_poll_svr_init(void)
+{
+ ssidev_poll_svr_cachep = kmem_cache_create("ssidev_poll_svr",
+ sizeof(ssidev_poll_svr_t), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
+}
+#endif
+
static inline ssidev_poll_svr_t *ssidev_poll_svr_alloc(clusternode_t cnode,
caddr_t cpcp,
u_int events,
@@ -560,22 +580,39 @@
{
ssidev_poll_svr_t *psp;
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+ psp = kmem_cache_alloc(ssidev_poll_svr_cachep, GFP_KERNEL);
+#else
psp = kmalloc(sizeof(*psp), GFP_KERNEL);
+#endif
if (psp == NULL)
return NULL;
INIT_LIST_HEAD(&psp->ps_list);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ atomic_set(&psp->ps_usecount, 2);
+ INIT_RCU_HEAD(&psp->ps_rcu);
+#else
psp->ps_usecount = 2;
+#endif
init_MUTEX_LOCKED(&psp->ps_sem);
psp->ps_cnode = cnode;
psp->ps_cpcp = cpcp;
psp->ps_proc = NULL;
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ psp->ps_state = 0;
+#else
psp->ps_wakeup = 0;
+#endif
psp->ps_events = events;
psp->ps_icp = icp;
psp->ps_retval = 0;
psp->ps_pstate = pstate;
spin_lock(&ssidev_poll_svr_spinlock);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ list_add_rcu(&psp->ps_list, &ssidev_poll_svr_list);
+#else
list_add(&psp->ps_list, &ssidev_poll_svr_list);
+#endif
spin_unlock(&ssidev_poll_svr_spinlock);
return psp;
@@ -583,22 +620,62 @@
static inline void ssidev_poll_svr_free(ssidev_poll_svr_t *psp)
{
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ extern void ssidev_poll_svr_dealloc(struct rcu_head *);
+
+ if (psp == NULL)
+ return;
+ if (!atomic_dec_and_lock(&psp->ps_usecount, &ssidev_poll_svr_spinlock))
+ return;
+ list_del_rcu(&psp->ps_list);
+ spin_unlock(&ssidev_poll_svr_spinlock);
+ call_rcu(&psp->ps_rcu, ssidev_poll_svr_dealloc);
+}
+
+void ssidev_poll_svr_dealloc(struct rcu_head *ps_rcu)
+{
+ ssidev_poll_svr_t *psp = container_of(ps_rcu, ssidev_poll_svr_t, ps_rcu);
+
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+ kmem_cache_free(ssidev_poll_svr_cachep, psp);
+#else
+ kfree(psp);
+#endif
+#else
if (psp == NULL)
return;
spin_lock(&ssidev_poll_svr_spinlock);
if (--(psp->ps_usecount) == 0) {
list_del_init(&psp->ps_list);
spin_unlock(&ssidev_poll_svr_spinlock);
+#ifdef SSIDEV_POLL_SVR_KMEM_CACHE
+ kmem_cache_free(ssidev_poll_svr_cachep, psp);
+#else
kfree(psp);
+#endif
} else
spin_unlock(&ssidev_poll_svr_spinlock);
+#endif /* !RCU_SSIDEV_POLL_SVR_LIST */
}
static inline void ssidev_poll_wake_svr(clusternode_t cnode, caddr_t cpcp)
{
- struct list_head *ltmp;
ssidev_poll_svr_t *psp;
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ rcu_read_lock();
+ list_for_each_entry_rcu(psp, &ssidev_poll_svr_list, ps_list) {
+ if (psp->ps_cnode == cnode && psp->ps_cpcp == cpcp) {
+ if (!test_and_set_bit(ps_wakeup, &psp->ps_state) &&
+ psp->ps_proc != NULL)
+ wake_up_process(psp->ps_proc);
+ break;
+ }
+ }
+ rcu_read_unlock();
+#else
+ struct list_head *ltmp;
+
spin_lock(&ssidev_poll_svr_spinlock);
list_for_each(ltmp, &ssidev_poll_svr_list) {
psp = list_entry(ltmp, ssidev_poll_svr_t, ps_list);
@@ -611,6 +688,7 @@
}
}
spin_unlock(&ssidev_poll_svr_spinlock);
+#endif /* !RCU_SSIDEV_POLL_SVR_LIST */
}
void ssidev_poll_svr_nodedown(clusternode_t node)
@@ -618,6 +696,17 @@
struct list_head *ltmp, *lnext;
ssidev_poll_svr_t *psp;
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ rcu_read_lock();
+ list_for_each_safe_rcu(ltmp, lnext, &ssidev_poll_svr_list) {
+ psp = list_entry(ltmp, ssidev_poll_svr_t, ps_list);
+ if (psp->ps_cnode == node &&
+ !test_and_set_bit(ps_wakeup, &psp->ps_state) &&
+ psp->ps_proc != NULL)
+ wake_up_process(psp->ps_proc);
+ }
+ rcu_read_unlock();
+#else
spin_lock(&ssidev_poll_svr_spinlock);
lnext = ssidev_poll_svr_list.next;
while (lnext != &ssidev_poll_svr_list) {
@@ -632,6 +721,7 @@
}
}
spin_unlock(&ssidev_poll_svr_spinlock);
+#endif /* !RCU_SSIDEV_POLL_SVR_LIST */
}
static void ssidev_rpoll_svr(void *arg)
@@ -653,23 +743,40 @@
if (tmpret < 0)
psp->ps_retval = tmpret;
set_current_state(TASK_INTERRUPTIBLE);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ /* serialized by ps_wakeup bit */
+ psp->ps_proc = current;
+#else
spin_lock(&ssidev_poll_svr_spinlock);
psp->ps_proc = current;
spin_unlock(&ssidev_poll_svr_spinlock);
+#endif
ssi_procstate_set(psp->ps_pstate);
tmpret = ssidev_do_poll_node(icp, psp->ps_events, wait);
ssi_procstate_set(&save_pstate);
if (tmpret != 0)
psp->ps_retval = tmpret;
up(&psp->ps_sem);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ if (!psp->ps_retval && !test_bit(ps_wakeup, &psp->ps_state))
+#else
if (!psp->ps_retval && !psp->ps_wakeup)
+#endif
schedule();
set_current_state(TASK_RUNNING);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ psp->ps_proc = NULL;
+#else
spin_lock(&ssidev_poll_svr_spinlock);
psp->ps_proc = NULL;
spin_unlock(&ssidev_poll_svr_spinlock);
+#endif
poll_freewait(&table);
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ if (!psp->ps_retval && !test_bit(ps_wakeup, &psp->ps_state))
+#else
if (!psp->ps_retval && !psp->ps_wakeup)
+#endif
ssidev_rpoll_wake_cli(psp);
ssidev_poll_svr_free(psp);
@@ -714,7 +821,11 @@
}
*retval = spawn_daemon_proc("ssi rpoll svr", ssidev_rpoll_svr, psp);
if (*retval < 0) {
+#ifdef RCU_SSIDEV_POLL_SVR_LIST
+ atomic_set(&psp->ps_usecount, 1);
+#else
psp->ps_usecount = 1;
+#endif
ssidev_poll_svr_free(psp);
return 0;
------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com