[SSI] openssi/kernel/cluster/ssi/token clitok.c, 1.6, 1.7 mhsvrtok.c, 1.6, 1.7 msgsup.c, 1.6, 1.7 rsvrtok.c, 1.6, 1.7 svrtok.c, 1.5, 1.6
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-serv8553/cluster/ssi/token
Modified Files:
Tag: OPENSSI-FC
clitok.c mhsvrtok.c msgsup.c rsvrtok.c svrtok.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.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- rsvrtok.c 21 Oct 2004 23:40:49 -0000 1.6
+++ rsvrtok.c 3 Feb 2009 06:18:12 -0000 1.7
@@ -293,10 +293,13 @@
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,
@@ -586,6 +589,7 @@
/* 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 */
@@ -1075,6 +1079,7 @@
* 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: svrtok.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/svrtok.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- svrtok.c 21 Oct 2004 23:40:49 -0000 1.5
+++ svrtok.c 3 Feb 2009 06:18:13 -0000 1.6
@@ -110,44 +110,74 @@
/* NOTREACHED */
}
+#ifdef NRSVRFIFO_LINUX_LIST
+static inline void
+#else
STATIC void
-svrinitfifo(struct nrsvrfifo *fifop)
+#endif
+svrinitfifo(nrsvrfifo_t *fifop)
{
[...1041 lines suppressed...]
}
#endif /* !__KERNEL__ || DEBUG || DEBUG_TOOLS */
+#ifndef SVRTOK_KMEM_CACHE
int
svrtok_nd_free_memory(int count, unsigned int gfp_mask)
{
@@ -2281,6 +2627,7 @@
nrwant_free_count -= chunk;
nrwant_free = nrwantp;
UNLOCK_SPIN_LOCK(&nrwant_free_lock);
+ mb();
nrwantp = startp;
for (; chunk > 0; chunk--) {
nextp = nrwantp->wan_next;
@@ -2295,3 +2642,4 @@
return nrwant_free_count;
}
+#endif /* !SVRTOK_KMEM_CACHE */
Index: msgsup.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/msgsup.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- msgsup.c 10 Oct 2008 08:10:32 -0000 1.6
+++ msgsup.c 3 Feb 2009 06:18:12 -0000 1.7
@@ -115,6 +115,10 @@
#ifdef __KERNEL__
struct msg {
+#ifdef RCU_MSGSUP
+ struct list_head msg_list;
+ struct rcu_head msg_rcu;
+#endif
object_t obj;
int op;
range_off_t start;
@@ -127,28 +131,45 @@
#ifdef DEBUG
pid_t pid;
#endif /* DEBUG */
+#ifndef RCU_MSGSUP
struct msg *next;
struct msg *back;
+#endif
};
struct id {
+#ifdef RCU_MSGSUP
+ struct list_head id_list;
+ struct rcu_head id_rcu;
+#endif
long id;
+#ifndef RCU_MSGSUP
struct id *next;
+#endif
#ifdef DEBUG
pid_t pid;
#endif
};
-#endif
-#if defined(__KERNEL__)
-STATIC struct msg *msgsup_head = NULL;
+#ifdef RCU_MSGSUP
+STATIC kmem_cache_t *msgsup_cachep;
+STATIC kmem_cache_t *msgsup_id_cachep;
+STATIC LIST_HEAD(msgsup_head);
+STATIC LIST_HEAD(msgsup_idlist);
+#ifdef DEBUG
STATIC int msgsup_head_count = 0;
-STATIC struct id *msgsup_idlist = NULL;
+#endif
+MSG_LOCK_T(msgsup_idlist_lock);
+#else /* !RCU_MSGSUP */
+STATIC struct msg *msgsup_head = NULL;
STATIC struct msg *msg_free = NULL;
-STATIC int msg_free_count = 0;
-STATIC MSG_LOCK_T(msg_lock);
+STATIC struct id *msgsup_idlist = NULL;
STATIC struct id *msg_free_idlist = NULL;
+STATIC int msg_free_count = 0;
STATIC int msg_free_idlist_count = 0;
+STATIC int msgsup_head_count = 0;
+#endif /* !RCU_MSGSUP */
+STATIC MSG_LOCK_T(msg_lock);
#endif /* __KERNEL__ */
#ifdef DEBUG
@@ -165,11 +186,22 @@
{
struct id *ident;
+#ifdef RCU_MSGSUP
+ rcu_read_lock();
+ list_for_each_entry_rcu(ident, &msgsup_idlist, id_list) {
+ if (ident->id != id)
+ continue;
+ rcu_read_unlock();
+ return TRUE;
+ }
+ rcu_read_unlock();
+#else
for (ident = msgsup_idlist; ident ; ident = ident->next) {
if (ident->id == id) {
return TRUE;
}
}
+#endif
return FALSE;
}
@@ -181,6 +213,20 @@
STATIC void
msgsup_addid(long id)
{
+#ifdef RCU_MSGSUP
+ struct id *newid;
+
+ newid = kmem_cache_alloc(msgsup_id_cachep, GFP_KERNEL|__GFP_NOFAIL);
+ INIT_LIST_HEAD(&newid->id_list);
+ INIT_RCU_HEAD(&newid->id_rcu);
+ newid->id = id;
+#ifdef DEBUG
+ newid->pid = NSC_MY_PID;
+#endif
+ MSG_LOCK(msgsup_idlist_lock);
+ list_add_rcu(&newid->id_list, &msgsup_idlist);
+ MSG_UNLOCK(msgsup_idlist_lock);
+#else /* !RCU_MSGSUP */
struct id *newid;
if ((newid = msg_free_idlist)) {
@@ -200,12 +246,20 @@
newid->pid = NSC_MY_PID;
#endif
newid->next = msgsup_idlist;
-#ifdef TOKEN_MSGSUP_RACE_FIX
- mb();
-#endif
msgsup_idlist = newid;
+#endif /* !RCU_MSGSUP */
}
+#ifdef RCU_MSGSUP
+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);
+}
+#endif /* RCU_MSGSUP */
+
/*
* Remove an id from list.
* Called/Returns with MSG_LOCK() held.
@@ -213,28 +267,40 @@
STATIC void
msgsup_delid(long id)
{
- struct id **identp;
struct id *ident;
+#ifdef RCU_MSGSUP
+ struct list_head *pos, *n;
+
+ rcu_read_lock();
+ list_for_each_safe_rcu(pos, n, &msgsup_idlist) {
+ ident = list_entry(pos, typeof(*ident), id_list);
+ if (ident->id != id)
+ continue;
+ rcu_read_unlock();
+ MSG_LOCK(msgsup_idlist_lock);
+ list_del_rcu(&ident->id_list);
+ MSG_UNLOCK(msgsup_idlist_lock);
+ call_rcu(&ident->id_rcu, msgsup_id_free);
+ return;
+ }
+ rcu_read_unlock();
+#else
+ struct id **identp;
for (identp = &msgsup_idlist;*identp; identp = &((*identp)->next)) {
if ((*identp)->id == id) {
ident = *identp;
-#ifdef TOKEN_MSGSUP_RACE_FIX
- mb();
-#endif
/* delete entry */
*identp = (*identp)->next;
ident->next = msg_free_idlist;
-#ifdef TOKEN_MSGSUP_RACE_FIX
- mb();
-#endif
msg_free_idlist = ident;
msg_free_idlist_count++;
return;
}
}
+#endif /* !RCU_MSGSUP */
panic("msgsup_delid: entry not found");
}
@@ -243,6 +309,17 @@
msgsup_init()
{
MSG_INITLOCK(msg_lock);
+#ifdef RCU_MSGSUP
+ MSG_INITLOCK(msgsup_idlist_lock);
+ msgsup_cachep = kmem_cache_create("msgsup_msg_cache",
+ sizeof(struct msg), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
+ msgsup_id_cachep = kmem_cache_create("msgsup_id_cache",
+ sizeof(struct id), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
+#endif
}
#endif /* __KERNEL__ */
@@ -261,6 +338,11 @@
SSI_ASSERT(op != HINT);
+#ifdef RCU_MSGSUP
+ msgp = kmem_cache_alloc(msgsup_cachep, GFP_KERNEL|__GFP_NOFAIL);
+ INIT_LIST_HEAD(&msgp->msg_list);
+ INIT_RCU_HEAD(&msgp->msg_rcu);
+#else /* !RCU_MSGSUP */
MSG_LOCK(msg_lock);
if ((msgp = msg_free)) {
@@ -275,6 +357,7 @@
}
MSG_LOCK(msg_lock);
}
+#endif /* !RCU_MSGSUP */
msgp->obj = *objp; /* Copy object_t structure */
/* Call the hold_obj function if one is provided for the object */
@@ -307,13 +390,19 @@
#endif
/* Add new messages to back of list */
+#ifdef RCU_MSGSUP
+ MSG_LOCK(msg_lock);
+ 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);
+#else /* !RCU_MSGSUP */
if (msgsup_head) {
msgp->next = msgsup_head;
msgp->back = msgsup_head->back;
msgsup_head->back->next = msgp;
-#ifdef TOKEN_MSGSUP_RACE_FIX
- smp_wmb();
-#endif
msgsup_head->back = msgp;
} else {
msgp->next = msgp;
@@ -324,6 +413,7 @@
SSI_ASSERT(msgsup_head_count < 10000);
MSG_UNLOCK(msg_lock);
+#endif /* !RCU_MSGSUP */
#endif /* __KERNEL__ */
#if defined(SIMUL)
if (op & CFSCLI) {
@@ -338,18 +428,41 @@
}
#if defined(__KERNEL__)
+#ifdef RCU_MSGSUP
+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);
+}
+#endif /* RCU_MSGSUP */
+
void
process_msgs(int force)
{
+#ifdef RCU_MSGSUP
+ struct list_head *pos, *n;
+#endif
struct msg *save;
- int recurse = FALSE;
+ int recurse;
/* PERF: Optimize NOOP case */
+#ifdef RCU_MSGSUP
+ if (list_empty(&msgsup_head))
+ return;
+
+ recurse = msgsup_findid(NSC_UNIQUE_ID);
+ if (recurse) {
+ if (!force)
+ return;
+#else /* !RCU_MSGSUP */
if (msgsup_head == NULL)
return;
MSG_LOCK(msg_lock);
+ recurse = FALSE;
if (msgsup_findid(NSC_UNIQUE_ID)) {
if (!force) {
MSG_UNLOCK(msg_lock);
@@ -357,16 +470,47 @@
}
recurse = TRUE;
+#endif /* !RCU_MSGSUP */
#ifdef DEBUG
printk(KERN_WARNING
"process_msgs: forced recursive processing\n");
#endif
- }
-
- if (!recurse)
+ } else
msgsup_addid(NSC_UNIQUE_ID);
restart:
+#ifdef RCU_MSGSUP
+ rcu_read_lock();
+ list_for_each_safe_rcu(pos, n, &msgsup_head) {
+ save = list_entry(pos, typeof(*save), 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 */
+ if (save->id == 0) {
+ MSG_UNLOCK(msg_lock);
+ goto restart;
+ }
+ save->id = 0;
+#endif
+ list_del_rcu(&save->msg_list);
+#ifdef DEBUG
+ msgsup_head_count--;
+ SSI_ASSERT(msgsup_head_count >= 0);
+#endif
+ MSG_UNLOCK(msg_lock);
+ rcu_read_unlock();
+
+ TRANSPORT((&(save->obj)))(&(save->obj), save->seq,
+ save->op, save->oldmode, save->newmode, save->agent,
+ save->start, save->len);
+
+ call_rcu(&save->msg_rcu, msgsup_free);
+ goto restart;
+ }
+ rcu_read_unlock();
+#else /* !RCU_MSGSUP */
for (save = msgsup_head ; save ; save = save->next) {
if (save->id != NSC_UNIQUE_ID) {
@@ -403,22 +547,23 @@
MSG_LOCK(msg_lock);
save->next = msg_free;
-#ifdef TOKEN_MSGSUP_RACE_FIX
- mb();
-#endif
msg_free = save;
msg_free_count++;
goto restart;
}
+#endif /* !RCU_MSGSUP */
if (!recurse)
msgsup_delid(NSC_UNIQUE_ID);
+#ifndef RCU_MSGSUP
MSG_UNLOCK(msg_lock);
+#endif
}
#endif /* __KERNEL__ */
+#ifndef RCU_MSGSUP
int
msgsup_msg_free_memory(int count, unsigned int gfp_mask)
{
@@ -489,3 +634,4 @@
}
return msg_free_idlist_count;
}
+#endif /* !RCU_MSGSUP */
Index: clitok.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/clitok.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- clitok.c 10 Oct 2008 08:10:32 -0000 1.6
+++ clitok.c 3 Feb 2009 06:18:12 -0000 1.7
@@ -74,12 +74,16 @@
#define printf(a)
#endif
-STATIC void initfifo(struct fifo *fifop);
+STATIC void initfifo(fifo_t *fifop);
int check_req(object_t *objp, nrtcb_t *tcbp, int mode);
STATIC int get_hold(object_t *objp, struct nrreq *request, int flags);
STATIC int revoke_internal(object_t *objp, struct nrrevoke *revp, int direct);
STATIC void complete_req(object_t *objp, struct nrreq *);
+#ifdef CFSTOK_INTR
+int tok_wait(void *cookie);
+#else
void tok_wait(nrtcb_t *tcbp, void *cookie);
+#endif
STATIC int check_revok(object_t *, nrtcb_t *, int , int);
#ifdef SIMUL
@@ -127,17 +131,26 @@
once on the first line of fifo output
*/
STATIC void
-printfifo(object_t *objp, char *indent, char *msg, struct fifo *fifo)
+printfifo(object_t *objp, char *indent, char *msg, fifo_t *fifo)
{
struct nrreq *reqp;
+#ifdef TOKEN_FIFO_LINUX_LIST
+ printk(KERN_DEBUG "%s%s begin %p end %p\n", indent, msg,
+ list_entry(fifo->next, struct nrreq, req_list),
+ list_entry(fifo->prev, struct nrreq, req_list));
+
+ list_for_each_entry(reqp, fifo, req_list)
+ printk(KERN_DEBUG "\t%s REQ mode %s objp 0x%p\n", indent,
+ MSTR(objp, reqp->req_mode), reqp->req_objp);
+#else
printk(KERN_DEBUG "%s%s begin %s end %s\n", indent, msg,
ptr(fifo->fifo_req_begin), ptr(fifo->fifo_req_end));
for (reqp = fifo->fifo_req_begin;reqp;reqp= reqp->req_next)
printk(KERN_DEBUG "\t%s REQ mode %s objp 0x%p\n", indent,
MSTR(objp, reqp->req_mode), reqp->req_objp);
-
+#endif
}
@@ -153,10 +166,20 @@
printk(KERN_DEBUG "TCB 0x%p", tcbp);
printk(KERN_DEBUG "\t");
printk(KERN_DEBUG "%s %d", MSTR(objp,tcbp->tok_mode), tcbp->tok_hld_count);
+#ifdef TOKEN_FIFO_LINUX_LIST
+ if (_tok_request(tcbp)) {
+ struct nrreq *req = tok_request(tcbp);
+
+ printk(KERN_DEBUG " req: %s%s",
+ MSTR(objp, req->req_mode),
+ (((&req->req_list)->next != &tcbp->tok_reqfifo) ? "..." : ""));
+ }
+#else
if (tcbp->tok_request)
printk(KERN_DEBUG " req: %s%s",
MSTR(objp,tcbp->tok_request->req_mode),
(tcbp->tok_request->req_next ? "..." : ""));
+#endif /* !TOKEN_FIFO_LINUX_LIST */
}
#if defined(__KERNEL__)
@@ -232,35 +255,52 @@
/* Fifo manipluation routines */
/* Initialize a fifo (make it empty) */
+#ifdef TOKEN_FIFO_LINUX_LIST
+static inline void
+#else
STATIC void
-initfifo(struct fifo *fifop)
+#endif
+initfifo(fifo_t *fifop)
{
+#ifdef TOKEN_FIFO_LINUX_LIST
+ INIT_LIST_HEAD(fifop);
+#else
fifop->fifo_req_begin = NULL;
/* For consistency just set end pointer to NULL also */
fifop->fifo_req_end = NULL;
+#endif
}
/* Place new entry onto end of a fifo */
+#ifdef TOKEN_FIFO_LINUX_LIST
+static inline void
+#else
STATIC void
+#endif
insertfifo(
- struct fifo *fifop,
+ fifo_t *fifop,
struct nrreq *item)
{
+#ifdef TOKEN_FIFO_LINUX_LIST
+ list_add_tail(&item->req_list, fifop);
+#else
if (fifop->fifo_req_begin == NULL) { /* First entry */
fifop->fifo_req_begin = item;
fifop->fifo_req_end = item;
} else {
fifop->fifo_req_end->req_next = item;
- smp_wmb();
+ mb();
fifop->fifo_req_end = item;
}
item->req_next = NULL;
return;
+#endif
}
+#ifndef TOKEN_FIFO_LINUX_LIST
/* Retrieve and remove an entry from the front of a fifo */
STATIC struct nrreq *
-deletefifo(struct fifo *fifop)
+deletefifo(fifo_t *fifop)
{
struct nrreq *save_req;
@@ -275,25 +315,47 @@
fifop->fifo_req_end = NULL;
return(save_req);
}
+#endif /* !TOKEN_FIFO_LINUX_LIST */
STATIC int
-countfifo(struct fifo *fifop)
+countfifo(fifo_t *fifop)
{
+#ifdef TOKEN_FIFO_LINUX_LIST
+ struct list_head *pos;
+ int count = 0;
+
+ list_for_each(pos, fifop)
+ count++;
+#else
struct nrreq *req;
int count = 0;
for (req = fifop->fifo_req_begin ; req ; req = req->req_next)
count++;
+#endif
return count;
}
/* Request structure manilpulation routines */
+#ifdef CLITOK_KMEM_CACHE
+STATIC kmem_cache_t *nrreq_cachep;
+
+void
+nrreq_init(void)
+{
+ nrreq_cachep = kmem_cache_create("clitok_req_cache",
+ sizeof(struct nrreq), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
+}
+#else
/* Free request structures */
STATIC struct nrreq *nrreq_free = NULL;
STATIC int nrreq_free_count = 0;
STATIC int nrreq_malloc_count = 0;
SPIN_LOCK_T nrreq_free_lock;
+#endif
/*
* Pull a request structure off the free list or allocate a new one
@@ -303,6 +365,22 @@
{
struct nrreq *reqp;
+#ifdef CLITOK_KMEM_CACHE
+ reqp = kmem_cache_alloc(nrreq_cachep, GFP_KERNEL|__GFP_NOFAIL);
+#ifdef TOKEN_FIFO_LINUX_LIST
+ INIT_LIST_HEAD(&reqp->req_list);
+#endif
+#ifdef __KERNEL__
+#ifdef CFSTOK_INTR
+ INIT_INTR_EVENT(&reqp->req_done);
+#else
+ INIT_EVENT(&reqp->req_done);
+#endif
+#ifdef CFSTOK_INTR
+ reqp->req_release = 0;
+#endif
+#endif
+#else /* !CLITOK_KMEM_CACHE */
LOCK_SPIN_LOCK(&nrreq_free_lock);
if ((reqp = nrreq_free)) {
nrreq_free = reqp->req_next;
@@ -321,6 +399,7 @@
INIT_EVENT(&reqp->req_done);
#endif
}
+#endif /* !CLITOK_KMEM_CACHE */
return reqp;
}
@@ -330,6 +409,14 @@
void
tok_freereq(struct nrreq *reqp)
{
+#ifdef CLITOK_KMEM_CACHE
+#ifdef CFSTOK_INTR
+ DEINIT_INTR_EVENT(&reqp->req_done);
+#else
+ DEINIT_EVENT(&reqp->req_done);
+#endif
+ kmem_cache_free(nrreq_cachep, reqp);
+#else
#ifdef DEBUG
reqp->req_agent = 0;
#endif
@@ -339,12 +426,26 @@
nrreq_free = reqp;
nrreq_free_count++;
UNLOCK_SPIN_LOCK(&nrreq_free_lock);
+#endif /* !CLITOK_KMEM_CACHE */
}
+#ifdef CLITOK_KMEM_CACHE
+STATIC kmem_cache_t *nrrevoke_cachep;
+
+void
+nrrevoke_init(void)
+{
+ nrrevoke_cachep = kmem_cache_create("clitok_rev_cache",
+ sizeof(struct nrrevoke), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
+}
+#else
/* Free revoke structures */
STATIC struct nrrevoke *nrrev_free = NULL;
STATIC int nrrev_free_count = 0;
SPIN_LOCK_T nrrev_free_lock;
+#endif
/*
* Pull a revoke structure off the free list or allocate a new one
@@ -354,6 +455,12 @@
{
struct nrrevoke *revp;
+#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)) {
nrrev_free = (struct nrrevoke *)revp->rev_tcbp;
@@ -365,6 +472,7 @@
if (revp == NULL)
panic("allocnrrev: Can't malloc revoke struct\n");
}
+#endif
return revp;
}
@@ -374,12 +482,16 @@
STATIC void
freerev(struct nrrevoke *revp)
{
+#ifdef CLITOK_KMEM_CACHE
+ kmem_cache_free(nrrevoke_cachep, revp);
+#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);
+#endif
}
/*
@@ -416,15 +528,26 @@
#if defined(DEBUG) || defined(SIMUL)
char str[DBGSTRLEN];
#endif
+#ifdef CFSTOK_INTR
+ extern int tok_release(object_t *, nrtcb_t *, int, int);
+#endif
DBG(DBGCLI,("wakeup(0x%x) performed on requestor process\n", reqp));
#ifdef __KERNEL__
+#ifdef CFSTOK_INTR
+ SIGNAL_INTR_EVENT(&reqp->req_done);
+ if (tas(&reqp->req_release)) {
+ (void) tok_release(objp, reqp->req_tcbp, reqp->req_mode, 0);
+ tok_freereq(reqp);
+ }
+#else
SIGNAL_EVENT(&(reqp->req_done));
#ifdef NOTYET
if (reqp->req_interrupted) {
tok_release(reqp->tcbp, ...);
}
#endif /* NOTYET */
+#endif /* !CFSTOK_INTR */
#endif /* __KERNEL__ */
#ifdef SIMUL
/* Change process Status */
@@ -466,12 +589,17 @@
STATIC void
process_reqfifo(
object_t *objp,
- struct fifo *fifo)
+ fifo_t *fifo)
{
struct nrreq *reqp;
+#ifdef TOKEN_FIFO_LINUX_LIST
+ struct nrreq *tmp;
+ list_for_each_entry_safe(reqp, tmp, fifo, req_list) {
+ list_del(&reqp->req_list);
+#else
while((reqp = (struct nrreq *)deletefifo(fifo))) {
-
+#endif
process_req(objp, reqp);
}
}
@@ -622,12 +750,23 @@
*
* SMP: Unlike other token entry points no locks are held on entry
*/
+#ifdef CFSTOK_INTR
+int
+tok_wait(
+ void *cookie)
+#else
void
tok_wait(
nrtcb_t *tcbp,
void *cookie)
+#endif
{
register struct nrreq *request = (struct nrreq *)cookie;
+#ifdef CFSTOK_INTR
+ int intr;
+
+ extern int tok_release(object_t *, nrtcb_t *, int, int);
+#endif
#ifdef __KERNEL__
SSI_ASSERT_NO_SPIN_LOCKS_HELD();
@@ -635,9 +774,22 @@
DBG(DBGCLI,("tok_hold: wait(0x%x) request in process...\n", request));
#ifdef __KERNEL__
+#ifdef CFSTOK_INTR
+ WAIT_INTR_EVENT(&request->req_done, 1, &intr);
+ if (!intr) {
+ tok_freereq(request);
+ } else if (tas(&request->req_release)) {
+ /* Lost the race */
+ (void) tok_release(request->req_objp, request->req_tcbp,
+ request->req_mode, 0);
+ tok_freereq(request);
+ }
+ DBG(DBGCLI,("tok_hold: request(0x%x) complete returning\n", request));
+ return intr;
+#else /* !CFSTOK_INTR */
WAIT_EVENT(&(request->req_done));
#ifdef NOTYET
- if (!WAIT_EVENT_SIG(&(request->req_done, PRIHI)) {
+ if (!WAIT_EVENT_SIG(&(request->req_done, PRIHI))) {
/* NSC_XXX: Need a lock here */
request->req_XXXX = XXXinterrupted;
return FALSE;
@@ -645,8 +797,8 @@
#endif
tok_freereq(request);
DBG(DBGCLI,("tok_hold: request(0x%x) complete returning\n", request));
+#endif /* !CFSTOK_INTR */
#endif /* __KERNEL__ */
- return;
}
int
@@ -732,7 +884,11 @@
* request will get the the hold, release it, and then the
* revoke will take affect.
*/
+#ifdef TOKEN_FIFO_LINUX_LIST
+ SSI_ASSERT(!(flags & TOK_RECURSIVE) || tcbp->tok_hld_count || tcbp->tok_revptr == NULL || (_tok_request(tcbp) && tcbp->tok_revptr && tok_request(tcbp)->req_mode == tcbp->tok_revptr->rev_oldmode));
+#else
SSI_ASSERT(!(flags & TOK_RECURSIVE) || tcbp->tok_hld_count || tcbp->tok_revptr == NULL || (tcbp->tok_request && tcbp->tok_revptr && tcbp->tok_request->req_mode == tcbp->tok_revptr->rev_oldmode));
+#endif
if (!ALLOWS(objp, (int)tcbp->tok_mode, request->req_mode)) {
@@ -743,7 +899,11 @@
SSI_ASSERT(!(flags & TOK_RECURSIVE));
/* If someone already requesting, just wait */
+#ifdef TOKEN_FIFO_LINUX_LIST
+ if (_tok_request(tcbp)) {
+#else
if (tcbp->tok_request) {
+#endif
DBG(DBGCLI|DBGSIM,("CLI M waiting %s %d reqmode %s\n",
DSPOBJ(objp,str),
@@ -857,6 +1017,60 @@
return TRUE;
}
+static inline void
+__token_wait_and_hold(
+ object_t *objp,
+ nrtcb_t *tcbp,
+ int newmode)
+{
+#ifdef TOKEN_FIFO_LINUX_LIST
+ struct nrreq *request, *tmp;
+#else
+ struct nrreq *request;
+#endif
+ fifo_t fifo;
+
+ /* Wakeup and hold token for all requestors that are compatible */
+#ifdef TOKEN_FIFO_LINUX_LIST
+ list_for_each_entry_safe(request, tmp, &tcbp->tok_reqfifo, req_list) {
+#else
+ fifo = tcbp->tok_reqfifo;
+ initfifo(&(tcbp->tok_reqfifo)); /* Clear req fifo */
+ while((request = deletefifo(&fifo))) {
+#endif
+ if (ALLOWS(objp, newmode, request->req_mode)) {
+#ifdef TOKEN_FIFO_LINUX_LIST
+ list_del(&request->req_list);
+#endif
+
+ SSI_ASSERT((tcbp)->tok_hld_count < HLD_COUNT_MAX);
+
+ if (!((tcbp)->tok_hld_count < HLD_COUNT_MAX))
+ printk(KERN_WARNING "tok_reqfail: too many holds\n");
+ else
+ tcbp->tok_hld_count++;
+
+ /* Wakeup this requestor */
+ complete_req(objp, request);
+#ifndef TOKEN_FIFO_LINUX_LIST
+ } else {
+ /* This request isn't compatible, handle it below */
+ insertfifo(&tcbp->tok_reqfifo, request);
+#endif
+ }
+ }
+
+ /* Process other requests which had to wait */
+#ifdef TOKEN_FIFO_LINUX_LIST
+ INIT_LIST_HEAD(&fifo);
+ list_splice_init(&tcbp->tok_reqfifo, &fifo);
+#else
+ fifo = tcbp->tok_reqfifo;
+ initfifo(&(tcbp->tok_reqfifo)); /* Clear req fifo */
+#endif
+ process_reqfifo(objp, &fifo);
+}
+
/*
* Process grant of a request for token
* We only accept grants that client requested. Unsolicited
@@ -873,8 +1087,6 @@
int oldmode,
int newmode)
{
- struct nrreq *request;
- struct fifo fifo;
#if defined(DEBUG) || defined(SIMUL)
char str[DBGSTRLEN];
#endif
@@ -889,38 +1101,19 @@
SSI_ASSERT(tcbp->tok_mode == oldmode);
+#ifdef TOKEN_FIFO_LINUX_LIST
+ SSI_ASSERT(_tok_request(tcbp));
+ /* The first requestor on fifo sent request, he must be compatible */
+ SSI_ASSERT(ALLOWS(objp, newmode, (int)tok_request(tcbp)->req_mode));
+#else
SSI_ASSERT(tcbp->tok_request);
/* The first requestor on fifo sent request, he must be compatible */
SSI_ASSERT(ALLOWS(objp, newmode, (int)tcbp->tok_request->req_mode));
+#endif
tcbp->tok_mode = newmode;
- /* Wakeup and hold token for all requestors that are compatible */
- fifo = tcbp->tok_reqfifo;
- initfifo(&(tcbp->tok_reqfifo)); /* Clear req fifo */
- while((request = deletefifo(&fifo))) {
-
- if (ALLOWS(objp, newmode, request->req_mode)) {
-
- SSI_ASSERT((tcbp)->tok_hld_count < HLD_COUNT_MAX);
-
- if (!((tcbp)->tok_hld_count < HLD_COUNT_MAX))
- printk(KERN_WARNING "tok_grant: too many holds\n");
- else
- tcbp->tok_hld_count++;
-
- /* Wakeup this requestor */
- complete_req(objp, request);
- } else {
- /* This request isn't compatible, handle it below */
- insertfifo(&tcbp->tok_reqfifo, request);
- }
- }
-
- /* Process other requests which had to wait */
- fifo = tcbp->tok_reqfifo;
- initfifo(&(tcbp->tok_reqfifo)); /* Clear req fifo */
- process_reqfifo(objp, &fifo);
+ __token_wait_and_hold(objp, tcbp, newmode);
}
/*
@@ -1016,8 +1209,13 @@
* that is pending. If a request is pending the revoke might have
* arrived before the grant.
*/
+#ifdef TOKEN_FIFO_LINUX_LIST
+ if (oldmode != tcbp->tok_mode && (!_tok_request(tcbp) ||
+ (oldmode != tok_request(tcbp)->req_mode)))
+#else
if (oldmode != tcbp->tok_mode && ((tcbp->tok_request == NULL) ||
(oldmode != tcbp->tok_request->req_mode)))
+#endif
return FALSE;
return TRUE;
@@ -1043,9 +1241,15 @@
MSTR(objp,revp->rev_oldmode), MSTR(objp,revp->rev_newmode)));
/* check_revok() should catch prevent us SSI_ASSERTing here */
+#ifdef TOKEN_FIFO_LINUX_LIST
+ SSI_ASSERT(revp->rev_oldmode == tcbp->tok_mode ||
+ (_tok_request(tcbp) &&
+ (revp->rev_oldmode == tok_request(tcbp)->req_mode)));
+#else
SSI_ASSERT(revp->rev_oldmode == tcbp->tok_mode ||
((tcbp->tok_request != NULL) &&
(revp->rev_oldmode == tcbp->tok_request->req_mode)));
+#endif
if (tcbp->tok_revptr != revp) {
/* If run into revoke we've recieved overlapping
@@ -1064,8 +1268,13 @@
* the revoke, if it's needs to be processed after the grant
* and subsequent release
*/
+#ifdef TOKEN_FIFO_LINUX_LIST
+ if (_tok_request(tcbp) &&
+ tok_request(tcbp)->req_mode == revp->rev_oldmode)
+#else
if (tcbp->tok_request &&
tcbp->tok_request->req_mode == revp->rev_oldmode)
+#endif
return FALSE;
}
@@ -1126,8 +1335,13 @@
/* No need to lock TCB because we must be protected by caller */
/* NSC_XXX: Should be return status here instead of panic? */
+#ifdef TOKEN_FIFO_LINUX_LIST
+ if (tcbp->tok_mode != TOK_NOMODE || _tok_request(tcbp) ||
+ tcbp->tok_revptr)
+#else
if (tcbp->tok_mode != TOK_NOMODE || tcbp->tok_request ||
tcbp->tok_revptr)
+#endif
panic("tok_destroy: Tokens still in use");
return;
@@ -1190,20 +1404,26 @@
int newmode,
agent_t agent)
{
- struct fifo fifo;
- struct nrreq *request;
struct nrrevoke *revp;
#if defined(DEBUG) || defined(SIMUL)
char str[DBGSTRLEN];
#endif
SSI_ASSERT(tcbp);
+#ifdef TOKEN_FIFO_LINUX_LIST
+ SSI_ASSERT(_tok_request(tcbp));
+#else
SSI_ASSERT(tcbp->tok_request);
+#endif
/* The old mode can be TOK_NOMODE */
SSI_ASSERT(oldmode >= 0 && oldmode < TOK_NUMMODES(objp));
SSI_ASSERT(newmode > 0 && newmode < TOK_NUMMODES(objp));
/* Check that state is correct as set by requesting code */
+#ifdef TOKEN_FIFO_LINUX_LIST
+ SSI_ASSERT(tok_request(tcbp)->req_mode == newmode);
+#else
SSI_ASSERT(tcbp->tok_request->req_mode == newmode);
+#endif
DBG(DBGCLI|DBGSIM,("CLI R reqfail %s %d from:%s to:%s\n",
DSPOBJ(objp,str), agent,
@@ -1242,40 +1462,24 @@
if (!ALLOWS(objp, (int)tcbp->tok_mode, newmode)) {
DBG(DBGCLI|DBGSIM|DBGREQUEST,("CLI S request %s %d from:%s to:%s (reqfail)\n",
+#ifdef TOKEN_FIFO_LINUX_LIST
+DSPOBJ(objp,str), tok_request(tcbp)->req_agent,
+#else
DSPOBJ(objp,str), tcbp->tok_request->req_agent,
+#endif
MSTR(objp,tcbp->tok_mode), MSTR(objp,newmode)));
+#ifdef TOKEN_FIFO_LINUX_LIST
+ MSGSEND(objp, REQUEST, (range_off_t)0, (range_off_t)0, tok_request(tcbp)->req_agent,
+ tcbp->tok_mode, tok_request(tcbp)->req_mode);
+#else
MSGSEND(objp, REQUEST, (range_off_t)0, (range_off_t)0, tcbp->tok_request->req_agent,
tcbp->tok_mode, tcbp->tok_request->req_mode);
+#endif
return;
}
- /* Wakeup and hold token for all requestors that are compatible */
- fifo = tcbp->tok_reqfifo;
- initfifo(&(tcbp->tok_reqfifo)); /* Clear req fifo */
- while((request = deletefifo(&fifo))) {
-
- if (ALLOWS(objp, newmode, request->req_mode)) {
-
- SSI_ASSERT((tcbp)->tok_hld_count < HLD_COUNT_MAX);
-
- if (!((tcbp)->tok_hld_count < HLD_COUNT_MAX))
- printk(KERN_WARNING "tok_reqfail: too many holds\n");
- else
- tcbp->tok_hld_count++;
-
- /* Wakeup this requestor */
- complete_req(objp, request);
- } else {
- /* This request isn't compatible, handle it below */
- insertfifo(&tcbp->tok_reqfifo, request);
- }
- }
-
- /* Process other requests which had to wait */
- fifo = tcbp->tok_reqfifo;
- initfifo(&(tcbp->tok_reqfifo)); /* Clear req fifo */
- process_reqfifo(objp, &fifo);
+ __token_wait_and_hold(objp, tcbp, newmode);
}
int
@@ -1293,7 +1497,11 @@
}
/* If holds, requests or revokes, don't do anything */
+#ifdef TOKEN_FIFO_LINUX_LIST
+ if (tcbp->tok_hld_count || _tok_request(tcbp) || tcbp->tok_revptr) {
+#else
if (tcbp->tok_hld_count || tcbp->tok_request || tcbp->tok_revptr) {
+#endif
return(FALSE);
}
@@ -1379,12 +1587,14 @@
retp->eff_mode = TOK_NOMODE;
} else
retp->flags |= CLISTAT_NOTREVOKED;
+#ifdef TOKEN_FIFO_LINUX_LIST
+ if (_tok_request(tcbp)) {
+#else
if (tcbp->tok_request) {
+#endif
retp->flags |= CLISTAT_REQPEND;
}
- retp->mode = tcbp->tok_mode;
- mb();
- retp->uc_mode = retp->mode;
+ retp->uc_mode = retp->mode = tcbp->tok_mode;
retp->hold_count = tcbp->tok_hld_count;
#ifdef DEBUG
@@ -1405,7 +1615,7 @@
nrtcb_t *tcbp)
{
struct nrrevoke *revp;
- struct fifo fifo;
+ fifo_t fifo;
#if defined(DEBUG) || defined(SIMUL)
char str[DBGSTRLEN];
#endif
@@ -1415,16 +1625,26 @@
tcbp->tok_mode = TOK_ALL(objp);
if ((revp = tcbp->tok_revptr)) {
+#ifdef TOKEN_FIFO_LINUX_LIST
+ INIT_LIST_HEAD(&fifo);
+ list_splice_init(&revp->rev_reqfifo, &fifo);
+#else
fifo = revp->rev_reqfifo;
initfifo(&(revp->rev_reqfifo));
+#endif
freerev(revp);
tcbp->tok_revptr = NULL;
process_reqfifo(objp, &fifo);
}
/* Process requests waiting for grant */
+#ifdef TOKEN_FIFO_LINUX_LIST
+ INIT_LIST_HEAD(&fifo);
+ list_splice_init(&tcbp->tok_reqfifo, &fifo);
+#else
fifo = tcbp->tok_reqfifo;
initfifo(&(tcbp->tok_reqfifo));
+#endif
process_reqfifo(objp, &fifo);
}
#endif
@@ -1496,8 +1716,10 @@
agent_t agent,
int do_haves)
{
- struct fifo fifo;
+ fifo_t fifo;
+#ifndef TOKEN_FIFO_LINUX_LIST
struct nrreq *request;
+#endif
struct nrrevoke *revp;
#if defined(DEBUG) || defined(SIMUL)
char str[DBGSTRLEN];
@@ -1521,23 +1743,36 @@
* have to re-send to us, anyway.
*/
if ((revp = tcbp->tok_revptr)) {
+#ifdef TOKEN_FIFO_LINUX_LIST
+ /* Merge revoke reqfifo with tok_reqfifo */
+ list_splice_init(&revp->rev_reqfifo, &tcbp->tok_reqfifo);
+#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);
+#endif
}
/* Process all pending requests */
+#ifdef TOKEN_FIFO_LINUX_LIST
+ INIT_LIST_HEAD(&fifo);
+ list_splice_init(&tcbp->tok_reqfifo, &fifo);
+#else
fifo = tcbp->tok_reqfifo;
initfifo(&(tcbp->tok_reqfifo)); /* Clear req fifo */
+#endif
process_reqfifo(objp, &fifo);
}
}
+#ifndef CLITOK_KMEM_CACHE
int
clitok_req_free_memory(int count, unsigned int gfp_mask)
{
@@ -1610,3 +1845,4 @@
return nrrev_free_count;
}
+#endif /* !CLITOK_KMEM_CACHE */
Index: mhsvrtok.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/token/mhsvrtok.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- mhsvrtok.c 10 Oct 2008 08:10:32 -0000 1.6
+++ mhsvrtok.c 3 Feb 2009 06:18:12 -0000 1.7
@@ -70,9 +70,22 @@
/* Multi-node support routines */
+#ifdef MHSVRTOK_KMEM_CACHE
+STATIC kmem_cache_t *mhnode_cachep;
+
+void
+mhnode_init(void)
+{
+ mhnode_cachep = kmem_cache_create("mhsvrtok_cache",
+ sizeof(struct mhnode_ent), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+ NULL, NULL);
+}
+#else
STATIC struct mhnode_ent *mhnode_free = NULL;
STATIC int mhnode_free_count = 0;
SPIN_LOCK_T mhnode_free_lock;
+#endif
STATIC struct mhnode_ent *
mhsvrallocnode(agent_t agent)
@@ -81,6 +94,9 @@
SSI_ASSERT(agent != 0);
+#ifdef MHSVRTOK_KMEM_CACHE
+ newnode = kmem_cache_alloc(mhnode_cachep, GFP_KERNEL|__GFP_NOFAIL);
+#else
LOCK_SPIN_LOCK(&mhnode_free_lock);
if ((newnode = mhnode_free)) {
mhnode_free = newnode->nd_next;
@@ -92,6 +108,7 @@
if (newnode == NULL)
panic("svrallocnode: Can't malloc node struct\n");
}
+#endif
newnode->nd_agent = agent;
newnode->nd_numtoks = 0;
newnode->nd_next = NULL;
@@ -119,6 +136,9 @@
/* If the list is empty the ndcount must be zero */
SSI_ASSERT(tcbp->tok_ndcount == 0 || tcbp->tok_ndlist);
+#ifdef MHSVRTOK_KMEM_CACHE
+ kmem_cache_free(mhnode_cachep, savep);
+#else
/* Put node entry only free list */
LOCK_SPIN_LOCK(&mhnode_free_lock);
savep->nd_next = mhnode_free;
@@ -128,6 +148,7 @@
mhnode_free = savep;
mhnode_free_count++;
UNLOCK_SPIN_LOCK(&mhnode_free_lock);
+#endif /* !MHSVRTOK_KMEM_CACHE */
}
/*
@@ -453,6 +474,7 @@
}
#endif /* !__KERNEL__ || DEBUG || DEBUG_TOOLS */
+#ifndef MHSVRTOK_KMEM_CACHE
int
mhsvrtok_free_memory(int count, unsigned int gfp_mask)
{
@@ -488,3 +510,4 @@
}
return mhnode_free_count;
}
+#endif /* !MHSVRTOK_KMEM_CACHE */
------------------------------------------------------------------------------
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