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: