dtracy: avoid dmachlock() race
between being commited to a machno and having acquired the lock, the scheduler could come in an schedule us on a different processor. the solution is to have dtmachlock() take a special -1 argument to mean "current mach" and return the actual mach number after the lock has been acquired and interrupts being disabled.
This commit is contained in:
parent
ac3147a9c5
commit
4f0bfe0fb8
6 changed files with 28 additions and 20 deletions
|
@ -241,7 +241,7 @@ void dtsync(void);
|
||||||
DTProbe *dtpnew(char *, DTProvider *, void *aux);
|
DTProbe *dtpnew(char *, DTProvider *, void *aux);
|
||||||
int dtpmatch(char *, DTProbe ***);
|
int dtpmatch(char *, DTProbe ***);
|
||||||
int dtplist(DTProbe ***);
|
int dtplist(DTProbe ***);
|
||||||
void dtptrigger(DTProbe *, int, DTTrigInfo *);
|
void dtptrigger(DTProbe *, DTTrigInfo *);
|
||||||
|
|
||||||
/* expression functions */
|
/* expression functions */
|
||||||
int dteverify(DTExpr *);
|
int dteverify(DTExpr *);
|
||||||
|
@ -285,7 +285,7 @@ uvlong dttime(void); /* return current timestamp */
|
||||||
void *dtrealloc(void *, ulong);
|
void *dtrealloc(void *, ulong);
|
||||||
void dtfree(void *);
|
void dtfree(void *);
|
||||||
void *dtmalloc(ulong);
|
void *dtmalloc(ulong);
|
||||||
void dtmachlock(int); /* lock the per-cpu lock */
|
int dtmachlock(int); /* lock the per-cpu lock */
|
||||||
void dtmachunlock(int); /* unlock the per-cpu lock */
|
void dtmachunlock(int); /* unlock the per-cpu lock */
|
||||||
void dtcoherence(void); /* memory barrier */
|
void dtcoherence(void); /* memory barrier */
|
||||||
uvlong dtgetvar(int); /* return the value of a variable */
|
uvlong dtgetvar(int); /* return the value of a variable */
|
||||||
|
|
|
@ -512,10 +512,18 @@ dtrealloc(void *v, ulong n)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
dtmachlock(int i)
|
dtmachlock(int i)
|
||||||
{
|
{
|
||||||
|
while(i < 0) {
|
||||||
|
i = dtmachlock(m->machno);
|
||||||
|
if(i == m->machno)
|
||||||
|
return i;
|
||||||
|
dtmachunlock(i);
|
||||||
|
i = -1;
|
||||||
|
}
|
||||||
ilock(&machlocks[i]);
|
ilock(&machlocks[i]);
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -20,10 +20,10 @@ extern Syscall *systab[];
|
||||||
uintptr rc;\
|
uintptr rc;\
|
||||||
DTTrigInfo info;\
|
DTTrigInfo info;\
|
||||||
memset(&info, 0, sizeof(info));\
|
memset(&info, 0, sizeof(info));\
|
||||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
dtptrigger(dtpsysentry[y], &info);\
|
||||||
rc = z(va);\
|
rc = z(va);\
|
||||||
info.arg[9] = (uvlong) rc;\
|
info.arg[9] = (uvlong) rc;\
|
||||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
dtptrigger(dtpsysreturn[y], &info);\
|
||||||
return rc;\
|
return rc;\
|
||||||
}
|
}
|
||||||
#define WRAP1(x,y,z,type0)\
|
#define WRAP1(x,y,z,type0)\
|
||||||
|
@ -33,10 +33,10 @@ extern Syscall *systab[];
|
||||||
DTTrigInfo info;\
|
DTTrigInfo info;\
|
||||||
memset(&info, 0, sizeof(info));\
|
memset(&info, 0, sizeof(info));\
|
||||||
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
||||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
dtptrigger(dtpsysentry[y], &info);\
|
||||||
rc = z(va);\
|
rc = z(va);\
|
||||||
info.arg[9] = (uvlong) rc;\
|
info.arg[9] = (uvlong) rc;\
|
||||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
dtptrigger(dtpsysreturn[y], &info);\
|
||||||
return rc;\
|
return rc;\
|
||||||
}
|
}
|
||||||
#define WRAP2(x,y,z,type0,type1)\
|
#define WRAP2(x,y,z,type0,type1)\
|
||||||
|
@ -47,10 +47,10 @@ extern Syscall *systab[];
|
||||||
memset(&info, 0, sizeof(info));\
|
memset(&info, 0, sizeof(info));\
|
||||||
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
||||||
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
||||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
dtptrigger(dtpsysentry[y], &info);\
|
||||||
rc = z(va);\
|
rc = z(va);\
|
||||||
info.arg[9] = (uvlong) rc;\
|
info.arg[9] = (uvlong) rc;\
|
||||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
dtptrigger(dtpsysreturn[y], &info);\
|
||||||
return rc;\
|
return rc;\
|
||||||
}
|
}
|
||||||
#define WRAP3(x,y,z,type0,type1,type2)\
|
#define WRAP3(x,y,z,type0,type1,type2)\
|
||||||
|
@ -62,10 +62,10 @@ extern Syscall *systab[];
|
||||||
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
||||||
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
||||||
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
||||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
dtptrigger(dtpsysentry[y], &info);\
|
||||||
rc = z(va);\
|
rc = z(va);\
|
||||||
info.arg[9] = (uvlong) rc;\
|
info.arg[9] = (uvlong) rc;\
|
||||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
dtptrigger(dtpsysreturn[y], &info);\
|
||||||
return rc;\
|
return rc;\
|
||||||
}
|
}
|
||||||
#define WRAP4(x,y,z,type0,type1,type2,type3)\
|
#define WRAP4(x,y,z,type0,type1,type2,type3)\
|
||||||
|
@ -78,10 +78,10 @@ extern Syscall *systab[];
|
||||||
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
||||||
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
||||||
info.arg[3] = (uvlong) va_arg(vb, type3);\
|
info.arg[3] = (uvlong) va_arg(vb, type3);\
|
||||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
dtptrigger(dtpsysentry[y], &info);\
|
||||||
rc = z(va);\
|
rc = z(va);\
|
||||||
info.arg[9] = (uvlong) rc;\
|
info.arg[9] = (uvlong) rc;\
|
||||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
dtptrigger(dtpsysreturn[y], &info);\
|
||||||
return rc;\
|
return rc;\
|
||||||
}
|
}
|
||||||
/*TODO*/
|
/*TODO*/
|
||||||
|
@ -96,10 +96,10 @@ extern Syscall *systab[];
|
||||||
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
||||||
info.arg[3] = (uvlong) va_arg(vb, type3);\
|
info.arg[3] = (uvlong) va_arg(vb, type3);\
|
||||||
info.arg[4] = (uvlong) va_arg(vb, type4);\
|
info.arg[4] = (uvlong) va_arg(vb, type4);\
|
||||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
dtptrigger(dtpsysentry[y], &info);\
|
||||||
rc = z(va);\
|
rc = z(va);\
|
||||||
info.arg[9] = (uvlong) rc;\
|
info.arg[9] = (uvlong) rc;\
|
||||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
dtptrigger(dtpsysreturn[y], &info);\
|
||||||
return rc;\
|
return rc;\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ dtracytimer(void *)
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
for(;;){
|
for(;;){
|
||||||
tsleep(&up->sleep, return0, nil, 1000);
|
tsleep(&up->sleep, return0, nil, 1000);
|
||||||
dtptrigger(timerprobe, m->machno, &info);
|
dtptrigger(timerprobe, &info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ devpipe.$O: ../port/netif.h
|
||||||
netif.$O: ../port/netif.h
|
netif.$O: ../port/netif.h
|
||||||
devuart.$O: ../port/netif.h
|
devuart.$O: ../port/netif.h
|
||||||
devbridge.$O: ../port/netif.h ../ip/ip.h ../ip/ipv6.h
|
devbridge.$O: ../port/netif.h ../ip/ip.h ../ip/ipv6.h
|
||||||
|
devdtracy.$O dtracysys.$O dtracytimer.$O: /sys/include/dtracy.h
|
||||||
devdraw.$O: screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/memlayer.h /sys/include/cursor.h
|
devdraw.$O: screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/memlayer.h /sys/include/cursor.h
|
||||||
devmouse.$O: screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/cursor.h
|
devmouse.$O: screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/cursor.h
|
||||||
swcursor.$O: screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/cursor.h
|
swcursor.$O: screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/cursor.h
|
||||||
|
|
|
@ -336,13 +336,12 @@ dtgexec(DTActGr *g, DTTrigInfo *info)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dtptrigger(DTProbe *p, int machno, DTTrigInfo *info)
|
dtptrigger(DTProbe *p, DTTrigInfo *info)
|
||||||
{
|
{
|
||||||
DTEnab *e;
|
DTEnab *e;
|
||||||
|
|
||||||
info->ts = dttime();
|
info->ts = dttime();
|
||||||
dtmachlock(machno);
|
info->machno = dtmachlock(-1);
|
||||||
info->machno = machno;
|
|
||||||
for(e = p->enablist.probnext; e != &p->enablist; e = e->probnext)
|
for(e = p->enablist.probnext; e != &p->enablist; e = e->probnext)
|
||||||
if(e->gr->chan->state == DTCGO){
|
if(e->gr->chan->state == DTCGO){
|
||||||
info->ch = e->gr->chan;
|
info->ch = e->gr->chan;
|
||||||
|
@ -350,5 +349,5 @@ dtptrigger(DTProbe *p, int machno, DTTrigInfo *info)
|
||||||
if(dtgexec(e->gr, info) < 0)
|
if(dtgexec(e->gr, info) < 0)
|
||||||
e->gr->chan->state = DTCFAULT;
|
e->gr->chan->state = DTCFAULT;
|
||||||
}
|
}
|
||||||
dtmachunlock(machno);
|
dtmachunlock(info->machno);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue