svn commit: r202408 - in stable/8/sys/boot: common sparc64/loader

Marius Strobl marius at FreeBSD.org
Fri Jan 15 19:06:34 UTC 2010


Author: marius
Date: Fri Jan 15 19:06:33 2010
New Revision: 202408
URL: http://svn.freebsd.org/changeset/base/202408

Log:
  MFC: r201932
  
  - Add code allowing a network device to only be open and closed once
    by keeping it opened after the first open and closing it via the
    cleanup handler when NETIF_OPEN_CLOSE_ONCE is defined in order to
    avoid the open-close-dance on every file access which with firmware
    that for example performs an auto-negotiation on every open causes
    netbooting to take horribly long. Basically the behavior with this
    knob enabled resembles the one employed between r60506 and r177108
    (and for sparc64 also again since r182919) with the addition that
    the network device now is closed eventually before entering the
    kernel and before rebooting. Actually I think this should be the
    desired MI behavior, however the U-Boot loader actually requires
    net_close() to be called after every transaction in order for some
    local shutdown operations to be performed (and which I think thus
    will break on concurrent opens, i.e. when netdev_opens is > 1, like
    the loader does at least for disks when LOADER_GZIP_SUPPORT is
    enabled).
  - Use NETIF_OPEN_CLOSE_ONCE to replace the hack, which artificially
    increased netdev_opens for sparc64 in order to keep the network
    device opened forever, as at least some firmware versions require
    the network device to be closed eventually before entering the
    kernel or otherwise will DMA received packets to stale memory.
    The powerpc OFW loader probably wants NETIF_OPEN_CLOSE_ONCE to be
    set as well for the same reasons.

Modified:
  stable/8/sys/boot/common/dev_net.c
  stable/8/sys/boot/sparc64/loader/Makefile
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)

Modified: stable/8/sys/boot/common/dev_net.c
==============================================================================
--- stable/8/sys/boot/common/dev_net.c	Fri Jan 15 18:31:44 2010	(r202407)
+++ stable/8/sys/boot/common/dev_net.c	Fri Jan 15 19:06:33 2010	(r202408)
@@ -71,12 +71,14 @@ __FBSDID("$FreeBSD$");
 int debug = 0;
 #endif
 
+static char *netdev_name;
 static int netdev_sock = -1;
 static int netdev_opens;
 
 static int	net_init(void);
 static int	net_open(struct open_file *, ...);
 static int	net_close(struct open_file *);
+static void	net_cleanup(void);
 static int	net_strategy();
 static void	net_print(int);
 
@@ -90,7 +92,8 @@ struct devsw netdev = {
 	net_open,
 	net_close,
 	noioctl,
-	net_print
+	net_print,
+	net_cleanup
 };
 
 static int
@@ -116,6 +119,12 @@ net_open(struct open_file *f, ...)
 	devname = va_arg(args, char*);
 	va_end(args);
 
+#ifdef	NETIF_OPEN_CLOSE_ONCE
+	/* Before opening another interface, close the previous one first. */
+	if (netdev_sock >= 0 && strcmp(devname, netdev_name) != 0)
+		net_cleanup();
+#endif
+
 	/* On first open, do netif open, mount, etc. */
 	if (netdev_opens == 0) {
 		/* Find network interface. */
@@ -125,6 +134,7 @@ net_open(struct open_file *f, ...)
 				printf("net_open: netif_open() failed\n");
 				return (ENXIO);
 			}
+			netdev_name = strdup(devname);
 #ifdef	NETIF_DEBUG
 			if (debug)
 				printf("net_open: netif_open() succeeded\n");
@@ -135,14 +145,12 @@ net_open(struct open_file *f, ...)
 			error = net_getparams(netdev_sock);
 			if (error) {
 				/* getparams makes its own noise */
+				free(netdev_name);
 				netif_close(netdev_sock);
 				netdev_sock = -1;
 				return (error);
 			}
 		}
-#if defined(__sparc64__)
-		netdev_opens++;
-#endif
 	}
 	netdev_opens++;
 	f->f_devdata = &netdev_sock;
@@ -152,30 +160,46 @@ net_open(struct open_file *f, ...)
 static int
 net_close(struct open_file *f)
 {
+
 #ifdef	NETIF_DEBUG
 	if (debug)
 		printf("net_close: opens=%d\n", netdev_opens);
 #endif
 
-	/* On last close, do netif close, etc. */
 	f->f_devdata = NULL;
+
+#ifndef	NETIF_OPEN_CLOSE_ONCE
 	/* Extra close call? */
 	if (netdev_opens <= 0)
 		return (0);
 	netdev_opens--;
 	/* Not last close? */
 	if (netdev_opens > 0)
-		return(0);
-	rootip.s_addr = 0;
+		return (0);
+	/* On last close, do netif close, etc. */
+#ifdef	NETIF_DEBUG
+	if (debug)
+		printf("net_close: calling net_cleanup()\n");
+#endif
+	net_cleanup();
+#endif
+	return (0);
+}
+
+static void
+net_cleanup(void)
+{
+
 	if (netdev_sock >= 0) {
 #ifdef	NETIF_DEBUG
 		if (debug)
-			printf("net_close: calling netif_close()\n");
+			printf("net_cleanup: calling netif_close()\n");
 #endif
+		rootip.s_addr = 0;
+		free(netdev_name);
 		netif_close(netdev_sock);
 		netdev_sock = -1;
 	}
-	return (0);
 }
 
 static int

Modified: stable/8/sys/boot/sparc64/loader/Makefile
==============================================================================
--- stable/8/sys/boot/sparc64/loader/Makefile	Fri Jan 15 18:31:44 2010	(r202407)
+++ stable/8/sys/boot/sparc64/loader/Makefile	Fri Jan 15 19:06:33 2010	(r202408)
@@ -51,11 +51,15 @@ CFLAGS+=	-DBOOT_FORTH -I${.CURDIR}/../..
 LIBFICL=	${.OBJDIR}/../../ficl/libficl.a
 .endif
 
-# Always add MI sources 
+# Always add MI sources
 .PATH:		${.CURDIR}/../../common
 .include	"${.CURDIR}/../../common/Makefile.inc"
 CFLAGS+=	-I${.CURDIR}/../../common
 CFLAGS+=	-I.
+# Avoid the open-close-dance for every file access as some firmwares perform
+# an auto-negotiation on every open of the network interface and thus causes
+# netbooting to take horribly long.
+CFLAGS+=	-DNETIF_OPEN_CLOSE_ONCE
 
 CLEANFILES+=	vers.c loader.help
 


More information about the svn-src-all mailing list