--- /n/sources/plan9/sys/src/9k/port/proc.c Mon Jun 29 00:00:00 2026 +++ /sys/src/9k/port/proc.c Wed Jul 1 00:00:00 2026 @@ -843,16 +843,19 @@ wakeup(Rendez *r) lock(r); p = r->p; - if(p != nil){ + if(p == nil) + unlock(r); + else{ lock(&p->rlock); if(p->state != Wakeme || p->r != r) panic("wakeup: state"); r->p = nil; p->r = nil; - ready(p); unlock(&p->rlock); + unlock(r); + /* hands off r */ + ready(p); } - unlock(r); splx(s); @@ -909,9 +912,16 @@ postnote(Proc *p, int dolock, char *n, int flag) panic("postnote: state %d %d %d", r->p != p, p->r != r, p->state); p->r = nil; r->p = nil; - ready(p); + /* + * The unlock must precede ready(p), in case the readied process + * immediately deallocates the Rendez. This can happen with semacquire, + * where the Rendez is on the stack. + */ unlock(r); - break; + unlock(&p->rlock); + ready(p); + splx(s); + return ret; } /* give other process time to get out of critical section and try again */