diff options
author | Luigi Rizzo <luigi@FreeBSD.org> | 2013-05-09 17:07:30 +0000 |
---|---|---|
committer | Luigi Rizzo <luigi@FreeBSD.org> | 2013-05-09 17:07:30 +0000 |
commit | 4dc07530d7f3ba585bcad476d00d2d072d055510 (patch) | |
tree | 4012346dfa1cfa1f370bdd2b1e3a313b2be31c03 /sys/dev/e1000 | |
parent | 140547811568d87edd7f53188ae607a9a33a9585 (diff) | |
download | src-4dc07530d7f3ba585bcad476d00d2d072d055510.tar.gz src-4dc07530d7f3ba585bcad476d00d2d072d055510.zip |
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
Notes
Notes:
svn path=/head/; revision=250414
Diffstat (limited to 'sys/dev/e1000')
-rw-r--r-- | sys/dev/e1000/if_em.c | 12 | ||||
-rw-r--r-- | sys/dev/e1000/if_em.h | 1 | ||||
-rw-r--r-- | sys/dev/e1000/if_lem.c | 18 | ||||
-rw-r--r-- | sys/dev/e1000/if_lem.h | 1 |
4 files changed, 27 insertions, 5 deletions
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index b210d4e6ddbe..2ca4d3e11131 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -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 *rxr) * 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; diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h index f1afbadb32d1..09d81d25033f 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -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; diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c index 0ecf651f1f8c..553aeefebf32 100644 --- a/sys/dev/e1000/if_lem.c +++ b/sys/dev/e1000/if_lem.c @@ -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 pending) 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 adapter *adapter) * 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; diff --git a/sys/dev/e1000/if_lem.h b/sys/dev/e1000/if_lem.h index c1973e55be6e..235277d740c8 100644 --- a/sys/dev/e1000/if_lem.h +++ b/sys/dev/e1000/if_lem.h @@ -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 |