[SSI] openssi/kernel/cluster/ssi/token clitok.c, 1.8, 1.9 mhsvrtok.c, 1.7, 1.8 msgsup.c, 1.8, 1.9 rsvrtok.c, 1.7, 1.8 svrtok.c, 1.7, 1.8 tokseq.c, 1.8, 1.9
Roger Tsang <[email protected]>
| Newsgroups | gmane.linux.cluster.ssic.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv16224/kernel/cluster/ssi/token
Modified Files:
Tag: OPENSSI-FC
clitok.c mhsvrtok.c msgsup.c rsvrtok.c svrtok.c tokseq.c
Log Message:
Bug fixes and enhancements. See ChangeLog.
Index: rsvrtok.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/rsvrtok.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- rsvrtok.c 3 Feb 2009 06:18:12 -0000 1.7
+++ rsvrtok.c 27 Oct 2009 03:18:29 -0000 1.8
@@ -293,13 +293,10 @@
contextp = svrglue_alloc_ctx();
gluectxp = (tokctx_mod_t *)contextp;
- mb();
contextp += svr_top_glue_ctx_size;
rctxp = (tokctx_mod_t *)contextp;
- mb();
contextp += tnc_rtok_ctx_size;
nrctxp = (tokctx_mod_t *)contextp;
- mb();
contextp += tns_nrtok_ctx_size;
svrglue_init_ctx(gluectxp,
@@ -589,7 +586,6 @@
/* If start earlier than requested start adjust start,len */
if (qret->start < start) {
qret->len -= (start - qret->start);
- mb();
qret->start = start;
}
/* If end later than requested adjust length */
@@ -1079,7 +1075,6 @@
* has no bearing on split ranges from server to client.
*/
save_op_range = rng_ctx->tc_op_range;
- mb();
rng_ctx->tc_op_range = rng_ctx->tc_curchunk->rc_range;
nr_ret = svrtok_clear(
Index: tokseq.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/tokseq.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- tokseq.c 24 Mar 2009 04:26:28 -0000 1.8
+++ tokseq.c 27 Oct 2009 03:18:29 -0000 1.9
@@ -112,7 +112,7 @@
((tokseqnum_t)(newtqp->tsq_seq - base_seq) > (tokseqnum_t)((*tqpp)->tsq_seq - base_seq)))
tqpp = &((*tqpp)->tsq_next);
#ifdef TOKEN_TOKSEQ_RACE_FIX
- mb();
+ rmb();
#endif
newtqp->tsq_next = *tqpp;
*tqpp = newtqp;
@@ -156,6 +156,7 @@
/* Called w. tcb locked (via whatever means).
* Could be a macro for speed.
*/
+/* SSI_XXX: Not called with tcb locked. serverfunc() may acquire tcb lock. */
void
tokseq_accept(tokseq_t *tsp, int agent, tokseqnum_t recvd,
void (*serverfunc)(void *), void *args, int argsize,
@@ -372,9 +373,6 @@
list = tsp->ts_conns[agent].tsp_queue;
qlen = tsp->ts_conns[agent].tsp_qlen;
-#ifdef TOKEN_TOKSEQ_RACE_FIX
- mb();
-#endif
tsp->ts_conns[agent].tsp_qlen = 0;
tsp->ts_conns[agent].tsp_queue = NULL;
Index: clitok.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/clitok.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- clitok.c 24 Mar 2009 04:26:28 -0000 1.8
+++ clitok.c 27 Oct 2009 03:18:29 -0000 1.9
@@ -257,19 +257,19 @@
/* Initialize a fifo (make it empty) */
#ifdef TOKEN_FIFO_LINUX_LIST
static inline void
-#else
-STATIC void
-#endif
initfifo(fifo_t *fifop)
{
-#ifdef TOKEN_FIFO_LINUX_LIST
INIT_LIST_HEAD(fifop);
+}
#else
+STATIC void
+initfifo(fifo_t *fifop)
+{
fifop->fifo_req_begin = NULL;
/* For consistency just set end pointer to NULL also */
fifop->fifo_req_end = NULL;
-#endif
}
+#endif
/* Place new entry onto end of a fifo */
#ifdef TOKEN_FIFO_LINUX_LIST
@@ -289,7 +289,7 @@
fifop->fifo_req_end = item;
} else {
fifop->fifo_req_end->req_next = item;
- mb();
+ wmb();
fifop->fifo_req_end = item;
}
item->req_next = NULL;
@@ -308,7 +308,6 @@
if (fifop->fifo_req_begin == NULL)
return NULL;
save_req = fifop->fifo_req_begin;
- mb();
fifop->fifo_req_begin = fifop->fifo_req_begin->req_next;
/* If the last one removed, set end pointer for consistency */
if (fifop->fifo_req_begin == NULL)
@@ -344,7 +343,7 @@
void
nrreq_init(void)
{
- nrreq_cachep = kmem_cache_create("clitok_req_cache",
+ nrreq_cachep = kmem_cache_create("ssi_clitok_req",
sizeof(struct nrreq), 0,
SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
NULL, NULL);
@@ -422,7 +421,6 @@
#endif
LOCK_SPIN_LOCK(&nrreq_free_lock);
reqp->req_next = nrreq_free;
- mb();
nrreq_free = reqp;
nrreq_free_count++;
UNLOCK_SPIN_LOCK(&nrreq_free_lock);
@@ -435,7 +433,7 @@
void
nrrevoke_init(void)
{
- nrrevoke_cachep = kmem_cache_create("clitok_rev_cache",
+ nrrevoke_cachep = kmem_cache_create("ssi_clitok_rev",
sizeof(struct nrrevoke), 0,
SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
NULL, NULL);
@@ -457,9 +455,6 @@
#ifdef CLITOK_KMEM_CACHE
revp = kmem_cache_alloc(nrrevoke_cachep, GFP_KERNEL|__GFP_NOFAIL);
-#ifdef TOKEN_FIFO_LINUX_LIST
- INIT_LIST_HEAD(&revp->rev_reqfifo);
-#endif
#else
LOCK_SPIN_LOCK(&nrrev_free_lock);
if ((revp = nrrev_free)) {
@@ -487,7 +482,6 @@
#else
LOCK_SPIN_LOCK(&nrrev_free_lock);
revp->rev_tcbp = (nrtcb_t *)nrrev_free;
- mb();
nrrev_free = revp;
nrrev_free_count++;
UNLOCK_SPIN_LOCK(&nrrev_free_lock);
@@ -535,13 +529,12 @@
DBG(DBGCLI,("wakeup(0x%x) performed on requestor process\n", reqp));
#ifdef __KERNEL__
#ifdef CFSTOK_INTR
- SIGNAL_INTR_EVENT(&reqp->req_done);
- /* SSI_XXX: what if called more than once? */
- if (tas(&reqp->req_release)) {
- reqp->req_release = 0;
- /* Caller should have TCB lock */
+ if (xchg(&reqp->req_release, TOK_COMPLETED) == TOK_INTERRUPTED) {
+ /* Called with CFSTOK_XLOCK on cnode */
(void) tok_release(objp, reqp->req_tcbp, reqp->req_mode, 0);
- }
+ tok_freereq(reqp);
+ } else
+ SIGNAL_INTR_EVENT(&reqp->req_done);
#else
SIGNAL_EVENT(&(reqp->req_done));
#ifdef NOTYET
@@ -781,10 +774,10 @@
ssi_mask_signals(current, &old_blocked, 1);
WAIT_INTR_EVENT(&request->req_done, 1, &intr);
ssi_unmask_signals(current, &old_blocked, 1);
- if (intr && tas(&request->req_release))
- /* Got interrupted but also got woken */
- intr = request->req_release = 0;
- tok_freereq(request);
+ if (intr && xchg(&request->req_release, TOK_INTERRUPTED) == TOK_COMPLETED)
+ intr = 0; /* Lost the race */
+ if (!intr)
+ tok_freereq(request);
DBG(DBGCLI,("tok_hold: request(0x%x) complete returning\n", request));
return intr;
#else /* !CFSTOK_INTR */
@@ -921,6 +914,9 @@
MSGSEND(objp, REQUEST, (range_off_t)0, (range_off_t)0, request->req_agent,
tcbp->tok_mode, request->req_mode);
}
+#ifdef TOKEN_FIFO_LINUX_LIST
+ rmb();
+#endif
insertfifo(&((tcbp)->tok_reqfifo), request);
return FALSE;
}
@@ -1114,6 +1110,8 @@
tcbp->tok_mode = newmode;
+ barrier();
+
__token_wait_and_hold(objp, tcbp, newmode);
}
@@ -1154,11 +1152,11 @@
return;
}
revp = allocnrrev();
+ initfifo(&revp->rev_reqfifo);
revp->rev_oldmode = oldmode;
revp->rev_newmode = newmode;
revp->rev_agent = agent;
revp->rev_tcbp = tcbp;
- initfifo(&(revp->rev_reqfifo));
if (revoke_internal(objp, revp, direct)) {
/* Process requests waiting behind revoke */
@@ -1744,17 +1742,15 @@
* have to re-send to us, anyway.
*/
if ((revp = tcbp->tok_revptr)) {
+ tcbp->tok_revptr = NULL;
#ifdef TOKEN_FIFO_LINUX_LIST
/* Merge revoke reqfifo with tok_reqfifo */
list_splice_init(&revp->rev_reqfifo, &tcbp->tok_reqfifo);
+ freerev(revp);
#else
fifo = revp->rev_reqfifo;
initfifo(&(revp->rev_reqfifo));
-#endif
freerev(revp);
- tcbp->tok_revptr = NULL;
-
-#ifndef TOKEN_FIFO_LINUX_LIST
/* Merge revoke reqfifo with tok_reqfifo */
while((request = deletefifo(&fifo)))
insertfifo(&tcbp->tok_reqfifo, request);
Index: svrtok.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/svrtok.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- svrtok.c 24 Mar 2009 04:26:28 -0000 1.7
+++ svrtok.c 27 Oct 2009 03:18:29 -0000 1.8
@@ -143,10 +143,9 @@
fifop->fifo_req_end = item;
} else {
fifop->fifo_req_end->wan_next = item;
- mb();
+ wmb();
fifop->fifo_req_end = item;
}
- mb();
item->wan_next = NULL;
return;
#endif
@@ -170,12 +169,10 @@
if (fifop->fifo_req_begin == NULL)
return NULL;
save_req = fifop->fifo_req_begin;
- mb();
fifop->fifo_req_begin = fifop->fifo_req_begin->wan_next;
/* If the last one removed, set end pointer for consistency */
if (fifop->fifo_req_begin == NULL)
fifop->fifo_req_end = NULL;
- mb();
save_req->wan_next = NULL;
#endif
return(save_req);
@@ -221,7 +218,7 @@
void
node_ent_init(void)
{
- node_ent_cachep = kmem_cache_create("svrtok_nd_cache",
+ node_ent_cachep = kmem_cache_create("ssi_svrtok_nd",
sizeof(struct node_ent), 0,
SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
NULL, NULL);
@@ -260,8 +257,8 @@
newnode->nd_agent = agent;
newnode->nd_mode = mode;
newnode->nd_flags = flags;
- svrinitfifo(&(newnode->nd_givefifo));
newnode->nd_next = NULL;
+ svrinitfifo(&(newnode->nd_givefifo));
return(newnode);
}
@@ -303,7 +300,6 @@
/* Put node entry only free list */
LOCK_SPIN_LOCK(&node_free_lock);
savep->nd_next = node_free;
- mb();
node_free = savep;
node_free_count++;
UNLOCK_SPIN_LOCK(&node_free_lock);
@@ -326,9 +322,9 @@
int newmode,
int getinstall)
{
+ int oldmode;
struct node_ent **savepp;
struct node_ent *next;
- int oldmode;
for (savepp = &(tcbp->tok_ndlist); *savepp;
savepp = &((*savepp)->nd_next)) {
@@ -358,14 +354,14 @@
#endif
oldmode = (*savepp)->nd_mode;
- mb();
+ rmb();
(*savepp)->nd_mode = newmode;
return oldmode;
}
}
/* Insert newly allocated in agent order */
next = *savepp;
- mb();
+ rmb();
*savepp = svrallocnode(agent, newmode, (short)0);
(*savepp)->nd_next = next;
@@ -579,8 +575,6 @@
for (savepp = &(tcbp->tok_ndlist); *savepp;
savepp = &((*savepp)->nd_next)) {
- if (GT_AGENT((*savepp)->nd_agent, agent))
- break;
if (EQ_AGENT((*savepp)->nd_agent, agent)) {
#ifdef NRSVRFIFO_LINUX_LIST
struct nrwant *tmp;
@@ -601,6 +595,8 @@
/* Only one node_ent per agent */
return;
}
+ if (GT_AGENT((*savepp)->nd_agent, agent))
+ break;
}
}
@@ -645,8 +641,8 @@
* Since reqfifo isn't being duplicated, we
* should attempt to process the givebacks.
*/
- for (nodepp = &(newtcbp->tok_ndlist); *nodepp ;
- nodepp = &(*nodepp)->nd_next) {
+ for (nodepp = &(newtcbp->tok_ndlist); *nodepp;
+ nodepp = &((*nodepp)->nd_next)) {
process_give(objp, newtcbp, nodepp);
if ((*nodepp) == NULL)
break;
@@ -661,7 +657,7 @@
void
nrwant_init(void)
{
- nrwant_cachep = kmem_cache_create("svrtok_wt_cache",
+ nrwant_cachep = kmem_cache_create("ssi_svrtok_wt",
sizeof(struct nrwant), 0,
SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
NULL, NULL);
@@ -1471,7 +1467,9 @@
svrinsertfifo(&tcbp->tok_reqfifo, wantp);
return FALSE;
}
-
+#ifdef NRSVRFIFO_LINUX_LIST
+ rmb();
+#endif
svrinsertfifo(&tcbp->tok_reqfifo, wantp);
if (wantp->wan_flags & SVRTOK_QUERY) {
@@ -1941,7 +1939,6 @@
nrsvrtcb_t *tcbp,
agent_t agent)
{
- int ret;
#if defined(DEBUG) || defined(SIMUL)
char str[DBGSTRLEN];
#endif
@@ -2006,7 +2003,7 @@
if (!(wantp->wan_flags & SVRTOK_QUERY) &&
EQ_AGENT(wantp->wan_agent, agent)) {
#ifdef NRSVRFIFO_LINUX_LIST
- list_del_init(&wantp->wan_list);
+ list_del(&wantp->wan_list);
#endif
freenrwant(wantp);
} else
@@ -2028,9 +2025,7 @@
}
/* We will return TRUE to caller if all tokens back at server */
- ret = svrtok_notokens(tcbp);
-
- return ret;
+ return svrtok_notokens(tcbp);
}
/*
@@ -2628,7 +2623,6 @@
nrwant_free_count -= chunk;
nrwant_free = nrwantp;
UNLOCK_SPIN_LOCK(&nrwant_free_lock);
- mb();
nrwantp = startp;
for (; chunk > 0; chunk--) {
nextp = nrwantp->wan_next;
Index: msgsup.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/msgsup.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- msgsup.c 19 Feb 2009 08:01:02 -0000 1.8
+++ msgsup.c 27 Oct 2009 03:18:29 -0000 1.9
@@ -60,6 +60,12 @@
#ifdef __KERNEL__
#include <linux/sched.h>
+#ifdef RCU_MSGSUP_HASH
+#include <linux/bootmem.h>
+#include <linux/hash.h>
+#include <cluster/config.h>
+#endif
+#ifdef SSI_SKIP
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
@@ -77,9 +83,10 @@
#include <asm/system.h>
#include <cluster/nsc.h>
#include <cluster/synch.h>
+#include <cluster/assert.h>
+#endif /* SSI_SKIP */
#include <cluster/ssi/token/tokseq.h>
#include <cluster/ssi/token/msgsup.h>
-#include <cluster/assert.h>
#else /* ~__KERNEL__ */
#include <stdio.h>
#include <string.h>
@@ -105,7 +112,7 @@
#define MSG_LOCK(lock) LOCK_SPIN_LOCK(&(lock))
#define MSG_UNLOCK(lock) UNLOCK_SPIN_LOCK(&(lock))
#define MSG_INITLOCK(lock) INIT_SPIN_LOCK(&(lock))
-#define MSG_LOCK_T(lock) SPIN_LOCK_T lock
+#define MSG_LOCK_T(lock) SPIN_LOCK_T lock __cacheline_aligned_in_smp
#else /* ~ __KERNEL__ */
#define MSG_LOCK(lock)
#define MSG_UNLOCK(lock)
@@ -117,7 +124,10 @@
struct msg {
#ifdef RCU_MSGSUP
struct list_head msg_list;
- struct rcu_head msg_rcu;
+ long id;
+#endif
+#ifdef RCU_MSGSUP_HASH
+ int in_process_msgs; /* non-zero: being processed by process_msgs() */
#endif
object_t obj;
int op;
@@ -126,17 +136,22 @@
agent_t agent;
int oldmode;
int newmode;
+#ifndef RCU_MSGSUP
long id;
+#endif
int seq;
+#ifdef RCU_MSGSUP
+ struct rcu_head msg_rcu;
+#else
#ifdef DEBUG
pid_t pid;
#endif /* DEBUG */
-#ifndef RCU_MSGSUP
struct msg *next;
struct msg *back;
-#endif
+#endif /* !RCU_MSGSUP */
};
+#ifndef RCU_MSGSUP_HASH
struct id {
#ifdef RCU_MSGSUP
struct list_head id_list;
@@ -150,16 +165,23 @@
pid_t pid;
#endif
};
+#endif /* !RCU_MSGSUP_HASH */
#ifdef RCU_MSGSUP
STATIC kmem_cache_t *msgsup_cachep;
+#ifdef RCU_MSGSUP_HASH
+STATIC struct list_head *msgsup_hashtable;
+STATIC unsigned int m_hash_shift;
+#define MSG_HASH hash_long(NSC_UNIQUE_ID, m_hash_shift)
+#else
STATIC kmem_cache_t *msgsup_id_cachep;
STATIC LIST_HEAD(msgsup_head);
STATIC LIST_HEAD(msgsup_idlist);
+MSG_LOCK_T(msgsup_idlist_lock);
#ifdef DEBUG
STATIC int msgsup_head_count = 0;
#endif
-MSG_LOCK_T(msgsup_idlist_lock);
+#endif /* !RCU_MSGSUP_HASH */
#else /* !RCU_MSGSUP */
STATIC struct msg *msgsup_head = NULL;
STATIC struct msg *msg_free = NULL;
@@ -177,6 +199,7 @@
#endif
#ifdef __KERNEL__
+#ifndef RCU_MSGSUP_HASH
/*
* See if id is already on list.
* Called/Returns with MSG_LOCK() held.
@@ -254,9 +277,8 @@
void
msgsup_id_free(struct rcu_head *id_rcu)
{
- struct id *ident = container_of(id_rcu, struct id, id_rcu);
-
- kmem_cache_free(msgsup_id_cachep, ident);
+ kmem_cache_free(msgsup_id_cachep,
+ container_of(id_rcu, struct id, id_rcu));
}
#endif /* RCU_MSGSUP */
@@ -275,6 +297,7 @@
if (ident->id != id)
continue;
MSG_LOCK(msgsup_idlist_lock);
+ /* Linux: No race. id == NSC_UNIQUE_ID == current */
list_del_rcu(&ident->id_list);
MSG_UNLOCK(msgsup_idlist_lock);
rcu_read_unlock();
@@ -302,22 +325,45 @@
panic("msgsup_delid: entry not found");
}
+#endif /* !RCU_MSGSUP_HASH */
void
msgsup_init()
{
+#ifdef RCU_MSGSUP_HASH
+ int loop;
+
+ msgsup_hashtable =
+ alloc_large_system_hash("SSI Token Message",
+ sizeof(struct list_head),
+ 0,
+ (num_physpages >= 128 * 1024) ?
+ (25 - PAGE_SHIFT) :
+ (27 - PAGE_SHIFT),
+ HASH_HIGHMEM,
+ &m_hash_shift,
+ NULL,
+ (MAXLOCPID + 1) >> 4);
+
+ for (loop = 0; loop < (1 << m_hash_shift); loop++)
+ INIT_LIST_HEAD(&msgsup_hashtable[loop]);
+#endif /* RCU_MSGSUP_HASH */
+
MSG_INITLOCK(msg_lock);
#ifdef RCU_MSGSUP
- MSG_INITLOCK(msgsup_idlist_lock);
- msgsup_cachep = kmem_cache_create("msgsup_msg_cache",
+ msgsup_cachep = kmem_cache_create("ssi_msgsup_msg",
sizeof(struct msg), 0,
SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
NULL, NULL);
- msgsup_id_cachep = kmem_cache_create("msgsup_id_cache",
+#ifndef RCU_MSGSUP_HASH
+ MSG_INITLOCK(msgsup_idlist_lock);
+
+ msgsup_id_cachep = kmem_cache_create("ssi_msgsup_id",
sizeof(struct id), 0,
SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
NULL, NULL);
-#endif
+#endif /* !RCU_MSGSUP_HASH */
+#endif /* RCU_MSGSUP */
}
#endif /* __KERNEL__ */
@@ -339,6 +385,9 @@
#ifdef RCU_MSGSUP
msgp = kmem_cache_alloc(msgsup_cachep, GFP_KERNEL|__GFP_NOFAIL);
INIT_LIST_HEAD(&msgp->msg_list);
+#ifdef RCU_MSGSUP_HASH
+ msgp->in_process_msgs = 0;
+#endif
INIT_RCU_HEAD(&msgp->msg_rcu);
#else /* !RCU_MSGSUP */
MSG_LOCK(msg_lock);
@@ -390,12 +439,15 @@
/* Add new messages to back of list */
#ifdef RCU_MSGSUP
MSG_LOCK(msg_lock);
+#ifdef RCU_MSGSUP_HASH
+ list_add_tail_rcu(&msgp->msg_list, &msgsup_hashtable[MSG_HASH]);
+#else
list_add_tail_rcu(&msgp->msg_list, &msgsup_head);
#ifdef DEBUG
msgsup_head_count++;
SSI_ASSERT(msgsup_head_count < 10000);
#endif
- MSG_UNLOCK(msg_lock);
+#endif /* !RCU_MSGSUP_HASH */
#else /* !RCU_MSGSUP */
if (msgsup_head) {
msgp->next = msgsup_head;
@@ -409,9 +461,9 @@
}
msgsup_head_count++;
SSI_ASSERT(msgsup_head_count < 10000);
+#endif /* !RCU_MSGSUP */
MSG_UNLOCK(msg_lock);
-#endif /* !RCU_MSGSUP */
#endif /* __KERNEL__ */
#if defined(SIMUL)
if (op & CFSCLI) {
@@ -430,9 +482,8 @@
void
msgsup_free(struct rcu_head *msg_rcu)
{
- struct msg *msgp = container_of(msg_rcu, struct msg, msg_rcu);
-
- kmem_cache_free(msgsup_cachep, msgp);
+ kmem_cache_free(msgsup_cachep,
+ container_of(msg_rcu, struct msg, msg_rcu));
}
#endif /* RCU_MSGSUP */
@@ -440,11 +491,21 @@
process_msgs(int force)
{
struct msg *save;
+#ifdef RCU_MSGSUP_HASH
+ unsigned long hashval = MSG_HASH;
+ int recurse = FALSE;
+#else
int recurse;
/* PERF: Optimize NOOP case */
#ifdef RCU_MSGSUP
- if (list_empty(&msgsup_head))
+ rcu_read_lock();
+ list_for_each_entry_rcu(save, &msgsup_head, msg_list) {
+ if (save->id == NSC_UNIQUE_ID)
+ break;
+ }
+ rcu_read_unlock();
+ if (&save->msg_list == &msgsup_head) /* NOOP */
return;
recurse = msgsup_findid(NSC_UNIQUE_ID);
@@ -472,16 +533,56 @@
#endif
} else
msgsup_addid(NSC_UNIQUE_ID);
+#endif /* !RCU_MSGSUP_HASH */
restart:
#ifdef RCU_MSGSUP
+#ifdef RCU_MSGSUP_HASH
+ rcu_read_lock();
+ list_for_each_entry_rcu(save, &msgsup_hashtable[hashval], msg_list) {
+ if (save->id != NSC_UNIQUE_ID)
+ continue;
+ /* SSI: No race. NSC_UNIQUE_ID == current */
+ if (save->in_process_msgs) {
+ if (!recurse) {
+ if (!force)
+ break;
+ WARN_ON(save->in_process_msgs++ > 16);
+ recurse = TRUE;
+ }
+ /* already being processed */
+ continue;
+ }
+ save->in_process_msgs = 1;
+ rcu_read_unlock();
+
+#ifdef DEBUG
+ if (recurse)
+ printk(KERN_WARNING
+ "%s: forced recursive processing\n", __FUNCTION__);
+#endif
+
+ TRANSPORT((&(save->obj)))(&(save->obj), save->seq,
+ save->op, save->oldmode, save->newmode, save->agent,
+ save->start, save->len);
+
+ /* Only remove from list after recursive processing. */
+ MSG_LOCK(msg_lock);
+ list_del_rcu(&save->msg_list);
+ MSG_UNLOCK(msg_lock);
+
+ call_rcu(&save->msg_rcu, msgsup_free);
+ goto restart;
+ }
+ rcu_read_unlock();
+#else /* !RCU_MSGSUP_HASH */
rcu_read_lock();
list_for_each_entry_rcu(save, &msgsup_head, msg_list) {
if (save->id != NSC_UNIQUE_ID)
continue;
MSG_LOCK(msg_lock);
#ifdef SSI_SKIP
- /* Linux: No need to check. See NSC_UNIQUE_ID */
+ /* SSI: No race. NSC_UNIQUE_ID == current */
if (save->id == 0) {
MSG_UNLOCK(msg_lock);
goto restart;
@@ -504,6 +605,7 @@
goto restart;
}
rcu_read_unlock();
+#endif /* !RCU_MSGSUP_HASH */
#else /* !RCU_MSGSUP */
for (save = msgsup_head ; save ; save = save->next) {
@@ -548,8 +650,10 @@
}
#endif /* !RCU_MSGSUP */
+#ifndef RCU_MSGSUP_HASH
if (!recurse)
msgsup_delid(NSC_UNIQUE_ID);
+#endif
#ifndef RCU_MSGSUP
MSG_UNLOCK(msg_lock);
Index: mhsvrtok.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/mhsvrtok.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mhsvrtok.c 3 Feb 2009 06:18:12 -0000 1.7
+++ mhsvrtok.c 27 Oct 2009 03:18:29 -0000 1.8
@@ -76,7 +76,7 @@
void
mhnode_init(void)
{
- mhnode_cachep = kmem_cache_create("mhsvrtok_cache",
+ mhnode_cachep = kmem_cache_create("ssi_mhsvrtok",
sizeof(struct mhnode_ent), 0,
SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
NULL, NULL);
@@ -142,9 +142,6 @@
/* Put node entry only free list */
LOCK_SPIN_LOCK(&mhnode_free_lock);
savep->nd_next = mhnode_free;
-#ifdef MHSVRTOK_RACE_FIX
- mb();
-#endif
mhnode_free = savep;
mhnode_free_count++;
UNLOCK_SPIN_LOCK(&mhnode_free_lock);
@@ -176,7 +173,7 @@
/* Insert newly allocated in agent order */
next = *savepp;
#ifdef MHSVRTOK_RACE_FIX
- mb();
+ rmb();
#endif
*savepp = mhsvrallocnode(agent);
(*savepp)->nd_next = next;
@@ -185,7 +182,6 @@
found:
(*savepp)->nd_numtoks++;
- return;
}
STATIC void
@@ -193,7 +189,7 @@
object_t *objp,
mhsvrtcb_t *tcbp,
agent_t agent,
- int count)
+ unsigned int count)
{
struct mhnode_ent **savepp;
@@ -209,8 +205,11 @@
mhsvrfreenode(tcbp, savepp);
}
+ /* Only one mhnode_ent per agent */
return;
}
+ if (GT_AGENT((*savepp)->nd_agent, agent))
+ break;
}
#if defined(DEBUG) || defined(SIMUL)
@@ -234,8 +233,6 @@
for (savepp = &(tcbp->tok_ndlist); *savepp;
savepp = &((*savepp)->nd_next)) {
- if (GT_AGENT((*savepp)->nd_agent, agent))
- break;
if (EQ_AGENT((*savepp)->nd_agent, agent)) {
(*savepp)->nd_numtoks = 0;
mhsvrfreenode(tcbp, savepp);
@@ -243,6 +240,8 @@
/* Only one mhnode_ent per agent */
return;
}
+ if (GT_AGENT((*savepp)->nd_agent, agent))
+ break;
}
}
@@ -403,7 +402,6 @@
mhsvrtcb_t *tcbp,
agent_t agent)
{
- int ret;
#if defined(DEBUG) || defined(SIMUL)
char str[DBGSTRLEN];
#endif
@@ -414,9 +412,7 @@
mhsvrclearnode(tcbp, agent);
/* We will return TRUE to caller if all tokens back at server */
- ret = mhsvrtok_notokens(tcbp);
-
- return ret;
+ return mhsvrtok_notokens(tcbp);
}
#if !defined(__KERNEL__) || defined(DEBUG) || defined(DEBUG_TOOLS)
------------------------------------------------------------------------------
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