shithub: riscv

Download patch

ref: 5d64e428ebec115f9129a8f1de2f418e5418c8f4
parent: fa08484d47b270a9c62310a3cd0124aef0cdd7d3
author: cinap_lenrek <[email protected]>
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);
 }
 
 /*