From 75768576cca9653b0748032d47eb6a106eb04cd8 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 13 Mar 2003 18:31:15 +0000 Subject: [PATCH] Add a new userland-visible ktrace flag KTR_DROP and an internal ktrace flag KTRFAC_DROP to track instances when ktrace events are dropped due to the request pool being exhausted. When a thread tries to post a ktrace event and is unable to due to no available ktrace request objects, it sets KTRFAC_DROP in its process' p_traceflag field. The next trace event to successfully post from that process will set the KTR_DROP flag in the header of the request going out and clear KTRFAC_DROP. The KTR_DROP flag is the high bit in the type field of the ktr_header structure. Older kdump binaries will simply complain about an unknown type when seeing an entry with KTR_DROP set. Note that KTR_DROP being set on a record in a ktrace file does not tell you anything except that at least one event from this process was dropped prior to this event. The user has no way of knowing what types of events were dropped nor how many were dropped. Requested by: phk --- sys/kern/kern_ktrace.c | 7 ++++++- sys/sys/ktrace.h | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 8685eb1576ae..a8aa2b9cf089 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -226,6 +226,10 @@ ktr_getrequest(int type) if (req != NULL) { STAILQ_REMOVE_HEAD(&ktr_free, ktr_list); req->ktr_header.ktr_type = type; + if (p->p_traceflag & KTRFAC_DROP) { + req->ktr_header.ktr_type |= KTR_DROP; + p->p_traceflag &= ~KTRFAC_DROP; + } KASSERT(p->p_tracevp != NULL, ("ktrace: no trace vnode")); KASSERT(p->p_tracecred != NULL, ("ktrace: no trace cred")); req->ktr_vp = p->p_tracevp; @@ -238,6 +242,7 @@ ktr_getrequest(int type) req->ktr_header.ktr_buffer = NULL; req->ktr_header.ktr_len = 0; } else { + p->p_traceflag |= KTRFAC_DROP; pm = print_message; print_message = 0; mtx_unlock(&ktrace_mtx); @@ -762,7 +767,7 @@ ktr_writerequest(struct ktr_request *req) if (vp == NULL) return; kth = &req->ktr_header; - datalen = data_lengths[kth->ktr_type]; + datalen = data_lengths[(ushort)kth->ktr_type & ~KTR_DROP]; buflen = kth->ktr_len; cred = req->ktr_cred; td = curthread; diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h index 2970ce0fe69a..8fffcaf6925d 100644 --- a/sys/sys/ktrace.h +++ b/sys/sys/ktrace.h @@ -144,6 +144,12 @@ struct ktr_csw { #define KTR_USER_MAXLEN 2048 /* maximum length of passed data */ #define KTR_USER 7 +/* + * KTR_DROP - If this bit is set in ktr_type, then at least one event + * between the previous record and this record was dropped. + */ +#define KTR_DROP 0x8000 + /* * kernel trace points (in p_traceflag) */ @@ -160,6 +166,7 @@ struct ktr_csw { */ #define KTRFAC_ROOT 0x80000000 /* root set this trace */ #define KTRFAC_INHERIT 0x40000000 /* pass trace flags to children */ +#define KTRFAC_DROP 0x20000000 /* last event was dropped */ #ifdef _KERNEL extern struct mtx ktrace_mtx;