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.
This commit is contained in:
cinap_lenrek 2012-09-30 16:14:27 +02:00
parent fa08484d47
commit 5d64e428eb
2 changed files with 13 additions and 2 deletions

View file

@ -863,7 +863,13 @@ procread(Chan *c, void *va, long n, vlong off)
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 @@ procread(Chan *c, void *va, long n, vlong off)
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);

View file

@ -1494,7 +1494,7 @@ killbig(char *why)
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 @@ killbig(char *why)
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 @@ killbig(char *why)
qunlock(&s->lk);
}
}
qunlock(&kp->seglock);
}
/*