Module Name:    src
Committed By:   rin
Date:           Sun May 31 08:33:48 UTC 2020

Modified Files:
        src/sys/kern: kern_timeout.c

Log Message:
db_show_callout(): struct callout_cpu and cpu_info are too much for stack.

XXX
DDB can be running in the interrupt context, e.g., when activated from
console. Therefore, use kmem_intr_alloc(9) instead of kmem_alloc(9).

Frame size, e.g. for m68k, becomes:
    9212 (oops!) --> 0


To generate a diff of this commit:
cvs rdiff -u -r1.61 -r1.62 src/sys/kern/kern_timeout.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/kern/kern_timeout.c
diff -u src/sys/kern/kern_timeout.c:1.61 src/sys/kern/kern_timeout.c:1.62
--- src/sys/kern/kern_timeout.c:1.61	Sun Apr 19 20:35:29 2020
+++ src/sys/kern/kern_timeout.c	Sun May 31 08:33:47 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_timeout.c,v 1.61 2020/04/19 20:35:29 ad Exp $	*/
+/*	$NetBSD: kern_timeout.c,v 1.62 2020/05/31 08:33:47 rin Exp $	*/
 
 /*-
  * Copyright (c) 2003, 2006, 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_timeout.c,v 1.61 2020/04/19 20:35:29 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_timeout.c,v 1.62 2020/05/31 08:33:47 rin Exp $");
 
 /*
  * Timeouts are kept in a hierarchical timing wheel.  The c_time is the
@@ -834,8 +834,9 @@ db_show_callout_bucket(struct callout_cp
 void
 db_show_callout(db_expr_t addr, bool haddr, db_expr_t count, const char *modif)
 {
-	struct callout_cpu *cc, ccb;
-	struct cpu_info *ci, cib;
+	struct callout_cpu *cc, *ccp;
+	struct cpu_info *ci, *cip;
+	const size_t ccs = sizeof(*cc), cis = sizeof(*ci);
 	int b;
 
 #ifndef CRASH
@@ -843,25 +844,40 @@ db_show_callout(db_expr_t addr, bool had
 #endif
 	db_printf("    ticks  wheel               arg  func\n");
 
+	ccp = kmem_intr_alloc(ccs, KM_NOSLEEP); /* XXX ddb */
+	if (ccp == NULL) {
+		db_printf("%s: cannot allocate callout_cpu\n", __func__);
+		return;
+	}
+	cip = kmem_intr_alloc(cis, KM_NOSLEEP); /* XXX ddb */
+	if (cip == NULL) {
+		kmem_intr_free(ccp, ccs);
+		db_printf("%s: cannot allocate cpu_info\n", __func__);
+		return;
+	}
+
 	/*
 	 * Don't lock the callwheel; all the other CPUs are paused
 	 * anyhow, and we might be called in a circumstance where
 	 * some other CPU was paused while holding the lock.
 	 */
 	for (ci = db_cpu_first(); ci != NULL; ci = db_cpu_next(ci)) {
-		db_read_bytes((db_addr_t)ci, sizeof(cib), (char *)&cib);
-		cc = cib.ci_data.cpu_callout;
-		db_read_bytes((db_addr_t)cc, sizeof(ccb), (char *)&ccb);
-		db_show_callout_bucket(&ccb, &cc->cc_todo, &ccb.cc_todo);
+		db_read_bytes((db_addr_t)ci, cis, (char *)cip);
+		cc = cip->ci_data.cpu_callout;
+		db_read_bytes((db_addr_t)cc, ccs, (char *)ccp);
+		db_show_callout_bucket(ccp, &cc->cc_todo, &ccp->cc_todo);
 	}
 	for (b = 0; b < BUCKETS; b++) {
 		for (ci = db_cpu_first(); ci != NULL; ci = db_cpu_next(ci)) {
-			db_read_bytes((db_addr_t)ci, sizeof(cib), (char *)&cib);
-			cc = cib.ci_data.cpu_callout;
-			db_read_bytes((db_addr_t)cc, sizeof(ccb), (char *)&ccb);
-			db_show_callout_bucket(&ccb, &cc->cc_wheel[b],
-			    &ccb.cc_wheel[b]);
+			db_read_bytes((db_addr_t)ci, cis, (char *)cip);
+			cc = cip->ci_data.cpu_callout;
+			db_read_bytes((db_addr_t)cc, ccs, (char *)ccp);
+			db_show_callout_bucket(ccp, &cc->cc_wheel[b],
+			    &ccp->cc_wheel[b]);
 		}
 	}
+
+	kmem_intr_free(ccp, ccs);
+	kmem_intr_free(cip, cis);
 }
 #endif /* DDB */

Reply via email to