[SSI] openssi/kernel/cluster/ssi/vproc dvp_move.c,1.17,1.18

Roger Tsang <[email protected]> Tue, 04 May 2010 04:42:28 +0000
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv16722/cluster/ssi/vproc

Modified Files:
      Tag: OPENSSI-FC
	dvp_move.c 
Log Message:
VPROC (#ifdef VPROC_RCU_MOVEMENT_LIST):
- Fix move_data struct leak in move_out_nodedown(). Bug introduced in OPENSSI-FC-1-9-6-PRE39.
- No need to acquire mh_lock in put_move_data(); there is no race. move_data struct is removed from mh_datalist before final put_move_data().

VPROC:
- Remove unnecessary memory barriers.


Index: dvp_move.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/vproc/dvp_move.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- dvp_move.c	3 May 2010 06:18:14 -0000	1.17
+++ dvp_move.c	4 May 2010 04:42:26 -0000	1.18
@@ -263,6 +263,7 @@
 	return h;
 }
 
+/* Might acquire movement_list_lock */
 void
 put_move_header(struct move_header *h)
 {
@@ -352,14 +353,10 @@
 }
 #endif /* !VPROC_RCU_MOVEMENT_LIST */
 
-/* Might acquire movement_list_lock, mh_lock */
+/* Might acquire movement_list_lock */
 static void
 put_move_data(struct move_data *d)
 {
-#ifdef VPROC_RCU_MOVEMENT_LIST
-	struct move_header *h;
-#endif
-
 #ifdef DEBUG
 	if (unlikely(d->m_magic != ((u_long)&d->m_magic) + 1)) {
 		panic("%s:move_data %p has invalid magic number %p\n",
@@ -368,15 +365,13 @@
 #endif
 	BUG_ON(atomic_read(&d->m_refcnt) < 1);
 #ifdef VPROC_RCU_MOVEMENT_LIST
-	h = d->m_mhp;
-
-	if (!atomic_dec_and_lock(&d->m_refcnt, &h->mh_lock))
+	if (!atomic_dec_and_test(&d->m_refcnt))
 		return;
 #ifdef DEBUG
 	d->m_magic = 0;
 #endif
-	d->m_mhp = NULL;
-	spin_unlock(&h->mh_lock);
+	/* NB: already removed from mh_datalist in drop_move_data() */
+	put_move_header(d->m_mhp);
 
 	if (unlikely(d->m_taskp))
 		panic("%s:move_data %p freed with m_taskp %p set\n",
@@ -384,7 +379,6 @@
 	if (unlikely(atomic_read(&d->m_hashed)))
 		panic("%s:move_data %p still hashed\n", __FUNCTION__, d);
 
-	put_move_header(h); /* for d->m_mhp */
 	call_rcu(&d->m_rcu, free_move_data);
 #else /* VPROC_RCU_MOVEMENT_LIST */
 	if (!atomic_dec_and_lock(&d->m_refcnt, &movement_list_lock))
@@ -627,8 +621,6 @@
 {
 	struct move_data *d;
 
-	smp_mb(); /* ensure all CPU's see new state */
-
 	rcu_read_lock();
 	list_for_each_entry_rcu(d, &h->mh_datalist, m_list) {
 		if (!__get_move_data(d))
@@ -740,6 +732,7 @@
 	list_for_each_entry(d, &h->mh_datalist, m_list) {
 		d->m_state = state;
 	}
+	smp_mb(); /* ensure all CPU's see new state */
 }
 
 
@@ -851,9 +844,7 @@
 #ifdef VPROC_RCU_MOVEMENT_LIST
 	if (aborting)
 		free_move_datalist(h);
-	else
 #endif
-	smp_mb(); /* ensure all CPU's see new state */
 
 	wake_up_all(&h->mh_wqh);
 
@@ -1992,7 +1983,7 @@
 			       state);
 		goto out;
 	}
-	l->m_state = PM_MIGRATE_IN_THREAD;
+	set_mb(l->m_state, PM_MIGRATE_IN_THREAD);
 
 	get_move_data(d); /* for l->m_threadlist */
 	list_add_tail(&d->m_threadlist, &l->m_threadlist);
@@ -2000,10 +1991,9 @@
 	d->m_migargs  = args;
 	spin_unlock(&h->mh_lock);
 
-	if (state == PM_MIGRATE_IN_DONE) {
-		smp_mb(); /* ensure CPU's see new state */
+	if (state == PM_MIGRATE_IN_DONE)
 		wake_up_all(&l->m_wqh);
-	}
+
 	(void)move_data_wait_for_state_change(d, PM_MIGRATE_IN_START);
 
 	spin_lock(&h->mh_lock);
@@ -2349,6 +2339,7 @@
 
 			move_data_wait_for_state_change(d,
 						PM_MIGRATE_OUT_START);
+			put_move_data(d);
 			goto again;
 		} else if (d->m_state == PM_MIGRATE_OUT) {
 			spin_lock(&h->mh_lock);


------------------------------------------------------------------------------