It is possible to change 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.
Global settings Service restart is necessary for the global settings to take effect. Command to set interrupt mode for all interfaces: ovs-vsctl set Open_vSwitch . other_config:dpdk-lsc-interrupt=true Command to set polling mode for all interfaces: ovs-vsctl set Open_vSwitch . other_config:dpdk-lsc-interrupt=false or: ovs-vsctl remove Open_vSwitch . other_config dpdk-lsc-interrupt Interface specific settings (override global settings) Service restart is not necessary to take effect. Command to set interrupt mode for a specific interface: ovs-vsctl set interface <interface_name> options:dpdk-lsc-interrupt=true Command to set polling mode for a specific interface: ovs-vsctl set interface <interface_name> options:dpdk-lsc-interrupt=false Command to reset to globally defined mode for a specific interface: ovs-vsctl remove interface <interface_name> options dpdk-lsc-interrupt Signed-off-by: Robert Mulik <[email protected]> --- lib/dpdk.c | 8 ++++++++ lib/netdev-dpdk.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- lib/netdev-dpdk.h | 9 +++++++++ vswitchd/vswitch.xml | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 1 deletion(-) diff --git a/lib/dpdk.c b/lib/dpdk.c index 6710d10..28687eb 100644 --- a/lib/dpdk.c +++ b/lib/dpdk.c @@ -351,6 +351,14 @@ dpdk_init__(const struct smap *ovs_other_config) VLOG_INFO("IOMMU support for vhost-user-client %s.", vhost_iommu_enabled ? "enabled" : "disabled"); + if (smap_get_bool(ovs_other_config, "dpdk-lsc-interrupt", false)) { + netdev_dpdk_set_default_lsc_detect_mode( + NETDEV_DPDK_LSC_DETECT_INTERRUPT_MODE); + } else { + netdev_dpdk_set_default_lsc_detect_mode( + NETDEV_DPDK_LSC_DETECT_POLL_MODE); + } + argv = grow_argv(&argv, 0, 1); argc = 1; argv[0] = xstrdup(ovs_get_program_name()); diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index e32c7f6..cb52222 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -148,7 +148,7 @@ typedef uint16_t dpdk_port_t; #define VHOST_ENQ_RETRY_NUM 8 #define IF_NAME_SZ (PATH_MAX > IFNAMSIZ ? PATH_MAX : IFNAMSIZ) -static const struct rte_eth_conf port_conf = { +static struct rte_eth_conf port_conf = { .rxmode = { .mq_mode = ETH_MQ_RX_RSS, .split_hdr_size = 0, @@ -167,6 +167,10 @@ static const struct rte_eth_conf port_conf = { .txmode = { .mq_mode = ETH_MQ_TX_NONE, }, + .intr_conf = { + /* LSC interrupt mode disabled, polling mode used. */ + .lsc = (uint16_t)NETDEV_DPDK_LSC_DETECT_POLL_MODE, + }, }; /* @@ -416,6 +420,9 @@ struct netdev_dpdk { int requested_n_rxq; int requested_rxq_size; int requested_txq_size; + enum netdev_dpdk_lsc_detect_mode requested_lsc_detect_mode; + + enum netdev_dpdk_lsc_detect_mode lsc_detect_mode; /* Number of rx/tx descriptors for physical devices */ int rxq_size; @@ -457,6 +464,19 @@ int netdev_dpdk_get_vid(const struct netdev_dpdk *dev); struct ingress_policer * netdev_dpdk_get_ingress_policer(const struct netdev_dpdk *dev); +void +netdev_dpdk_set_default_lsc_detect_mode( + enum netdev_dpdk_lsc_detect_mode default_lsc) +{ + port_conf.intr_conf.lsc = (uint16_t)default_lsc; +} + +enum netdev_dpdk_lsc_detect_mode +netdev_dpdk_get_default_lsc_detect_mode(void) +{ + return port_conf.intr_conf.lsc; +} + static bool is_dpdk_class(const struct netdev_class *class) { @@ -690,6 +710,8 @@ dpdk_eth_dev_queue_setup(struct netdev_dpdk *dev, int n_rxq, int n_txq) int i; struct rte_eth_conf conf = port_conf; + conf.intr_conf.lsc = dev->lsc_detect_mode; + /* For some NICs (e.g. Niantic), scatter_rx mode needs to be explicitly * enabled. */ if (dev->mtu > ETHER_MTU) { @@ -895,6 +917,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_detect_mode = netdev_dpdk_get_default_lsc_detect_mode(); ovsrcu_index_init(&dev->vid, -1); dev->vhost_reconfigured = false; dev->attached = false; @@ -1469,6 +1492,25 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args, "The old 'dpdk<port_id>' names are not supported", netdev_get_name(netdev)); err = EINVAL; + goto out; + } + + struct smap_node *node = smap_get_node(args, "dpdk-lsc-interrupt"); + uint16_t lsc; + + if (node) { + lsc = smap_get_bool(args, "dpdk-lsc-interrupt", false); + } else { + lsc = netdev_dpdk_get_default_lsc_detect_mode(); + } + if (lsc > NETDEV_DPDK_LSC_DETECT_MAX) { + VLOG_WARN("%s: invalid LSC value %d\n", dev->up.name, lsc); + err = EINVAL; + goto out; + } else if (dev->requested_lsc_detect_mode != + (enum netdev_dpdk_lsc_detect_mode)lsc) { + dev->requested_lsc_detect_mode = (enum netdev_dpdk_lsc_detect_mode)lsc; + netdev_request_reconfigure(netdev); } if (err) { @@ -3423,6 +3465,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_detect_mode == dev->requested_lsc_detect_mode && dev->rxq_size == dev->requested_rxq_size && dev->txq_size == dev->requested_txq_size && dev->socket_id == dev->requested_socket_id) { @@ -3438,6 +3481,8 @@ netdev_dpdk_reconfigure(struct netdev *netdev) goto out; } + dev->lsc_detect_mode = dev->requested_lsc_detect_mode; + netdev->n_txq = dev->requested_n_txq; netdev->n_rxq = dev->requested_n_rxq; diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h index b7d02a7..93fdd1d 100644 --- a/lib/netdev-dpdk.h +++ b/lib/netdev-dpdk.h @@ -25,8 +25,17 @@ struct dp_packet; #ifdef DPDK_NETDEV +enum netdev_dpdk_lsc_detect_mode { + NETDEV_DPDK_LSC_DETECT_POLL_MODE, + NETDEV_DPDK_LSC_DETECT_INTERRUPT_MODE, + NETDEV_DPDK_LSC_DETECT_MAX = NETDEV_DPDK_LSC_DETECT_INTERRUPT_MODE, +}; + void netdev_dpdk_register(void); void free_dpdk_buf(struct dp_packet *); +void netdev_dpdk_set_default_lsc_detect_mode( + enum netdev_dpdk_lsc_detect_mode default_lsc); +enum netdev_dpdk_lsc_detect_mode netdev_dpdk_get_default_lsc_detect_mode(void); #else diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index 58c0ebd..a4a0150 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -320,6 +320,30 @@ </p> </column> + <column name="other_config" key="dpdk-lsc-interrupt" + type='{"type": "boolean"}'> + <p> + Set this value to <code>true</code> to set interrupt mode for Link + State Change (LSC) detection instead of poll mode for DPDK + interfaces. + </p> + <p> + The default value is <code>false</code>. Changing this value requires + restarting the daemon + </p> + <p> + If this value is <code>false</code> at startup, poll mode is used for + all netdev dpdk interfaces. + </p> + <p> + This value can be overridden for a single interface in the options + section of that interface. + </p> + <p> + This parameter has any effect only on netdev dpdk interfaces. + </p> + </column> + <column name="other_config" key="dpdk-extra" type='{"type": "string"}'> <p> @@ -3593,6 +3617,28 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \ </column> </group> + <group title="Link State Change detection mode"> + <column name="options" key="dpdk-lsc-interrupt" + type='{"type": "boolean"}'> + <p> + Set this value to <code>true</code> to set interrupt mode for Link + State Change (LSC) detection instead of poll mode for the DPDK + interface. + </p> + <p> + If this value is not set, the value is taken from the global + settings. + </p> + <p> + If this value is set, the global LSC interrupt settings are + overridden. + </p> + <p> + This parameter has any effect only on netdev dpdk interfaces. + </p> + </column> + </group> + <group title="Common Columns"> The overall purpose of these columns is described under <code>Common Columns</code> at the beginning of this document. -- 1.9.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
