git: 9front

Download patch

ref: f585c54bf108dac970f5ca891e21d03479f7a9f5
parent: dd636dce1997cbdb129de319919ce8aaa2db57b8
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun Sep 30 12:14:27 EDT 2012

fix devproc and killbig segment race

we have to acquire p->seglock before we lock the individual
segments of the process and lock them. if we dont then pexit()
might free the segments before we can lock them causing the
"qunlock called with qlock not held, from ..." prints.

--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -863,7 +863,13 @@
 			l = TK2MS(l);
 			readnum(0, statbuf+j+NUMSIZE*i, NUMSIZE, l, NUMSIZE);
 		}
+
 		l = 0;
+		eqlock(&p->seglock);
+		if(waserror()){
+			qunlock(&p->seglock);
+			nexterror();
+		}
 		for(i=0; i<NSEG; i++){
 			if(s = p->seg[i]){
 				eqlock(&s->lk);
@@ -871,6 +877,9 @@
 				qunlock(&s->lk);
 			}
 		}
+		poperror();
+		qunlock(&p->seglock);
+
 		readnum(0, statbuf+j+NUMSIZE*6, NUMSIZE, l*BY2PG/1024, NUMSIZE);
 		readnum(0, statbuf+j+NUMSIZE*7, NUMSIZE, p->basepri, NUMSIZE);
 		readnum(0, statbuf+j+NUMSIZE*8, NUMSIZE, p->priority, NUMSIZE);
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -1494,7 +1494,7 @@
 	kp = 0;
 	ep = procalloc.arena+conf.nproc;
 	for(p = procalloc.arena; p < ep; p++) {
-		if(p->state == Dead || p->kp)
+		if(p->state == Dead || p->kp || !canqlock(&p->seglock))
 			continue;
 		l = 0;
 		for(i=1; i<NSEG; i++) {
@@ -1504,12 +1504,13 @@
 			l += (ulong)mcountseg(s);
 			qunlock(&s->lk);
 		}
+		qunlock(&p->seglock);
 		if(l > max && ((p->procmode&0222) || strcmp(eve, p->user)!=0)) {
 			kp = p;
 			max = l;
 		}
 	}
-	if(kp == 0)
+	if(kp == 0 || !canqlock(&kp->seglock))
 		return;
 	print("%lud: %s killed: %s\n", kp->pid, kp->text, why);
 	for(p = procalloc.arena; p < ep; p++) {
@@ -1526,6 +1527,7 @@
 			qunlock(&s->lk);
 		}
 	}
+	qunlock(&kp->seglock);
 }
 
 /*
--