Subject: kern/19929: ktrace support for SA upcalls.
To: None <gnats-bugs@gnats.netbsd.org>
From: Nick Hudson <skrll@netbsd.org>
List: netbsd-bugs
Date: 01/19/2003 14:06:23
>Number: 19929
>Category: kern
>Synopsis: ktrace support for SA upcalls.
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Jan 19 06:15:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator: Nick Hudson
>Release: NetBSD 1.6M
>Organization:
None
>Environment:
System: NetBSD btcl045611 1.6M NetBSD 1.6M (TECRA8100) #0: Sun Jan 19 09:36:02 UTC 2003 nick@btcl045611:/home/nick/work/netbsd/nathanw_sa/src/sys/arch/i386/compile/TECRA8100 i386
Architecture: i386
Machine: i386
>Description:
Attached is a diff for ktrace support for SA upcalls. Unfortunately it
has problems when ktrwrite blocks and causes another upcall, which
causes another call to ktrsaupcall. Someone who knows how to deal with
this can hopefully make use of the diff.
The choice of option letter in ktrace(1) was purely random.
>How-To-Repeat:
ktrace a threaded program.
>Fix:
Index: lib/libc/sys/ktrace.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/ktrace.2,v
retrieving revision 1.7.6.4
diff -c -r1.7.6.4 ktrace.2
*** lib/libc/sys/ktrace.2 2002/10/18 02:16:58 1.7.6.4
--- lib/libc/sys/ktrace.2 2003/01/19 10:33:54
***************
*** 99,104 ****
--- 99,105 ----
.It KTRFAC_PSIG Trace posted signals.
.It KTRFAC_CSW Trace context switch points.
.It KTRFAC_EMUL Trace emulation changes.
+ .It KTRFAC_SAUPCALL Trace emulation changes.
.It KTRFAC_INHERIT Inherit tracing to future children.
.El
.Pp
Index: sys/kern/kern_ktrace.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_ktrace.c,v
retrieving revision 1.67
diff -c -r1.67 kern_ktrace.c
*** sys/kern/kern_ktrace.c 2003/01/18 10:06:27 1.67
--- sys/kern/kern_ktrace.c 2003/01/19 10:33:54
***************
*** 364,369 ****
--- 364,410 ----
}
void
+ ktrsaupcall(struct proc *p, int type, int nevent, int nint, void *sas,
+ void *ap)
+ {
+ struct ktr_header kth;
+ struct ktr_saupcall *ktp;
+ size_t len;
+ struct sa_t **sapp;
+ int i;
+
+ p->p_traceflag |= KTRFAC_ACTIVE;
+ ktrinitheader(&kth, p, KTR_SAUPCALL);
+
+ len = sizeof(struct ktr_saupcall);
+ ktp = malloc(len + sizeof(struct sa_t) * (nevent + nint + 1), M_TEMP,
+ M_WAITOK);
+
+ ktp->type = type;
+ ktp->nevent = nevent;
+ ktp->nint = nint;
+ ktp->sas = sas;
+ ktp->ap = ap;
+ /*
+ * Copy the sa_t's
+ */
+ sapp = (struct sa_t **) sas;
+
+ for (i = nevent + nint; i >= 0; i--) {
+ if (copyin(*sapp, (char *)ktp + len, sizeof(struct sa_t)) == 0)
+ len += sizeof(struct sa_t);
+ sapp++;
+ }
+
+ kth.ktr_buf = (void *)ktp;
+ kth.ktr_len = len;
+ (void) ktrwrite(p, &kth);
+
+ free(ktp, M_TEMP);
+ p->p_traceflag &= ~KTRFAC_ACTIVE;
+ }
+
+ void
ktrmmsg(p, msgh, size)
struct proc *p;
const void *msgh;
Index: sys/kern/kern_sa.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sa.c,v
retrieving revision 1.2
diff -c -r1.2 kern_sa.c
*** sys/kern/kern_sa.c 2003/01/18 10:06:22 1.2
--- sys/kern/kern_sa.c 2003/01/19 10:33:55
***************
*** 39,44 ****
--- 39,46 ----
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.2 2003/01/18 10:06:22 thorpej Exp $");
+ #include "opt_ktrace.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/pool.h>
***************
*** 50,55 ****
--- 52,58 ----
#include <sys/sa.h>
#include <sys/savar.h>
#include <sys/syscallargs.h>
+ #include <sys/ktrace.h>
#include <uvm/uvm_extern.h>
***************
*** 334,341 ****
int
sys_sa_preempt(struct lwp *l, void *v, register_t *retval)
{
! /* XXX Implement me. */
return (ENOSYS);
}
--- 337,357 ----
int
sys_sa_preempt(struct lwp *l, void *v, register_t *retval)
{
+ struct sys_sa_preempt_args /* {
+ syscallarg(int) sa_id;
+ } */ *uap = v;
+ struct sadata *sa = l->l_proc->p_sa;
! DPRINTF(("sys_sa_preempt(%d.%d)\n", l->l_proc->p_pid,
! l->l_lid));
!
! /* We have to be using scheduler activations */
! if (sa == NULL)
! return (EINVAL);
!
! if (SCARG(uap, sa_id) < 1)
! return (EINVAL);
!
return (ENOSYS);
}
***************
*** 592,604 ****
mi_switch(l, l2);
DPRINTFN(4,("sa_switch(%d.%d flag %x) returned.\n", p->p_pid, l->l_lid, l->l_flag));
! KDASSERT(l->l_wchan == 0);
SCHED_ASSERT_UNLOCKED();
if (sa->sa_woken == l)
sa->sa_woken = NULL;
-
/*
* The process is trying to exit. In this case, the last thing
* we want to do is put something back on the cache list.
--- 608,622 ----
mi_switch(l, l2);
DPRINTFN(4,("sa_switch(%d.%d flag %x) returned.\n", p->p_pid, l->l_lid, l->l_flag));
! KDASSERT(l && l->l_wchan == 0);
SCHED_ASSERT_UNLOCKED();
+ KDASSERT(sa);
+ DPRINTFN(4,("sa_switch(%d.%d sa->sa_woken=%p, l=%p) checking woken.\n", p->p_pid, l->l_lid, sa->sa_woken, l));
if (sa->sa_woken == l)
sa->sa_woken = NULL;
+ DPRINTFN(4,("sa_switch(%d.%d p->p_flag=%x)\n", p->p_pid, l->l_lid, p->p_flag));
/*
* The process is trying to exit. In this case, the last thing
* we want to do is put something back on the cache list.
***************
*** 607,612 ****
--- 625,631 ----
if (p->p_flag & P_WEXIT)
return;
+ DPRINTFN(4,("sa_switch(%d.%d check that SA_BLOCKED happened\n", p->p_pid, l->l_lid));
/*
* Okay, now we've been woken up. This means that it's time
* for a SA_UNBLOCKED upcall when we get back to userlevel, provided
***************
*** 938,943 ****
--- 957,966 ----
DPRINTFN(7,("sa_upcall_userret(%d.%d): type %d\n",p->p_pid,
l->l_lid, type));
+ #ifdef KTRACE
+ if (KTRPOINT(p, KTR_SAUPCALL))
+ ktrsaupcall(p, type, nevents, nint, sapp, ap);
+ #endif
cpu_upcall(l, type, nevents, nint, sapp, ap, stack, sa->sa_upcall);
KERNEL_PROC_UNLOCK(l);
}
Index: sys/sys/ktrace.h
===================================================================
RCS file: /cvsroot/src/sys/sys/ktrace.h,v
retrieving revision 1.27
diff -c -r1.27 ktrace.h
*** sys/sys/ktrace.h 2002/12/21 16:23:56 1.27
--- sys/sys/ktrace.h 2003/01/19 10:33:56
***************
*** 173,178 ****
--- 173,193 ----
};
/*
+ * KTR_SAUPCALL - schedular activiated upcall.
+ */
+ #define KTR_SAUPCALL 10
+ struct ktr_saupcall {
+ int type;
+ int nevent;
+ int nint;
+ void *sas;
+ void *ap;
+ /*
+ * followed by nevent sa_t's from sas[]
+ */
+ };
+
+ /*
* kernel trace points (in p_traceflag)
*/
#define KTRFAC_MASK 0x00ffffff
***************
*** 185,190 ****
--- 200,206 ----
#define KTRFAC_EMUL (1<<KTR_EMUL)
#define KTRFAC_USER (1<<KTR_USER)
#define KTRFAC_MMSG (1<<KTR_MMSG)
+ #define KTRFAC_SAUPCALL (1<<KTR_SAUPCALL)
/*
* trace flags (also in p_traceflags)
*/
***************
*** 214,219 ****
--- 230,236 ----
void ktrsysret(struct proc *, register_t, int, register_t);
void ktruser(struct proc *, const char *, void *, size_t, int);
void ktrmmsg(struct proc *, const void *, size_t);
+ void ktrsaupcall(struct proc *, int, int, int, void *, void *);
void ktrderef(struct proc *);
void ktradref(struct proc *);
Index: usr.bin/kdump/kdump.c
===================================================================
RCS file: /cvsroot/src/usr.bin/kdump/kdump.c,v
retrieving revision 1.46
diff -c -r1.46 kdump.c
*** usr.bin/kdump/kdump.c 2002/12/09 21:29:28 1.46
--- usr.bin/kdump/kdump.c 2003/01/19 10:33:56
***************
*** 70,75 ****
--- 70,76 ----
#include "setemul.h"
#include <sys/syscall.h>
+ #include <sys/sa.h>
int timestamp, decimal, plain, tail, maxdata, numeric;
pid_t do_pid = -1;
***************
*** 109,114 ****
--- 110,116 ----
void ktrcsw __P((struct ktr_csw *));
void ktruser __P((struct ktr_user *, int));
void ktrmmsg __P((struct ktr_mmsg *, int));
+ void ktrsaupcall __P((struct ktr_saupcall *));
void usage __P((void));
void eprint __P((int));
char *ioctlname __P((long));
***************
*** 238,243 ****
--- 240,248 ----
case KTR_MMSG:
ktrmmsg((struct ktr_mmsg *)m, ktrlen);
break;
+ case KTR_SAUPCALL:
+ ktrsaupcall((struct ktr_saupcall *)m);
+ break;
}
if (tail)
(void)fflush(stdout);
***************
*** 284,290 ****
type = "PSIG";
break;
case KTR_CSW:
! type = "CSW";
break;
case KTR_EMUL:
type = "EMUL";
--- 289,295 ----
type = "PSIG";
break;
case KTR_CSW:
! type = "CSW ";
break;
case KTR_EMUL:
type = "EMUL";
***************
*** 295,300 ****
--- 300,308 ----
case KTR_MMSG:
type = "MMSG";
break;
+ case KTR_SAUPCALL:
+ type = "UPCL";
+ break;
default:
(void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
type = unknown;
***************
*** 686,691 ****
--- 694,744 ----
if (aligned_len != sizeof(struct ktr_mmsg))
printf("\n");
+ }
+
+ void
+ ktrsaupcall(upcl)
+ struct ktr_saupcall *upcl;
+ {
+ char *dp = (char *)upcl + sizeof (struct ktr_saupcall);
+ struct sa_t *sap;
+ int i;
+
+ printf("sa_handler(");
+ switch (upcl->type) {
+ case SA_UPCALL_NEWPROC:
+ printf("NEWPROC");
+ break;
+ case SA_UPCALL_PREEMPTED:
+ printf("PREEMPTED");
+ break;
+ case SA_UPCALL_BLOCKED:
+ printf("BLOCKED");
+ break;
+ case SA_UPCALL_UNBLOCKED:
+ printf("UNBLOCKED");
+ break;
+ case SA_UPCALL_SIGNAL:
+ printf("SIGNAL");
+ break;
+ case SA_UPCALL_SIGEV:
+ printf("SIGEV");
+ break;
+ case SA_UPCALL_USER:
+ printf("USER");
+ break;
+ default:
+ printf("unknown");
+ }
+
+ (void)printf(", %d, %d, %p, %p)\n", upcl->nevent, upcl->nint,
+ upcl->sas, upcl->ap);
+ sap = (struct sa_t *)dp;
+ for (i = 0; i <= upcl->nevent + upcl->nint; i++, sap++) {
+ (void)printf(" ");
+ (void)printf("{ ucontext_t=%p, sa_id=%d, sa_cpu=%d }\n",
+ sap->sa_context, sap->sa_id, sap->sa_cpu);
+ }
}
static const char *
Index: usr.bin/ktrace/ktrace.1
===================================================================
RCS file: /cvsroot/src/usr.bin/ktrace/ktrace.1,v
retrieving revision 1.17
diff -c -r1.17 ktrace.1
*** usr.bin/ktrace/ktrace.1 2002/12/18 20:10:37 1.17
--- usr.bin/ktrace/ktrace.1 2003/01/19 10:33:56
***************
*** 73,79 ****
Kernel trace data is logged to the file
.Pa ktrace.out .
The kernel operations that are traced include system calls, namei
! translations, signal processing, and
.Tn I/O .
.Pp
Once tracing is enabled on a process, trace data will be logged until
--- 73,79 ----
Kernel trace data is logged to the file
.Pa ktrace.out .
The kernel operations that are traced include system calls, namei
! translations, signal processing, schedular activiations upcalls and
.Tn I/O .
.Pp
Once tracing is enabled on a process, trace data will be logged until
***************
*** 134,139 ****
--- 134,141 ----
.It Cm i
trace
.Tn I/O
+ .It Cm p
+ schedular activiation upcalls
.It Cm s
trace signal processing
.It Cm u
***************
*** 144,150 ****
.It Cm w
trace context switches
.It Cm +
! trace the default set of trace points (c, e, i, m, n, s, u)
.El
.It Fl e Ar emulation
If an emulation of a process is unknown,
--- 146,152 ----
.It Cm w
trace context switches
.It Cm +
! trace the default set of trace points (c, e, n, i, p, s, u, m)
.El
.It Fl e Ar emulation
If an emulation of a process is unknown,
Index: usr.bin/ktrace/ktrace.h
===================================================================
RCS file: /cvsroot/src/usr.bin/ktrace/ktrace.h,v
retrieving revision 1.11
diff -c -r1.11 ktrace.h
*** usr.bin/ktrace/ktrace.h 2002/12/09 21:29:27 1.11
--- usr.bin/ktrace/ktrace.h 2003/01/19 10:33:56
***************
*** 37,43 ****
#define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \
KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_EMUL | KTRFAC_USER | \
! KTRFAC_MMSG)
#define ALL_POINTS (DEF_POINTS | KTRFAC_CSW)
--- 37,43 ----
#define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \
KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_EMUL | KTRFAC_USER | \
! KTRFAC_MMSG | KTRFAC_SAUPCALL)
#define ALL_POINTS (DEF_POINTS | KTRFAC_CSW)
Index: usr.bin/ktrace/subr.c
===================================================================
RCS file: /cvsroot/src/usr.bin/ktrace/subr.c,v
retrieving revision 1.9
diff -c -r1.9 subr.c
*** usr.bin/ktrace/subr.c 2002/12/09 21:29:27 1.9
--- usr.bin/ktrace/subr.c 2003/01/19 10:33:56
***************
*** 73,78 ****
--- 73,81 ----
case 'i':
facs |= KTRFAC_GENIO;
break;
+ case 'p':
+ facs |= KTRFAC_SAUPCALL;
+ break;
case 's':
facs |= KTRFAC_PSIG;
break;
>Release-Note:
>Audit-Trail:
>Unformatted: