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);
|
||||
int dtpmatch(char *, DTProbe ***);
|
||||
int dtplist(DTProbe ***);
|
||||
void dtptrigger(DTProbe *, int, DTTrigInfo *);
|
||||
void dtptrigger(DTProbe *, DTTrigInfo *);
|
||||
|
||||
/* expression functions */
|
||||
int dteverify(DTExpr *);
|
||||
|
@ -285,7 +285,7 @@ uvlong dttime(void); /* return current timestamp */
|
|||
void *dtrealloc(void *, ulong);
|
||||
void dtfree(void *);
|
||||
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 dtcoherence(void); /* memory barrier */
|
||||
uvlong dtgetvar(int); /* return the value of a variable */
|
||||
|
|
|
@ -512,10 +512,18 @@ dtrealloc(void *v, ulong n)
|
|||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
dtmachlock(int i)
|
||||
{
|
||||
while(i < 0) {
|
||||
i = dtmachlock(m->machno);
|
||||
if(i == m->machno)
|
||||
return i;
|
||||
dtmachunlock(i);
|
||||
i = -1;
|
||||
}
|
||||
ilock(&machlocks[i]);
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -20,10 +20,10 @@ extern Syscall *systab[];
|
|||
uintptr rc;\
|
||||
DTTrigInfo info;\
|
||||
memset(&info, 0, sizeof(info));\
|
||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysentry[y], &info);\
|
||||
rc = z(va);\
|
||||
info.arg[9] = (uvlong) rc;\
|
||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysreturn[y], &info);\
|
||||
return rc;\
|
||||
}
|
||||
#define WRAP1(x,y,z,type0)\
|
||||
|
@ -33,10 +33,10 @@ extern Syscall *systab[];
|
|||
DTTrigInfo info;\
|
||||
memset(&info, 0, sizeof(info));\
|
||||
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysentry[y], &info);\
|
||||
rc = z(va);\
|
||||
info.arg[9] = (uvlong) rc;\
|
||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysreturn[y], &info);\
|
||||
return rc;\
|
||||
}
|
||||
#define WRAP2(x,y,z,type0,type1)\
|
||||
|
@ -47,10 +47,10 @@ extern Syscall *systab[];
|
|||
memset(&info, 0, sizeof(info));\
|
||||
info.arg[0] = (uvlong) va_arg(vb, type0);\
|
||||
info.arg[1] = (uvlong) va_arg(vb, type1);\
|
||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysentry[y], &info);\
|
||||
rc = z(va);\
|
||||
info.arg[9] = (uvlong) rc;\
|
||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysreturn[y], &info);\
|
||||
return rc;\
|
||||
}
|
||||
#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[1] = (uvlong) va_arg(vb, type1);\
|
||||
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysentry[y], &info);\
|
||||
rc = z(va);\
|
||||
info.arg[9] = (uvlong) rc;\
|
||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysreturn[y], &info);\
|
||||
return rc;\
|
||||
}
|
||||
#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[2] = (uvlong) va_arg(vb, type2);\
|
||||
info.arg[3] = (uvlong) va_arg(vb, type3);\
|
||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysentry[y], &info);\
|
||||
rc = z(va);\
|
||||
info.arg[9] = (uvlong) rc;\
|
||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysreturn[y], &info);\
|
||||
return rc;\
|
||||
}
|
||||
/*TODO*/
|
||||
|
@ -96,10 +96,10 @@ extern Syscall *systab[];
|
|||
info.arg[2] = (uvlong) va_arg(vb, type2);\
|
||||
info.arg[3] = (uvlong) va_arg(vb, type3);\
|
||||
info.arg[4] = (uvlong) va_arg(vb, type4);\
|
||||
dtptrigger(dtpsysentry[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysentry[y], &info);\
|
||||
rc = z(va);\
|
||||
info.arg[9] = (uvlong) rc;\
|
||||
dtptrigger(dtpsysreturn[y], m->machno, &info);\
|
||||
dtptrigger(dtpsysreturn[y], &info);\
|
||||
return rc;\
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ dtracytimer(void *)
|
|||
memset(&info, 0, sizeof(info));
|
||||
for(;;){
|
||||
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
|
||||
devuart.$O: ../port/netif.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
|
||||
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
|
||||
|
|
|
@ -336,13 +336,12 @@ dtgexec(DTActGr *g, DTTrigInfo *info)
|
|||
}
|
||||
|
||||
void
|
||||
dtptrigger(DTProbe *p, int machno, DTTrigInfo *info)
|
||||
dtptrigger(DTProbe *p, DTTrigInfo *info)
|
||||
{
|
||||
DTEnab *e;
|
||||
|
||||
info->ts = dttime();
|
||||
dtmachlock(machno);
|
||||
info->machno = machno;
|
||||
info->machno = dtmachlock(-1);
|
||||
for(e = p->enablist.probnext; e != &p->enablist; e = e->probnext)
|
||||
if(e->gr->chan->state == DTCGO){
|
||||
info->ch = e->gr->chan;
|
||||
|
@ -350,5 +349,5 @@ dtptrigger(DTProbe *p, int machno, DTTrigInfo *info)
|
|||
if(dtgexec(e->gr, info) < 0)
|
||||
e->gr->chan->state = DTCFAULT;
|
||||
}
|
||||
dtmachunlock(machno);
|
||||
dtmachunlock(info->machno);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue