summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/trap.c14
-rw-r--r--sys/amd64/amd64/trap.c10
-rw-r--r--sys/conf/files1
-rw-r--r--sys/i386/i386/trap.c10
-rw-r--r--sys/ia64/ia64/trap.c14
-rw-r--r--sys/kern/kern_mutex.c7
-rw-r--r--sys/kern/subr_trap.c10
-rw-r--r--sys/kern/subr_turnstile.c7
-rw-r--r--sys/kern/subr_witness.c7
-rw-r--r--sys/sys/mutex.h2
10 files changed, 78 insertions, 4 deletions
diff --git a/sys/alpha/alpha/trap.c b/sys/alpha/alpha/trap.c
index 50a386d..698c09b 100644
--- a/sys/alpha/alpha/trap.c
+++ b/sys/alpha/alpha/trap.c
@@ -88,6 +88,11 @@ int unaligned_fixup __P((unsigned long, unsigned long,
static void printtrap __P((const unsigned long, const unsigned long,
const unsigned long, const unsigned long, struct trapframe *, int, int));
+
+#ifdef WITNESS
+extern char *syscallnames[];
+#endif
+
/*
* Define the code needed before returning to user mode, for
* trap and syscall.
@@ -737,6 +742,15 @@ syscall(code, framep)
*/
STOPEVENT(p, S_SCX, code);
mtx_exit(&Giant, MTX_DEF);
+
+ mtx_assert(&sched_lock, MA_NOTOWNED);
+ mtx_assert(&Giant, MA_NOTOWNED);
+#ifdef WITNESS
+ if (witness_list(p)) {
+ panic("system call %s returning with mutex(s) held\n",
+ syscallnames[code]);
+ }
+#endif
}
/*
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index fa768ec..5974535 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -164,6 +164,10 @@ static int panic_on_nmi = 1;
SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW,
&panic_on_nmi, 0, "Panic on NMI");
+#ifdef WITNESS
+extern char *syscallnames[];
+#endif
+
static __inline int
userret(p, frame, oticks, have_giant)
struct proc *p;
@@ -1221,6 +1225,12 @@ bad:
mtx_assert(&sched_lock, MA_NOTOWNED);
mtx_assert(&Giant, MA_NOTOWNED);
+#ifdef WITNESS
+ if (witness_list(p)) {
+ panic("system call %s returning with mutex(s) held\n",
+ syscallnames[code]);
+ }
+#endif
}
void
diff --git a/sys/conf/files b/sys/conf/files
index ea0602b..9aba2cc 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -664,6 +664,7 @@ kern/sys_generic.c standard
kern/sys_pipe.c standard
kern/sys_process.c standard
kern/sys_socket.c standard
+kern/syscalls.c optional witness
kern/sysv_ipc.c standard
kern/sysv_msg.c optional sysvmsg
kern/sysv_sem.c optional sysvsem
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index fa768ec..5974535 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -164,6 +164,10 @@ static int panic_on_nmi = 1;
SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW,
&panic_on_nmi, 0, "Panic on NMI");
+#ifdef WITNESS
+extern char *syscallnames[];
+#endif
+
static __inline int
userret(p, frame, oticks, have_giant)
struct proc *p;
@@ -1221,6 +1225,12 @@ bad:
mtx_assert(&sched_lock, MA_NOTOWNED);
mtx_assert(&Giant, MA_NOTOWNED);
+#ifdef WITNESS
+ if (witness_list(p)) {
+ panic("system call %s returning with mutex(s) held\n",
+ syscallnames[code]);
+ }
+#endif
}
void
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
index 64f7752..3ef9440 100644
--- a/sys/ia64/ia64/trap.c
+++ b/sys/ia64/ia64/trap.c
@@ -74,6 +74,10 @@ u_int32_t want_resched;
static int unaligned_fixup(struct trapframe *framep, struct proc *p);
+#ifdef WITNESS
+extern char *syscallnames[];
+#endif
+
/*
* Define the code needed before returning to user mode, for
* trap and syscall.
@@ -614,6 +618,16 @@ syscall(int code, u_int64_t *args, struct trapframe *framep)
*/
STOPEVENT(p, S_SCX, code);
mtx_exit(&Giant, MTX_DEF);
+
+ mtx_assert(&sched_lock, MA_NOTOWNED);
+ mtx_assert(&Giant, MA_NOTOWNED);
+#ifdef WITNESS
+ if (witness_list(p)) {
+ panic("system call %s returning with mutex(s) held\n",
+ syscallnames[code]);
+ }
+#endif
+}
}
/*
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c
index ee931c0..85d5624 100644
--- a/sys/kern/kern_mutex.c
+++ b/sys/kern/kern_mutex.c
@@ -1353,17 +1353,22 @@ witness_free(struct witness *w)
w_free = w;
}
-void
+int
witness_list(struct proc *p)
{
struct mtx *m;
+ int nheld;
+ nheld = 0;
for ((m = LIST_FIRST(&p->p_heldmtx)); m != NULL;
m = LIST_NEXT(m, mtx_held)) {
printf("\t\"%s\" (%p) locked at %s:%d\n",
m->mtx_description, m,
m->mtx_witness->w_file, m->mtx_witness->w_line);
+ nheld++;
}
+
+ return (nheld);
}
void
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index fa768ec..5974535 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -164,6 +164,10 @@ static int panic_on_nmi = 1;
SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW,
&panic_on_nmi, 0, "Panic on NMI");
+#ifdef WITNESS
+extern char *syscallnames[];
+#endif
+
static __inline int
userret(p, frame, oticks, have_giant)
struct proc *p;
@@ -1221,6 +1225,12 @@ bad:
mtx_assert(&sched_lock, MA_NOTOWNED);
mtx_assert(&Giant, MA_NOTOWNED);
+#ifdef WITNESS
+ if (witness_list(p)) {
+ panic("system call %s returning with mutex(s) held\n",
+ syscallnames[code]);
+ }
+#endif
}
void
diff --git a/sys/kern/subr_turnstile.c b/sys/kern/subr_turnstile.c
index ee931c0..85d5624 100644
--- a/sys/kern/subr_turnstile.c
+++ b/sys/kern/subr_turnstile.c
@@ -1353,17 +1353,22 @@ witness_free(struct witness *w)
w_free = w;
}
-void
+int
witness_list(struct proc *p)
{
struct mtx *m;
+ int nheld;
+ nheld = 0;
for ((m = LIST_FIRST(&p->p_heldmtx)); m != NULL;
m = LIST_NEXT(m, mtx_held)) {
printf("\t\"%s\" (%p) locked at %s:%d\n",
m->mtx_description, m,
m->mtx_witness->w_file, m->mtx_witness->w_line);
+ nheld++;
}
+
+ return (nheld);
}
void
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index ee931c0..85d5624 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -1353,17 +1353,22 @@ witness_free(struct witness *w)
w_free = w;
}
-void
+int
witness_list(struct proc *p)
{
struct mtx *m;
+ int nheld;
+ nheld = 0;
for ((m = LIST_FIRST(&p->p_heldmtx)); m != NULL;
m = LIST_NEXT(m, mtx_held)) {
printf("\t\"%s\" (%p) locked at %s:%d\n",
m->mtx_description, m,
m->mtx_witness->w_file, m->mtx_witness->w_line);
+ nheld++;
}
+
+ return (nheld);
}
void
diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h
index 610ec1e..1c074b3 100644
--- a/sys/sys/mutex.h
+++ b/sys/sys/mutex.h
@@ -300,7 +300,7 @@ void witness_enter(struct mtx *, int, const char *, int);
void witness_try_enter(struct mtx *, int, const char *, int);
void witness_exit(struct mtx *, int, const char *, int);
void witness_display(void(*)(const char *fmt, ...));
-void witness_list(struct proc *);
+int witness_list(struct proc *);
int witness_sleep(int, struct mtx *, const char *, int);
void witness_save(struct mtx *, const char **, int *);
void witness_restore(struct mtx *, const char *, int);
OpenPOWER on IntegriCloud