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);
}
/*