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.