Page MenuHomeFreeBSD

D1994.id4096.diff
No OneTemporary

D1994.id4096.diff

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/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);
@@ -384,10 +387,20 @@
SYSCTL_INT(_hw_em, OID_AUTO, sbp, CTLFLAG_RDTUN, &em_debug_sbp, 0,
"Show bad packets in promiscuous mode");
+#ifdef EM_MULTIQUEUE
+static int em_enable_msix = FALSE;
+#else
static int em_enable_msix = TRUE;
+#endif
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 = 0;
+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 +471,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 +589,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 */
@@ -2437,14 +2481,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 +2737,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 +2761,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 +2806,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 */

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 8, 4:51 PM (6 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31108477
Default Alt Text
D1994.id4096.diff (7 KB)

Event Timeline