svn commit: r250414 - head/sys/dev/e1000

Luigi Rizzo luigi at FreeBSD.org
Thu May 9 17:07:32 UTC 2013


Author: luigi
Date: Thu May  9 17:07:30 2013
New Revision: 250414
URL: http://svnweb.freebsd.org/changeset/base/250414

Log:
  if_lem.c:  make sure that lem_rxeof() can drain the entire rx queue
  	irrespective of the setting of lem_rx_process_limit, while
  	giving a chance to the taskqueue scheduler to act after
  	each chunk.
  	This makes lem_rxeof similar to the one in if_em.c and if_igb.c .
  
  if_lem.c and if_em.c: add a sysctl to manually configure the
  	'itr' moderation register.
  
  Approved by:	Jack Vogel

Modified:
  head/sys/dev/e1000/if_em.c
  head/sys/dev/e1000/if_em.h
  head/sys/dev/e1000/if_lem.c
  head/sys/dev/e1000/if_lem.h

Modified: head/sys/dev/e1000/if_em.c
==============================================================================
--- head/sys/dev/e1000/if_em.c	Thu May  9 16:57:02 2013	(r250413)
+++ head/sys/dev/e1000/if_em.c	Thu May  9 17:07:30 2013	(r250414)
@@ -335,6 +335,9 @@ MODULE_DEPEND(em, ether, 1, 1, 1);
 #define EM_USECS_TO_TICKS(usecs)	((1000 * (usecs) + 512) / 1024)
 #define M_TSO_LEN			66
 
+#define MAX_INTS_PER_SEC	8000
+#define DEFAULT_ITR		(1000000000/(MAX_INTS_PER_SEC * 256))
+
 /* Allow common code without TSO */
 #ifndef CSUM_TSO
 #define CSUM_TSO	0
@@ -570,6 +573,11 @@ em_attach(device_t dev)
 	    &adapter->tx_abs_int_delay,
 	    E1000_REGISTER(hw, E1000_TADV),
 	    em_tx_abs_int_delay_dflt);
+	em_add_int_delay_sysctl(adapter, "itr",
+	    "interrupt delay limit in usecs/4",
+	    &adapter->tx_itr,
+	    E1000_REGISTER(hw, E1000_ITR),
+	    DEFAULT_ITR);
 
 	/* Sysctl for limiting the amount of work done in the taskqueue */
 	em_set_sysctl_value(adapter, "rx_processing_limit",
@@ -4271,8 +4279,6 @@ em_free_receive_buffers(struct rx_ring *
  *  Enable receive unit.
  *
  **********************************************************************/
-#define MAX_INTS_PER_SEC	8000
-#define DEFAULT_ITR	     1000000000/(MAX_INTS_PER_SEC * 256)
 
 static void
 em_initialize_receive_unit(struct adapter *adapter)
@@ -5618,6 +5624,8 @@ em_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
 		return (EINVAL);
 	info->value = usecs;
 	ticks = EM_USECS_TO_TICKS(usecs);
+	if (info->offset == E1000_ITR)	/* units are 256ns here */
+		ticks *= 4;
 
 	adapter = info->adapter;
 	

Modified: head/sys/dev/e1000/if_em.h
==============================================================================
--- head/sys/dev/e1000/if_em.h	Thu May  9 16:57:02 2013	(r250413)
+++ head/sys/dev/e1000/if_em.h	Thu May  9 17:07:30 2013	(r250414)
@@ -429,6 +429,7 @@ struct adapter {
 	struct em_int_delay_info tx_abs_int_delay;
 	struct em_int_delay_info rx_int_delay;
 	struct em_int_delay_info rx_abs_int_delay;
+	struct em_int_delay_info tx_itr;
 
 	/* Misc stats maintained by the driver */
 	unsigned long	dropped_pkts;

Modified: head/sys/dev/e1000/if_lem.c
==============================================================================
--- head/sys/dev/e1000/if_lem.c	Thu May  9 16:57:02 2013	(r250413)
+++ head/sys/dev/e1000/if_lem.c	Thu May  9 17:07:30 2013	(r250414)
@@ -281,6 +281,9 @@ MODULE_DEPEND(lem, ether, 1, 1, 1);
 #define EM_TICKS_TO_USECS(ticks)	((1024 * (ticks) + 500) / 1000)
 #define EM_USECS_TO_TICKS(usecs)	((1000 * (usecs) + 512) / 1024)
 
+#define MAX_INTS_PER_SEC	8000
+#define DEFAULT_ITR		(1000000000/(MAX_INTS_PER_SEC * 256))
+
 static int lem_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV);
 static int lem_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR);
 static int lem_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV);
@@ -442,6 +445,11 @@ lem_attach(device_t dev)
 		    &adapter->tx_abs_int_delay,
 		    E1000_REGISTER(&adapter->hw, E1000_TADV),
 		    lem_tx_abs_int_delay_dflt);
+		lem_add_int_delay_sysctl(adapter, "itr",
+		    "interrupt delay limit in usecs/4",
+		    &adapter->tx_itr,
+		    E1000_REGISTER(&adapter->hw, E1000_ITR),
+		    DEFAULT_ITR);
 	}
 
 	/* Sysctls for limiting the amount of work done in the taskqueue */
@@ -1337,12 +1345,16 @@ lem_handle_rxtx(void *context, int pendi
 
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		lem_rxeof(adapter, adapter->rx_process_limit, NULL);
+		bool more = lem_rxeof(adapter, adapter->rx_process_limit, NULL);
 		EM_TX_LOCK(adapter);
 		lem_txeof(adapter);
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 			lem_start_locked(ifp);
 		EM_TX_UNLOCK(adapter);
+		if (more) {
+			taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
+			return;
+		}
 	}
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
@@ -3269,8 +3281,6 @@ lem_setup_receive_structures(struct adap
  *  Enable receive unit.
  *
  **********************************************************************/
-#define MAX_INTS_PER_SEC	8000
-#define DEFAULT_ITR	     1000000000/(MAX_INTS_PER_SEC * 256)
 
 static void
 lem_initialize_receive_unit(struct adapter *adapter)
@@ -4596,6 +4606,8 @@ lem_sysctl_int_delay(SYSCTL_HANDLER_ARGS
 		return (EINVAL);
 	info->value = usecs;
 	ticks = EM_USECS_TO_TICKS(usecs);
+	if (info->offset == E1000_ITR)	/* units are 256ns here */
+		ticks *= 4;
 
 	adapter = info->adapter;
 	

Modified: head/sys/dev/e1000/if_lem.h
==============================================================================
--- head/sys/dev/e1000/if_lem.h	Thu May  9 16:57:02 2013	(r250413)
+++ head/sys/dev/e1000/if_lem.h	Thu May  9 17:07:30 2013	(r250414)
@@ -363,6 +363,7 @@ struct adapter {
 	struct em_int_delay_info tx_abs_int_delay;
 	struct em_int_delay_info rx_int_delay;
 	struct em_int_delay_info rx_abs_int_delay;
+	struct em_int_delay_info tx_itr;
 
 	/*
 	 * Transmit definitions


More information about the svn-src-all mailing list