[U-Boot] netloop: speed up NetLoop

Heiko Schocher hs at denx.de
Tue Feb 10 09:38:52 CET 2009


NetLoop polls every cycle with getenv some environment variables.
This is horribly slow, especially when the environment is big.

This patch reads only the environment variables in NetLoop,
when they were changed.

Also moved the init part of the NetLoop function in a seperate
function.

Signed-off-by: Heiko Schocher <hs at denx.de>
---

changes since first patch:
- added comments from Wolfgang Denk
- added comments from Kim Philips without:
  I keep get_env_id (), because it looks better so to me

 common/cmd_nvedit.c |    6 ++
 include/common.h    |    1 +
 net/eth.c           |   11 ++++-
 net/net.c           |  134 ++++++++++++++++++++++++++++----------------------
 4 files changed, 91 insertions(+), 61 deletions(-)

diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 1fcb4c9..9070b72 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -75,7 +75,12 @@ DECLARE_GLOBAL_DATA_PTR;
 static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
 #define	N_BAUDRATES (sizeof(baudrate_table) / sizeof(baudrate_table[0]))

+static int env_id = 1;

+int get_env_id (void)
+{
+	return env_id;
+}
 /************************************************************************
  * Command interface: print one or all environment variables
  */
@@ -160,6 +165,7 @@ int _do_setenv (int flag, int argc, char *argv[])
 		return 1;
 	}

+	env_id++;
 	/*
 	 * search if variable with this name already exists
 	 */
diff --git a/include/common.h b/include/common.h
index afee188..b75ea60 100644
--- a/include/common.h
+++ b/include/common.h
@@ -269,6 +269,7 @@ void	forceenv     (char *, char *);
 #ifdef CONFIG_AUTO_COMPLETE
 int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf);
 #endif
+int get_env_id (void);

 void	pci_init      (void);
 void	pci_init_board(void);
diff --git a/net/eth.c b/net/eth.c
index b7ef09f..ff5bd85 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -28,6 +28,9 @@

 #if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI)

+static char *act = NULL;
+static int  env_changed_id = 0;
+
 /*
  * CPU and board-specific Ethernet initializations.  Aliased function
  * signals caller to move on
@@ -439,13 +442,17 @@ void eth_try_another(int first_restart)
 #ifdef CONFIG_NET_MULTI
 void eth_set_current(void)
 {
-	char *act;
 	struct eth_device* old_current;
+	int	env_id;

 	if (!eth_current)	/* XXX no current */
 		return;

-	act = getenv("ethact");
+	env_id = get_env_id();
+	if ((act == NULL) || (env_changed_id != env_id)) {
+		act = getenv("ethact");
+		env_changed_id = env_id;
+	}
 	if (act != NULL) {
 		old_current = eth_current;
 		do {
diff --git a/net/net.c b/net/net.c
index e6547f9..797d156 100644
--- a/net/net.c
+++ b/net/net.c
@@ -209,6 +209,8 @@ uchar		NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
 ulong		NetArpWaitTimerStart;
 int		NetArpWaitTry;

+int		env_changed_id = 0;
+
 void ArpRequest (void)
 {
 	int i;
@@ -276,6 +278,78 @@ void ArpTimeoutCheck(void)
 	}
 }

+int
+NetInitLoop(proto_t protocol)
+{
+	bd_t *bd = gd->bd;
+	int env_id = get_env_id ();
+
+	/* update only when the environment has changed */
+	if (env_changed_id == env_id)
+		return 0;
+
+	switch (protocol) {
+#if defined(CONFIG_CMD_NFS)
+	case NFS:
+#endif
+#if defined(CONFIG_CMD_PING)
+	case PING:
+#endif
+#if defined(CONFIG_CMD_SNTP)
+	case SNTP:
+#endif
+	case NETCONS:
+	case TFTP:
+		NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
+		NetOurGatewayIP = getenv_IPaddr ("gatewayip");
+		NetOurSubnetMask= getenv_IPaddr ("netmask");
+		NetOurVLAN = getenv_VLAN("vlan");
+		NetOurNativeVLAN = getenv_VLAN("nvlan");
+
+		switch (protocol) {
+#if defined(CONFIG_CMD_NFS)
+		case NFS:
+#endif
+		case NETCONS:
+		case TFTP:
+			NetServerIP = getenv_IPaddr ("serverip");
+			break;
+#if defined(CONFIG_CMD_PING)
+		case PING:
+			/* nothing */
+			break;
+#endif
+#if defined(CONFIG_CMD_SNTP)
+		case SNTP:
+			/* nothing */
+			break;
+#endif
+		default:
+			break;
+		}
+
+		break;
+	case BOOTP:
+	case RARP:
+		/*
+		 * initialize our IP addr to 0 in order to accept ANY
+		 * IP addr assigned to us by the BOOTP / RARP server
+		 */
+		NetOurIP = 0;
+		NetServerIP = getenv_IPaddr ("serverip");
+		NetOurVLAN = getenv_VLAN("vlan");	/* VLANs must be read */
+		NetOurNativeVLAN = getenv_VLAN("nvlan");
+	case CDP:
+		NetOurVLAN = getenv_VLAN("vlan");	/* VLANs must be read */
+		NetOurNativeVLAN = getenv_VLAN("nvlan");
+		break;
+	default:
+		break;
+	}
+	env_changed_id = env_id;
+	return 0;
+}
+
 /**********************************************************************/
 /*
  *	Main network processing loop.
@@ -340,65 +414,7 @@ restart:
 	 *	here on, this code is a state machine driven by received
 	 *	packets and timer events.
 	 */
-
-	switch (protocol) {
-#if defined(CONFIG_CMD_NFS)
-	case NFS:
-#endif
-#if defined(CONFIG_CMD_PING)
-	case PING:
-#endif
-#if defined(CONFIG_CMD_SNTP)
-	case SNTP:
-#endif
-	case NETCONS:
-	case TFTP:
-		NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
-		NetOurGatewayIP = getenv_IPaddr ("gatewayip");
-		NetOurSubnetMask= getenv_IPaddr ("netmask");
-		NetOurVLAN = getenv_VLAN("vlan");
-		NetOurNativeVLAN = getenv_VLAN("nvlan");
-
-		switch (protocol) {
-#if defined(CONFIG_CMD_NFS)
-		case NFS:
-#endif
-		case NETCONS:
-		case TFTP:
-			NetServerIP = getenv_IPaddr ("serverip");
-			break;
-#if defined(CONFIG_CMD_PING)
-		case PING:
-			/* nothing */
-			break;
-#endif
-#if defined(CONFIG_CMD_SNTP)
-		case SNTP:
-			/* nothing */
-			break;
-#endif
-		default:
-			break;
-		}
-
-		break;
-	case BOOTP:
-	case RARP:
-		/*
-		 * initialize our IP addr to 0 in order to accept ANY
-		 * IP addr assigned to us by the BOOTP / RARP server
-		 */
-		NetOurIP = 0;
-		NetServerIP = getenv_IPaddr ("serverip");
-		NetOurVLAN = getenv_VLAN("vlan");	/* VLANs must be read */
-		NetOurNativeVLAN = getenv_VLAN("nvlan");
-	case CDP:
-		NetOurVLAN = getenv_VLAN("vlan");	/* VLANs must be read */
-		NetOurNativeVLAN = getenv_VLAN("nvlan");
-		break;
-	default:
-		break;
-	}
+	NetInitLoop(protocol);

 	switch (net_check_prereq (protocol)) {
 	case 1:
-- 
1.6.0.6

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany


More information about the U-Boot mailing list