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

fixes for VERIFYFREE, make proc inherit from rcu_freed

上级 79ba4240
......@@ -6,8 +6,8 @@ using std::atomic;
struct buf : public rcu_freed {
atomic<int> flags;
u32 dev;
u64 sector;
const u32 dev;
const u64 sector;
struct buf *prev; // LRU cache list
struct buf *next;
struct buf *qnext; // disk queue
......@@ -16,7 +16,17 @@ struct buf : public rcu_freed {
struct spinlock lock;
u8 data[512];
buf() : rcu_freed("buf") {}
buf(u32 d, u64 s) : rcu_freed("buf"), dev(d), sector(s) {
snprintf(lockname, sizeof(lockname), "cv:buf:%d", sector);
initlock(&lock, lockname+3, LOCKSTAT_BIO);
initcondvar(&cv, lockname);
}
~buf() {
destroycondvar(&cv);
destroylock(&lock);
}
virtual void do_gc() { delete this; }
NEW_DELETE_OPS(buf)
};
......
......@@ -46,6 +46,7 @@ extern u64 ticks;
extern struct spinlock tickslock;
extern struct condvar cv_ticks;
void initcondvar(struct condvar *, const char *);
void destroycondvar(struct condvar *);
void cv_sleep(struct condvar *cv, struct spinlock*);
void cv_sleepto(struct condvar *cv, struct spinlock*, u64);
void cv_wakeup(struct condvar *cv);
......
......@@ -18,7 +18,12 @@
#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
#if 0
#define __offsetof offsetof
#else
#define __offsetof(type, field) (((uptr) &((type*)0x1000000)->field)-0x1000000)
#endif
#define __mpalign__ __attribute__((aligned(CACHELINE)))
#define __padout__ char __padout[0] __attribute__((aligned(CACHELINE)))
#define __noret__ __attribute__((noreturn))
......@@ -2,6 +2,7 @@
#include "spinlock.h"
#include "atomic.hh"
#include "cpputil.hh"
// Saved registers for kernel context switches.
// (also implicitly defined in swtch.S)
......@@ -36,7 +37,7 @@ struct mtrace_stacks {
enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
// Per-process state
struct proc {
struct proc : public rcu_freed {
struct vmap *vmap; // va -> vma
uptr brk; // Top of heap
char *kstack; // Bottom of kernel stack for this process
......@@ -73,4 +74,31 @@ struct proc {
u64 cv_wakeup; // Wakeup time for this process
LIST_ENTRY(proc) cv_waiters; // Linked list of processes waiting for oncv
LIST_ENTRY(proc) cv_sleep; // Linked list of processes sleeping on a cv
proc(int npid) : rcu_freed("proc"), vmap(0), brk(0), kstack(0),
state(EMBRYO), pid(npid), parent(0), tf(0), context(0), killed(0),
cwd(0), tsc(0), curcycles(0), cpuid(0), epoch(0), epoch_depth(0),
on_runq(-1), cpu_pin(0), runq(0), oncv(0), cv_wakeup(0)
{
snprintf(lockname, sizeof(lockname), "cv:proc:%d", pid);
initlock(&lock, lockname+3, LOCKSTAT_PROC);
initlock(&gc_epoch_lock, lockname+3, LOCKSTAT_PROC);
initcondvar(&cv, lockname);
memset(&childq, 0, sizeof(childq));
memset(&child_next, 0, sizeof(child_next));
memset(ofile, 0, sizeof(ofile));
memset(&runqlink, 0, sizeof(runqlink));
memset(&cv_waiters, 0, sizeof(cv_waiters));
memset(&cv_sleep, 0, sizeof(cv_sleep));
}
~proc() {
destroylock(&lock);
destroylock(&gc_epoch_lock);
destroycondvar(&cv);
}
virtual void do_gc() { delete this; }
NEW_DELETE_OPS(proc)
};
......@@ -100,20 +100,13 @@ bget(u32 dev, u64 sector, int *writer)
victim->flags |= B_BUSY;
bufns->remove(mkpair(victim->dev, victim->sector), &victim);
release(&victim->lock);
destroylock(&victim->lock);
gc_delayed(victim);
b = new buf();
b->dev = dev;
b->sector = sector;
b = new buf(dev, sector);
b->flags = B_BUSY;
*writer = 1;
snprintf(b->lockname, sizeof(b->lockname), "cv:buf:%d", b->sector);
initlock(&b->lock, b->lockname+3, LOCKSTAT_BIO);
initcondvar(&b->cv, b->lockname);
gc_begin_epoch();
if (bufns->insert(mkpair(b->dev, b->sector), b) < 0) {
destroylock(&b->lock);
gc_delayed(b);
goto loop;
}
......@@ -169,12 +162,9 @@ initbio(void)
bufns = new xns<pair<u32, u64>, buf*, bio_hash>(false);
for (u64 i = 0; i < NBUF; i++) {
struct buf *b = new buf();
b->dev = 0xdeadbeef;
b->sector = -i; /* dummy to pre-allocate NBUF spaces for evict */
struct buf *b = new buf(0xdeadbeef, -i);
/* dummy to pre-allocate NBUF spaces for evict */
b->flags = 0;
initlock(&b->lock, "bcache-lock", LOCKSTAT_BIO);
initcondvar(&b->cv, "bcache-cv");
if (bufns->insert(mkpair(b->dev, b->sector), b) < 0)
panic("binit ns_insert");
}
......
......@@ -139,3 +139,9 @@ initcondvar(struct condvar *cv, const char *n)
initlock(&cv->lock, n, LOCKSTAT_CONDVAR);
LIST_INIT(&cv->waiters);
}
void
destroycondvar(struct condvar *cv)
{
destroylock(&cv->lock);
}
......@@ -231,6 +231,7 @@ inode::~inode()
}
destroylock(&lock);
destroycondvar(&cv);
}
struct inode*
......
......@@ -30,7 +30,7 @@ pipealloc(struct file **f0, struct file **f1)
*f0 = *f1 = 0;
if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0)
goto bad;
if((p = (struct pipe*)kalloc()) == 0)
if((p = (pipe*)kmalloc(sizeof(*p))) == 0)
goto bad;
p->readopen = 1;
p->writeopen = 1;
......@@ -52,7 +52,7 @@ pipealloc(struct file **f0, struct file **f1)
bad:
if(p) {
destroylock(&p->lock);
kfree((char*)p);
kmfree((char*)p, sizeof(*p));
}
if(*f0)
fileclose(*f0);
......@@ -74,7 +74,7 @@ pipeclose(struct pipe *p, int writable)
if(p->readopen == 0 && p->writeopen == 0){
release(&p->lock);
destroylock(&p->lock);
kfree((char*)p);
kmfree((char*)p, sizeof(*p));
} else
release(&p->lock);
}
......
......@@ -177,25 +177,10 @@ exit(void)
panic("zombie exit");
}
class delayed_proc_free : public rcu_freed {
private:
proc *_p;
public:
delayed_proc_free(proc *p) : rcu_freed("delayed proc free"), _p(p) {}
virtual void do_gc() {
kmfree(_p, sizeof(struct proc));
delete this;
}
NEW_DELETE_OPS(delayed_proc_free)
};
static void
freeproc(struct proc *p)
{
destroylock(&p->lock);
gc_delayed(new delayed_proc_free(p));
gc_delayed(p);
}
// Look in the process table for an UNUSED proc.
......@@ -208,23 +193,15 @@ allocproc(void)
struct proc *p;
char *sp;
p = (proc*) kmalloc(sizeof(struct proc));
p = new proc(xnspid->allockey());
if (p == 0) return 0;
memset(p, 0, sizeof(*p));
p->state = EMBRYO;
p->pid = xnspid->allockey();
p->cpuid = mycpu()->id;
p->on_runq = -1;
p->cpu_pin = 0;
initprocgc(p);
#if MTRACE
p->mtrace_stacks.curr = -1;
#endif
snprintf(p->lockname, sizeof(p->lockname), "cv:proc:%d", p->pid);
initlock(&p->lock, p->lockname+3, LOCKSTAT_PROC);
initcondvar(&p->cv, p->lockname);
initcilkframe(&p->cilkframe);
if (xnspid->insert(p->pid, p) < 0)
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论