changeset 289:bd1db6a90df9

Fix problems with overflowing scatter-gather lists.
author gthomas
date Tue, 13 Aug 2002 15:55:53 +0000
parents 9d1f104153ba
children 3ecf91f6663a
files packages/io/eth/current/ChangeLog packages/io/eth/current/cdl/eth_drivers.cdl packages/io/eth/current/include/eth_drv.h packages/io/eth/current/src/net/eth_drv.c
diffstat 4 files changed, 34 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/packages/io/eth/current/ChangeLog
+++ b/packages/io/eth/current/ChangeLog
@@ -1,3 +1,13 @@
+2002-08-13  Gary Thomas  <gthomas@ecoscentric.com>
+
+	* src/net/eth_drv.c (eth_drv_send): Print a better message
+	if the scatter-gather list overflows.
+
+	* include/eth_drv.h (MAX_ETH_DRV_SG): 
+	* cdl/eth_drivers.cdl: Add control over size of scatter-gather
+	data lists used to pass requests to physical layer.  Previous
+	value was sometimes too small.
+
 2002-07-31  Gary Thomas  <gary@chez-thomas.org>
 
 	* src/net/eth_drv.c (eth_drv_start): Fix compile error when
--- a/packages/io/eth/current/cdl/eth_drivers.cdl
+++ b/packages/io/eth/current/cdl/eth_drivers.cdl
@@ -109,6 +109,17 @@ cdl_package CYGPKG_IO_ETH_DRIVERS {
                 properties of the system even in extremis."
 	}
 
+    	cdl_option CYGNUM_IO_ETH_DRIVERS_SG_LIST_SIZE {
+	    display	"Size of scatter-gather I/O lists"
+	    flavor	data
+	    default_value 32
+	    description "
+	        A scatter-gather list is used to pass requests to/from
+                the physical device driver.  This list can typically be
+                small, as the data is normally already packed into reasonable
+                chunks."
+	}
+
 	cdl_component CYGPKG_IO_ETH_DRIVERS_SIMULATED_FAILURES {
 	    display		"Simulate network failures for testing"
 	    flavor		bool
--- a/packages/io/eth/current/include/eth_drv.h
+++ b/packages/io/eth/current/include/eth_drv.h
@@ -57,6 +57,7 @@
 #define _ETH_DRV_H_
 
 #include <pkgconf/system.h>
+#include <pkgconf/io_eth_drivers.h>
 
 #ifdef CYGPKG_NET
 #include <sys/param.h>
@@ -86,9 +87,7 @@ struct eth_drv_sg {
     CYG_ADDRWORD len;
 };
 
-// This is 16 to ensure that an MTU made of mbufs (not clusters) will fit.
-// 1600 is more that the MTU of 1500; it must be right.
-#define MAX_ETH_DRV_SG 16
+#define MAX_ETH_DRV_SG CYGNUM_IO_ETH_DRIVERS_SG_LIST_SIZE
 
 struct eth_drv_sc;
 
--- a/packages/io/eth/current/src/net/eth_drv.c
+++ b/packages/io/eth/current/src/net/eth_drv.c
@@ -619,6 +619,9 @@ static void
 eth_drv_send(struct ifnet *ifp)
 {
     struct eth_drv_sc *sc = ifp->if_softc;
+#if MAX_ETH_DRV_SG > 64
+    static  // Avoid large stack requirements
+#endif
     struct eth_drv_sg sg_list[MAX_ETH_DRV_SG];
     int sg_len;
     struct mbuf *m0, *m;
@@ -692,8 +695,12 @@ eth_drv_send(struct ifnet *ifp)
 #endif
             if ( MAX_ETH_DRV_SG < sg_len ) {
 #ifdef CYGPKG_IO_ETH_DRIVERS_WARN_NO_MBUFS
+                int needed = 0;
+                struct mbuf *m1;
+                for (m1 = m0; m1 ; m1 = m1->m_next) needed++;
                 START_CONSOLE();
-                diag_printf("too many mbufs to tx, %d > %d\n", sg_len, MAX_ETH_DRV_SG );
+                diag_printf("too many mbufs to tx, %d > %d, need %d\n", 
+                            sg_len, MAX_ETH_DRV_SG, needed );
                 END_CONSOLE();
 #endif
                 sg_len = 0;
@@ -784,6 +791,9 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
     struct mbuf *top, **mp, *m;
     int mlen;
     unsigned char *data;
+#if MAX_ETH_DRV_SG > 64
+    static  // Avoid large stack requirements
+#endif
     struct eth_drv_sg sg_list[MAX_ETH_DRV_SG];
     int sg_len;