Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133121130
D1994.id4104.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D1994.id4104.diff
View Options
Index: share/man/man4/em.4
===================================================================
--- share/man/man4/em.4
+++ share/man/man4/em.4
@@ -45,6 +45,16 @@
.Cd "device em"
.Ed
.Pp
+Optional multiqueue support is available via the following kernel
+compile options:
+.Bd -ragged -offset indent
+.Cd "options EM_MULTIQUEUE"
+.Ed
+.Pp
+Note: Activating EM_MULTIQUEUE support will disable MSI-X features
+by default. Until these issues are resolved, activating MSI-X will crash
+your system with EM_MULTIQUEUE enabled.
+.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
@@ -197,6 +207,16 @@
prompt before booting the kernel or stored in
.Xr loader.conf 5 .
.Bl -tag -width indent
+.It Va hw.em.eee_setting
+Disable or Enable Energy Efficient Ethernet. Default 1 (disabled).
+.It Va hw.em.msix
+Enable or Disable MSI-X style interrupts. Default 1 (on) unless
+.Cd "options EM_MULTIQUEUE"
+is defined in which case Default 0 (off).
+.It Va hw.em.smart_pwr_down
+Enable or Disable smart power down features on newer adapters. Default 0 (off).
+.It Va hw.em.sbp
+Show bad packets when in promiscuous mode. Default 0 (off).
.It Va hw.em.rxd
Number of receive descriptors allocated by the driver.
The default value is 1024 for adapters newer than 82547,
@@ -228,6 +248,12 @@
.Va hw.em.tx_int_delay
is non-zero, this tunable limits the maximum delay in which a transmit
interrupt is generated.
+.It Va hw.em.num_queues
+Number of h/w queues that we will run on this adapter. Max 2. Defaults to 1.
+Only valid with kernel configuration
+.Cd "options EM_MULTIQUEUE".
+Not compatible with
+.Va hw.em.msix = 1
.El
.Sh FILES
.Bl -tag -width /dev/led/em*
@@ -271,6 +297,9 @@
.Xr polling 4 ,
.Xr vlan 4 ,
.Xr ifconfig 8
+.Sh NOTES
+Enabling EM_MULTIQUEUE in your kernel configuration will disable MSI-X by
+default. At this time MSI-X support does not work with this option.
.Sh HISTORY
The
.Nm
Index: sys/conf/NOTES
===================================================================
--- sys/conf/NOTES
+++ sys/conf/NOTES
@@ -2983,3 +2983,6 @@
# Module to enable execution of application via emulators like QEMU
options IMAGACT_BINMISC
+
+# Intel em(4) driver
+options EM_MULTIQUEUE # Activate multiqueue features/disable MSI-X
Index: sys/conf/options
===================================================================
--- sys/conf/options
+++ sys/conf/options
@@ -935,3 +935,6 @@
RANDOM_YARROW opt_random.h
RANDOM_FORTUNA opt_random.h
RANDOM_DEBUG opt_random.h
+
+# Intel em(4) driver
+EM_MULTIQUEUE opt_em.h
Index: sys/dev/e1000/e1000_defines.h
===================================================================
--- sys/dev/e1000/e1000_defines.h
+++ sys/dev/e1000/e1000_defines.h
@@ -158,10 +158,12 @@
E1000_RXDEXT_STATERR_CXE | \
E1000_RXDEXT_STATERR_RXE)
+#define E1000_MRQC_RSS_ENABLE_2Q 0x00000001
#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000
#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000
+#define E1000_MRQC_RSS_FIELD_IPV6_EX 0x00080000
#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000
Index: sys/dev/e1000/if_em.h
===================================================================
--- sys/dev/e1000/if_em.h
+++ sys/dev/e1000/if_em.h
@@ -249,6 +249,14 @@
* solve it just using this define.
*/
#define EM_EIAC 0x000DC
+/*
+ * 82574 only reports 3 MSI-X vectors by default;
+ * defines assisting with making it report 5 are
+ * located here.
+ */
+#define EM_NVM_PCIE_CTRL 0x1B
+#define EM_NVM_MSIX_N_MASK (0x7 << EM_NVM_MSIX_N_SHIFT)
+#define EM_NVM_MSIX_N_SHIFT 7
/*
* Bus dma allocation structure used by
Index: sys/dev/e1000/if_em.c
===================================================================
--- sys/dev/e1000/if_em.c
+++ sys/dev/e1000/if_em.c
@@ -32,6 +32,7 @@
******************************************************************************/
/*$FreeBSD$*/
+#include "opt_em.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -299,6 +300,8 @@
static void em_handle_rx(void *context, int pending);
static void em_handle_link(void *context, int pending);
+static void em_enable_vectors_82574(struct adapter *);
+
static void em_set_sysctl_value(struct adapter *, const char *,
const char *, int *, int);
static int em_set_flowcntl(SYSCTL_HANDLER_ARGS);
@@ -388,6 +391,12 @@
SYSCTL_INT(_hw_em, OID_AUTO, enable_msix, CTLFLAG_RDTUN, &em_enable_msix, 0,
"Enable MSI-X interrupts");
+#ifdef EM_MULTIQUEUE
+static int em_num_queues = 2;
+SYSCTL_INT(_hw_em, OID_AUTO, num_queues, CTLFLAG_RDTUN, &em_num_queues, 0,
+ "82574 only: Number of queues to configure, 0 indicates autoconfigure");
+#endif
+
/* How many packets rxeof tries to clean at a time */
static int em_rx_process_limit = 100;
SYSCTL_INT(_hw_em, OID_AUTO, rx_process_limit, CTLFLAG_RDTUN,
@@ -458,6 +467,32 @@
return (ENXIO);
}
+/*
+ * 82574 only:
+ * Write a new value to the EEPROM increasing the number of MSIX
+ * vectors from 3 to 5, for proper multiqueue support.
+ */
+static void
+em_enable_vectors_82574(struct adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ device_t dev = adapter->dev;
+ u16 edata;
+
+ e1000_read_nvm(hw, EM_NVM_PCIE_CTRL, 1, &edata);
+ printf("Current cap: %#06x\n", edata);
+ if (((edata & EM_NVM_MSIX_N_MASK) >> EM_NVM_MSIX_N_SHIFT) != 4
+ && adapter->num_queues > 1) {
+ device_printf(dev, "Writing to eeprom: increasing "
+ "reported MSIX vectors from 3 to 5...\n");
+ edata &= ~(EM_NVM_MSIX_N_MASK);
+ edata |= 4 << EM_NVM_MSIX_N_SHIFT;
+ e1000_write_nvm(hw, EM_NVM_PCIE_CTRL, 1, &edata);
+ e1000_update_nvm_checksum(hw);
+ device_printf(dev, "Writing to eeprom: done\n");
+ }
+}
+
/*********************************************************************
* Device initialization routine
*
@@ -550,6 +585,11 @@
goto err_pci;
}
+ /*
+ * Setup MSI/X or MSI if PCI Express
+ */
+ adapter->msix = em_setup_msix(adapter);
+
e1000_get_bus_info(hw);
/* Set up some sysctls for the tunable interrupt delays */
@@ -964,8 +1004,16 @@
{
struct adapter *adapter = if_getsoftc(ifp);
struct tx_ring *txr = adapter->tx_rings;
- int error;
+ int i, error;
+
+#ifdef EM_MULTIQUEUE
+ if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE)
+ i = m->m_pkthdr.flowid % adapter->num_queues;
+ else
+ i = curcpu % adapter->num_queues;
+ txr = &adapter->tx_rings[i];
+#endif
if (EM_TX_TRYLOCK(txr)) {
error = em_mq_start_locked(ifp, txr, m);
EM_TX_UNLOCK(txr);
@@ -2437,14 +2485,6 @@
rman_get_bushandle(adapter->memory);
adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle;
- /* Default to a single queue */
- adapter->num_queues = 1;
-
- /*
- * Setup MSI/X or MSI if PCI Express
- */
- adapter->msix = em_setup_msix(adapter);
-
adapter->hw.back = &adapter->osdep;
return (0);
@@ -2701,14 +2741,19 @@
device_t dev = adapter->dev;
int val;
+ /* Nearly always going to use one queue */
+ adapter->num_queues = 1;
+
/*
- ** Setup MSI/X for Hartwell: tests have shown
- ** use of two queues to be unstable, and to
- ** provide no great gain anyway, so we simply
- ** seperate the interrupts and use a single queue.
+ ** Try using MSI-X for Hartwell adapters
*/
if ((adapter->hw.mac.type == e1000_82574) &&
(em_enable_msix == TRUE)) {
+#ifdef EM_MULTIQUEUE
+ adapter->num_queues = (em_num_queues == 1) ? 1 : 2;
+ if (adapter->num_queues > 1)
+ em_enable_vectors_82574(adapter);
+#endif
/* Map the MSIX BAR */
int rid = PCIR_BAR(EM_MSIX_BAR);
adapter->msix_mem = bus_alloc_resource_any(dev,
@@ -2720,16 +2765,31 @@
goto msi;
}
val = pci_msix_count(dev);
- /* We only need/want 3 vectors */
+
+#ifdef EM_MULTIQUEUE
+ /* We need 5 vectors in the multiqueue case */
+ if (adapter->num_queues == 2) {
+ if (val >= 5)
+ val = 5;
+ else {
+ adapter->num_queues = 1;
+ device_printf(adapter->dev,
+ "Insufficient MSIX vectors for >1 queue, "
+ "using single queue...\n");
+ goto msix_one;
+ }
+ } else
+#endif
+msix_one:
if (val >= 3)
val = 3;
else {
- device_printf(adapter->dev,
- "MSIX: insufficient vectors, using MSI\n");
+ device_printf(adapter->dev,
+ "Insufficient MSIX vectors, using MSI\n");
goto msi;
}
- if ((pci_alloc_msix(dev, &val) == 0) && (val == 3)) {
+ if ((pci_alloc_msix(dev, &val) == 0)) {
device_printf(adapter->dev,
"Using MSIX interrupts "
"with %d vectors\n", val);
@@ -2750,7 +2810,7 @@
}
val = 1;
if (pci_alloc_msi(dev, &val) == 0) {
- device_printf(adapter->dev,"Using an MSI interrupt\n");
+ device_printf(adapter->dev, "Using an MSI interrupt\n");
return (val);
}
/* Should only happen due to manual configuration */
@@ -4278,12 +4338,54 @@
}
rxcsum = E1000_READ_REG(hw, E1000_RXCSUM);
- if (if_getcapenable(ifp) & IFCAP_RXCSUM)
+ if (if_getcapenable(ifp) & IFCAP_RXCSUM) {
+#ifdef EM_MULTIQUEUE
+ rxcsum |= E1000_RXCSUM_TUOFL |
+ E1000_RXCSUM_IPOFL |
+ E1000_RXCSUM_PCSD;
+#else
rxcsum |= E1000_RXCSUM_TUOFL;
- else
+ E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum);
+#endif
+ } else
rxcsum &= ~E1000_RXCSUM_TUOFL;
- E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum);
+
+#ifdef EM_MULTIQUEUE
+ if (adapter->num_queues > 1) {
+ uint32_t rss_key[10];
+ uint32_t reta;
+ int i;
+
+ /*
+ * Configure RSS key
+ */
+ arc4rand(rss_key, sizeof(rss_key), 0);
+ for (i = 0; i < 10; ++i)
+ E1000_WRITE_REG_ARRAY(hw,E1000_RSSRK(0), i, rss_key[i]);
+
+ /*
+ * Configure RSS redirect table in following fashion:
+ * (hash & ring_cnt_mask) == rdr_table[(hash & rdr_table_mask)]
+ */
+ reta = 0;
+ for (i = 0; i < 4; ++i) {
+ uint32_t q;
+ q = (i % 2) << 7;
+ reta |= q << (8 * i);
+ }
+ for (i = 0; i < 32; ++i)
+ E1000_WRITE_REG(hw, E1000_RETA(i), reta);
+
+ E1000_WRITE_REG(hw, E1000_MRQC, E1000_MRQC_RSS_ENABLE_2Q |
+ E1000_MRQC_RSS_FIELD_IPV4_TCP |
+ E1000_MRQC_RSS_FIELD_IPV4 |
+ E1000_MRQC_RSS_FIELD_IPV6_TCP_EX |
+ E1000_MRQC_RSS_FIELD_IPV6_EX |
+ E1000_MRQC_RSS_FIELD_IPV6 |
+ E1000_MRQC_RSS_FIELD_IPV6_TCP);
+#endif
+ }
/*
** XXX TEMPORARY WORKAROUND: on some systems with 82573
** long latencies are observed, like Lenovo X60. This
@@ -4317,7 +4419,6 @@
#endif /* DEV_NETMAP */
E1000_WRITE_REG(hw, E1000_RDT(i), rdt);
}
-
/* Set PTHRESH for improved jumbo performance */
if (((adapter->hw.mac.type == e1000_ich9lan) ||
(adapter->hw.mac.type == e1000_pch2lan) ||
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 24, 3:50 AM (18 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24117205
Default Alt Text
D1994.id4104.diff (10 KB)
Attached To
Mode
D1994: Enable em(4) multiqueue as a compile time option
Attached
Detach File
Event Timeline
Log In to Comment