ref: c0951f2a3182d8b70ffe579bfd9da24c2b86e232
parent: de6172c0abcbd9977dd1e39029248079f6f1e9c7
author: cinap_lenrek <[email protected]>
date: Tue Apr 23 10:23:05 EDT 2024
kern: don't touch proc in wakeup() after procwakeup() In case the Rendez structure is backed by dynamic memory that might be freed after we ready the sleeping process, we must not touch it (unlock(&r->lk)) after procwakeup(). (Also remove unused copy of rendez.c).
--- a/kern/rendez.c
+++ /dev/null
@@ -1,89 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-
-void
-sleep(Rendez *r, int (*f)(void*), void *arg)
-{
- int s;
-
- s = splhi();
-
- lock(&r->lk);
- lock(&up->rlock);
- if(r->p){
- print("double sleep %lud %lud\n", r->p->pid, up->pid);
- }
-
- /*
- * Wakeup only knows there may be something to do by testing
- * r->p in order to get something to lock on.
- * Flush that information out to memory in case the sleep is
- * committed.
- */
- r->p = up;
-
- if((*f)(arg) || up->notepending){
- /*
- * if condition happened or a note is pending
- * never mind
- */
- r->p = nil;
- unlock(&up->rlock);
- unlock(&r->lk);
- } else {
- /*
- * now we are committed to
- * change state and call scheduler
- */
- up->state = Wakeme;
- up->r = r;
-
- /* statistics */
- /* m->cs++; */
-
- unlock(&up->rlock);
- unlock(&r->lk);
-
- procsleep();
- }
-
- if(up->notepending) {
- up->notepending = 0;
- splx(s);
- error(Eintr);
- }
-
- splx(s);
-}
-
-Proc*
-wakeup(Rendez *r)
-{
- Proc *p;
- int s;
-
- s = splhi();
-
- lock(&r->lk);
- p = r->p;
-
- if(p != nil){
- lock(&p->rlock);
- if(p->state != Wakeme || p->r != r)
- panic("wakeup: state");
- r->p = nil;
- p->r = nil;
- p->state = Running;
- procwakeup(p);
- unlock(&p->rlock);
- }
- unlock(&r->lk);
-
- splx(s);
-
- return p;
-}
-
--- a/kern/sleep.c
+++ b/kern/sleep.c
@@ -70,18 +70,19 @@
lock(&r->lk);
p = r->p;
- if(p != nil){
+ if(p == nil)
+ unlock(&r->lk);
+ else {
lock(&p->rlock);
if(p->state != Wakeme || p->r != r)
panic("wakeup: state");
+ p->state = Running;
r->p = nil;
p->r = nil;
- p->state = Running;
- procwakeup(p);
unlock(&p->rlock);
+ unlock(&r->lk);
+ procwakeup(p);
}
- unlock(&r->lk);
-
splx(s);
return p;