- work around 64-bit padding to make 64-bit and 32-bit kernel file systems have the same disk layout. this is the cheap way out, but reduces unnecessary churn for now - be explicit about the amount of padding required at the beginning of a msgbuf. this bug was found when the private msgbufs in the 82563 driver were change from 4k alignment to 8 byte alignment resulting in random crashes, often with corrupt locks. a million wstat messages teased out the problem. eventually a lock would be corrupted with the wstat message. a ha! - no need to print "someone's exiting". Reference: /n/atom/patch/applied/fsmsgbufpad Date: Mon Apr 14 07:04:46 CES 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/fs/port/main.c Mon Apr 14 06:59:20 2014 +++ /sys/src/fs/port/main.c Mon Apr 14 06:59:20 2014 @@ -425,3 +425,9 @@ /* pokewcp(); */ } } + +void +_assert(char *fmt) +{ + panic("assert failed at %#p: %s", getcallerpc(&fmt), fmt); +} --- /sys/src/fs/port/clock.c Mon Apr 14 06:59:22 2014 +++ /sys/src/fs/port/clock.c Mon Apr 14 06:59:22 2014 @@ -111,11 +111,11 @@ p = m->proc; if(p == nil) p = m->intrp; - if(p) + if(p != nil) p->time.count += 10*TK2MS(1); else m->idle.count += 10*TK2MS(1); - m->intrp = 0; + m->intrp = nil; if(m->machno == 0){ lights(Lreal, (sys->ticks>>6)&1); @@ -127,10 +127,8 @@ } } - if(active.exiting && active.machs&(1<machno)){ - print("cpu%d: someone's exiting\n", m->machno); + if(active.exiting && active.machs&(1<machno)) exit(); - } checkalarms(); } --- /sys/src/fs/port/all.h Mon Apr 14 06:59:24 2014 +++ /sys/src/fs/port/all.h Mon Apr 14 06:59:24 2014 @@ -53,7 +53,7 @@ Device* devnone; Startsb startsb[5]; int predawn; /* set in early boot, causes polling ttyout */ -short mballocs[MAXCAT]; +int mballocs[MAXCAT]; Filsys filsys[10]; /* named file systems -- from config block */ char service[50]; /* my name -- from config block */ int aindex; --- /sys/src/fs/port/sub.c Mon Apr 14 06:59:26 2014 +++ /sys/src/fs/port/sub.c Mon Apr 14 06:59:28 2014 @@ -486,7 +486,7 @@ n = --sb->fbuf.nfree; sb->tfree--; if(n < 0 || n >= FEPERBUF) { - print("bufalloc: %Z: bad freelist\n", dev); + print("bufalloc: %Z: bad freelist %lld free\n", dev, n); n = 0; sb->fbuf.free[0] = 0; } @@ -882,7 +882,7 @@ msgalloc.smsgbuf = 0; for(i=0; ixdata = ialloc(LARGEBUF+256, 256); + mb->xdata = ialloc(LARGEBUF+MBALIGN, MBALIGN); mb->flags = LARGE; mb->free = 0; mbfree(mb); @@ -890,7 +890,7 @@ } for(i=0; ixdata = ialloc(SMALLBUF+256, 256); + mb->xdata = ialloc(SMALLBUF+MBALIGN, MBALIGN); mb->flags = 0; mb->free = 0; mbfree(mb); @@ -916,11 +916,11 @@ ilock(&msgalloc); if(count > SMALLBUF) { if(count > LARGEBUF) - panic("msgbuf count"); + panic("msgbuf count count %d > %d from %#p", count, LARGEBUF, getcallerpc(&count)); mb = msgalloc.lmsgbuf; if(mb == 0) { mb = ialloc(sizeof(Msgbuf), 0); - mb->xdata = ialloc(LARGEBUF+256, 256); + mb->xdata = ialloc(LARGEBUF+MBALIGN, MBALIGN); cons.nlarge++; } else msgalloc.lmsgbuf = mb->next; @@ -929,7 +929,7 @@ mb = msgalloc.smsgbuf; if(mb == 0) { mb = ialloc(sizeof(Msgbuf), 0); - mb->xdata = ialloc(SMALLBUF+256, 256); + mb->xdata = ialloc(SMALLBUF+MBALIGN, MBALIGN); cons.nsmall++; } else msgalloc.smsgbuf = mb->next; @@ -942,7 +942,7 @@ mb->next = 0; mb->param = 0; mb->category = category; - mb->data = mb->xdata+256; + mb->data = mb->xdata+MBALIGN; mb->free = 0; return mb; } @@ -954,6 +954,8 @@ int i; Msgbuf *a, *mb; + if(align < MBALIGN) + align = MBALIGN; /* * put the Msgbuf in the tail of the allocation if it fits. otherwise * don't waste a whole align @@ -1005,9 +1007,13 @@ return; } + mb->chan = nil; + mb->data = nil; + mb->free = nil; + mb->flags |= FREE; + ilock(&msgalloc); mballocs[mb->category]--; - mb->flags |= FREE; if(mb->flags & LARGE) { mb->next = msgalloc.lmsgbuf; msgalloc.lmsgbuf = mb; @@ -1015,8 +1021,6 @@ mb->next = msgalloc.smsgbuf; msgalloc.smsgbuf = mb; } - mb->data = 0; - mb->free = 0; iunlock(&msgalloc); } @@ -1149,7 +1153,7 @@ panic("send null a %#p", getcallerpc(q)); if(u == nil) panic("send with no u %#p", getcallerpc(q)); - if(u->nlock){ + if(u->nlock || m->ilockdepth > 0){ print("send with locks %#p", getcallerpc(q)); printlocks(u); } @@ -1173,8 +1177,8 @@ iunlock(q); return; } - if(u->nlock) - print("%d: q blocking nlock %ld\n", u->pid, u->nlock); + if(0) + print("%d: q block nlock %ld sz %d\n", u->pid, u->nlock, q->size); p = q->wtail; if(p == 0) q->whead = u; --- /sys/src/fs/port/portdat.h Mon Apr 14 06:59:30 2014 +++ /sys/src/fs/port/portdat.h Mon Apr 14 06:59:31 2014 @@ -61,6 +61,7 @@ #define DIRPERBUF (BUFSIZE/sizeof(Dentry)) #define INDPERBUF (BUFSIZE/sizeof(Off)) #define FEPERBUF ((BUFSIZE-sizeof(Super1)-sizeof(Off))/sizeof(Off)) +#define MBALIGN 256 /* slop at beginning of buffer */ #define SMALLBUF (MAXMSG) #define LARGEBUF (MAXMSG+MAXDAT+256) #define RAGAP (300*1024)/BUFSIZE /* readahead parameter */ @@ -153,12 +154,14 @@ void* args[1]; /* list of saved pointers, [->size] */ }; +#pragma pack on struct Tag { - short pad; /* make tag end at a long boundary */ + uchar pad[2]; /* make tag end at a long boundary */ short tag; Off path; }; +#pragma pack off struct Device { @@ -270,11 +273,13 @@ #define QTFILE 0x00 /* plain file */ /* DONT TOUCH, this is the disk structure */ +#pragma pack on struct Qid9p1 { Off path; /* was long */ ulong version; /* should be Off */ }; +#pragma pack off struct Hiob { @@ -433,6 +438,7 @@ }; /* DONT TOUCH, this is the disk structure */ +#pragma pack on struct Dentry { char name[NAMELEN]; @@ -447,13 +453,14 @@ #define DWRITE 0x2 #define DEXEC 0x1 Userid muid; - Qid9p1 qid; + Qid9p1 qid; /* 64-bit unsafe */ Off size; Off dblock[NDBLOCK]; Off iblocks[NIBLOCK]; long atime; long mtime; }; +#pragma pack off /* DONT TOUCH, this is the disk structure */ struct Super1 @@ -709,19 +716,23 @@ }; /* DONT TOUCH, this is the disk structure */ +#pragma pack on struct Centry { ushort age; short state; Off waddr; /* worm addr */ }; +#pragma pack off /* DONT TOUCH, this is the disk structure */ +#pragma pack on struct Bucket { long agegen; /* generator for ages in this bkt */ Centry entry[CEPERBK]; }; +#pragma pack off /* * scsi i/o