Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Feb 2010 08:50:06 +0000 (UTC)
From:      Marko Zec <zec@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r203748 - stable/8/sys/net
Message-ID:  <201002100850.o1A8o6tD038842@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: zec
Date: Wed Feb 10 08:50:06 2010
New Revision: 203748
URL: http://svn.freebsd.org/changeset/base/203748

Log:
  MFC r203483:
    Instead of spamming the console on each curvnet recursion event, print
    out each such call graph only once, along with a stack backtrace.  This
    should make kernels built with VNET_DEBUG reasonably usable again in
    busy / production environments.
  
    Introduce a new DDB command "show vnetrcrs" which dumps the whole log
    of distinctive curvnet recursion events.  This might be useful when
    recursion reports get burried / lost too deep in the message buffer.
    In the later case stack backtraces are not available.
  
    Reviewed by:  bz

Modified:
  stable/8/sys/net/vnet.c
  stable/8/sys/net/vnet.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/netinet/   (props changed)

Modified: stable/8/sys/net/vnet.c
==============================================================================
--- stable/8/sys/net/vnet.c	Wed Feb 10 07:15:21 2010	(r203747)
+++ stable/8/sys/net/vnet.c	Wed Feb 10 08:50:06 2010	(r203748)
@@ -37,8 +37,10 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_ddb.h"
+#include "opt_kdb.h"
 
 #include <sys/param.h>
+#include <sys/kdb.h>
 #include <sys/kernel.h>
 #include <sys/jail.h>
 #include <sys/systm.h>
@@ -616,6 +618,65 @@ vnet_sysuninit(void)
 	VNET_SYSINIT_RUNLOCK();
 }
 
+#ifdef VNET_DEBUG
+struct vnet_recursion {
+	SLIST_ENTRY(vnet_recursion)	 vnr_le;
+	const char			*prev_fn;
+	const char			*where_fn;
+	int				 where_line;
+	struct vnet			*old_vnet;
+	struct vnet			*new_vnet;
+};
+
+static SLIST_HEAD(, vnet_recursion) vnet_recursions =
+    SLIST_HEAD_INITIALIZER(vnet_recursions);
+
+static void
+vnet_print_recursion(struct vnet_recursion *vnr, int brief)
+{
+
+	if (!brief)
+		printf("CURVNET_SET() recursion in ");
+	printf("%s() line %d, prev in %s()", vnr->where_fn, vnr->where_line,
+	    vnr->prev_fn);
+	if (brief)
+		printf(", ");
+	else
+		printf("\n    ");
+	printf("%p -> %p\n", vnr->old_vnet, vnr->new_vnet);
+}
+
+void
+vnet_log_recursion(struct vnet *old_vnet, const char *old_fn, int line)
+{
+	struct vnet_recursion *vnr;
+
+	/* Skip already logged recursion events. */
+	SLIST_FOREACH(vnr, &vnet_recursions, vnr_le)
+		if (vnr->prev_fn == old_fn &&
+		    vnr->where_fn == curthread->td_vnet_lpush &&
+		    vnr->where_line == line &&
+		    (vnr->old_vnet == vnr->new_vnet) == (curvnet == old_vnet))
+			return;
+
+	vnr = malloc(sizeof(*vnr), M_VNET, M_NOWAIT | M_ZERO);
+	if (vnr == NULL)
+		panic("%s: malloc failed", __func__);
+	vnr->prev_fn = old_fn;
+	vnr->where_fn = curthread->td_vnet_lpush;
+	vnr->where_line = line;
+	vnr->old_vnet = old_vnet;
+	vnr->new_vnet = curvnet;
+
+	SLIST_INSERT_HEAD(&vnet_recursions, vnr, vnr_le);
+
+	vnet_print_recursion(vnr, 0);
+#ifdef KDB
+	kdb_backtrace();
+#endif
+}
+#endif /* VNET_DEBUG */
+
 #ifdef DDB
 DB_SHOW_COMMAND(vnets, db_show_vnets)
 {
@@ -637,4 +698,14 @@ DB_SHOW_COMMAND(vnets, db_show_vnets)
 			break;
 	}
 }
+
+#ifdef VNET_DEBUG
+DB_SHOW_COMMAND(vnetrcrs, db_show_vnetrcrs)
+{
+	struct vnet_recursion *vnr;
+
+	SLIST_FOREACH(vnr, &vnet_recursions, vnr_le)
+		vnet_print_recursion(vnr, 1);
+}
 #endif
+#endif /* DDB */

Modified: stable/8/sys/net/vnet.h
==============================================================================
--- stable/8/sys/net/vnet.h	Wed Feb 10 07:15:21 2010	(r203747)
+++ stable/8/sys/net/vnet.h	Wed Feb 10 08:50:06 2010	(r203748)
@@ -108,6 +108,8 @@ void	vnet_destroy(struct vnet *vnet);
  * assertions.
  */
 #ifdef VNET_DEBUG
+void vnet_log_recursion(struct vnet *, const char *, int);
+
 #define	VNET_ASSERT(condition)						\
 	if (!(condition)) {						\
 		printf("VNET_ASSERT @ %s:%d %s():\n",			\
@@ -125,9 +127,7 @@ void	vnet_destroy(struct vnet *vnet);
 #define	CURVNET_SET_VERBOSE(arg)					\
 	CURVNET_SET_QUIET(arg)						\
 	if (saved_vnet)							\
-		printf("CURVNET_SET(%p) in %s() on cpu %d, prev %p in %s()\n", \
-		       curvnet,	curthread->td_vnet_lpush, curcpu,	\
-		       saved_vnet, saved_vnet_lpush);
+		vnet_log_recursion(saved_vnet, saved_vnet_lpush, __LINE__);
 
 #define	CURVNET_SET(arg)	CURVNET_SET_VERBOSE(arg)
  



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002100850.o1A8o6tD038842>