From d0870c725cfb676b363d73631ad239507c3ca316 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 22 Nov 2004 00:46:14 +0000 Subject: [PATCH] Add support for adjusting the interrupt throttling rate via hw.emX.int_throttle_ceil, and change the default from 8000hz to 10000hz to improve throughput with default TCP window sizes through a GiGE switch in a LAN environment. Note the following test results using iperf between two machines: * Shuttle Athlon 64 3200+ box, EM card in 32 bit PCI slot * 2 machines connected through a GiGE switch * All other hw.em0 delays set to 0 on both sides * throttle settings set on both sides * -w option set on iperf client AND server for 63.5KB window * software interrupt throttling has been turned off for these tests throttle result result freq (32.5KB win) (63.5KB win) (default) -------- -------------- ----------- maxrate 481 MBit/s 533 MBit/s (not sure what's going on here) 120000 518 MBit/s 558 MBit/s (not sure what's going on here) 100000 613 MBit/s 667 MBit/s (not sure what's going on here) 70000 679 MBit/s 691 MBit/s 60000 668 MBit/s 694 MBit/s 50000 678 MBit/s 684 MBit/s 40000 694 MBit/s 696 MBit/s 30000 694 MBit/s 696 MBit/s 20000 698 MBit/s 703 MBit/s 10000 707 MBit/s 716 MBit/s 9000 708 MBit/s 716 MBit/s 8000 710 MBit/s 717 MBit/s <--- drop off pt 32.5KB win 7000 683 MBit/s 716 MBit/s 6000 680 MBit/s 720 MBit/s 5000 652 MBit/s 718 MBit/s <--- drop off pt 63.5KB win 4000 555 Mbit/s 695 MBit/s 3000 522 MBit/s 533 MBit/s <--- GiGE throttling likely 2000 449 MBit/s 384 MBit/s (256 ring descriptors = 1000 260 MBit/s 193 MBit/s 2500 hz minimum) --- sys/dev/netif/em/if_em.c | 59 ++++++++++++++++++++++++++++++++++------ sys/dev/netif/em/if_em.h | 3 +- 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/sys/dev/netif/em/if_em.c b/sys/dev/netif/em/if_em.c index 4e075b36db..e71969ad19 100644 --- a/sys/dev/netif/em/if_em.c +++ b/sys/dev/netif/em/if_em.c @@ -34,9 +34,9 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ /*$FreeBSD: src/sys/dev/em/if_em.c,v 1.2.2.15 2003/06/09 22:10:15 pdeuskar Exp $*/ -/*$DragonFly: src/sys/dev/netif/em/if_em.c,v 1.21 2004/10/20 09:17:22 dillon Exp $*/ +/*$DragonFly: src/sys/dev/netif/em/if_em.c,v 1.22 2004/11/22 00:46:14 dillon Exp $*/ -#include +#include "if_em.h" /********************************************************************* * Set this to one to display debug statistics @@ -166,6 +166,7 @@ static int em_sysctl_debug_info(SYSCTL_HANDLER_ARGS); static uint32_t em_fill_descriptors(uint64_t address, uint32_t length, PDESC_ARRAY desc_array); static int em_sysctl_int_delay(SYSCTL_HANDLER_ARGS); +static int em_sysctl_int_throttle(SYSCTL_HANDLER_ARGS); static void em_add_int_delay_sysctl(struct adapter *, const char *, const char *, struct em_int_delay_info *, int, int); @@ -203,11 +204,13 @@ static int em_tx_int_delay_dflt = E1000_TICKS_TO_USECS(EM_TIDV); static int em_rx_int_delay_dflt = E1000_TICKS_TO_USECS(EM_RDTR); static int em_tx_abs_int_delay_dflt = E1000_TICKS_TO_USECS(EM_TADV); static int em_rx_abs_int_delay_dflt = E1000_TICKS_TO_USECS(EM_RADV); +static int em_int_throttle_ceil = 10000; TUNABLE_INT("hw.em.tx_int_delay", &em_tx_int_delay_dflt); TUNABLE_INT("hw.em.rx_int_delay", &em_rx_int_delay_dflt); TUNABLE_INT("hw.em.tx_abs_int_delay", &em_tx_abs_int_delay_dflt); TUNABLE_INT("hw.em.rx_abs_int_delay", &em_rx_abs_int_delay_dflt); +TUNABLE_INT("hw.em.int_throttle_ceil", &em_int_throttle_ceil); /********************************************************************* * Device identification routine @@ -342,6 +345,10 @@ em_attach(device_t dev) &adapter->tx_abs_int_delay, E1000_REG_OFFSET(&adapter->hw, TADV), em_tx_abs_int_delay_dflt); + SYSCTL_ADD_PROC(&adapter->sysctl_ctx, + SYSCTL_CHILDREN(adapter->sysctl_tree), + OID_AUTO, "int_throttle_ceil", CTLTYPE_INT|CTLFLAG_RW, + adapter, 0, em_sysctl_int_throttle, "I", NULL); } /* Parameters (to be read from user) */ @@ -2310,12 +2317,13 @@ em_initialize_receive_unit(struct adapter *adapter) E1000_WRITE_REG(&adapter->hw, RADV, adapter->rx_abs_int_delay.value); - /* Set the interrupt throttling rate. Value is calculated - * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) - */ -#define MAX_INTS_PER_SEC 8000 -#define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256) - E1000_WRITE_REG(&adapter->hw, ITR, DEFAULT_ITR); + /* Set the interrupt throttling rate in 256ns increments */ + if (em_int_throttle_ceil) { + E1000_WRITE_REG(&adapter->hw, ITR, + 1000000000 / 256 / em_int_throttle_ceil); + } else { + E1000_WRITE_REG(&adapter->hw, ITR, 0); + } } /* Setup the Base and Length of the Rx Descriptor Ring */ @@ -3032,3 +3040,38 @@ em_add_int_delay_sysctl(struct adapter *adapter, const char *name, OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, info, 0, em_sysctl_int_delay, "I", description); } + +static int +em_sysctl_int_throttle(SYSCTL_HANDLER_ARGS) +{ + struct adapter *adapter = (void *)arg1; + int error; + int throttle; + + throttle = em_int_throttle_ceil; + error = sysctl_handle_int(oidp, &throttle, 0, req); + if (error || req->newptr == NULL) + return error; + if (throttle < 0 || throttle > 1000000000 / 256) + return EINVAL; + if (throttle) { + /* + * Set the interrupt throttling rate in 256ns increments, + * recalculate sysctl value assignment to get exact frequency. + */ + throttle = 1000000000 / 256 / throttle; + em_int_throttle_ceil = 1000000000 / 256 / throttle; + crit_enter(); + E1000_WRITE_REG(&adapter->hw, ITR, throttle); + crit_exit(); + } else { + em_int_throttle_ceil = 0; + crit_enter(); + E1000_WRITE_REG(&adapter->hw, ITR, 0); + crit_exit(); + } + device_printf(adapter->dev, "Interrupt moderation set to %d/sec\n", + em_int_throttle_ceil); + return 0; +} + diff --git a/sys/dev/netif/em/if_em.h b/sys/dev/netif/em/if_em.h index 931b7fbd46..b9a8afb69a 100644 --- a/sys/dev/netif/em/if_em.h +++ b/sys/dev/netif/em/if_em.h @@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ /*$FreeBSD: src/sys/dev/em/if_em.h,v 1.1.2.13 2003/06/09 21:43:41 pdeuskar Exp $*/ -/*$DragonFly: src/sys/dev/netif/em/if_em.h,v 1.7 2004/06/04 16:32:11 joerg Exp $*/ +/*$DragonFly: src/sys/dev/netif/em/if_em.h,v 1.8 2004/11/22 00:46:14 dillon Exp $*/ #ifndef _EM_H_DEFINED_ #define _EM_H_DEFINED_ @@ -74,6 +74,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include "opt_bdg.h" #include -- 2.41.0