M pc/apic.c => pc/apic.c +10 -0
@@ 154,6 154,7 @@ lapicinit(Apic* apic)
lapicw(LapicSVR, LapicENABLE|VectorSPURIOUS);
clkin = lapictimerinit();
+
/*
* Some Pentium revisions have a bug whereby spurious
* interrupts are generated in the through-local mode.
@@ 165,8 166,17 @@ lapicinit(Apic* apic)
wrmsr(0x0E, 1<<14); /* TR12 */
break;
}
+
+ /*
+ * Set the local interrupts. It's likely these should just be
+ * masked off for SMP mode as some Pentium Pros have problems if
+ * LINT[01] are set to ExtINT.
+ * Acknowledge any outstanding interrupts.
lapicw(LapicLINT0, apic->lintr[0]);
lapicw(LapicLINT1, apic->lintr[1]);
+ */
+ lapiceoi(0);
+
lvt = (lapicr(LapicVER)>>16) & 0xFF;
if(lvt >= 4)
lapicw(LapicPCINT, ApicIMASK);
M pc/dat.h => pc/dat.h +1 -1
@@ 13,9 13,9 @@ typedef struct Pcidev Pcidev;
typedef struct PCMmap PCMmap;
typedef struct Page Page;
typedef struct PMMU PMMU;
+typedef struct Proc Proc;
typedef struct Segdesc Segdesc;
typedef struct Ureg Ureg;
-typedef struct Proc Proc;
/*
* parameters for sysproc.c
M pc/etherelnk3.c => pc/etherelnk3.c +15 -16
@@ 1435,14 1435,14 @@ setfullduplex(int port)
}
static int
-miir(Ether* ether, int phyad, int regad)
+miir(int port, int phyad, int regad)
{
- int data, i, port, w, x;
-
- port = ether->port+PhysicalMgmt;
+ int data, i, w, x;
w = (STATUS(port)>>13) & 0x07;
- COMMAND(ether->port, SelectRegisterWindow, Wdiagnostic);
+ COMMAND(port, SelectRegisterWindow, Wdiagnostic);
+
+ port += PhysicalMgmt;
/*
* Taken from the Cyclone manual appendix describing
@@ 1505,26 1505,26 @@ miir(Ether* ether, int phyad, int regad)
microdelay(1);
outs(port, mgmtClk);
- COMMAND(ether->port, SelectRegisterWindow, w);
+ port -= PhysicalMgmt;
+ COMMAND(port, SelectRegisterWindow, w);
if(data & 0x10000)
return -1;
-print("%d/%d: data=%uX\n", phyad, regad, data);
return data & 0xFFFF;
}
static void
-scanphy(Ether* ether)
+scanphy(int port)
{
int i, x;
for(i = 0; i < 32; i++){
- if((x = miir(ether, i, 2)) == -1)
+ if((x = miir(port, i, 2)) == -1 || x == 0)
continue;
x <<= 6;
- x |= miir(ether, i, 3)>>10;
- XCVRDEBUG("phy%d: oui %uX reg1 %uX\n", i, x, miir(ether, i, 1));
+ x |= miir(port, i, 3)>>10;
+ XCVRDEBUG("phy%d: oui %uX reg1 %uX\n", i, x, miir(port, i, 1));
USED(x);
}
}
@@ 1748,17 1748,17 @@ if(did == 0x9055)
else
if(xcvr & autoSelect)
xcvr = autoselect(port, xcvr, rxstatus9);
- XCVRDEBUG("autoselect returns: xcvr %uX\n", xcvr);
+ XCVRDEBUG("autoselect returns: xcvr %uX, did 0x%uX\n", xcvr, did);
switch(xcvr){
case xcvrMii:
/*
* Quick hack.
- scanphy(ether);
+ scanphy(port);
*/
phyaddr = 24;
- an = miir(ether, phyaddr, 0x04);
- an &= miir(ether, phyaddr, 0x05) & 0x03E0;
+ an = miir(port, phyaddr, 0x04);
+ an &= miir(port, phyaddr, 0x05) & 0x03E0;
XCVRDEBUG("mii an: %uX\n", an);
for(i = 0; i < ether->nopt; i++){
if(cistrcmp(ether->opt[i], "fullduplex") == 0)
@@ 1869,7 1869,6 @@ else
*/
ctlr->upenabled = 1;
x = eepromdata(port, 0x0F);
- //print("software info 2: %uX\n", x);
if(!(x & 0x01))
outl(port+PktStatus, upRxEarlyEnable);
M pc/l.s => pc/l.s +1 -0
@@ 142,6 142,7 @@ _clearbss:
*/
TEXT idle(SB), $0
_idle:
+ STI
HLT
JMP _idle
M pc/main.c => pc/main.c +10 -0
@@ 542,6 542,16 @@ procsave(Proc *p)
fpsave(&up->fpsave);
p->fpstate = FPinactive;
}
+
+ /*
+ * Switch to the prototype page tables for this processor.
+ * While this processor is in the scheduler, the process could run
+ * on another processor and exit, returning the page tables to
+ * the free list where they could be reallocated and overwritten.
+ * When this processor eventually has to get an entry from the
+ * trashed page tables it will crash.
+ */
+ mmuflushtlb(PADDR(m->pdb));
}
void
M pc/mmu.c => pc/mmu.c +65 -76
@@ 24,7 24,7 @@ Segdesc gdt[6] =
#define PTX(va) ((((ulong)(va))>>12) & 0x03FF)
static void
-taskswitch(ulong pagetbl, ulong stack)
+taskswitch(ulong pdb, ulong stack)
{
Tss *tss;
@@ 35,8 35,8 @@ taskswitch(ulong pagetbl, ulong stack)
tss->esp1 = stack;
tss->ss2 = KDSEL;
tss->esp2 = stack;
- tss->cr3 = pagetbl;
- putcr3(pagetbl);
+ tss->cr3 = pdb;
+ putcr3(pdb);
}
void
@@ 81,126 81,115 @@ flushmmu(void)
}
static void
-mmuptefree(Proc* p)
+mmuptefree(Proc* proc)
{
ulong *pdb;
- Page **lpg, *pg;
-
- if(p->mmupdb && p->mmuused){
- pdb = (ulong*)p->mmupdb->va;
- lpg = &p->mmuused;
- for(pg = *lpg; pg; pg = pg->next){
- pdb[pg->daddr] = 0;
- lpg = &pg->next;
+ Page **last, *page;
+
+ if(proc->mmupdb && proc->mmuused){
+ pdb = (ulong*)proc->mmupdb->va;
+ last = &proc->mmuused;
+ for(page = *last; page; page = page->next){
+ pdb[page->daddr] = 0;
+ last = &page->next;
}
- *lpg = p->mmufree;
- p->mmufree = p->mmuused;
- p->mmuused = 0;
+ *last = proc->mmufree;
+ proc->mmufree = proc->mmuused;
+ proc->mmuused = 0;
}
}
void
-mmuswitch(Proc* p)
+mmuswitch(Proc* proc)
{
- ulong *top;
+ ulong *pdb;
- if(p->newtlb){
- mmuptefree(p);
- p->newtlb = 0;
+ if(proc->newtlb){
+ mmuptefree(proc);
+ proc->newtlb = 0;
}
- if(p->mmupdb){
- top = (ulong*)p->mmupdb->va;
- top[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)];
- taskswitch(p->mmupdb->pa, (ulong)(p->kstack+KSTACK));
+ if(proc->mmupdb){
+ pdb = (ulong*)proc->mmupdb->va;
+ pdb[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)];
+ taskswitch(proc->mmupdb->pa, (ulong)(proc->kstack+KSTACK));
}
else
- taskswitch(PADDR(m->pdb), (ulong)(p->kstack+KSTACK));
+ taskswitch(PADDR(m->pdb), (ulong)(proc->kstack+KSTACK));
}
void
-mmurelease(Proc* p)
+mmurelease(Proc* proc)
{
- Page *pg, *next;
+ Page *page, *next;
/*
* Release any pages allocated for a page directory base or page-tables
* for this process:
* switch to the prototype pdb for this processor (m->pdb);
- * call mmuptefree() to place all pages used for page-tables (p->mmuused)
- * onto the process' free list (p->mmufree). This has the side-effect of
- * cleaning any user entries in the pdb (p->mmupdb);
+ * call mmuptefree() to place all pages used for page-tables (proc->mmuused)
+ * onto the process' free list (proc->mmufree). This has the side-effect of
+ * cleaning any user entries in the pdb (proc->mmupdb);
* if there's a pdb put it in the cache of pre-initialised pdb's
* for this processor (m->pdbpool) or on the process' free list;
* finally, place any pages freed back into the free pool (palloc).
* This routine is only called from sched() with palloc locked.
*/
taskswitch(PADDR(m->pdb), (ulong)m + BY2PG);
- mmuptefree(p);
+ mmuptefree(proc);
- if(p->mmupdb){
+ if(proc->mmupdb){
if(m->pdbcnt > 10){
- p->mmupdb->next = p->mmufree;
- p->mmufree = p->mmupdb;
+ proc->mmupdb->next = proc->mmufree;
+ proc->mmufree = proc->mmupdb;
}
else{
- p->mmupdb->next = m->pdbpool;
- m->pdbpool = p->mmupdb;
+ proc->mmupdb->next = m->pdbpool;
+ m->pdbpool = proc->mmupdb;
m->pdbcnt++;
}
- p->mmupdb = 0;
+ proc->mmupdb = 0;
}
- for(pg = p->mmufree; pg; pg = next){
- next = pg->next;
- if(--pg->ref)
- panic("mmurelease: pg->ref %d\n", pg->ref);
- pg->ref = 0;
- if(palloc.head){
- pg->next = palloc.head;
- palloc.head->prev = pg;
- }
- else{
- palloc.tail = pg;
- pg->next = 0;
- }
- palloc.head = pg;
- pg->prev = 0;
-
- palloc.freecount++;
+ for(page = proc->mmufree; page; page = next){
+ next = page->next;
+ if(--page->ref)
+ panic("mmurelease: page->ref %d\n", page->ref);
+ pagechainhead(page);
}
- if(p->mmufree && palloc.r.p)
+ if(proc->mmufree && palloc.r.p)
wakeup(&palloc.r);
- p->mmufree = 0;
+ proc->mmufree = 0;
}
static Page*
mmupdballoc(void)
{
int s;
- Page *pg;
+ Page *page;
s = splhi();
if(m->pdbpool == 0){
spllo();
- pg = newpage(0, 0, 0);
- pg->va = VA(kmap(pg));
- memmove((void*)pg->va, m->pdb, BY2PG);
+ page = newpage(0, 0, 0);
+ page->va = VA(kmap(page));
+ memmove((void*)page->va, m->pdb, BY2PG);
}
else{
- pg = m->pdbpool;
- m->pdbpool = pg->next;
+ page = m->pdbpool;
+ m->pdbpool = page->next;
m->pdbcnt--;
}
splx(s);
- return pg;
+ return page;
}
void
-putmmu(ulong va, ulong pa, Page* pg)
+putmmu(ulong va, ulong pa, Page*)
{
int pdbx;
- ulong *pdb, *pt;
+ Page *page;
+ ulong *pdb, *pte;
int s;
if(up->mmupdb == 0)
@@ 210,22 199,22 @@ putmmu(ulong va, ulong pa, Page* pg)
if(PPN(pdb[pdbx]) == 0){
if(up->mmufree == 0){
- pg = newpage(1, 0, 0);
- pg->va = VA(kmap(pg));
+ page = newpage(1, 0, 0);
+ page->va = VA(kmap(page));
}
else {
- pg = up->mmufree;
- up->mmufree = pg->next;
- memset((void*)pg->va, 0, BY2PG);
+ page = up->mmufree;
+ up->mmufree = page->next;
+ memset((void*)page->va, 0, BY2PG);
}
- pdb[pdbx] = PPN(pg->pa)|PTEUSER|PTEWRITE|PTEVALID;
- pg->daddr = pdbx;
- pg->next = up->mmuused;
- up->mmuused = pg;
+ pdb[pdbx] = PPN(page->pa)|PTEUSER|PTEWRITE|PTEVALID;
+ page->daddr = pdbx;
+ page->next = up->mmuused;
+ up->mmuused = page;
}
- pt = KADDR(PPN(pdb[pdbx]));
- pt[PTX(va)] = pa|PTEUSER;
+ pte = KADDR(PPN(pdb[pdbx]));
+ pte[PTX(va)] = pa|PTEUSER;
s = splhi();
pdb[PDX(MACHADDR)] = m->pdb[PDX(MACHADDR)];
M pc/mp.c => pc/mp.c +12 -31
@@ 271,7 271,15 @@ mklintr(PCMPintr* p)
if((bus = mpgetbus(p->busno)) == 0)
return 0;
intin = p->intin;
- v = mpintrinit(bus, p, VectorLAPIC+intin);
+
+ /*
+ * Pentium Pros have problems if LINT[01] are set to ExtINT
+ * so just bag it. Should be OK for SMP mode.
+ */
+ if(p->intr == PcmpExtINT || p->intr == PcmpNMI)
+ v = ApicIMASK;
+ else
+ v = mpintrinit(bus, p, VectorLAPIC+intin);
if(p->apicno == 0xFF){
for(apic = mpapic; apic <= &mpapic[MaxAPICNO]; apic++){
@@ 446,21 454,6 @@ mpstartap(Apic* apic)
nvramwrite(0x0F, 0x00);
}
-static void
-senddbgnmi(void)
-{
- /*
- * NMI all excluding self.
- */
- lapicicrw(0, 0x000C0000|ApicNMI);
-}
-
-static void
-mpdbg(Ureg* ureg, void*)
-{
- iprint("MPDBG: cpu%d: PC 0x%uX\n", m->machno, ureg->pc);
-}
-
void
mpinit(void)
{
@@ 568,9 561,6 @@ mpinit(void)
*/
if(conf.nmach > 1)
conf.copymode = 1;
-
- consdebug = senddbgnmi;
- intrenable(VectorNMI, mpdbg, 0, BUSUNKNOWN);
}
static int
@@ 695,34 685,25 @@ mpintrenable(int v, int tbdf, Irqctl* irqctl)
return -1;
}
+static Lock mpshutdownlock;
+
void
mpshutdown(void)
{
- int apicno, machno;
-
/*
* To be done...
*/
- if(m->machno){
+ if(!canlock(&mpshutdownlock)){
/*
* If this processor received the CTRL-ALT-DEL from
* the keyboard, acknowledge it. Send an INIT to self.
*/
if(lapicisr(VectorKBD))
lapiceoi(VectorKBD);
- lapicicrw(0, 0x00040000|ApicINIT);
idle();
}
print("apshutdown: active = 0x%2.2uX\n", active.machs);
- if(active.machs){
- for(machno = 1; machno < conf.nmach; machno++){
- if(!(active.machs & (1<<machno)))
- continue;
- apicno = machno2apicno[machno];
- lapicicrw(1<<apicno, ApicNMI);
- }
- }
delay(1000);
splhi();
M pc/trap.c => pc/trap.c +5 -0
@@ 171,6 171,7 @@ trap(Ureg* ureg)
sched();
splhi();
up->preempted = 0;
+ return;
}
}
else if(v <= 16 && user){
@@ 418,6 419,10 @@ syscall(Ureg* ureg)
splhi();
notify(ureg);
}
+ if (up->nlocks != 0) {
+ print("nlock = %d\n", up->nlocks);
+ up->nlocks = 0;
+ }
}
/*
M port/page.c => port/page.c +65 -71
@@ 7,7 7,6 @@
#define pghash(daddr) palloc.hash[(daddr>>PGSHIFT)&(PGHSIZE-1)]
-static Lock pglock;
struct Palloc palloc;
void
@@ 63,6 62,59 @@ pageinit(void)
print("%dK swap\n", vm);
}
+static void
+pageunchain(Page *p)
+{
+ if(canlock(&palloc))
+ panic("pageunchain");
+ if(p->prev)
+ p->prev->next = p->next;
+ else
+ palloc.head = p->next;
+ if(p->next)
+ p->next->prev = p->prev;
+ else
+ palloc.tail = p->prev;
+ p->prev = p->next = nil;
+ palloc.freecount--;
+}
+
+void
+pagechaintail(Page *p)
+{
+ if(canlock(&palloc))
+ panic("pagechaintail");
+ if(palloc.tail) {
+ p->prev = palloc.tail;
+ palloc.tail->next = p;
+ }
+ else {
+ palloc.head = p;
+ p->prev = 0;
+ }
+ palloc.tail = p;
+ p->next = 0;
+ palloc.freecount++;
+}
+
+void
+pagechainhead(Page *p)
+{
+ if(canlock(&palloc))
+ panic("pagechainhead");
+ if(palloc.head) {
+ p->next = palloc.head;
+ palloc.head->prev = p;
+ }
+ else {
+ palloc.tail = p;
+ p->next = 0;
+ }
+ palloc.head = p;
+ p->prev = 0;
+ palloc.freecount++;
+}
+
Page*
newpage(int clear, Segment **s, ulong va)
{
@@ 71,7 123,6 @@ newpage(int clear, Segment **s, ulong va)
uchar ct;
int i, hw, dontalloc, color;
-
lock(&palloc);
color = getpgcolor(va);
hw = swapalloc.highwater;
@@ 124,15 175,7 @@ newpage(int clear, Segment **s, ulong va)
ct = PG_NEWCOL;
}
- if(p->prev)
- p->prev->next = p->next;
- else
- palloc.head = p->next;
- if(p->next)
- p->next->prev = p->prev;
- else
- palloc.tail = p->prev;
- palloc.freecount--;
+ pageunchain(p);
lock(p);
if(p->ref != 0)
@@ 178,31 221,10 @@ putpage(Page *p)
return;
}
- if(p->image && p->image != &swapimage) {
- if(palloc.tail) {
- p->prev = palloc.tail;
- palloc.tail->next = p;
- }
- else {
- palloc.head = p;
- p->prev = 0;
- }
- palloc.tail = p;
- p->next = 0;
- }
- else {
- if(palloc.head) {
- p->next = palloc.head;
- palloc.head->prev = p;
- }
- else {
- palloc.tail = p;
- p->next = 0;
- }
- palloc.head = p;
- p->prev = 0;
- }
- palloc.freecount++;
+ if(p->image && p->image != &swapimage)
+ pagechaintail(p);
+ else
+ pagechainhead(p);
if(palloc.r.p != 0)
wakeup(&palloc.r);
@@ 222,9 244,7 @@ auxpage()
unlock(&palloc);
return 0;
}
- p->next->prev = 0;
- palloc.head = p->next;
- palloc.freecount--;
+ pageunchain(p);
lock(p);
if(p->ref != 0)
@@ 246,8 266,9 @@ duppage(Page *p) /* Always call with p locked */
retries = 0;
retry:
+
if(retries++ > 10000)
- panic("duppage");
+ panic("duppage %d", retries);
/* No dup for swap/cache pages */
if(p->ref == 0 || p->image == nil || p->image->notext)
@@ 286,26 307,8 @@ retry:
return;
}
- if(np->prev)
- np->prev->next = np->next;
- else
- palloc.head = np->next;
- if(np->next)
- np->next->prev = np->prev;
- else
- palloc.tail = np->prev;
-
- /* Link back onto tail to give us lru in the free list */
- if(palloc.tail) {
- np->prev = palloc.tail;
- palloc.tail->next = np;
- np->next = 0;
- palloc.tail = np;
- }
- else {
- palloc.head = palloc.tail = np;
- np->prev = np->next = 0;
- }
+ pageunchain(np);
+ pagechaintail(np);
lock(np);
unlock(&palloc);
@@ 411,17 414,8 @@ lookpage(Image *i, ulong daddr)
unlock(&palloc);
return 0;
}
- if(++f->ref == 1) {
- if(f->prev)
- f->prev->next = f->next;
- else
- palloc.head = f->next;
- if(f->next)
- f->next->prev = f->prev;
- else
- palloc.tail = f->prev;
- palloc.freecount--;
- }
+ if(++f->ref == 1)
+ pageunchain(f);
unlock(&palloc);
unlock(f);
M port/portdat.h => port/portdat.h +2 -1
@@ 536,7 536,6 @@ struct Proc
QLock *qlock; /* addrof qlock being queued for DEBUG */
int state;
char *psstate; /* What /proc/#/status reports */
- Page *upage; /* page from palloc */
Segment *seg[NSEG];
ulong pid;
ulong noteid; /* Equivalent of note group */
@@ 602,6 601,8 @@ struct Proc
Note lastnote;
int (*notify)(void*, char*);
+ int nlocks; /* Number of locks held */
+
Mach *wired;
Mach *mp; /* machine this process last ran on */
ulong priority; /* priority level */
M port/portfns.h => port/portfns.h +1 -0
@@ 170,6 170,7 @@ int nrand(int);
int okaddr(ulong, ulong, int);
int openmode(ulong);
Block* padblock(Block*, int);
+void pagechainhead(Page*);
void pageinit(void);
void panic(char*, ...);
int parseether(uchar*, char*);
M port/proc.c => port/proc.c +3 -1
@@ 66,6 66,7 @@ schedinit(void) /* never returns */
/*
* Holding locks from pexit:
* procalloc
+ * palloc
*/
mmurelease(up);
@@ 330,6 331,7 @@ newproc(void)
panic("pidalloc");
if(p->kstack == 0)
p->kstack = smalloc(KSTACK);
+ p->nlocks = 0;
return p;
}
@@ 812,7 814,7 @@ pexit(char *exitstr, int freemem)
}
qunlock(&up->debug);
- /* Sched must not loop for this lock */
+ /* Sched must not loop for these locks */
lock(&procalloc);
lock(&palloc);
M port/qio.c => port/qio.c +41 -17
@@ 19,7 19,7 @@ static ulong consumecnt;
static ulong producecnt;
static ulong qcopycnt;
-static int debuging;
+static int debugging;
#define QDEBUG if(0)
@@ 62,15 62,24 @@ enum
Qflow = (1<<3),
Hdrspc = 64, /* leave room for high-level headers */
+
+ Bdead = 0x51494F42, /* "QIOB" */
};
void
checkb(Block *b, char *msg)
{
- void *dead = (void*)0xDEADBABE;
+ void *dead = (void*)Bdead;
if(b == dead)
panic("checkb b %s %lux", msg, b);
+ if(b->base == dead || b->lim == dead || b->next == dead
+ || b->rp == dead || b->wp == dead){
+ print("checkb: base 0x%8.8luX lim 0x%8.8luX next 0x%8.8luX\n",
+ b->base, b->lim, b->next);
+ print("checkb: rp 0x%8.8luX wp 0x%8.8luX\n", b->rp, b->wp);
+ panic("checkb dead: %s\n", msg);
+ }
if(b->base > b->lim)
panic("checkb 0 %s %lux %lux", msg, b->base, b->lim);
@@ 83,20 92,13 @@ checkb(Block *b, char *msg)
if(b->wp > b->lim)
panic("checkb 4 %s %lux %lux", msg, b->wp, b->lim);
- if(b->base == dead || b->lim == dead || b->next == dead
- || b->rp == dead || b->wp == dead){
- print("checkb: base 0x%8.8luX lim 0x%8.8luX next 0x%8.8luX\n",
- b->base, b->lim, b->next);
- print("checkb: rp 0x%8.8luX wp 0x%8.8luX\n", b->rp, b->wp);
- panic("checkb dead: %s\n", msg);
- }
}
void
ixsummary(void)
{
- debuging ^= 1;
- print("ialloc %d/%d %d\n", ialloc.bytes, conf.ialloc, debuging);
+ debugging ^= 1;
+ print("ialloc %d/%d %d\n", ialloc.bytes, conf.ialloc, debugging);
print("pad %lud, concat %lud, pullup %lud, copy %lud\n",
padblockcnt, concatblockcnt, pullupblockcnt, copyblockcnt);
print("consume %lud, produce %lud, qcopy %lud\n",
@@ 177,6 179,8 @@ iallocb(int size)
void
freeb(Block *b)
{
+ void *dead = (void*)Bdead;
+
/*
* drivers which perform non cache coherent DMA manage their own buffer
* pool of uncached buffers and provide their own free routine.
@@ 192,11 196,11 @@ freeb(Block *b)
}
/* poison the block in case someone is still holding onto it */
- b->next = (void*)0xdeadbabe;
- b->rp = (void*)0xdeadbabe;
- b->wp = (void*)0xdeadbabe;
- b->lim = (void*)0xdeadbabe;
- b->base = (void*)0xdeadbabe;
+ b->next = dead;
+ b->rp = dead;
+ b->wp = dead;
+ b->lim = dead;
+ b->base = dead;
free(b);
}
@@ 225,12 229,15 @@ padblock(Block *bp, int size)
int n;
Block *nbp;
+ QDEBUG checkb(bp, "padblock 1");
if(size >= 0){
if(bp->rp - bp->base >= size){
bp->rp -= size;
return bp;
}
+ if(bp->next)
+ panic("padblock 0x%uX", getcallerpc(bp));
n = BLEN(bp);
padblockcnt++;
nbp = allocb(size+n);
@@ 246,6 253,8 @@ padblock(Block *bp, int size)
if(bp->lim - bp->wp >= size)
return bp;
+ if(bp->next)
+ panic("padblock 0x%uX", getcallerpc(bp));
n = BLEN(bp);
padblockcnt++;
nbp = allocb(size+n);
@@ 253,6 262,7 @@ padblock(Block *bp, int size)
nbp->wp += n;
freeb(bp);
}
+ QDEBUG checkb(nbp, "padblock 1");
return nbp;
}
@@ 293,6 303,7 @@ concatblock(Block *bp)
}
concatblockcnt += BLEN(nb);
freeblist(bp);
+ QDEBUG checkb(nb, "concatblock 1");
return nb;
}
@@ 333,6 344,7 @@ pullupblock(Block *bp, int n)
pullupblockcnt++;
bp->wp += n;
nbp->rp += n;
+ QDEBUG checkb(bp, "pullupblock 1");
return bp;
}
else {
@@ 343,8 355,10 @@ pullupblock(Block *bp, int n)
nbp->next = 0;
freeb(nbp);
n -= i;
- if(n == 0)
+ if(n == 0){
+ QDEBUG checkb(bp, "pullupblock 2");
return bp;
+ }
}
}
freeb(bp);
@@ 360,6 374,7 @@ trimblock(Block *bp, int offset, int len)
ulong l;
Block *nb, *startb;
+ QDEBUG checkb(bp, "trimblock 1");
if(blocklen(bp) < offset+len) {
freeblist(bp);
return nil;
@@ 400,6 415,7 @@ copyblock(Block *bp, int count)
int l;
Block *nbp;
+ QDEBUG checkb(bp, "copyblock 0");
nbp = allocb(count);
for(; count > 0 && bp != 0; bp = bp->next){
l = BLEN(bp);
@@ 414,6 430,7 @@ copyblock(Block *bp, int count)
nbp->wp += count;
}
copyblockcnt++;
+ QDEBUG checkb(nbp, "copyblock 1");
return nbp;
}
@@ 432,6 449,7 @@ adjustblock(Block* bp, int len)
if(bp->rp+len > bp->lim){
nbp = copyblock(bp, len);
freeblist(bp);
+ QDEBUG checkb(nbp, "adjustblock 1");
return nbp;
}
@@ 440,6 458,7 @@ adjustblock(Block* bp, int len)
if(len > n)
memset(bp->wp, 0, len-n);
bp->wp = bp->rp+len;
+ QDEBUG checkb(bp, "adjustblock 2");
return bp;
}
@@ 468,6 487,7 @@ pullblock(Block **bph, int count)
bytes += n;
count -= n;
bp->rp += n;
+ QDEBUG checkb(bp, "pullblock ");
if(BLEN(bp) == 0) {
*bph = bp->next;
bp->next = nil;
@@ 498,6 518,7 @@ qget(Queue *q)
q->bfirst = b->next;
b->next = 0;
q->len -= BLEN(b);
+ QDEBUG checkb(b, "qget");
/* if writer flow controlled, restart */
if((q->state & Qflow) && q->len < q->limit/2){
@@ 528,6 549,7 @@ qdiscard(Queue *q, int len)
b = q->bfirst;
if(b == nil)
break;
+ QDEBUG checkb(b, "qdiscard");
n = BLEN(b);
if(n <= len - sofar){
q->bfirst = b->next;
@@ 732,6 754,7 @@ qcopy(Queue *q, int len, ulong offset)
n -= offset - sofar;
break;
}
+ QDEBUG checkb(b, "qcopy");
b = b->next;
}
@@ 952,6 975,7 @@ qbwrite(Queue *q, Block *b)
q->blast = b;
b->next = 0;
q->len += n;
+ QDEBUG checkb(b, "qbwrite");
if(q->state & Qstarve){
q->state &= ~Qstarve;
M port/taslock.c => port/taslock.c +27 -2
@@ 29,6 29,7 @@ lock(Lock *l)
l->p = up;
l->isilock = 0;
if(up){
+ up->nlocks++;
l->pri = up->priority;
up->priority = PriLock;
}
@@ 56,6 57,7 @@ lock(Lock *l)
l->p = up;
l->isilock = 0;
if(up){
+ up->nlocks++;
l->pri = up->priority;
up->priority = PriLock;
}
@@ 74,6 76,8 @@ ilock(Lock *l)
x = splhi();
if(tas(&l->key) == 0){
+ if (up)
+ up->nlocks++;
l->sr = x;
l->pc = pc;
l->p = up;
@@ 90,6 94,8 @@ ilock(Lock *l)
;
x = splhi();
if(tas(&l->key) == 0){
+ if (up)
+ up->nlocks++;
l->sr = x;
l->pc = pc;
l->p = up;
@@ 109,6 115,7 @@ canlock(Lock *l)
l->p = up;
l->isilock = 0;
if(up){
+ up->nlocks++;
l->pri = up->priority;
up->priority = PriLock;
}
@@ 119,6 126,9 @@ void
unlock(Lock *l)
{
int p;
+ ulong pc;
+
+ pc = getcallerpc(l);
p = l->pri;
if(l->key == 0)
@@ 127,8 137,18 @@ unlock(Lock *l)
print("iunlock of lock: pc %lux, held by %lux\n", getcallerpc(l), l->pc);
l->pc = 0;
l->key = 0;
- if(up && p < up->priority)
- up->priority = p;
+ if(up) {
+ if (up != l->p) {
+ print("different unlocker 0x%lux pc 0x%lux held by pc 0x%lux proc %d\n",
+ l->key, pc, l->pc, l->p ? l->p->pid : 0);
+ dumpaproc(up);
+ }
+ if (--up->nlocks < 0)
+ print("number of locks < 0: pc %lux, held by %lux\n",
+ getcallerpc(l), l->pc);
+ if (p < up->priority)
+ up->priority = p;
+ }
coherence();
}
@@ 145,6 165,11 @@ iunlock(Lock *l)
sr = l->sr;
l->pc = 0;
l->key = 0;
+ if(up) {
+ if (--up->nlocks < 0)
+ print("number of locks < 0: pc %lux, held by %lux\n",
+ getcallerpc(l), l->pc);
+ }
splx(sr);
coherence();
}