From f8b64a61bce6a765021b8484e6a1189e43c8a91a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Mulik?= Date: Mon, 23 Apr 2018 11:42:41 +0000 Subject: [PATCH] Configurable Link State Change (LSC) detection mode It is possible to set LSC detection mode to polling or interrupt mode for DPDK interfaces. The default is polling mode. To set interrupt mode, option dpdk-lsc-interrupt has to be set to true. For detailed description and usage see the dpdk install documentation. Signed-off-by: Robert Mulik Signed-off-by: Ian Stokes --- Documentation/topics/dpdk/phy.rst | 24 +++++++++++++++++++++++ NEWS | 1 + lib/netdev-dpdk.c | 32 ++++++++++++++++++++++++++----- vswitchd/vswitch.xml | 17 ++++++++++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) diff --git a/Documentation/topics/dpdk/phy.rst b/Documentation/topics/dpdk/phy.rst index 477b291e4..14706233d 100644 --- a/Documentation/topics/dpdk/phy.rst +++ b/Documentation/topics/dpdk/phy.rst @@ -224,3 +224,27 @@ Jumbo Frames DPDK physical ports can be configured to use Jumbo Frames. For more information, refer to :doc:`jumbo-frames`. + +Link State Change (LSC) detection configuration +----------------------------------------------- + +There are two methods to get the information when Link State Change (LSC) +happens on a network interface: by polling or interrupt. + +Configuring the lsc detection mode has no direct effect on OVS itself, +instead it configures the NIC how it should handle link state changes. +Processing the link state update request triggered by OVS takes less time +using interrupt mode, since the NIC updates its link state in the +background, while in polling mode the link state has to be fetched from +the firmware every time to fulfil this request. + +Note that not all PMD drivers support LSC interrupts. + +The default configuration is polling mode. To set interrupt mode, option +``dpdk-lsc-interrupt`` has to be set to ``true``. + +Command to set interrupt mode for a specific interface:: + $ ovs-vsctl set interface options:dpdk-lsc-interrupt=true + +Command to set polling mode for a specific interface:: + $ ovs-vsctl set interface options:dpdk-lsc-interrupt=false diff --git a/NEWS b/NEWS index 39f42c5c6..328d6ecb9 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,7 @@ Post-v2.9.0 - DPDK: * New 'check-dpdk' Makefile target to run a new system testsuite. See Testing topic for the details. + * Add LSC interrupt support for DPDK physical devices. - Userspace datapath: * Commands ovs-appctl dpif-netdev/pmd-*-show can now work on a single PMD * Detailed PMD performance metrics available with new command diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index c9ef4886e..acdf03a7b 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -444,6 +444,12 @@ struct netdev_dpdk { /* DPDK-ETH hardware offload features, * from the enum set 'dpdk_hw_ol_features' */ uint32_t hw_ol_features; + + /* Properties for link state change detection mode. + * If lsc_interrupt_mode is set to false, poll mode is used, + * otherwise interrupt mode is used. */ + bool requested_lsc_interrupt_mode; + bool lsc_interrupt_mode; ); PADDED_MEMBERS(CACHE_LINE_SIZE, @@ -765,7 +771,7 @@ dpdk_watchdog(void *dummy OVS_UNUSED) } static int -dpdk_eth_dev_queue_setup(struct netdev_dpdk *dev, int n_rxq, int n_txq) +dpdk_eth_dev_port_config(struct netdev_dpdk *dev, int n_rxq, int n_txq) { int diag = 0; int i; @@ -785,6 +791,7 @@ dpdk_eth_dev_queue_setup(struct netdev_dpdk *dev, int n_rxq, int n_txq) } } + conf.intr_conf.lsc = dev->lsc_interrupt_mode; conf.rxmode.hw_ip_checksum = (dev->hw_ol_features & NETDEV_RX_CHECKSUM_OFFLOAD) != 0; /* A device may report more queues than it makes available (this has @@ -888,10 +895,13 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) n_rxq = MIN(info.max_rx_queues, dev->up.n_rxq); n_txq = MIN(info.max_tx_queues, dev->up.n_txq); - diag = dpdk_eth_dev_queue_setup(dev, n_rxq, n_txq); + diag = dpdk_eth_dev_port_config(dev, n_rxq, n_txq); if (diag) { - VLOG_ERR("Interface %s(rxq:%d txq:%d) configure error: %s", - dev->up.name, n_rxq, n_txq, rte_strerror(-diag)); + VLOG_ERR("Interface %s(rxq:%d txq:%d lsc interrupt mode:%s) " + "configure error: %s", + dev->up.name, n_rxq, n_txq, + dev->lsc_interrupt_mode ? "true" : "false", + rte_strerror(-diag)); return -diag; } @@ -984,6 +994,7 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no, dev->flags = 0; dev->requested_mtu = ETHER_MTU; dev->max_packet_len = MTU_TO_FRAME_LEN(dev->mtu); + dev->requested_lsc_interrupt_mode = 0; ovsrcu_index_init(&dev->vid, -1); dev->vhost_reconfigured = false; dev->attached = false; @@ -1408,6 +1419,8 @@ netdev_dpdk_get_config(const struct netdev *netdev, struct smap *args) } else { smap_add(args, "rx_csum_offload", "false"); } + smap_add(args, "lsc_interrupt_mode", + dev->lsc_interrupt_mode ? "true" : "false"); } ovs_mutex_unlock(&dev->mutex); @@ -1531,7 +1544,7 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, char **errp) { struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); - bool rx_fc_en, tx_fc_en, autoneg; + bool rx_fc_en, tx_fc_en, autoneg, lsc_interrupt_mode; enum rte_eth_fc_mode fc_mode; static const enum rte_eth_fc_mode fc_mode_set[2][2] = { {RTE_FC_NONE, RTE_FC_TX_PAUSE}, @@ -1608,6 +1621,12 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, goto out; } + lsc_interrupt_mode = smap_get_bool(args, "dpdk-lsc-interrupt", false); + if (dev->requested_lsc_interrupt_mode != lsc_interrupt_mode) { + dev->requested_lsc_interrupt_mode = lsc_interrupt_mode; + netdev_request_reconfigure(netdev); + } + rx_fc_en = smap_get_bool(args, "rx-flow-ctrl", false); tx_fc_en = smap_get_bool(args, "tx-flow-ctrl", false); autoneg = smap_get_bool(args, "flow-ctrl-autoneg", false); @@ -3669,6 +3688,7 @@ netdev_dpdk_reconfigure(struct netdev *netdev) if (netdev->n_txq == dev->requested_n_txq && netdev->n_rxq == dev->requested_n_rxq && dev->mtu == dev->requested_mtu + && dev->lsc_interrupt_mode == dev->requested_lsc_interrupt_mode && dev->rxq_size == dev->requested_rxq_size && dev->txq_size == dev->requested_txq_size && dev->socket_id == dev->requested_socket_id) { @@ -3684,6 +3704,8 @@ netdev_dpdk_reconfigure(struct netdev *netdev) goto out; } + dev->lsc_interrupt_mode = dev->requested_lsc_interrupt_mode; + netdev->n_txq = dev->requested_n_txq; netdev->n_rxq = dev->requested_n_rxq; diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 185a40ab3..7ab90d570 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -3662,6 +3662,23 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \ + + +

+ Set this value to true to configure interrupt mode for + Link State Change (LSC) detection instead of poll mode for the DPDK + interface. +

+

+ If this value is not set, poll mode is configured. +

+

+ This parameter has an effect only on netdev dpdk interfaces. +

+
+
+ The overall purpose of these columns is described under Common Columns at the beginning of this document.