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:
cinap_lenrek 2019-03-30 09:17:46 +01:00
parent ac3147a9c5
commit 4f0bfe0fb8
6 changed files with 28 additions and 20 deletions

View file

@ -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 */

View file

@ -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

View file

@ -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;\
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);
}