ref: 4f0bfe0fb8dc608a94fe429c5ddb12e58997e1ce
parent: ac3147a9c58f339f9b978ab087464912c16bc8f8
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Mar 30 05:17:46 EDT 2019
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.
--- a/sys/include/dtracy.h
+++ b/sys/include/dtracy.h
@@ -241,7 +241,7 @@
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 @@
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 */
--- a/sys/src/9/port/devdtracy.c
+++ b/sys/src/9/port/devdtracy.c
@@ -512,10 +512,18 @@
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
--- a/sys/src/9/port/dtracysys.c
+++ b/sys/src/9/port/dtracysys.c
@@ -20,10 +20,10 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;\
}
--- a/sys/src/9/port/dtracytimer.c
+++ b/sys/src/9/port/dtracytimer.c
@@ -17,7 +17,7 @@
memset(&info, 0, sizeof(info));
for(;;){
tsleep(&up->sleep, return0, nil, 1000);
- dtptrigger(timerprobe, m->machno, &info);
+ dtptrigger(timerprobe, &info);
}
}
--- a/sys/src/9/port/portmkfile
+++ b/sys/src/9/port/portmkfile
@@ -80,6 +80,7 @@
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
--- a/sys/src/libdtracy/prog.c
+++ b/sys/src/libdtracy/prog.c
@@ -336,13 +336,12 @@
}
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 @@
if(dtgexec(e->gr, info) < 0)
e->gr->chan->state = DTCFAULT;
}
- dtmachunlock(machno);
+ dtmachunlock(info->machno);
}