summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-09-30 16:14:27 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2012-09-30 16:14:27 +0200
commit5d64e428ebec115f9129a8f1de2f418e5418c8f4 (patch)
treeb72e28eacf495862f3eb2196633da00ffcf9c603
parentfa08484d47b270a9c62310a3cd0124aef0cdd7d3 (diff)
downloadplan9front-5d64e428ebec115f9129a8f1de2f418e5418c8f4.tar.xz
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.
-rw-r--r--sys/src/9/port/devproc.c9
-rw-r--r--sys/src/9/port/proc.c6
2 files changed, 13 insertions, 2 deletions
diff --git a/sys/src/9/port/devproc.c b/sys/src/9/port/devproc.c
index 5f777d864..6fd600bcf 100644
--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -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);
diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c
index 76aa3d0dd..a64ef4749 100644
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -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);
}
/*