From 5d64e428ebec115f9129a8f1de2f418e5418c8f4 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 30 Sep 2012 16:14:27 +0200 Subject: [PATCH] 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. --- sys/src/9/port/devproc.c | 9 +++++++++ sys/src/9/port/proc.c | 6 ++++-- 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; iseg[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; ilk); } + 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); } /*