summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_event.c
diff options
context:
space:
mode:
authorjmg <jmg@FreeBSD.org>2006-09-24 02:23:29 +0000
committerjmg <jmg@FreeBSD.org>2006-09-24 02:23:29 +0000
commit689b605f8bab05430d9aaca0c589ffdbccc5a57f (patch)
tree5812e67459515483c31b411f2f28d2a644c3e14d /sys/kern/kern_event.c
parentbce860ebf1e3373ec472ac9230244e71561ab281 (diff)
downloadFreeBSD-src-689b605f8bab05430d9aaca0c589ffdbccc5a57f.zip
FreeBSD-src-689b605f8bab05430d9aaca0c589ffdbccc5a57f.tar.gz
add KTRACE hooks into kevent... This will help people debug their kqueue
programs to find out exactly which events were registered and which were returned... This should be lower in kern_kevent, but that would require special munging due to locks and the functions used to copyin/copyout kevents... If someone wants to teach ktrace how to output pretty kevents, I have a kevent prety printer that can be used...
Diffstat (limited to 'sys/kern/kern_event.c')
-rw-r--r--sys/kern/kern_event.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index c3b37f5..8692808 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -28,6 +28,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_ktrace.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -57,6 +59,9 @@ __FBSDID("$FreeBSD$");
#include <sys/syscallsubr.h>
#include <sys/taskqueue.h>
#include <sys/uio.h>
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
#include <vm/uma.h>
@@ -560,6 +565,12 @@ kevent(struct thread *td, struct kevent_args *uap)
kevent_copyout,
kevent_copyin};
int error;
+#ifdef KTRACE
+ struct uio ktruio;
+ struct iovec ktriov;
+ struct uio *ktruioin = NULL;
+ struct uio *ktruioout = NULL;
+#endif
if (uap->timeout != NULL) {
error = copyin(uap->timeout, &ts, sizeof(ts));
@@ -569,8 +580,33 @@ kevent(struct thread *td, struct kevent_args *uap)
} else
tsp = NULL;
- return (kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
- &k_ops, tsp));
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_GENIO)) {
+ ktriov.iov_base = uap->changelist;
+ ktriov.iov_len = uap->nchanges * sizeof(struct kevent);
+ ktruio = (struct uio){ .uio_iov = &ktriov, .uio_iovcnt = 1,
+ .uio_segflg = UIO_USERSPACE, .uio_rw = UIO_READ,
+ .uio_td = td };
+ ktruioin = cloneuio(&ktruio);
+ ktriov.iov_base = uap->eventlist;
+ ktriov.iov_len = uap->nevents * sizeof(struct kevent);
+ ktruioout = cloneuio(&ktruio);
+ }
+#endif
+
+ error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
+ &k_ops, tsp);
+
+#ifdef KTRACE
+ if (ktruioin != NULL) {
+ ktruioin->uio_resid = uap->nchanges * sizeof(struct kevent);
+ ktrgenio(uap->fd, UIO_WRITE, ktruioin, 0);
+ ktruioout->uio_resid = td->td_retval[0] * sizeof(struct kevent);
+ ktrgenio(uap->fd, UIO_READ, ktruioout, error);
+ }
+#endif
+
+ return (error);
}
/*
OpenPOWER on IntegriCloud