Module Name:    src
Committed By:   thorpej
Date:           Sun Mar 16 22:34:36 UTC 2025

Modified Files:
        src/sys/arch/alpha/alpha: fp_complete.c

Log Message:
Convert the 24 year-old "temporary trap shadow instrumentation" to use
event counters (so they're generally visible) and atomics to adjust them
(so they're not total jibberish on MP systems).


To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/alpha/alpha/fp_complete.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/alpha/alpha/fp_complete.c
diff -u src/sys/arch/alpha/alpha/fp_complete.c:1.32 src/sys/arch/alpha/alpha/fp_complete.c:1.33
--- src/sys/arch/alpha/alpha/fp_complete.c:1.32	Sun Mar 16 19:27:30 2025
+++ src/sys/arch/alpha/alpha/fp_complete.c	Sun Mar 16 22:34:36 2025
@@ -1,4 +1,4 @@
-/* $NetBSD: fp_complete.c,v 1.32 2025/03/16 19:27:30 thorpej Exp $ */
+/* $NetBSD: fp_complete.c,v 1.33 2025/03/16 22:34:36 thorpej Exp $ */
 
 /*-
  * Copyright (c) 2001 Ross Harvey
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: fp_complete.c,v 1.32 2025/03/16 19:27:30 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fp_complete.c,v 1.33 2025/03/16 22:34:36 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -130,21 +130,22 @@ static struct evcnt fpevent_reuse;
  * user code has met AARM trap shadow generation requirements.
  */
 
+static struct evcnt ts_scans;      /* trap shadow scans */
+static struct evcnt ts_insns;      /* total scanned insns */
+static struct evcnt ts_insns_max;  /* per-scan high water mark */
+static struct evcnt ts_resolved;   /* cases trigger pc found */
+static struct evcnt ts_unresolved; /* cases it wasn't, code problems? */
+
+static struct evcnt fp_ill_opc;    /* unexpected op codes */
+static struct evcnt fp_ill_func;   /* unexpected function codes */
+static struct evcnt fp_ill_anyop;  /* this "cannot happen" */
+
+static struct evcnt fp_vax;        /* traps from VAX FP insns */
+
 struct alpha_shadow {
-	uint64_t resolved;	/* cases trigger pc found */
-	uint64_t unresolved;	/* cases it wasn't, code problems? */
-	uint64_t scans;		/* trap shadow scans */
-	uint64_t len;		/* number of instructions examined */
 	uint64_t uop;		/* bit mask of unexpected opcodes */
-	uint64_t sqrts;	/* ev6+ square root single count */
-	uint64_t sqrtt;	/* ev6+ square root double count */
-	uint32_t ufunc;	/* bit mask of unexpected functions */
-	uint32_t max;		/* max trap shadow scan */
-	uint32_t nilswop;	/* unexpected op codes */
-	uint32_t nilswfunc;	/* unexpected function codes */
-	uint32_t nilanyop;	/* this "cannot happen" */
-	uint32_t vax;		/* sigs from vax fp opcodes */
-} alpha_shadow, alpha_shadow_zero;
+	uint32_t ufunc;		/* bit mask of unexpected functions */
+} alpha_shadow;
 
 static float64 float64_unk(float64, float64);
 static float64 compare_un(float64, float64);
@@ -178,7 +179,7 @@ this_cannot_happen(int what_cannot_happe
 	static uint64_t reported;
 
 	inst.bits = bits;
-	++alpha_shadow.nilswfunc;
+	atomic_inc_ulong(&fp_ill_func.ev_count);
 	if (bits != -1)
 		alpha_shadow.uop |= 1UL << inst.generic_format.opcode;
 	if (1UL << what_cannot_happen & reported)
@@ -567,6 +568,7 @@ alpha_fp_interpret(unsigned long pc, str
 	switch(inst.generic_format.opcode) {
 	default:
 		/* this "cannot happen" */
+		atomic_inc_ulong(&fp_ill_opc.ev_count);
 		this_cannot_happen(2, inst.bits);
 		return;
 	case op_any_float:
@@ -577,12 +579,13 @@ alpha_fp_interpret(unsigned long pc, str
 			alpha_lds(inst.float_detail.fc, &sfc);
 			float_raise(FP_X_INV);
 		} else {
-			++alpha_shadow.nilanyop;
+			atomic_inc_ulong(&fp_ill_anyop.ev_count);
 			this_cannot_happen(3, inst.bits);
 		}
 		break;
 	case op_vax_float:
-		++alpha_shadow.vax;	/* fall thru */
+		atomic_inc_ulong(&fp_vax.ev_count);
+		/* FALLTHROUGH */		/* XXX */
 	case op_ieee_float:
 	case op_fix_float:
 		switch(inst.float_detail.src) {
@@ -682,13 +685,13 @@ alpha_fp_complete_at(unsigned long trigg
 int
 alpha_fp_complete(u_long a0, u_long a1, struct lwp *l, uint64_t *ucode)
 {
-	int t;
-	int sig;
 	uint64_t op_class;
 	alpha_instruction inst;
 	/* "trigger_pc" is Compaq's term for the earliest faulting op */
 	alpha_instruction *trigger_pc, *usertrap_pc;
 	alpha_instruction *pc, *win_begin, tsw[TSWINSIZE];
+	long insn_count = 0;
+	int sig;
 
 	if (alpha_fp_complete_debug) {
 		printf("%s: [%s:%d] a0[AESR]=0x%lx a1[regmask]=0x%lx "
@@ -731,10 +734,9 @@ alpha_fp_complete(u_long a0, u_long a1, 
  */
 	trigger_pc = 0;
 	win_begin = pc;
-	++alpha_shadow.scans;
-	t = alpha_shadow.len;
+	atomic_inc_ulong(&ts_scans.ev_count);
 	for (--pc; a1; --pc) {
-		++alpha_shadow.len;
+		insn_count++;
 		if (pc < win_begin) {
 			win_begin = pc - TSWINSIZE + 1;
 			if (copyin(win_begin, tsw, sizeof tsw)) {
@@ -768,15 +770,16 @@ alpha_fp_complete(u_long a0, u_long a1, 
 		}
 		/* Some shadow-safe op, probably load, store, or FPTI class */
 	}
-	t = alpha_shadow.len - t;
-	if (t > alpha_shadow.max)
-		alpha_shadow.max = t;
+	if (insn_count > atomic_load_relaxed(&ts_insns_max.ev_count)) {
+		atomic_store_relaxed(&ts_insns_max.ev_count, insn_count);
+	}
+	atomic_add_long(&ts_insns.ev_count, insn_count);
 	if (__predict_true(trigger_pc != 0 && a1 == 0)) {
-		++alpha_shadow.resolved;
+		atomic_inc_ulong(&ts_resolved.ev_count);
 		sig = alpha_fp_complete_at((u_long)trigger_pc, l, ucode);
 		goto resolved;
 	} else {
-		++alpha_shadow.unresolved;
+		atomic_inc_ulong(&ts_unresolved.ev_count);
 	}
 
  unresolved: /* obligatory statement */;
@@ -828,6 +831,24 @@ alpha_fp_init(void)
 	    "FP", "proc use");
 	evcnt_attach_dynamic_nozero(&fpevent_reuse, EVCNT_TYPE_MISC, NULL,
 	    "FP", "proc re-use");
+
+	evcnt_attach_dynamic_nozero(&ts_scans, EVCNT_TYPE_MISC, NULL,
+	    "FP", "TS scans");
+	evcnt_attach_dynamic_nozero(&ts_insns, EVCNT_TYPE_MISC, NULL,
+	    "FP", "TS total insns");
+	evcnt_attach_dynamic_nozero(&ts_insns_max, EVCNT_TYPE_MISC, NULL,
+	    "FP", "TS max single-scan insns");
+	evcnt_attach_dynamic_nozero(&ts_resolved, EVCNT_TYPE_MISC, NULL,
+	    "FP", "TS resolved");
+	evcnt_attach_dynamic_nozero(&ts_unresolved, EVCNT_TYPE_MISC, NULL,
+	    "FP", "TS unresolved");
+
+	evcnt_attach_dynamic_nozero(&fp_ill_opc, EVCNT_TYPE_MISC, NULL,
+	    "FP", "illegal op code");
+	evcnt_attach_dynamic_nozero(&fp_ill_func, EVCNT_TYPE_MISC, NULL,
+	    "FP", "illegal function code");
+	evcnt_attach_dynamic_nozero(&fp_ill_anyop, EVCNT_TYPE_MISC, NULL,
+	    "FP", "illegal any_float function code");
 }
 
 /*

Reply via email to