提交 176b9120 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

release rcu lock while calling free function

上级 db4dc1c3
...@@ -86,7 +86,6 @@ struct proc { ...@@ -86,7 +86,6 @@ struct proc {
unsigned long long curcycles; unsigned long long curcycles;
unsigned cpuid; unsigned cpuid;
struct spinlock lock; struct spinlock lock;
STAILQ_ENTRY(proc) run_next;
SLIST_HEAD(childlist, proc) childq; SLIST_HEAD(childlist, proc) childq;
SLIST_ENTRY(proc) child_next; SLIST_ENTRY(proc) child_next;
struct condvar cv; struct condvar cv;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
struct rcu { struct rcu {
unsigned long epoch; unsigned long epoch;
struct rcu *next; TAILQ_ENTRY(rcu) link;
union { union {
struct { struct {
void (*dofree)(void *); void (*dofree)(void *);
...@@ -25,8 +25,10 @@ struct rcu { ...@@ -25,8 +25,10 @@ struct rcu {
}; };
int type; int type;
}; };
static struct { struct rcu *x __attribute__((aligned (CACHELINE))); } rcu_delayed_head[NCPU];
static struct { struct rcu *x __attribute__((aligned (CACHELINE))); } rcu_delayed_tail[NCPU]; TAILQ_HEAD(rcu_head, rcu);
static struct { struct rcu_head x __attribute__((aligned (CACHELINE))); } rcu_q[NCPU];
static uint global_epoch __attribute__ ((aligned (CACHELINE))); static uint global_epoch __attribute__ ((aligned (CACHELINE)));
static struct { uint x __attribute__((aligned (CACHELINE))); } min_epoch[NCPU]; static struct { uint x __attribute__((aligned (CACHELINE))); } min_epoch[NCPU];
static struct { struct spinlock l __attribute__((aligned (CACHELINE))); } rcu_lock[NCPU]; static struct { struct spinlock l __attribute__((aligned (CACHELINE))); } rcu_lock[NCPU];
...@@ -37,8 +39,10 @@ enum { rcu_debug = 0 }; ...@@ -37,8 +39,10 @@ enum { rcu_debug = 0 };
void void
rcuinit(void) rcuinit(void)
{ {
for (int i = 0; i < NCPU; i++) for (int i = 0; i < NCPU; i++) {
initlock(&rcu_lock[i].l, "rcu"); initlock(&rcu_lock[i].l, "rcu");
TAILQ_INIT(&rcu_q[i].x);
}
} }
struct rcu * struct rcu *
...@@ -70,9 +74,11 @@ rcu_gc(void) ...@@ -70,9 +74,11 @@ rcu_gc(void)
pushcli(); pushcli();
acquire(&rcu_lock[cpu->id].l); acquire(&rcu_lock[cpu->id].l);
for (r = rcu_delayed_head[cpu->id].x; r != NULL; r = nr) { for (r = TAILQ_FIRST(&rcu_q[cpu->id].x); r != NULL; r = nr) {
if (r->epoch >= min_epoch[cpu->id].x) if (r->epoch >= min_epoch[cpu->id].x)
break; break;
release(&rcu_lock[cpu->id].l);
// cprintf("free: %d (%x %x)\n", r->epoch, r->dofree, r->item); // cprintf("free: %d (%x %x)\n", r->epoch, r->dofree, r->item);
switch (r->type) { switch (r->type) {
case 1: case 1:
...@@ -84,12 +90,12 @@ rcu_gc(void) ...@@ -84,12 +90,12 @@ rcu_gc(void)
default: default:
panic("rcu type"); panic("rcu type");
} }
acquire(&rcu_lock[cpu->id].l);
delayed_nfree[cpu->id].v--; delayed_nfree[cpu->id].v--;
n++; n++;
rcu_delayed_head[cpu->id].x = r->next; nr = TAILQ_NEXT(r, link);
if (rcu_delayed_head[cpu->id].x == 0) TAILQ_REMOVE(&rcu_q[cpu->id].x, r, link);
rcu_delayed_tail[cpu->id].x = 0;
nr = r->next;
kmfree(r); kmfree(r);
} }
release(&rcu_lock[cpu->id].l); release(&rcu_lock[cpu->id].l);
...@@ -109,32 +115,23 @@ rcu_delayed_int(struct rcu *r) ...@@ -109,32 +115,23 @@ rcu_delayed_int(struct rcu *r)
pushcli(); pushcli();
acquire(&rcu_lock[cpu->id].l); acquire(&rcu_lock[cpu->id].l);
// cprintf("rcu_delayed: %d\n", global_epoch); // cprintf("rcu_delayed: %d\n", global_epoch);
if (rcu_delayed_tail[cpu->id].x != 0) TAILQ_INSERT_TAIL(&rcu_q[cpu->id].x, r, link);
rcu_delayed_tail[cpu->id].x->next = r;
rcu_delayed_tail[cpu->id].x = r;
if (rcu_delayed_head[cpu->id].x == 0)
rcu_delayed_head[cpu->id].x = r;
release(&rcu_lock[cpu->id].l);
delayed_nfree[cpu->id].v++; delayed_nfree[cpu->id].v++;
release(&rcu_lock[cpu->id].l);
popcli(); popcli();
} }
void void
rcu_delayed(void *e, void (*dofree)(void *)) rcu_delayed(void *e, void (*dofree)(void *))
{ {
if (rcu_debug) { if (rcu_debug)
cprintf("rcu_delayed: %x %x\n", dofree, e); cprintf("rcu_delayed: %x %x\n", dofree, e);
for (struct rcu *r = rcu_delayed_head[cpu->id].x; r; r = r->next)
if (r->f1.item == e && r->f1.dofree == dofree)
panic("rcu_delayed double free");
}
struct rcu *r = rcu_alloc(); struct rcu *r = rcu_alloc();
if (r == 0) if (r == 0)
panic("rcu_delayed"); panic("rcu_delayed");
r->f1.dofree = dofree; r->f1.dofree = dofree;
r->f1.item = e; r->f1.item = e;
r->next = 0;
r->epoch = global_epoch; r->epoch = global_epoch;
r->type = 1; r->type = 1;
rcu_delayed_int(r); rcu_delayed_int(r);
...@@ -149,7 +146,6 @@ rcu_delayed2(int a1, uint a2, void (*dofree)(int,uint)) ...@@ -149,7 +146,6 @@ rcu_delayed2(int a1, uint a2, void (*dofree)(int,uint))
r->f2.dofree = dofree; r->f2.dofree = dofree;
r->f2.arg1 = a1; r->f2.arg1 = a1;
r->f2.arg2 = a2; r->f2.arg2 = a2;
r->next = 0;
r->epoch = global_epoch; r->epoch = global_epoch;
r->type = 2; r->type = 2;
rcu_delayed_int(r); rcu_delayed_int(r);
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论