Define a netdev_dpdk_common structure that is a 1:1 copy of netdev_dpdk at this point.
At this point of the changes, the "common" fields can be identified by looking at common_construct() content. Then move helpers that are not eth/vhost specific, and prefer accessing common fields with a common-> pointer. Signed-off-by: David Marchand <[email protected]> --- lib/automake.mk | 4 +- lib/netdev-dpdk-common.c | 159 +++++++ lib/netdev-dpdk-common.h | 228 +++++++++ lib/netdev-dpdk.c | 991 ++++++++++++++++++--------------------- 4 files changed, 859 insertions(+), 523 deletions(-) create mode 100644 lib/netdev-dpdk-common.c create mode 100644 lib/netdev-dpdk-common.h diff --git a/lib/automake.mk b/lib/automake.mk index 2dfca79da8..48b3288429 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -441,7 +441,9 @@ lib_libopenvswitch_la_SOURCES += \ lib/dpif-offload-dpdk.c \ lib/dpif-offload-dpdk-netdev.c \ lib/dpif-offload-dpdk-private.h \ - lib/netdev-dpdk.c + lib/netdev-dpdk.c \ + lib/netdev-dpdk-common.c \ + lib/netdev-dpdk-common.h else lib_libopenvswitch_la_SOURCES += \ lib/dpdk-stub.c diff --git a/lib/netdev-dpdk-common.c b/lib/netdev-dpdk-common.c new file mode 100644 index 0000000000..e58f4049ab --- /dev/null +++ b/lib/netdev-dpdk-common.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2014, 2015, 2016, 2017 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <config.h> + +#include "netdev-dpdk-common.h" +#include "netdev-provider.h" +#include "openvswitch/vlog.h" + +VLOG_DEFINE_THIS_MODULE(netdev_dpdk_common); + +void +netdev_dpdk_common_update_ol_flags(struct netdev_dpdk_common *common) +{ + const struct { + enum dpdk_hw_ol_features hw_ol_feature; + enum netdev_ol_flags flag; + } ol_flags_map[] = { + { NETDEV_TX_IPV4_CKSUM_OFFLOAD, NETDEV_TX_OFFLOAD_IPV4_CKSUM }, + { NETDEV_TX_TCP_CKSUM_OFFLOAD, NETDEV_TX_OFFLOAD_TCP_CKSUM }, + { NETDEV_TX_UDP_CKSUM_OFFLOAD, NETDEV_TX_OFFLOAD_UDP_CKSUM }, + { NETDEV_TX_SCTP_CKSUM_OFFLOAD, NETDEV_TX_OFFLOAD_SCTP_CKSUM }, + { NETDEV_TX_TSO_OFFLOAD, NETDEV_TX_OFFLOAD_TCP_TSO }, + { NETDEV_TX_VXLAN_TNL_TSO_OFFLOAD, NETDEV_TX_VXLAN_TNL_TSO }, + { NETDEV_TX_GRE_TNL_TSO_OFFLOAD, NETDEV_TX_GRE_TNL_TSO }, + { NETDEV_TX_GENEVE_TNL_TSO_OFFLOAD, NETDEV_TX_GENEVE_TNL_TSO }, + { NETDEV_TX_OUTER_IP_CKSUM_OFFLOAD, NETDEV_TX_OFFLOAD_OUTER_IP_CKSUM }, + { NETDEV_TX_OUTER_UDP_CKSUM_OFFLOAD, + NETDEV_TX_OFFLOAD_OUTER_UDP_CKSUM }, + }; + uint32_t hw_ol_features = common->hw_ol_features; + struct netdev *netdev = &common->up; + + for (unsigned int i = 0; i < ARRAY_SIZE(ol_flags_map); i++) { + if (hw_ol_features & ol_flags_map[i].hw_ol_feature) { + netdev->ol_flags |= ol_flags_map[i].flag; + } else { + netdev->ol_flags &= ~ol_flags_map[i].flag; + } + } +} + +int +netdev_dpdk_common_get_numa_id(const struct netdev *netdev) +{ + const struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); + + return common->socket_id; +} + +void +netdev_dpdk_common_get_etheraddr(const struct netdev_dpdk_common *common, + struct eth_addr *mac) +{ + *mac = common->hwaddr; +} + +void +netdev_dpdk_common_get_mtu(const struct netdev_dpdk_common *common, int *mtup) +{ + *mtup = common->mtu; +} + +int +netdev_dpdk_common_get_ifindex(const struct netdev_dpdk_common *common) +{ + const struct netdev *netdev = &common->up; + + /* Calculate hash from the netdev name. Ensure that ifindex is a 24-bit + * positive integer to meet RFC 2863 recommendations. + */ + return hash_string(netdev->name, 0) % 0xfffffe + 1; +} + +int +netdev_dpdk_common_set_mtu(struct netdev_dpdk_common *common, int mtu) +{ + struct netdev *netdev = &common->up; + + /* XXX: Ensure that the overall frame length of the requested MTU does not + * surpass the NETDEV_DPDK_MAX_PKT_LEN. DPDK device drivers differ in how + * the L2 frame length is calculated for a given MTU when + * rte_eth_dev_set_mtu(mtu) is called e.g. i40e driver includes 2 x vlan + * headers, the em driver includes 1 x vlan header, the ixgbe driver does + * not include vlan headers. As such we should use + * MTU_TO_MAX_FRAME_LEN(mtu) which includes an additional 2 x vlan headers + * (8 bytes) for comparison. This avoids a failure later with + * rte_eth_dev_set_mtu(). This approach should be used until DPDK provides + * a method to retrieve the upper bound MTU for a given device. + */ + if (MTU_TO_MAX_FRAME_LEN(mtu) > NETDEV_DPDK_MAX_PKT_LEN + || mtu < RTE_ETHER_MIN_MTU) { + VLOG_WARN("%s: unsupported MTU %d\n", netdev->name, mtu); + return EINVAL; + } + + if (common->requested_mtu != mtu) { + common->requested_mtu = mtu; + netdev_request_reconfigure(netdev); + } + + return 0; +} + +void +netdev_dpdk_common_get_sw_custom_stats(struct netdev_dpdk_common *common, + struct netdev_custom_stats *stats) +{ + int i, n; + +#define SW_CSTATS \ + SW_CSTAT(tx_retries) \ + SW_CSTAT(tx_failure_drops) \ + SW_CSTAT(tx_mtu_exceeded_drops) \ + SW_CSTAT(tx_qos_drops) \ + SW_CSTAT(rx_qos_drops) \ + SW_CSTAT(tx_invalid_hwol_drops) + +#define SW_CSTAT(NAME) + 1 + stats->size = SW_CSTATS; +#undef SW_CSTAT + stats->counters = xcalloc(stats->size, sizeof *stats->counters); + + rte_spinlock_lock(&common->stats_lock); + i = 0; +#define SW_CSTAT(NAME) \ + stats->counters[i++].value = common->sw_stats->NAME; + SW_CSTATS; +#undef SW_CSTAT + rte_spinlock_unlock(&common->stats_lock); + + i = 0; + n = 0; +#define SW_CSTAT(NAME) \ + if (stats->counters[i].value != UINT64_MAX) { \ + ovs_strlcpy(stats->counters[n].name, \ + "ovs_"#NAME, NETDEV_CUSTOM_STATS_NAME_SIZE); \ + stats->counters[n].value = stats->counters[i].value; \ + n++; \ + } \ + i++; + SW_CSTATS; +#undef SW_CSTAT + + stats->size = n; +} diff --git a/lib/netdev-dpdk-common.h b/lib/netdev-dpdk-common.h new file mode 100644 index 0000000000..3e25558eb5 --- /dev/null +++ b/lib/netdev-dpdk-common.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2014, 2015, 2016, 2017 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NETDEV_DPDK_COMMON_H +#define NETDEV_DPDK_COMMON_H + +#include <config.h> + +#include <stdbool.h> +#include <stdint.h> + +#include <rte_ether.h> +#include <rte_ethdev.h> + +#include "netdev-provider.h" +#include "openvswitch/compiler.h" +#include "ovs-thread.h" + +struct dpdk_tx_queue; +struct ingress_policer; +struct qos_conf; + +#define ETHER_HDR_MAX_LEN (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN \ + + (2 * VLAN_HEADER_LEN)) +#define MTU_TO_MAX_FRAME_LEN(mtu) ((mtu) + ETHER_HDR_MAX_LEN) +#define NETDEV_DPDK_MAX_PKT_LEN 9728 + +/* Custom software stats for dpdk ports */ +struct netdev_dpdk_sw_stats { + /* No. of retries when unable to transmit. */ + uint64_t tx_retries; + /* Packet drops when unable to transmit; Probably Tx queue is full. */ + uint64_t tx_failure_drops; + /* Packet length greater than device MTU. */ + uint64_t tx_mtu_exceeded_drops; + /* Packet drops in egress policer processing. */ + uint64_t tx_qos_drops; + /* Packet drops in ingress policer processing. */ + uint64_t rx_qos_drops; + /* Packet drops in HWOL processing. */ + uint64_t tx_invalid_hwol_drops; +}; + +struct netdev_dpdk_common { + PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline0, + uint16_t port_id; + + /* If true, device was attached by rte_eth_dev_attach(). */ + bool attached; + /* If true, rte_eth_dev_start() was successfully called. */ + bool started; + /* If true, this is a port representor. */ + bool is_representor; + struct eth_addr hwaddr; + /* 1 pad bytes here. */ + int mtu; + int socket_id; + int buf_size; + int max_packet_len; + enum netdev_flags flags; + int link_reset_cnt; + union { + /* Device arguments for dpdk ports. */ + char *devargs; + /* Identifier used to distinguish vhost devices from each other. */ + char *vhost_id; + }; + struct dpdk_tx_queue *tx_q; + struct rte_eth_link link; + ); + + PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline1, + struct ovs_mutex mutex; + struct dpdk_mp *dpdk_mp; + + /* virtio identifier for vhost devices */ + ovsrcu_index vid; + + /* True if vHost device is 'up' and has been reconfigured at least + * once */ + bool vhost_reconfigured; + + atomic_uint8_t vhost_tx_retries_max; + + /* Flags for virtio features recovery mechanism. */ + uint8_t virtio_features_state; + + /* 1 pad byte here. */ + ); + + PADDED_MEMBERS(CACHE_LINE_SIZE, + struct netdev up; + struct ovs_list list_node; + + /* QoS configuration and lock for the device */ + OVSRCU_TYPE(struct qos_conf *) qos_conf; + + /* Ingress Policer */ + OVSRCU_TYPE(struct ingress_policer *) ingress_policer; + uint32_t policer_rate; + uint32_t policer_burst; + + /* Array of vhost rxq states, see vring_state_changed. */ + bool *vhost_rxq_enabled; + + /* Ensures that Rx metadata delivery is configured only once. */ + bool rx_metadata_delivery_configured; + ); + + PADDED_MEMBERS(CACHE_LINE_SIZE, + struct netdev_stats stats; + struct netdev_dpdk_sw_stats *sw_stats; + /* Protects stats */ + rte_spinlock_t stats_lock; + /* 36 pad bytes here. */ + ); + + PADDED_MEMBERS(CACHE_LINE_SIZE, + /* The following properties cannot be changed when a device is running, + * so we remember the request and update them next time + * netdev_dpdk*_reconfigure() is called */ + int requested_mtu; + int requested_n_txq; + /* User input for n_rxq (see dpdk_set_rxq_config). */ + int user_n_rxq; + /* user_n_rxq + an optional rx steering queue (see + * netdev_dpdk_reconfigure). This field is different from the other + * requested_* fields as it may contain a different value than the user + * input. */ + int requested_n_rxq; + int requested_rxq_size; + int requested_txq_size; + + /* Number of rx/tx descriptors for physical devices */ + int rxq_size; + int txq_size; + + /* Socket ID detected when vHost device is brought up */ + int requested_socket_id; + + /* Ignored by DPDK for vhost-user backends, only for VDUSE. */ + uint8_t vhost_max_queue_pairs; + + /* Denotes whether vHost port is client/server mode */ + uint64_t vhost_driver_flags; + + /* DPDK-ETH Flow control */ + struct rte_eth_fc_conf fc_conf; + + /* 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; + + /* VF configuration. */ + struct eth_addr requested_hwaddr; + + /* Requested rx queue steering flags, + * from the enum set 'dpdk_rx_steer_flags'. */ + uint64_t requested_rx_steer_flags; + uint64_t rx_steer_flags; + size_t rx_steer_flows_num; + struct rte_flow **rx_steer_flows; + ); + + PADDED_MEMBERS(CACHE_LINE_SIZE, + /* Names of all XSTATS counters */ + struct rte_eth_xstat_name *rte_xstats_names; + int rte_xstats_names_size; + int rte_xstats_ids_size; + uint64_t *rte_xstats_ids; + ); +}; + +static inline struct netdev_dpdk_common * +netdev_dpdk_common_cast(const struct netdev *netdev) +{ + return CONTAINER_OF(netdev, struct netdev_dpdk_common, up); +} + +enum dpdk_hw_ol_features { + NETDEV_RX_CHECKSUM_OFFLOAD = 1 << 0, + NETDEV_RX_HW_CRC_STRIP = 1 << 1, + NETDEV_RX_HW_SCATTER = 1 << 2, + NETDEV_TX_IPV4_CKSUM_OFFLOAD = 1 << 3, + NETDEV_TX_TCP_CKSUM_OFFLOAD = 1 << 4, + NETDEV_TX_UDP_CKSUM_OFFLOAD = 1 << 5, + NETDEV_TX_SCTP_CKSUM_OFFLOAD = 1 << 6, + NETDEV_TX_TSO_OFFLOAD = 1 << 7, + NETDEV_TX_VXLAN_TNL_TSO_OFFLOAD = 1 << 8, + NETDEV_TX_GENEVE_TNL_TSO_OFFLOAD = 1 << 9, + NETDEV_TX_OUTER_IP_CKSUM_OFFLOAD = 1 << 10, + NETDEV_TX_OUTER_UDP_CKSUM_OFFLOAD = 1 << 11, + NETDEV_TX_GRE_TNL_TSO_OFFLOAD = 1 << 12, +}; + +void netdev_dpdk_common_update_ol_flags(struct netdev_dpdk_common *common); + +int netdev_dpdk_common_get_numa_id(const struct netdev *netdev); +void netdev_dpdk_common_get_etheraddr(const struct netdev_dpdk_common *common, + struct eth_addr *mac); +void netdev_dpdk_common_get_mtu(const struct netdev_dpdk_common *common, + int *mtup); +int netdev_dpdk_common_get_ifindex(const struct netdev_dpdk_common *common); +int netdev_dpdk_common_set_mtu(struct netdev_dpdk_common *common, int mtu); +void +netdev_dpdk_common_get_sw_custom_stats(struct netdev_dpdk_common *common, + struct netdev_custom_stats *stats); + +#endif /* NETDEV_DPDK_COMMON_H */ diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index b63d6fa5d6..d6ba8f534c 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -52,6 +52,7 @@ #include "fatal-signal.h" #include "if-notifier.h" #include "mpsc-queue.h" +#include "netdev-dpdk-common.h" #include "netdev-provider.h" #include "netdev-vport.h" #include "odp-util.h" @@ -100,15 +101,11 @@ static bool per_port_memory = false; /* Status of per port memory support */ * The minimum mbuf size is limited to avoid scatter behaviour and drop in * performance for standard Ethernet MTU. */ -#define ETHER_HDR_MAX_LEN (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN \ - + (2 * VLAN_HEADER_LEN)) #define MTU_TO_FRAME_LEN(mtu) ((mtu) + RTE_ETHER_HDR_LEN + \ RTE_ETHER_CRC_LEN) -#define MTU_TO_MAX_FRAME_LEN(mtu) ((mtu) + ETHER_HDR_MAX_LEN) #define FRAME_LEN_TO_MTU(frame_len) ((frame_len) \ - RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN) #define NETDEV_DPDK_MBUF_ALIGN 1024 -#define NETDEV_DPDK_MAX_PKT_LEN 9728 /* Max and min number of packets in the mempool. OVS tries to allocate a * mempool with MAX_NB_MBUF: if this fails (because the system doesn't have @@ -194,22 +191,6 @@ static const struct rte_vhost_device_ops virtio_net_device_ops = .destroy_connection = destroy_connection, }; -/* Custom software stats for dpdk ports */ -struct netdev_dpdk_sw_stats { - /* No. of retries when unable to transmit. */ - uint64_t tx_retries; - /* Packet drops when unable to transmit; Probably Tx queue is full. */ - uint64_t tx_failure_drops; - /* Packet length greater than device MTU. */ - uint64_t tx_mtu_exceeded_drops; - /* Packet drops in egress policer processing. */ - uint64_t tx_qos_drops; - /* Packet drops in ingress policer processing. */ - uint64_t rx_qos_drops; - /* Packet drops in HWOL processing. */ - uint64_t tx_invalid_hwol_drops; -}; - /* Quality of Service */ /* An instance of a QoS configuration. Always associated with a particular @@ -397,22 +378,6 @@ struct ingress_policer { rte_spinlock_t policer_lock; }; -enum dpdk_hw_ol_features { - NETDEV_RX_CHECKSUM_OFFLOAD = 1 << 0, - NETDEV_RX_HW_CRC_STRIP = 1 << 1, - NETDEV_RX_HW_SCATTER = 1 << 2, - NETDEV_TX_IPV4_CKSUM_OFFLOAD = 1 << 3, - NETDEV_TX_TCP_CKSUM_OFFLOAD = 1 << 4, - NETDEV_TX_UDP_CKSUM_OFFLOAD = 1 << 5, - NETDEV_TX_SCTP_CKSUM_OFFLOAD = 1 << 6, - NETDEV_TX_TSO_OFFLOAD = 1 << 7, - NETDEV_TX_VXLAN_TNL_TSO_OFFLOAD = 1 << 8, - NETDEV_TX_GENEVE_TNL_TSO_OFFLOAD = 1 << 9, - NETDEV_TX_OUTER_IP_CKSUM_OFFLOAD = 1 << 10, - NETDEV_TX_OUTER_UDP_CKSUM_OFFLOAD = 1 << 11, - NETDEV_TX_GRE_TNL_TSO_OFFLOAD = 1 << 12, -}; - enum dpdk_rx_steer_flags { DPDK_RX_STEER_LACP = 1 << 0, }; @@ -433,16 +398,18 @@ enum dpdk_rx_steer_flags { * In order to avoid confusion in variables names, following naming convention * should be used, if possible: * - * 'struct netdev' : 'netdev' - * 'struct netdev_dpdk' : 'dev' - * 'struct netdev_rxq' : 'rxq' - * 'struct netdev_rxq_dpdk' : 'rx' + * 'struct netdev' : 'netdev' + * 'struct netdev_dpdk_common': 'common' + * 'struct netdev_dpdk_eth' : 'dev' + * 'struct netdev_dpdk_vhost' : 'dev' + * 'struct netdev_rxq' : 'rxq' + * 'struct netdev_rxq_dpdk' : 'rx' * * Example: * struct netdev *netdev = netdev_from_name(name); * struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); * - * Also, 'netdev' should be used instead of 'dev->up', where 'netdev' was + * Also, 'netdev' should be used instead of 'common->up', where 'netdev' was * already defined. */ @@ -591,8 +558,6 @@ static const struct netdev_class netdev_dpdk_class; static const struct netdev_class netdev_dpdk_vhost_class; static const struct netdev_class netdev_dpdk_vhost_client_class; -static int netdev_dpdk_get_sw_custom_stats(const struct netdev *, - struct netdev_custom_stats *); static void netdev_dpdk_configure_xstats(struct netdev_dpdk *dev); static void netdev_dpdk_clear_xstats(struct netdev_dpdk *dev); @@ -978,9 +943,8 @@ dpdk_mp_put(struct dpdk_mp *dmp) * requested_mtu. On success, a new configuration will be applied. * On error, device will be left unchanged. */ static int -netdev_dpdk_mempool_configure(struct netdev_dpdk *dev, +netdev_dpdk_mempool_configure(struct netdev_dpdk_common *common, struct dpdk_mp_config *cfg) - OVS_REQUIRES(dev->mutex) { struct dpdk_mp *dmp; int ret = 0; @@ -988,8 +952,8 @@ netdev_dpdk_mempool_configure(struct netdev_dpdk *dev, /* With shared memory we do not need to configure a mempool if the MTU * and socket ID have not changed, the previous configuration is still * valid so return 0 */ - if (!per_port_memory && dev->mtu == cfg->mtu - && dev->socket_id == cfg->socket_id) { + if (!per_port_memory && common->mtu == cfg->mtu + && common->socket_id == cfg->socket_id) { return ret; } @@ -997,14 +961,14 @@ netdev_dpdk_mempool_configure(struct netdev_dpdk *dev, if (!dmp) { VLOG_ERR("Failed to create memory pool for netdev " "%s, with MTU %d on socket %d: %s\n", - dev->up.name, cfg->mtu, cfg->socket_id, + common->up.name, cfg->mtu, cfg->socket_id, rte_strerror(rte_errno)); ret = rte_errno; } else { /* Check for any pre-existing dpdk_mp for the device before accessing * the associated mempool. */ - if (dev->dpdk_mp != NULL) { + if (common->dpdk_mp != NULL) { /* A new MTU was requested, decrement the reference count for the * devices current dpdk_mp. This is required even if a pointer to * same dpdk_mp is returned by dpdk_mp_get. The refcount for dmp @@ -1012,12 +976,12 @@ netdev_dpdk_mempool_configure(struct netdev_dpdk *dev, * must be decremented to keep an accurate refcount for the * dpdk_mp. */ - dpdk_mp_put(dev->dpdk_mp); + dpdk_mp_put(common->dpdk_mp); } - dev->dpdk_mp = dmp; - dev->mtu = cfg->mtu; - dev->socket_id = cfg->socket_id; - dev->max_packet_len = MTU_TO_FRAME_LEN(dev->mtu); + common->dpdk_mp = dmp; + common->mtu = cfg->mtu; + common->socket_id = cfg->socket_id; + common->max_packet_len = MTU_TO_FRAME_LEN(common->mtu); } return ret; @@ -1076,53 +1040,14 @@ dpdk_watchdog(void *dummy OVS_UNUSED) return NULL; } -static void -netdev_dpdk_update_netdev_flag(struct netdev_dpdk *dev, - enum dpdk_hw_ol_features hw_ol_features, - enum netdev_ol_flags flag) - OVS_REQUIRES(dev->mutex) -{ - struct netdev *netdev = &dev->up; - - if (dev->hw_ol_features & hw_ol_features) { - netdev->ol_flags |= flag; - } else { - netdev->ol_flags &= ~flag; - } -} - -static void -netdev_dpdk_update_netdev_flags(struct netdev_dpdk *dev) - OVS_REQUIRES(dev->mutex) -{ - netdev_dpdk_update_netdev_flag(dev, NETDEV_TX_IPV4_CKSUM_OFFLOAD, - NETDEV_TX_OFFLOAD_IPV4_CKSUM); - netdev_dpdk_update_netdev_flag(dev, NETDEV_TX_TCP_CKSUM_OFFLOAD, - NETDEV_TX_OFFLOAD_TCP_CKSUM); - netdev_dpdk_update_netdev_flag(dev, NETDEV_TX_UDP_CKSUM_OFFLOAD, - NETDEV_TX_OFFLOAD_UDP_CKSUM); - netdev_dpdk_update_netdev_flag(dev, NETDEV_TX_SCTP_CKSUM_OFFLOAD, - NETDEV_TX_OFFLOAD_SCTP_CKSUM); - netdev_dpdk_update_netdev_flag(dev, NETDEV_TX_TSO_OFFLOAD, - NETDEV_TX_OFFLOAD_TCP_TSO); - netdev_dpdk_update_netdev_flag(dev, NETDEV_TX_VXLAN_TNL_TSO_OFFLOAD, - NETDEV_TX_VXLAN_TNL_TSO); - netdev_dpdk_update_netdev_flag(dev, NETDEV_TX_GRE_TNL_TSO_OFFLOAD, - NETDEV_TX_GRE_TNL_TSO); - netdev_dpdk_update_netdev_flag(dev, NETDEV_TX_GENEVE_TNL_TSO_OFFLOAD, - NETDEV_TX_GENEVE_TNL_TSO); - netdev_dpdk_update_netdev_flag(dev, NETDEV_TX_OUTER_IP_CKSUM_OFFLOAD, - NETDEV_TX_OFFLOAD_OUTER_IP_CKSUM); - netdev_dpdk_update_netdev_flag(dev, NETDEV_TX_OUTER_UDP_CKSUM_OFFLOAD, - NETDEV_TX_OFFLOAD_OUTER_UDP_CKSUM); -} - static int dpdk_eth_dev_port_config(struct netdev_dpdk *dev, const struct rte_eth_dev_info *info, int n_rxq, int n_txq) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); struct rte_eth_conf conf = port_conf; + struct netdev *netdev = &common->up; uint16_t conf_mtu; int diag = 0; int i; @@ -1131,60 +1056,60 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, * scatter to support jumbo RX. * Setting scatter for the device is done after checking for * scatter support in the device capabilites. */ - if (dev->mtu > RTE_ETHER_MTU) { - if (dev->hw_ol_features & NETDEV_RX_HW_SCATTER) { + if (common->mtu > RTE_ETHER_MTU) { + if (common->hw_ol_features & NETDEV_RX_HW_SCATTER) { conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_SCATTER; } } conf.intr_conf.lsc = dev->lsc_interrupt_mode; - if (dev->hw_ol_features & NETDEV_RX_CHECKSUM_OFFLOAD) { + if (common->hw_ol_features & NETDEV_RX_CHECKSUM_OFFLOAD) { conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_CHECKSUM; } - if (!(dev->hw_ol_features & NETDEV_RX_HW_CRC_STRIP) + if (!(common->hw_ol_features & NETDEV_RX_HW_CRC_STRIP) && info->rx_offload_capa & RTE_ETH_RX_OFFLOAD_KEEP_CRC) { conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_KEEP_CRC; } - if (dev->hw_ol_features & NETDEV_TX_IPV4_CKSUM_OFFLOAD) { + if (common->hw_ol_features & NETDEV_TX_IPV4_CKSUM_OFFLOAD) { conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM; } - if (dev->hw_ol_features & NETDEV_TX_TCP_CKSUM_OFFLOAD) { + if (common->hw_ol_features & NETDEV_TX_TCP_CKSUM_OFFLOAD) { conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_TCP_CKSUM; } - if (dev->hw_ol_features & NETDEV_TX_UDP_CKSUM_OFFLOAD) { + if (common->hw_ol_features & NETDEV_TX_UDP_CKSUM_OFFLOAD) { conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_UDP_CKSUM; } - if (dev->hw_ol_features & NETDEV_TX_SCTP_CKSUM_OFFLOAD) { + if (common->hw_ol_features & NETDEV_TX_SCTP_CKSUM_OFFLOAD) { conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_SCTP_CKSUM; } - if (dev->hw_ol_features & NETDEV_TX_TSO_OFFLOAD) { + if (common->hw_ol_features & NETDEV_TX_TSO_OFFLOAD) { conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO; } - if (dev->hw_ol_features & NETDEV_TX_VXLAN_TNL_TSO_OFFLOAD) { + if (common->hw_ol_features & NETDEV_TX_VXLAN_TNL_TSO_OFFLOAD) { conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO; } - if (dev->hw_ol_features & NETDEV_TX_GENEVE_TNL_TSO_OFFLOAD) { + if (common->hw_ol_features & NETDEV_TX_GENEVE_TNL_TSO_OFFLOAD) { conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO; } - if (dev->hw_ol_features & NETDEV_TX_GRE_TNL_TSO_OFFLOAD) { + if (common->hw_ol_features & NETDEV_TX_GRE_TNL_TSO_OFFLOAD) { conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO; } - if (dev->hw_ol_features & NETDEV_TX_OUTER_IP_CKSUM_OFFLOAD) { + if (common->hw_ol_features & NETDEV_TX_OUTER_IP_CKSUM_OFFLOAD) { conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM; } - if (dev->hw_ol_features & NETDEV_TX_OUTER_UDP_CKSUM_OFFLOAD) { + if (common->hw_ol_features & NETDEV_TX_OUTER_UDP_CKSUM_OFFLOAD) { conf.txmode.offloads |= RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM; } @@ -1210,11 +1135,11 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, diag = rte_eth_dev_configure(dev->port_id, n_rxq, n_txq, &conf); if (diag) { VLOG_WARN("Interface %s eth_dev setup error %s\n", - dev->up.name, rte_strerror(-diag)); + netdev->name, rte_strerror(-diag)); break; } - diag = rte_eth_dev_set_mtu(dev->port_id, dev->mtu); + diag = rte_eth_dev_set_mtu(dev->port_id, common->mtu); if (diag) { /* A device may not support rte_eth_dev_set_mtu, in this case * flag a warning to the user and include the devices configured @@ -1223,20 +1148,20 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, rte_eth_dev_get_mtu(dev->port_id, &conf_mtu); VLOG_WARN("Interface %s does not support MTU configuration, " "max packet size supported is %"PRIu16".", - dev->up.name, conf_mtu); + netdev->name, conf_mtu); } else { VLOG_ERR("Interface %s MTU (%d) setup error: %s", - dev->up.name, dev->mtu, rte_strerror(-diag)); + netdev->name, common->mtu, rte_strerror(-diag)); break; } } for (i = 0; i < n_txq; i++) { diag = rte_eth_tx_queue_setup(dev->port_id, i, dev->txq_size, - dev->socket_id, NULL); + common->socket_id, NULL); if (diag) { VLOG_INFO("Interface %s unable to setup txq(%d): %s", - dev->up.name, i, rte_strerror(-diag)); + netdev->name, i, rte_strerror(-diag)); break; } } @@ -1249,11 +1174,11 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, for (i = 0; i < n_rxq; i++) { diag = rte_eth_rx_queue_setup(dev->port_id, i, dev->rxq_size, - dev->socket_id, NULL, - dev->dpdk_mp->mp); + common->socket_id, NULL, + common->dpdk_mp->mp); if (diag) { VLOG_INFO("Interface %s unable to setup rxq(%d): %s", - dev->up.name, i, rte_strerror(-diag)); + netdev->name, i, rte_strerror(-diag)); break; } } @@ -1264,8 +1189,8 @@ dpdk_eth_dev_port_config(struct netdev_dpdk *dev, continue; } - dev->up.n_rxq = n_rxq; - dev->up.n_txq = n_txq; + netdev->n_rxq = n_rxq; + netdev->n_txq = n_txq; return 0; } @@ -1285,6 +1210,7 @@ dpdk_eth_flow_ctrl_setup(struct netdev_dpdk *dev) OVS_REQUIRES(dev->mutex) static void dpdk_eth_dev_init_rx_metadata(struct netdev_dpdk *dev) { + struct netdev *netdev = &dev->up; uint64_t rx_metadata = 0; int ret; @@ -1299,12 +1225,12 @@ dpdk_eth_dev_init_rx_metadata(struct netdev_dpdk *dev) if (ret == 0) { if (!(rx_metadata & RTE_ETH_RX_METADATA_USER_MARK)) { VLOG_DBG("%s: The NIC will not provide per-packet USER_MARK", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); } } else { VLOG(ret == -ENOTSUP ? VLL_DBG : VLL_WARN, "%s: Cannot negotiate Rx metadata: %s", - netdev_get_name(&dev->up), rte_strerror(-ret)); + netdev_get_name(netdev), rte_strerror(-ret)); } dev->rx_metadata_delivery_configured = true; @@ -1314,7 +1240,9 @@ static int dpdk_eth_dev_init(struct netdev_dpdk *dev) OVS_REQUIRES(dev->mutex) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); struct rte_pktmbuf_pool_private *mbp_priv; + struct netdev *netdev = &common->up; struct rte_eth_dev_info info; struct rte_ether_addr eth_addr; int diag; @@ -1338,7 +1266,7 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) diag = rte_eth_dev_info_get(dev->port_id, &info); if (diag < 0) { VLOG_ERR("Interface %s rte_eth_dev_info_get error: %s", - dev->up.name, rte_strerror(-diag)); + netdev->name, rte_strerror(-diag)); return -diag; } @@ -1346,102 +1274,102 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) if (strstr(info.driver_name, "vf") != NULL) { VLOG_INFO("Virtual function detected, HW_CRC_STRIP will be enabled"); - dev->hw_ol_features |= NETDEV_RX_HW_CRC_STRIP; + common->hw_ol_features |= NETDEV_RX_HW_CRC_STRIP; } else { - dev->hw_ol_features &= ~NETDEV_RX_HW_CRC_STRIP; + common->hw_ol_features &= ~NETDEV_RX_HW_CRC_STRIP; } if ((info.rx_offload_capa & rx_chksm_offload_capa) != rx_chksm_offload_capa) { VLOG_WARN("Rx checksum offload is not supported on port " DPDK_PORT_ID_FMT, dev->port_id); - dev->hw_ol_features &= ~NETDEV_RX_CHECKSUM_OFFLOAD; + common->hw_ol_features &= ~NETDEV_RX_CHECKSUM_OFFLOAD; } else { - dev->hw_ol_features |= NETDEV_RX_CHECKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_RX_CHECKSUM_OFFLOAD; } if (info.rx_offload_capa & RTE_ETH_RX_OFFLOAD_SCATTER) { - dev->hw_ol_features |= NETDEV_RX_HW_SCATTER; + common->hw_ol_features |= NETDEV_RX_HW_SCATTER; } else { /* Do not warn on lack of scatter support */ - dev->hw_ol_features &= ~NETDEV_RX_HW_SCATTER; + common->hw_ol_features &= ~NETDEV_RX_HW_SCATTER; } if (info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) { - dev->hw_ol_features |= NETDEV_TX_IPV4_CKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_IPV4_CKSUM_OFFLOAD; } else { - dev->hw_ol_features &= ~NETDEV_TX_IPV4_CKSUM_OFFLOAD; + common->hw_ol_features &= ~NETDEV_TX_IPV4_CKSUM_OFFLOAD; } if (info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) { - dev->hw_ol_features |= NETDEV_TX_TCP_CKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_TCP_CKSUM_OFFLOAD; } else { - dev->hw_ol_features &= ~NETDEV_TX_TCP_CKSUM_OFFLOAD; + common->hw_ol_features &= ~NETDEV_TX_TCP_CKSUM_OFFLOAD; } if (info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) { - dev->hw_ol_features |= NETDEV_TX_UDP_CKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_UDP_CKSUM_OFFLOAD; } else { - dev->hw_ol_features &= ~NETDEV_TX_UDP_CKSUM_OFFLOAD; + common->hw_ol_features &= ~NETDEV_TX_UDP_CKSUM_OFFLOAD; } if (info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_SCTP_CKSUM) { - dev->hw_ol_features |= NETDEV_TX_SCTP_CKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_SCTP_CKSUM_OFFLOAD; } else { - dev->hw_ol_features &= ~NETDEV_TX_SCTP_CKSUM_OFFLOAD; + common->hw_ol_features &= ~NETDEV_TX_SCTP_CKSUM_OFFLOAD; } if (info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM) { - dev->hw_ol_features |= NETDEV_TX_OUTER_IP_CKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_OUTER_IP_CKSUM_OFFLOAD; } else { - dev->hw_ol_features &= ~NETDEV_TX_OUTER_IP_CKSUM_OFFLOAD; + common->hw_ol_features &= ~NETDEV_TX_OUTER_IP_CKSUM_OFFLOAD; } if (info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM) { - dev->hw_ol_features |= NETDEV_TX_OUTER_UDP_CKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_OUTER_UDP_CKSUM_OFFLOAD; } else { - dev->hw_ol_features &= ~NETDEV_TX_OUTER_UDP_CKSUM_OFFLOAD; + common->hw_ol_features &= ~NETDEV_TX_OUTER_UDP_CKSUM_OFFLOAD; } - dev->hw_ol_features &= ~NETDEV_TX_TSO_OFFLOAD; + common->hw_ol_features &= ~NETDEV_TX_TSO_OFFLOAD; if (userspace_tso_enabled()) { if (info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_TCP_TSO) { - dev->hw_ol_features |= NETDEV_TX_TSO_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_TSO_OFFLOAD; } else { VLOG_WARN("%s: Tx TSO offload is not supported.", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); } if (info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO) { - dev->hw_ol_features |= NETDEV_TX_VXLAN_TNL_TSO_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_VXLAN_TNL_TSO_OFFLOAD; } else { VLOG_WARN("%s: Tx Vxlan tunnel TSO offload is not supported.", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); } if (info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO) { - dev->hw_ol_features |= NETDEV_TX_GENEVE_TNL_TSO_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_GENEVE_TNL_TSO_OFFLOAD; } else { VLOG_WARN("%s: Tx Geneve tunnel TSO offload is not supported.", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); } if (info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO) { - dev->hw_ol_features |= NETDEV_TX_GRE_TNL_TSO_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_GRE_TNL_TSO_OFFLOAD; } else { VLOG_WARN("%s: Tx GRE tunnel TSO offload is not supported.", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); } } - n_rxq = MIN(info.max_rx_queues, dev->up.n_rxq); - n_txq = MIN(info.max_tx_queues, dev->up.n_txq); + n_rxq = MIN(info.max_rx_queues, netdev->n_rxq); + n_txq = MIN(info.max_tx_queues, netdev->n_txq); diag = dpdk_eth_dev_port_config(dev, &info, n_rxq, n_txq); if (diag) { VLOG_ERR("Interface %s(rxq:%d txq:%d lsc interrupt mode:%s) " "configure error: %s", - dev->up.name, n_rxq, n_txq, + netdev->name, n_rxq, n_txq, dev->lsc_interrupt_mode ? "true" : "false", rte_strerror(-diag)); return -diag; @@ -1449,7 +1377,7 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) diag = rte_eth_dev_start(dev->port_id); if (diag) { - VLOG_ERR("Interface %s start error: %s", dev->up.name, + VLOG_ERR("Interface %s start error: %s", netdev->name, rte_strerror(-diag)); return -diag; } @@ -1465,13 +1393,13 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) VLOG_INFO_RL(&rl, "Port "DPDK_PORT_ID_FMT": "ETH_ADDR_FMT, dev->port_id, ETH_ADDR_BYTES_ARGS(eth_addr.addr_bytes)); - memcpy(dev->hwaddr.ea, eth_addr.addr_bytes, ETH_ADDR_LEN); + memcpy(common->hwaddr.ea, eth_addr.addr_bytes, ETH_ADDR_LEN); if (rte_eth_link_get_nowait(dev->port_id, &dev->link) < 0) { memset(&dev->link, 0, sizeof dev->link); } - mbp_priv = rte_mempool_get_priv(dev->dpdk_mp->mp); - dev->buf_size = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM; + mbp_priv = rte_mempool_get_priv(common->dpdk_mp->mp); + common->buf_size = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM; return 0; } @@ -1524,50 +1452,51 @@ netdev_dpdk_vhost_alloc(void) } static void -common_construct(struct netdev *netdev, int socket_id) +common_construct(struct netdev_dpdk_common *common, int socket_id) OVS_REQUIRES(dpdk_mutex) { - struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + struct netdev *netdev = &common->up; - ovs_mutex_init(&dev->mutex); + ovs_mutex_init(&common->mutex); - rte_spinlock_init(&dev->stats_lock); + rte_spinlock_init(&common->stats_lock); /* If the 'sid' is negative, it means that the kernel fails * to obtain the pci numa info. In that situation, always * use 'SOCKET0'. */ - dev->socket_id = socket_id < 0 ? SOCKET0 : socket_id; - dev->requested_socket_id = dev->socket_id; - dev->requested_mtu = RTE_ETHER_MTU; - dev->max_packet_len = MTU_TO_FRAME_LEN(dev->mtu); + common->socket_id = socket_id < 0 ? SOCKET0 : socket_id; + common->requested_socket_id = common->socket_id; + common->requested_mtu = RTE_ETHER_MTU; + common->max_packet_len = MTU_TO_FRAME_LEN(common->mtu); - ovsrcu_init(&dev->qos_conf, NULL); + ovsrcu_init(&common->qos_conf, NULL); - ovsrcu_init(&dev->ingress_policer, NULL); - dev->policer_rate = 0; - dev->policer_burst = 0; + ovsrcu_init(&common->ingress_policer, NULL); + common->policer_rate = 0; + common->policer_burst = 0; netdev->n_rxq = 0; netdev->n_txq = 0; - dev->requested_n_rxq = NR_QUEUE; - dev->requested_n_txq = NR_QUEUE; + common->requested_n_rxq = NR_QUEUE; + common->requested_n_txq = NR_QUEUE; /* Initilize the hardware offload flags to 0 */ - dev->hw_ol_features = 0; + common->hw_ol_features = 0; - dev->flags = NETDEV_UP | NETDEV_PROMISC; + common->flags = NETDEV_UP | NETDEV_PROMISC; - ovs_list_push_back(&dpdk_list, &dev->list_node); + ovs_list_push_back(&dpdk_list, &common->list_node); netdev_request_reconfigure(netdev); - dev->sw_stats = xzalloc(sizeof *dev->sw_stats); + common->sw_stats = xzalloc(sizeof *common->sw_stats); } static int vhost_common_construct(struct netdev *netdev) OVS_REQUIRES(dpdk_mutex) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); int socket_id = rte_lcore_to_socket_id(rte_get_main_lcore()); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); @@ -1576,13 +1505,13 @@ vhost_common_construct(struct netdev *netdev) if (!dev->vhost_rxq_enabled) { return ENOMEM; } - dev->tx_q = netdev_dpdk_alloc_txq(OVS_VHOST_MAX_QUEUE_NUM); - if (!dev->tx_q) { + common->tx_q = netdev_dpdk_alloc_txq(OVS_VHOST_MAX_QUEUE_NUM); + if (!common->tx_q) { rte_free(dev->vhost_rxq_enabled); return ENOMEM; } for (unsigned i = 0; i < OVS_VHOST_MAX_QUEUE_NUM; i++) { - dev->tx_q[i].map = OVS_VHOST_QUEUE_MAP_UNKNOWN; + common->tx_q[i].map = OVS_VHOST_QUEUE_MAP_UNKNOWN; } ovsrcu_index_init(&dev->vid, -1); @@ -1592,7 +1521,7 @@ vhost_common_construct(struct netdev *netdev) dev->vhost_max_queue_pairs = VHOST_MAX_QUEUE_PAIRS_DEF; - common_construct(netdev, socket_id); + common_construct(common, socket_id); return 0; } @@ -1697,10 +1626,11 @@ netdev_dpdk_vhost_client_construct(struct netdev *netdev) static int netdev_dpdk_eth_construct(struct netdev *netdev) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); ovs_mutex_lock(&dpdk_mutex); - common_construct(netdev, SOCKET0); + common_construct(common, SOCKET0); dev->port_id = DPDK_ETH_PORT_ID_INVALID; dev->attached = false; @@ -1719,24 +1649,24 @@ netdev_dpdk_eth_construct(struct netdev *netdev) dev->rte_xstats_names_size = 0; dev->rte_xstats_ids = NULL; dev->rte_xstats_ids_size = 0; - dev->sw_stats->tx_retries = UINT64_MAX; + common->sw_stats->tx_retries = UINT64_MAX; ovs_mutex_unlock(&dpdk_mutex); return 0; } static void -common_destruct(struct netdev_dpdk *dev) +common_destruct(struct netdev_dpdk_common *common) OVS_REQUIRES(dpdk_mutex) - OVS_EXCLUDED(dev->mutex) + OVS_EXCLUDED(common->mutex) { - rte_free(dev->tx_q); - dpdk_mp_put(dev->dpdk_mp); + rte_free(common->tx_q); + dpdk_mp_put(common->dpdk_mp); - ovs_list_remove(&dev->list_node); + ovs_list_remove(&common->list_node); free(ovsrcu_get_protected(struct ingress_policer *, - &dev->ingress_policer)); - free(dev->sw_stats); - ovs_mutex_destroy(&dev->mutex); + &common->ingress_policer)); + free(common->sw_stats); + ovs_mutex_destroy(&common->mutex); } static void dpdk_rx_steer_unconfigure(struct netdev_dpdk *); @@ -1744,6 +1674,7 @@ static void dpdk_rx_steer_unconfigure(struct netdev_dpdk *); static void netdev_dpdk_eth_destruct(struct netdev *netdev) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); ovs_mutex_lock(&dpdk_mutex); @@ -1815,7 +1746,7 @@ netdev_dpdk_eth_destruct(struct netdev *netdev) netdev_dpdk_clear_xstats(dev); free(dev->devargs); - common_destruct(dev); + common_destruct(common); ovs_mutex_unlock(&dpdk_mutex); } @@ -1843,6 +1774,7 @@ dpdk_vhost_driver_unregister(struct netdev_dpdk *dev OVS_UNUSED, static void netdev_dpdk_vhost_destruct(struct netdev *netdev) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); bool is_client_mode; char *vhost_id; @@ -1863,7 +1795,7 @@ netdev_dpdk_vhost_destruct(struct netdev *netdev) dev->vhost_id = NULL; rte_free(dev->vhost_rxq_enabled); - common_destruct(dev); + common_destruct(common); ovs_mutex_unlock(&dpdk_mutex); @@ -2190,10 +2122,12 @@ netdev_dpdk_eth_run(const struct netdev_class *netdev_class OVS_UNUSED) ovs_mutex_lock(&dpdk_mutex); dev = netdev_dpdk_lookup_by_port_id(port_id); if (dev) { + struct netdev *netdev = &dev->up; + ovs_mutex_lock(&dev->mutex); - netdev_request_reconfigure(&dev->up); + netdev_request_reconfigure(netdev); VLOG_DBG_RL(&rl, "%s: Device reset requested.", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); ovs_mutex_unlock(&dev->mutex); } ovs_mutex_unlock(&dpdk_mutex); @@ -2314,6 +2248,7 @@ static int netdev_dpdk_eth_set_config(struct netdev *netdev, const struct smap *args, char **errp) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); bool rx_fc_en, tx_fc_en, autoneg, lsc_interrupt_mode; bool flow_control_requested = true; @@ -2370,10 +2305,10 @@ netdev_dpdk_eth_set_config(struct netdev *netdev, const struct smap *args, } else { int sid = rte_eth_dev_socket_id(new_port_id); - dev->requested_socket_id = sid < 0 ? SOCKET0 : sid; + common->requested_socket_id = sid < 0 ? SOCKET0 : sid; dev->devargs = xstrdup(new_devargs); dev->port_id = new_port_id; - netdev_request_reconfigure(&dev->up); + netdev_request_reconfigure(netdev); err = 0; } } @@ -2549,27 +2484,20 @@ netdev_dpdk_vhost_client_set_config(struct netdev *netdev, return 0; } -static int -netdev_dpdk_get_numa_id(const struct netdev *netdev) -{ - struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); - - return dev->socket_id; -} - /* Sets the number of tx queues for the dpdk interface. */ static int netdev_dpdk_eth_set_tx_multiq(struct netdev *netdev, unsigned int n_txq) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); ovs_mutex_lock(&dev->mutex); - if (dev->requested_n_txq == n_txq) { + if (common->requested_n_txq == n_txq) { goto out; } - dev->requested_n_txq = n_txq; + common->requested_n_txq = n_txq; netdev_request_reconfigure(netdev); out: @@ -2663,10 +2591,12 @@ netdev_dpdk_batch_init_packet_fields(struct dp_packet_batch *batch) /* Prepare the packet for HWOL. * Return True if the packet is OK to continue. */ static bool -netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) +netdev_dpdk_prep_hwol_packet(struct netdev_dpdk_common *common, + struct rte_mbuf *mbuf) { struct dp_packet *pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf); uint64_t unexpected = mbuf->ol_flags & RTE_MBUF_F_TX_OFFLOAD_MASK; + struct netdev *netdev = &common->up; const struct ip_header *ip; bool is_sctp; bool l3_csum; @@ -2679,8 +2609,8 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) if (OVS_UNLIKELY(unexpected)) { VLOG_WARN_RL(&rl, "%s: Unexpected Tx offload flags: %#"PRIx64, - netdev_get_name(&dev->up), unexpected); - netdev_dpdk_mbuf_dump(netdev_get_name(&dev->up), + netdev_get_name(netdev), unexpected); + netdev_dpdk_mbuf_dump(netdev_get_name(netdev), "Packet with unexpected ol_flags", mbuf); return false; } @@ -2781,11 +2711,12 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) hdr_len += mbuf->outer_l2_len + mbuf->outer_l3_len; } - if (OVS_UNLIKELY((hdr_len + mbuf->tso_segsz) > dev->max_packet_len)) { + if (OVS_UNLIKELY((hdr_len + mbuf->tso_segsz) + > common->max_packet_len)) { VLOG_WARN_RL(&rl, "%s: Oversized TSO packet. hdr: %"PRIu32", " "gso: %"PRIu32", max len: %"PRIu32"", - dev->up.name, hdr_len, mbuf->tso_segsz, - dev->max_packet_len); + netdev->name, hdr_len, mbuf->tso_segsz, + common->max_packet_len); return false; } mbuf->ol_flags |= RTE_MBUF_F_TX_TCP_SEG; @@ -2802,8 +2733,8 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) /* Prepare a batch for HWOL. * Return the number of good packets in the batch. */ static int -netdev_dpdk_prep_hwol_batch(struct netdev_dpdk *dev, struct rte_mbuf **pkts, - int pkt_cnt) +netdev_dpdk_prep_hwol_batch(struct netdev_dpdk_common *common, + struct rte_mbuf **pkts, int pkt_cnt) { int i = 0; int cnt = 0; @@ -2812,7 +2743,7 @@ netdev_dpdk_prep_hwol_batch(struct netdev_dpdk *dev, struct rte_mbuf **pkts, /* Prepare and filter bad HWOL packets. */ for (i = 0; i < pkt_cnt; i++) { pkt = pkts[i]; - if (!netdev_dpdk_prep_hwol_packet(dev, pkt)) { + if (!netdev_dpdk_prep_hwol_packet(common, pkt)) { rte_pktmbuf_free(pkt); continue; } @@ -2863,15 +2794,16 @@ static inline int netdev_dpdk_eth_tx_burst(struct netdev_dpdk *dev, int qid, struct rte_mbuf **pkts, int cnt) { + struct netdev *netdev = &dev->up; uint32_t nb_tx = 0; uint16_t nb_tx_prep = cnt; nb_tx_prep = rte_eth_tx_prepare(dev->port_id, qid, pkts, cnt); if (nb_tx_prep != cnt) { VLOG_WARN_RL(&rl, "%s: Output batch contains invalid packets. " - "Only %u/%u are valid: %s", netdev_get_name(&dev->up), + "Only %u/%u are valid: %s", netdev_get_name(netdev), nb_tx_prep, cnt, rte_strerror(rte_errno)); - netdev_dpdk_mbuf_dump(netdev_get_name(&dev->up), + netdev_dpdk_mbuf_dump(netdev_get_name(netdev), "First invalid packet", pkts[nb_tx_prep]); } @@ -2964,6 +2896,7 @@ static int netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq, struct dp_packet_batch *batch, int *qfill) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(rxq->netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev); struct ingress_policer *policer = netdev_dpdk_get_ingress_policer(dev); uint16_t nb_rx = 0; @@ -2972,11 +2905,11 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq, int vid = netdev_dpdk_get_vid(dev); if (OVS_UNLIKELY(vid < 0 || !dev->vhost_reconfigured - || !(dev->flags & NETDEV_UP))) { + || !(common->flags & NETDEV_UP))) { return EAGAIN; } - nb_rx = rte_vhost_dequeue_burst(vid, qid, dev->dpdk_mp->mp, + nb_rx = rte_vhost_dequeue_burst(vid, qid, common->dpdk_mp->mp, (struct rte_mbuf **) batch->packets, NETDEV_MAX_BURST); if (!nb_rx) { @@ -3002,10 +2935,10 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq, } if (OVS_UNLIKELY(qos_drops)) { - rte_spinlock_lock(&dev->stats_lock); - dev->stats.rx_dropped += qos_drops; - dev->sw_stats->rx_qos_drops += qos_drops; - rte_spinlock_unlock(&dev->stats_lock); + rte_spinlock_lock(&common->stats_lock); + common->stats.rx_dropped += qos_drops; + common->sw_stats->rx_qos_drops += qos_drops; + rte_spinlock_unlock(&common->stats_lock); } batch->count = nb_rx; @@ -3026,13 +2959,14 @@ static int netdev_dpdk_eth_rxq_recv(struct netdev_rxq *rxq, struct dp_packet_batch *batch, int *qfill) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(rxq->netdev); struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq); struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev); struct ingress_policer *policer = netdev_dpdk_get_ingress_policer(dev); int nb_rx; int dropped = 0; - if (OVS_UNLIKELY(!(dev->flags & NETDEV_UP))) { + if (OVS_UNLIKELY(!(common->flags & NETDEV_UP))) { return EAGAIN; } @@ -3061,10 +2995,10 @@ netdev_dpdk_eth_rxq_recv(struct netdev_rxq *rxq, struct dp_packet_batch *batch, /* Update stats to reflect dropped packets */ if (OVS_UNLIKELY(dropped)) { - rte_spinlock_lock(&dev->stats_lock); - dev->stats.rx_dropped += dropped; - dev->sw_stats->rx_qos_drops += dropped; - rte_spinlock_unlock(&dev->stats_lock); + rte_spinlock_lock(&common->stats_lock); + common->stats.rx_dropped += dropped; + common->sw_stats->rx_qos_drops += dropped; + rte_spinlock_unlock(&common->stats_lock); } batch->count = nb_rx; @@ -3074,11 +3008,12 @@ netdev_dpdk_eth_rxq_recv(struct netdev_rxq *rxq, struct dp_packet_batch *batch, } static inline int -netdev_dpdk_qos_run(struct netdev_dpdk *dev, struct rte_mbuf **pkts, +netdev_dpdk_qos_run(struct netdev_dpdk_common *common, struct rte_mbuf **pkts, int cnt, bool should_steal) { - struct qos_conf *qos_conf = ovsrcu_get(struct qos_conf *, &dev->qos_conf); + struct qos_conf *qos_conf; + qos_conf = ovsrcu_get(struct qos_conf *, &common->qos_conf); if (qos_conf) { rte_spinlock_lock(&qos_conf->lock); cnt = qos_conf->ops->qos_run(qos_conf, pkts, cnt, should_steal); @@ -3089,8 +3024,8 @@ netdev_dpdk_qos_run(struct netdev_dpdk *dev, struct rte_mbuf **pkts, } static int -netdev_dpdk_filter_packet_len(struct netdev_dpdk *dev, struct rte_mbuf **pkts, - int pkt_cnt) +netdev_dpdk_filter_packet_len(struct netdev_dpdk_common *common, + struct rte_mbuf **pkts, int pkt_cnt) { int i = 0; int cnt = 0; @@ -3100,11 +3035,11 @@ netdev_dpdk_filter_packet_len(struct netdev_dpdk *dev, struct rte_mbuf **pkts, * during the offloading preparation for performance reasons. */ for (i = 0; i < pkt_cnt; i++) { pkt = pkts[i]; - if (OVS_UNLIKELY((pkt->pkt_len > dev->max_packet_len) + if (OVS_UNLIKELY((pkt->pkt_len > common->max_packet_len) && !pkt->tso_segsz)) { VLOG_WARN_RL(&rl, "%s: Too big size %" PRIu32 " " - "max_packet_len %d", dev->up.name, pkt->pkt_len, - dev->max_packet_len); + "max_packet_len %d", common->up.name, pkt->pkt_len, + common->max_packet_len); rte_pktmbuf_free(pkt); continue; } @@ -3275,7 +3210,7 @@ dpdk_copy_dp_packet_to_mbuf(struct rte_mempool *mp, struct dp_packet *pkt_orig) static size_t dpdk_copy_batch_to_mbuf(struct netdev *netdev, struct dp_packet_batch *batch) { - struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); size_t i, size = dp_packet_batch_size(batch); struct dp_packet *packet; @@ -3285,7 +3220,7 @@ dpdk_copy_batch_to_mbuf(struct netdev *netdev, struct dp_packet_batch *batch) } else { struct dp_packet *pktcopy; - pktcopy = dpdk_copy_dp_packet_to_mbuf(dev->dpdk_mp->mp, packet); + pktcopy = dpdk_copy_dp_packet_to_mbuf(common->dpdk_mp->mp, packet); if (pktcopy) { dp_packet_batch_add(batch, pktcopy); } @@ -3298,12 +3233,13 @@ dpdk_copy_batch_to_mbuf(struct netdev *netdev, struct dp_packet_batch *batch) } static size_t -netdev_dpdk_common_send(struct netdev *netdev, struct dp_packet_batch *batch, +netdev_dpdk_common_send(struct netdev_dpdk_common *common, + struct dp_packet_batch *batch, struct netdev_dpdk_sw_stats *stats) { struct rte_mbuf **pkts = (struct rte_mbuf **) batch->packets; - struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); size_t cnt, pkt_cnt = dp_packet_batch_size(batch); + struct netdev *netdev = &common->up; struct dp_packet *packet; bool need_copy = false; @@ -3324,19 +3260,19 @@ netdev_dpdk_common_send(struct netdev *netdev, struct dp_packet_batch *batch, } /* Drop oversized packets. */ - cnt = netdev_dpdk_filter_packet_len(dev, pkts, pkt_cnt); + cnt = netdev_dpdk_filter_packet_len(common, pkts, pkt_cnt); stats->tx_mtu_exceeded_drops += pkt_cnt - cnt; pkt_cnt = cnt; if (netdev->ol_flags) { /* Prepare each mbuf for hardware offloading. */ - cnt = netdev_dpdk_prep_hwol_batch(dev, pkts, pkt_cnt); + cnt = netdev_dpdk_prep_hwol_batch(common, pkts, pkt_cnt); stats->tx_invalid_hwol_drops += pkt_cnt - cnt; pkt_cnt = cnt; } /* Apply Quality of Service policy. */ - cnt = netdev_dpdk_qos_run(dev, pkts, pkt_cnt, true); + cnt = netdev_dpdk_qos_run(common, pkts, pkt_cnt, true); stats->tx_qos_drops += pkt_cnt - cnt; return cnt; @@ -3347,6 +3283,7 @@ netdev_dpdk_vhost_send(struct netdev *netdev, int qid, struct dp_packet_batch *batch, bool concurrent_txq OVS_UNUSED) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); int max_retries = VHOST_ENQ_RETRY_MIN; int cnt, batch_cnt, vhost_batch_cnt; @@ -3357,22 +3294,22 @@ netdev_dpdk_vhost_send(struct netdev *netdev, int qid, int retries; batch_cnt = cnt = dp_packet_batch_size(batch); - qid = dev->tx_q[qid % netdev->n_txq].map; + qid = common->tx_q[qid % netdev->n_txq].map; if (OVS_UNLIKELY(vid < 0 || !dev->vhost_reconfigured || qid < 0 - || !(dev->flags & NETDEV_UP))) { - rte_spinlock_lock(&dev->stats_lock); - dev->stats.tx_dropped += cnt; - rte_spinlock_unlock(&dev->stats_lock); + || !(common->flags & NETDEV_UP))) { + rte_spinlock_lock(&common->stats_lock); + common->stats.tx_dropped += cnt; + rte_spinlock_unlock(&common->stats_lock); dp_packet_delete_batch(batch, true); return 0; } - if (OVS_UNLIKELY(!rte_spinlock_trylock(&dev->tx_q[qid].tx_lock))) { + if (OVS_UNLIKELY(!rte_spinlock_trylock(&common->tx_q[qid].tx_lock))) { COVERAGE_INC(vhost_tx_contention); - rte_spinlock_lock(&dev->tx_q[qid].tx_lock); + rte_spinlock_lock(&common->tx_q[qid].tx_lock); } - cnt = netdev_dpdk_common_send(netdev, batch, &stats); + cnt = netdev_dpdk_common_send(common, batch, &stats); dropped = batch_cnt - cnt; pkts = (struct rte_mbuf **) batch->packets; @@ -3408,23 +3345,23 @@ netdev_dpdk_vhost_send(struct netdev *netdev, int qid, } } while (cnt && (retries++ < max_retries)); - rte_spinlock_unlock(&dev->tx_q[qid].tx_lock); + rte_spinlock_unlock(&common->tx_q[qid].tx_lock); stats.tx_failure_drops += cnt; dropped += cnt; stats.tx_retries = MIN(retries, max_retries); if (OVS_UNLIKELY(dropped || stats.tx_retries)) { - struct netdev_dpdk_sw_stats *sw_stats = dev->sw_stats; + struct netdev_dpdk_sw_stats *sw_stats = common->sw_stats; - rte_spinlock_lock(&dev->stats_lock); - dev->stats.tx_dropped += dropped; + rte_spinlock_lock(&common->stats_lock); + common->stats.tx_dropped += dropped; sw_stats->tx_retries += stats.tx_retries; sw_stats->tx_failure_drops += stats.tx_failure_drops; sw_stats->tx_mtu_exceeded_drops += stats.tx_mtu_exceeded_drops; sw_stats->tx_qos_drops += stats.tx_qos_drops; sw_stats->tx_invalid_hwol_drops += stats.tx_invalid_hwol_drops; - rte_spinlock_unlock(&dev->stats_lock); + rte_spinlock_unlock(&common->stats_lock); } pkts = (struct rte_mbuf **) batch->packets; @@ -3437,44 +3374,45 @@ static int netdev_dpdk_eth_send(struct netdev *netdev, int qid, struct dp_packet_batch *batch, bool concurrent_txq) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct rte_mbuf **pkts = (struct rte_mbuf **) batch->packets; struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); int batch_cnt = dp_packet_batch_size(batch); struct netdev_dpdk_sw_stats stats; int cnt, dropped; - if (OVS_UNLIKELY(!(dev->flags & NETDEV_UP))) { - rte_spinlock_lock(&dev->stats_lock); - dev->stats.tx_dropped += dp_packet_batch_size(batch); - rte_spinlock_unlock(&dev->stats_lock); + if (OVS_UNLIKELY(!(common->flags & NETDEV_UP))) { + rte_spinlock_lock(&common->stats_lock); + common->stats.tx_dropped += dp_packet_batch_size(batch); + rte_spinlock_unlock(&common->stats_lock); dp_packet_delete_batch(batch, true); return 0; } if (OVS_UNLIKELY(concurrent_txq)) { - qid = qid % dev->up.n_txq; - rte_spinlock_lock(&dev->tx_q[qid].tx_lock); + qid = qid % netdev->n_txq; + rte_spinlock_lock(&common->tx_q[qid].tx_lock); } - cnt = netdev_dpdk_common_send(netdev, batch, &stats); + cnt = netdev_dpdk_common_send(common, batch, &stats); dropped = netdev_dpdk_eth_tx_burst(dev, qid, pkts, cnt); stats.tx_failure_drops += dropped; dropped += batch_cnt - cnt; if (OVS_UNLIKELY(dropped)) { - struct netdev_dpdk_sw_stats *sw_stats = dev->sw_stats; + struct netdev_dpdk_sw_stats *sw_stats = common->sw_stats; - rte_spinlock_lock(&dev->stats_lock); - dev->stats.tx_dropped += dropped; + rte_spinlock_lock(&common->stats_lock); + common->stats.tx_dropped += dropped; sw_stats->tx_failure_drops += stats.tx_failure_drops; sw_stats->tx_mtu_exceeded_drops += stats.tx_mtu_exceeded_drops; sw_stats->tx_qos_drops += stats.tx_qos_drops; sw_stats->tx_invalid_hwol_drops += stats.tx_invalid_hwol_drops; - rte_spinlock_unlock(&dev->stats_lock); + rte_spinlock_unlock(&common->stats_lock); } if (OVS_UNLIKELY(concurrent_txq)) { - rte_spinlock_unlock(&dev->tx_q[qid].tx_lock); + rte_spinlock_unlock(&common->tx_q[qid].tx_lock); } return 0; @@ -3485,16 +3423,17 @@ netdev_dpdk_eth_set_etheraddr__(struct netdev_dpdk *dev, const struct eth_addr mac) OVS_REQUIRES(dev->mutex) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); struct rte_ether_addr ea; int err; memcpy(ea.addr_bytes, mac.ea, ETH_ADDR_LEN); err = -rte_eth_dev_default_mac_addr_set(dev->port_id, &ea); if (!err) { - dev->hwaddr = mac; + common->hwaddr = mac; } else { VLOG_WARN("%s: Failed to set requested mac("ETH_ADDR_FMT"): %s", - netdev_get_name(&dev->up), ETH_ADDR_ARGS(mac), + netdev_get_name(&common->up), ETH_ADDR_ARGS(mac), rte_strerror(err)); } @@ -3504,11 +3443,12 @@ netdev_dpdk_eth_set_etheraddr__(struct netdev_dpdk *dev, static int netdev_dpdk_eth_set_etheraddr(struct netdev *netdev, const struct eth_addr mac) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); int err = 0; ovs_mutex_lock(&dev->mutex); - if (!eth_addr_equals(dev->hwaddr, mac)) { + if (!eth_addr_equals(common->hwaddr, mac)) { err = netdev_dpdk_eth_set_etheraddr__(dev, mac); if (!err) { netdev_change_seq_changed(netdev); @@ -3523,11 +3463,12 @@ static int netdev_dpdk_vhost_set_etheraddr(struct netdev *netdev, const struct eth_addr mac) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); ovs_mutex_lock(&dev->mutex); - if (!eth_addr_equals(dev->hwaddr, mac)) { - dev->hwaddr = mac; + if (!eth_addr_equals(common->hwaddr, mac)) { + common->hwaddr = mac; netdev_change_seq_changed(netdev); } ovs_mutex_unlock(&dev->mutex); @@ -3539,10 +3480,11 @@ static int netdev_dpdk_eth_get_etheraddr(const struct netdev *netdev, struct eth_addr *mac) { + const struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); ovs_mutex_lock(&dev->mutex); - *mac = dev->hwaddr; + netdev_dpdk_common_get_etheraddr(common, mac); ovs_mutex_unlock(&dev->mutex); return 0; @@ -3552,63 +3494,75 @@ static int netdev_dpdk_vhost_get_etheraddr(const struct netdev *netdev, struct eth_addr *mac) { + const struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); ovs_mutex_lock(&dev->mutex); - *mac = dev->hwaddr; + netdev_dpdk_common_get_etheraddr(common, mac); ovs_mutex_unlock(&dev->mutex); return 0; } static int -netdev_dpdk_get_mtu(const struct netdev *netdev, int *mtup) +netdev_dpdk_eth_get_mtu(const struct netdev *netdev, int *mtup) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); ovs_mutex_lock(&dev->mutex); - *mtup = dev->mtu; + netdev_dpdk_common_get_mtu(common, mtup); ovs_mutex_unlock(&dev->mutex); return 0; } static int -netdev_dpdk_set_mtu(struct netdev *netdev, int mtu) +netdev_dpdk_vhost_get_mtu(const struct netdev *netdev, int *mtup) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); - /* XXX: Ensure that the overall frame length of the requested MTU does not - * surpass the NETDEV_DPDK_MAX_PKT_LEN. DPDK device drivers differ in how - * the L2 frame length is calculated for a given MTU when - * rte_eth_dev_set_mtu(mtu) is called e.g. i40e driver includes 2 x vlan - * headers, the em driver includes 1 x vlan header, the ixgbe driver does - * not include vlan headers. As such we should use - * MTU_TO_MAX_FRAME_LEN(mtu) which includes an additional 2 x vlan headers - * (8 bytes) for comparison. This avoids a failure later with - * rte_eth_dev_set_mtu(). This approach should be used until DPDK provides - * a method to retrieve the upper bound MTU for a given device. - */ - if (MTU_TO_MAX_FRAME_LEN(mtu) > NETDEV_DPDK_MAX_PKT_LEN - || mtu < RTE_ETHER_MIN_MTU) { - VLOG_WARN("%s: unsupported MTU %d\n", dev->up.name, mtu); - return EINVAL; - } - ovs_mutex_lock(&dev->mutex); - if (dev->requested_mtu != mtu) { - dev->requested_mtu = mtu; - netdev_request_reconfigure(netdev); - } + netdev_dpdk_common_get_mtu(common, mtup); ovs_mutex_unlock(&dev->mutex); return 0; } +static int +netdev_dpdk_eth_set_mtu(struct netdev *netdev, int mtu) +{ + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + int ret; + + ovs_mutex_lock(&dev->mutex); + ret = netdev_dpdk_common_set_mtu(common, mtu); + ovs_mutex_unlock(&dev->mutex); + + return ret; +} + +static int +netdev_dpdk_vhost_set_mtu(struct netdev *netdev, int mtu) +{ + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + int ret; + + ovs_mutex_lock(&dev->mutex); + ret = netdev_dpdk_common_set_mtu(common, mtu); + ovs_mutex_unlock(&dev->mutex); + + return ret; +} + static int netdev_dpdk_vhost_get_stats(const struct netdev *netdev, struct netdev_stats *stats) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct rte_vhost_stat_name *vhost_stats_names = NULL; struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct rte_vhost_stat *vhost_stats = NULL; @@ -3659,11 +3613,11 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, VHOST_RXQ_STAT(rx_1024_to_1522_packets, "size_1024_1518_packets") \ VHOST_RXQ_STAT(rx_1523_to_max_packets, "size_1519_max_packets") -#define VHOST_RXQ_STAT(MEMBER, NAME) dev->stats.MEMBER = 0; +#define VHOST_RXQ_STAT(MEMBER, NAME) common->stats.MEMBER = 0; VHOST_RXQ_STATS; #undef VHOST_RXQ_STAT - for (int q = 0; q < dev->up.n_rxq; q++) { + for (int q = 0; q < common->up.n_rxq; q++) { qid = q * VIRTIO_QNUM + VIRTIO_TXQ; err = rte_vhost_vring_stats_get(vid, qid, vhost_stats, @@ -3676,7 +3630,7 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, for (int i = 0; i < vhost_stats_count; i++) { #define VHOST_RXQ_STAT(MEMBER, NAME) \ if (string_ends_with(vhost_stats_names[i].name, NAME)) { \ - dev->stats.MEMBER += vhost_stats[i].value; \ + common->stats.MEMBER += vhost_stats[i].value; \ continue; \ } VHOST_RXQ_STATS; @@ -3688,11 +3642,11 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, * Since vhost only reports good packets and has no error counter, * rx_undersized_errors is highjacked (see above) to retrieve * "undersize_packets". */ - dev->stats.rx_1_to_64_packets += dev->stats.rx_undersized_errors; - memset(&dev->stats.rx_undersized_errors, 0xff, - sizeof dev->stats.rx_undersized_errors); + common->stats.rx_1_to_64_packets += common->stats.rx_undersized_errors; + memset(&common->stats.rx_undersized_errors, 0xff, + sizeof common->stats.rx_undersized_errors); -#define VHOST_RXQ_STAT(MEMBER, NAME) stats->MEMBER = dev->stats.MEMBER; +#define VHOST_RXQ_STAT(MEMBER, NAME) stats->MEMBER = common->stats.MEMBER; VHOST_RXQ_STATS; #undef VHOST_RXQ_STAT @@ -3734,11 +3688,11 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, VHOST_TXQ_STAT(tx_1024_to_1522_packets, "size_1024_1518_packets") \ VHOST_TXQ_STAT(tx_1523_to_max_packets, "size_1519_max_packets") -#define VHOST_TXQ_STAT(MEMBER, NAME) dev->stats.MEMBER = 0; +#define VHOST_TXQ_STAT(MEMBER, NAME) common->stats.MEMBER = 0; VHOST_TXQ_STATS; #undef VHOST_TXQ_STAT - for (int q = 0; q < dev->up.n_txq; q++) { + for (int q = 0; q < common->up.n_txq; q++) { qid = q * VIRTIO_QNUM; err = rte_vhost_vring_stats_get(vid, qid, vhost_stats, @@ -3751,7 +3705,7 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, for (int i = 0; i < vhost_stats_count; i++) { #define VHOST_TXQ_STAT(MEMBER, NAME) \ if (string_ends_with(vhost_stats_names[i].name, NAME)) { \ - dev->stats.MEMBER += vhost_stats[i].value; \ + common->stats.MEMBER += vhost_stats[i].value; \ continue; \ } VHOST_TXQ_STATS; @@ -3761,18 +3715,18 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, /* OVS reports 64 bytes and smaller packets into "tx_1_to_64_packets". * Same as for rx, rx_undersized_errors is highjacked. */ - dev->stats.tx_1_to_64_packets += dev->stats.rx_undersized_errors; - memset(&dev->stats.rx_undersized_errors, 0xff, - sizeof dev->stats.rx_undersized_errors); + common->stats.tx_1_to_64_packets += common->stats.rx_undersized_errors; + memset(&common->stats.rx_undersized_errors, 0xff, + sizeof common->stats.rx_undersized_errors); -#define VHOST_TXQ_STAT(MEMBER, NAME) stats->MEMBER = dev->stats.MEMBER; +#define VHOST_TXQ_STAT(MEMBER, NAME) stats->MEMBER = common->stats.MEMBER; VHOST_TXQ_STATS; #undef VHOST_TXQ_STAT - rte_spinlock_lock(&dev->stats_lock); - stats->rx_dropped = dev->stats.rx_dropped; - stats->tx_dropped = dev->stats.tx_dropped; - rte_spinlock_unlock(&dev->stats_lock); + rte_spinlock_lock(&common->stats_lock); + stats->rx_dropped = common->stats.rx_dropped; + stats->tx_dropped = common->stats.tx_dropped; + rte_spinlock_unlock(&common->stats_lock); err = 0; out: @@ -3789,6 +3743,7 @@ static int netdev_dpdk_vhost_get_custom_stats(const struct netdev *netdev, struct netdev_custom_stats *custom_stats) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct rte_vhost_stat_name *vhost_stats_names = NULL; struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct rte_vhost_stat *vhost_stats = NULL; @@ -3799,7 +3754,7 @@ netdev_dpdk_vhost_get_custom_stats(const struct netdev *netdev, int qid; int vid; - netdev_dpdk_get_sw_custom_stats(netdev, custom_stats); + netdev_dpdk_common_get_sw_custom_stats(common, custom_stats); stat_offset = custom_stats->size; ovs_mutex_lock(&dev->mutex); @@ -3824,8 +3779,8 @@ netdev_dpdk_vhost_get_custom_stats(const struct netdev *netdev, } vhost_txq_stats_count = err; - stat_offset += dev->up.n_rxq * vhost_rxq_stats_count; - stat_offset += dev->up.n_txq * vhost_txq_stats_count; + stat_offset += netdev->n_rxq * vhost_rxq_stats_count; + stat_offset += netdev->n_txq * vhost_txq_stats_count; custom_stats->counters = xrealloc(custom_stats->counters, stat_offset * sizeof *custom_stats->counters); @@ -3835,7 +3790,7 @@ netdev_dpdk_vhost_get_custom_stats(const struct netdev *netdev, sizeof *vhost_stats_names); vhost_stats = xcalloc(vhost_rxq_stats_count, sizeof *vhost_stats); - for (int q = 0; q < dev->up.n_rxq; q++) { + for (int q = 0; q < netdev->n_rxq; q++) { qid = q * VIRTIO_QNUM + VIRTIO_TXQ; err = rte_vhost_vring_stats_get_names(vid, qid, vhost_stats_names, @@ -3869,7 +3824,7 @@ netdev_dpdk_vhost_get_custom_stats(const struct netdev *netdev, sizeof *vhost_stats_names); vhost_stats = xcalloc(vhost_txq_stats_count, sizeof *vhost_stats); - for (int q = 0; q < dev->up.n_txq; q++) { + for (int q = 0; q < netdev->n_txq; q++) { qid = q * VIRTIO_QNUM; err = rte_vhost_vring_stats_get_names(vid, qid, vhost_stats_names, @@ -3954,6 +3909,7 @@ static int netdev_dpdk_eth_get_stats(const struct netdev *netdev, struct netdev_stats *stats) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct rte_eth_stats rte_stats; bool gg; @@ -4015,10 +3971,10 @@ out: stats->rx_errors = rte_stats.ierrors; stats->tx_errors = rte_stats.oerrors; - rte_spinlock_lock(&dev->stats_lock); - stats->tx_dropped = dev->stats.tx_dropped; - stats->rx_dropped = dev->stats.rx_dropped; - rte_spinlock_unlock(&dev->stats_lock); + rte_spinlock_lock(&common->stats_lock); + stats->tx_dropped = common->stats.tx_dropped; + stats->rx_dropped = common->stats.rx_dropped; + rte_spinlock_unlock(&common->stats_lock); /* These are the available DPDK counters for packets not received due to * local resource constraints in DPDK and NIC respectively. */ @@ -4035,11 +3991,12 @@ netdev_dpdk_eth_get_custom_stats(const struct netdev *netdev, struct netdev_custom_stats *custom_stats) { - uint32_t i; + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); int rte_xstats_ret, sw_stats_size; + uint32_t i; - netdev_dpdk_get_sw_custom_stats(netdev, custom_stats); + netdev_dpdk_common_get_sw_custom_stats(common, custom_stats); ovs_mutex_lock(&dev->mutex); @@ -4080,56 +4037,6 @@ netdev_dpdk_eth_get_custom_stats(const struct netdev *netdev, return 0; } -static int -netdev_dpdk_get_sw_custom_stats(const struct netdev *netdev, - struct netdev_custom_stats *custom_stats) -{ - struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); - int i, n; - -#define SW_CSTATS \ - SW_CSTAT(tx_retries) \ - SW_CSTAT(tx_failure_drops) \ - SW_CSTAT(tx_mtu_exceeded_drops) \ - SW_CSTAT(tx_qos_drops) \ - SW_CSTAT(rx_qos_drops) \ - SW_CSTAT(tx_invalid_hwol_drops) - -#define SW_CSTAT(NAME) + 1 - custom_stats->size = SW_CSTATS; -#undef SW_CSTAT - custom_stats->counters = xcalloc(custom_stats->size, - sizeof *custom_stats->counters); - - ovs_mutex_lock(&dev->mutex); - - rte_spinlock_lock(&dev->stats_lock); - i = 0; -#define SW_CSTAT(NAME) \ - custom_stats->counters[i++].value = dev->sw_stats->NAME; - SW_CSTATS; -#undef SW_CSTAT - rte_spinlock_unlock(&dev->stats_lock); - - ovs_mutex_unlock(&dev->mutex); - - i = 0; - n = 0; -#define SW_CSTAT(NAME) \ - if (custom_stats->counters[i].value != UINT64_MAX) { \ - ovs_strlcpy(custom_stats->counters[n].name, \ - "ovs_"#NAME, NETDEV_CUSTOM_STATS_NAME_SIZE); \ - custom_stats->counters[n].value = custom_stats->counters[i].value; \ - n++; \ - } \ - i++; - SW_CSTATS; -#undef SW_CSTAT - - custom_stats->size = n; - return 0; -} - static int netdev_dpdk_eth_get_features(const struct netdev *netdev, enum netdev_features *current, @@ -4351,15 +4258,28 @@ netdev_dpdk_set_policing(struct netdev* netdev, uint32_t policer_rate, } static int -netdev_dpdk_get_ifindex(const struct netdev *netdev) +netdev_dpdk_eth_get_ifindex(const struct netdev *netdev) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + int ifindex; ovs_mutex_lock(&dev->mutex); - /* Calculate hash from the netdev name. Ensure that ifindex is a 24-bit - * postive integer to meet RFC 2863 recommendations. - */ - int ifindex = hash_string(netdev->name, 0) % 0xfffffe + 1; + ifindex = netdev_dpdk_common_get_ifindex(common); + ovs_mutex_unlock(&dev->mutex); + + return ifindex; +} + +static int +netdev_dpdk_vhost_get_ifindex(const struct netdev *netdev) +{ + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + int ifindex; + + ovs_mutex_lock(&dev->mutex); + ifindex = netdev_dpdk_common_get_ifindex(common); ovs_mutex_unlock(&dev->mutex); return ifindex; @@ -4416,24 +4336,25 @@ netdev_dpdk_eth_update_flags__(struct netdev_dpdk *dev, enum netdev_flags *old_flagsp) OVS_REQUIRES(dev->mutex) { - struct netdev *netdev = &dev->up; + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); + struct netdev *netdev = &common->up; if ((off | on) & ~(NETDEV_UP | NETDEV_PROMISC)) { return EINVAL; } - *old_flagsp = dev->flags; - dev->flags |= on; - dev->flags &= ~off; + *old_flagsp = common->flags; + common->flags |= on; + common->flags &= ~off; - if (dev->flags == *old_flagsp) { + if (common->flags == *old_flagsp) { return 0; } - if ((dev->flags ^ *old_flagsp) & NETDEV_UP) { + if ((common->flags ^ *old_flagsp) & NETDEV_UP) { int err; - if (dev->flags & NETDEV_UP) { + if (common->flags & NETDEV_UP) { err = rte_eth_dev_set_link_up(dev->port_id); } else { err = rte_eth_dev_set_link_down(dev->port_id); @@ -4444,12 +4365,12 @@ netdev_dpdk_eth_update_flags__(struct netdev_dpdk *dev, } else if (err < 0) { VLOG_ERR("Interface %s link change error: %s", netdev_get_name(netdev), rte_strerror(-err)); - dev->flags = *old_flagsp; + common->flags = *old_flagsp; return -err; } } - if (dev->flags & NETDEV_PROMISC) { + if (common->flags & NETDEV_PROMISC) { rte_eth_promiscuous_enable(dev->port_id); } @@ -4479,17 +4400,18 @@ netdev_dpdk_vhost_update_flags__(struct netdev_dpdk *dev, enum netdev_flags *old_flagsp) OVS_REQUIRES(dev->mutex) { - struct netdev *netdev = &dev->up; + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); + struct netdev *netdev = &common->up; if ((off | on) & ~(NETDEV_UP | NETDEV_PROMISC)) { return EINVAL; } - *old_flagsp = dev->flags; - dev->flags |= on; - dev->flags &= ~off; + *old_flagsp = common->flags; + common->flags |= on; + common->flags &= ~off; - if (dev->flags == *old_flagsp) { + if (common->flags == *old_flagsp) { return 0; } @@ -4503,10 +4425,10 @@ netdev_dpdk_vhost_update_flags__(struct netdev_dpdk *dev, /* Clear statistics if device is getting up. */ if (NETDEV_UP & on) { - rte_spinlock_lock(&dev->stats_lock); - memset(&dev->stats, 0, sizeof dev->stats); - memset(dev->sw_stats, 0, sizeof *dev->sw_stats); - rte_spinlock_unlock(&dev->stats_lock); + rte_spinlock_lock(&common->stats_lock); + memset(&common->stats, 0, sizeof common->stats); + memset(common->sw_stats, 0, sizeof *common->sw_stats); + rte_spinlock_unlock(&common->stats_lock); } } @@ -4621,6 +4543,7 @@ netdev_dpdk_link_speed_to_str__(uint32_t link_speed) static int netdev_dpdk_eth_get_status(const struct netdev *netdev, struct smap *args) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct rte_eth_dev_info dev_info; size_t rx_steer_flows_num; @@ -4650,7 +4573,7 @@ netdev_dpdk_eth_get_status(const struct netdev *netdev, struct smap *args) smap_add_format(args, "driver_name", "%s", dev_info.driver_name); smap_add_format(args, "min_rx_bufsize", "%u", dev_info.min_rx_bufsize); } - smap_add_format(args, "max_rx_pktlen", "%u", dev->max_packet_len); + smap_add_format(args, "max_rx_pktlen", "%u", common->max_packet_len); if (!diag) { smap_add_format(args, "max_rx_queues", "%u", dev_info.max_rx_queues); smap_add_format(args, "max_tx_queues", "%u", dev_info.max_tx_queues); @@ -4665,7 +4588,7 @@ netdev_dpdk_eth_get_status(const struct netdev *netdev, struct smap *args) smap_add_format(args, "n_txq", "%d", netdev->n_txq); smap_add(args, "rx_csum_offload", - dev->hw_ol_features & NETDEV_RX_CHECKSUM_OFFLOAD + common->hw_ol_features & NETDEV_RX_CHECKSUM_OFFLOAD ? "true" : "false"); /* Querying the DPDK library for iftype may be done in future, pending @@ -4693,7 +4616,7 @@ netdev_dpdk_eth_get_status(const struct netdev *netdev, struct smap *args) if (dev->is_representor) { smap_add_format(args, "dpdk-vf-mac", ETH_ADDR_FMT, - ETH_ADDR_ARGS(dev->hwaddr)); + ETH_ADDR_ARGS(common->hwaddr)); } if (rx_steer_flags && !rx_steer_flows_num) { @@ -4894,16 +4817,17 @@ netdev_dpdk_get_mempool_info(struct unixctl_conn *conn, } if (netdev) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); ovs_mutex_lock(&dev->mutex); ovs_mutex_lock(&dpdk_mp_mutex); - if (dev->dpdk_mp) { - rte_mempool_dump(stream, dev->dpdk_mp->mp); + if (common->dpdk_mp) { + rte_mempool_dump(stream, common->dpdk_mp->mp); fprintf(stream, " count: avail (%u), in use (%u)\n", - rte_mempool_avail_count(dev->dpdk_mp->mp), - rte_mempool_in_use_count(dev->dpdk_mp->mp)); + rte_mempool_avail_count(common->dpdk_mp->mp), + rte_mempool_in_use_count(common->dpdk_mp->mp)); } else { error = "Not allocated"; } @@ -4949,14 +4873,16 @@ static void netdev_dpdk_remap_txqs(struct netdev_dpdk *dev) OVS_REQUIRES(dev->mutex) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); + struct netdev *netdev = &common->up; int *enabled_queues, n_enabled = 0; - int i, k, total_txqs = dev->up.n_txq; + int i, k, total_txqs = netdev->n_txq; enabled_queues = xcalloc(total_txqs, sizeof *enabled_queues); for (i = 0; i < total_txqs; i++) { /* Enabled queues always mapped to themselves. */ - if (dev->tx_q[i].map == i) { + if (common->tx_q[i].map == i) { enabled_queues[n_enabled++] = i; } } @@ -4968,8 +4894,8 @@ netdev_dpdk_remap_txqs(struct netdev_dpdk *dev) k = 0; for (i = 0; i < total_txqs; i++) { - if (dev->tx_q[i].map != i) { - dev->tx_q[i].map = enabled_queues[k]; + if (common->tx_q[i].map != i) { + common->tx_q[i].map = enabled_queues[k]; k = (k + 1) % n_enabled; } } @@ -4978,9 +4904,9 @@ netdev_dpdk_remap_txqs(struct netdev_dpdk *dev) struct ds mapping = DS_EMPTY_INITIALIZER; ds_put_format(&mapping, "TX queue mapping for port '%s':\n", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); for (i = 0; i < total_txqs; i++) { - ds_put_format(&mapping, "%2d --> %2d\n", i, dev->tx_q[i].map); + ds_put_format(&mapping, "%2d --> %2d\n", i, common->tx_q[i].map); } VLOG_DBG("%s", ds_cstr(&mapping)); @@ -5006,7 +4932,10 @@ new_device(int vid) ovs_mutex_lock(&dpdk_mutex); /* Add device to the vhost port with the same name as that passed down. */ LIST_FOR_EACH(dev, list_node, &dpdk_list) { - if (!is_vhost_class(dev->up.netdev_class)) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); + struct netdev *netdev = &common->up; + + if (!is_vhost_class(netdev->netdev_class)) { continue; } ovs_mutex_lock(&dev->mutex); @@ -5021,19 +4950,19 @@ new_device(int vid) VLOG_INFO("Error getting NUMA info for vHost Device '%s'", ifname); #endif - newnode = dev->socket_id; + newnode = common->socket_id; } dev->virtio_features_state |= OVS_VIRTIO_F_NEGOTIATED; - if (dev->requested_n_txq < qp_num - || dev->requested_n_rxq < qp_num - || dev->requested_socket_id != newnode - || dev->dpdk_mp == NULL) { - dev->requested_socket_id = newnode; - dev->requested_n_rxq = qp_num; - dev->requested_n_txq = qp_num; - netdev_request_reconfigure(&dev->up); + if (common->requested_n_txq < qp_num + || common->requested_n_rxq < qp_num + || common->requested_socket_id != newnode + || common->dpdk_mp == NULL) { + common->requested_socket_id = newnode; + common->requested_n_rxq = qp_num; + common->requested_n_txq = qp_num; + netdev_request_reconfigure(netdev); } else { /* Reconfiguration not required. */ dev->vhost_reconfigured = true; @@ -5044,13 +4973,13 @@ new_device(int vid) "vHost Device '%s'", dev->vhost_id); } else { if (features & (1ULL << VIRTIO_NET_F_GUEST_CSUM)) { - dev->hw_ol_features |= NETDEV_TX_TCP_CKSUM_OFFLOAD; - dev->hw_ol_features |= NETDEV_TX_UDP_CKSUM_OFFLOAD; - dev->hw_ol_features |= NETDEV_TX_SCTP_CKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_TCP_CKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_UDP_CKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_SCTP_CKSUM_OFFLOAD; /* There is no support in virtio net to offload IPv4 csum, * but the vhost library handles IPv4 csum offloading. */ - dev->hw_ol_features |= NETDEV_TX_IPV4_CKSUM_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_IPV4_CKSUM_OFFLOAD; } if (userspace_tso_enabled() @@ -5059,24 +4988,24 @@ new_device(int vid) if (features & (1ULL << VIRTIO_NET_F_GUEST_TSO4) && features & (1ULL << VIRTIO_NET_F_GUEST_TSO6)) { - dev->hw_ol_features |= NETDEV_TX_TSO_OFFLOAD; + common->hw_ol_features |= NETDEV_TX_TSO_OFFLOAD; VLOG_DBG("%s: TSO enabled on vhost port", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); } else { VLOG_WARN("%s: Tx TSO offload is not supported.", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); } } } - netdev_dpdk_update_netdev_flags(dev); + netdev_dpdk_common_update_ol_flags(common); ovsrcu_index_set(&dev->vid, vid); exists = true; /* Disable notifications. */ set_irq_status(vid); - netdev_change_seq_changed(&dev->up); + netdev_change_seq_changed(netdev); ovs_mutex_unlock(&dev->mutex); break; } @@ -5101,10 +5030,11 @@ static void netdev_dpdk_txq_map_clear(struct netdev_dpdk *dev) OVS_REQUIRES(dev->mutex) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); int i; - for (i = 0; i < dev->up.n_txq; i++) { - dev->tx_q[i].map = OVS_VHOST_QUEUE_MAP_UNKNOWN; + for (i = 0; i < common->up.n_txq; i++) { + common->tx_q[i].map = OVS_VHOST_QUEUE_MAP_UNKNOWN; } } @@ -5125,7 +5055,10 @@ destroy_device(int vid) ovs_mutex_lock(&dpdk_mutex); LIST_FOR_EACH (dev, list_node, &dpdk_list) { - if (!is_vhost_class(dev->up.netdev_class)) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); + struct netdev *netdev = &common->up; + + if (!is_vhost_class(netdev->netdev_class)) { continue; } if (netdev_dpdk_get_vid(dev) == vid) { @@ -5134,14 +5067,14 @@ destroy_device(int vid) dev->vhost_reconfigured = false; ovsrcu_index_set(&dev->vid, -1); memset(dev->vhost_rxq_enabled, 0, - dev->up.n_rxq * sizeof *dev->vhost_rxq_enabled); + netdev->n_rxq * sizeof *dev->vhost_rxq_enabled); netdev_dpdk_txq_map_clear(dev); /* Clear offload capabilities before next new_device. */ - dev->hw_ol_features = 0; - netdev_dpdk_update_netdev_flags(dev); + common->hw_ol_features = 0; + netdev_dpdk_common_update_ol_flags(common); - netdev_change_seq_changed(&dev->up); + netdev_change_seq_changed(netdev); ovs_mutex_unlock(&dev->mutex); exists = true; break; @@ -5188,7 +5121,10 @@ vring_state_changed__(struct vhost_state_change *sc) ovs_mutex_lock(&dpdk_mutex); LIST_FOR_EACH (dev, list_node, &dpdk_list) { - if (!is_vhost_class(dev->up.netdev_class)) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); + struct netdev *netdev = &common->up; + + if (!is_vhost_class(netdev->netdev_class)) { continue; } ovs_mutex_lock(&dev->mutex); @@ -5198,13 +5134,13 @@ vring_state_changed__(struct vhost_state_change *sc) dev->vhost_rxq_enabled[qid] = sc->enable != 0; if (old_state != dev->vhost_rxq_enabled[qid]) { - netdev_change_seq_changed(&dev->up); + netdev_change_seq_changed(netdev); } } else { if (sc->enable) { - dev->tx_q[qid].map = qid; + common->tx_q[qid].map = qid; } else { - dev->tx_q[qid].map = OVS_VHOST_QUEUE_DISABLED; + common->tx_q[qid].map = OVS_VHOST_QUEUE_DISABLED; } netdev_dpdk_remap_txqs(dev); } @@ -5297,7 +5233,10 @@ destroy_connection(int vid) ovs_mutex_lock(&dpdk_mutex); LIST_FOR_EACH (dev, list_node, &dpdk_list) { - if (!is_vhost_class(dev->up.netdev_class)) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); + struct netdev *netdev = &common->up; + + if (!is_vhost_class(netdev->netdev_class)) { continue; } ovs_mutex_lock(&dev->mutex); @@ -5310,11 +5249,11 @@ destroy_connection(int vid) } /* Restore the number of queue pairs to default. */ - if (dev->requested_n_txq != qp_num - || dev->requested_n_rxq != qp_num) { - dev->requested_n_rxq = qp_num; - dev->requested_n_txq = qp_num; - netdev_request_reconfigure(&dev->up); + if (common->requested_n_txq != qp_num + || common->requested_n_rxq != qp_num) { + common->requested_n_rxq = qp_num; + common->requested_n_txq = qp_num; + netdev_request_reconfigure(netdev); } if (!(dev->virtio_features_state & OVS_VIRTIO_F_NEGOTIATED)) { @@ -5351,7 +5290,7 @@ destroy_connection(int vid) } if (!(dev->virtio_features_state & OVS_VIRTIO_F_NEGOTIATED)) { dev->virtio_features_state |= OVS_VIRTIO_F_RECONF_PENDING; - netdev_request_reconfigure(&dev->up); + netdev_request_reconfigure(netdev); } } @@ -6159,12 +6098,13 @@ dpdk_rx_steer_add_flow(struct netdev_dpdk *dev, const struct rte_flow_item items[], const char *desc) { + struct netdev *netdev = &dev->up; const struct rte_flow_attr attr = { .ingress = 1 }; const struct rte_flow_action actions[] = { { .type = RTE_FLOW_ACTION_TYPE_QUEUE, .conf = &(const struct rte_flow_action_queue) { - .index = dev->up.n_rxq - 1, + .index = netdev->n_rxq - 1, }, }, { .type = RTE_FLOW_ACTION_TYPE_END }, @@ -6178,7 +6118,7 @@ dpdk_rx_steer_add_flow(struct netdev_dpdk *dev, err = rte_flow_validate(dev->port_id, &attr, items, actions, &error); if (err) { VLOG_WARN("%s: rx-steering: device does not support %s flow: %s", - netdev_get_name(&dev->up), desc, + netdev_get_name(netdev), desc, error.message ? error.message : ""); goto out; } @@ -6187,7 +6127,7 @@ dpdk_rx_steer_add_flow(struct netdev_dpdk *dev, flow = rte_flow_create(dev->port_id, &attr, items, actions, &error); if (flow == NULL) { VLOG_WARN("%s: rx-steering: failed to add %s flow: %s", - netdev_get_name(&dev->up), desc, + netdev_get_name(netdev), desc, error.message ? error.message : ""); err = rte_errno; goto out; @@ -6199,7 +6139,7 @@ dpdk_rx_steer_add_flow(struct netdev_dpdk *dev, dev->rx_steer_flows_num = num; VLOG_INFO("%s: rx-steering: redirected %s traffic to rx queue %d", - netdev_get_name(&dev->up), desc, dev->up.n_rxq - 1); + netdev_get_name(netdev), desc, netdev->n_rxq - 1); out: return err; } @@ -6210,13 +6150,14 @@ static int dpdk_rx_steer_rss_configure(struct netdev_dpdk *dev, int rss_n_rxq) { struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE]; + struct netdev *netdev = &dev->up; struct rte_eth_dev_info info; int err; err = rte_eth_dev_info_get(dev->port_id, &info); if (err < 0) { VLOG_WARN("%s: failed to query RSS info: %s", - netdev_get_name(&dev->up), rte_strerror(-err)); + netdev_get_name(netdev), rte_strerror(-err)); goto error; } @@ -6261,7 +6202,7 @@ dpdk_rx_steer_rss_configure(struct netdev_dpdk *dev, int rss_n_rxq) err = rte_eth_dev_rss_reta_update(dev->port_id, reta_conf, info.reta_size); if (err < 0) { VLOG_WARN("%s: failed to configure RSS redirection table: err=%d", - netdev_get_name(&dev->up), err); + netdev_get_name(netdev), err); } error: @@ -6271,12 +6212,13 @@ error: static int dpdk_rx_steer_configure(struct netdev_dpdk *dev) { + struct netdev *netdev = &dev->up; int err = 0; - if (dev->up.n_rxq < 2) { + if (netdev->n_rxq < 2) { err = ENOTSUP; VLOG_WARN("%s: rx-steering: not enough available rx queues", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); goto out; } @@ -6301,16 +6243,16 @@ dpdk_rx_steer_configure(struct netdev_dpdk *dev) if (dev->rx_steer_flows_num) { /* Reconfigure RSS reta in all but the rx steering queue. */ - err = dpdk_rx_steer_rss_configure(dev, dev->up.n_rxq - 1); + err = dpdk_rx_steer_rss_configure(dev, netdev->n_rxq - 1); if (err) { goto out; } - if (dev->up.n_rxq == 2) { + if (netdev->n_rxq == 2) { VLOG_INFO("%s: rx-steering: redirected other traffic to " - "rx queue 0", netdev_get_name(&dev->up)); + "rx queue 0", netdev_get_name(netdev)); } else { VLOG_INFO("%s: rx-steering: applied rss on rx queues 0-%u", - netdev_get_name(&dev->up), dev->up.n_rxq - 2); + netdev_get_name(netdev), netdev->n_rxq - 2); } } @@ -6321,19 +6263,20 @@ out: static void dpdk_rx_steer_unconfigure(struct netdev_dpdk *dev) { + struct netdev *netdev = &dev->up; struct rte_flow_error error; if (!dev->rx_steer_flows_num) { return; } - VLOG_DBG("%s: rx-steering: reset flows", netdev_get_name(&dev->up)); + VLOG_DBG("%s: rx-steering: reset flows", netdev_get_name(netdev)); for (int i = 0; i < dev->rx_steer_flows_num; i++) { set_error(&error, RTE_FLOW_ERROR_TYPE_NONE); if (rte_flow_destroy(dev->port_id, dev->rx_steer_flows[i], &error)) { VLOG_WARN("%s: rx-steering: failed to destroy flow: %s", - netdev_get_name(&dev->up), + netdev_get_name(netdev), error.message ? error.message : ""); } } @@ -6350,6 +6293,7 @@ dpdk_rx_steer_unconfigure(struct netdev_dpdk *dev) static int netdev_dpdk_eth_reconfigure(struct netdev *netdev) { + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct dpdk_mp_config mp_cfg; bool pending_reset; @@ -6359,23 +6303,23 @@ netdev_dpdk_eth_reconfigure(struct netdev *netdev) ovs_mutex_lock(&dev->mutex); try_rx_steer = dev->requested_rx_steer_flags != 0; - dev->requested_n_rxq = dev->user_n_rxq; + common->requested_n_rxq = dev->user_n_rxq; if (try_rx_steer) { - dev->requested_n_rxq += 1; + common->requested_n_rxq += 1; } atomic_read_relaxed(&netdev_dpdk_pending_reset[dev->port_id], &pending_reset); - if (netdev->n_txq == dev->requested_n_txq - && netdev->n_rxq == dev->requested_n_rxq + if (netdev->n_txq == common->requested_n_txq + && netdev->n_rxq == common->requested_n_rxq && dev->rx_steer_flags == dev->requested_rx_steer_flags - && dev->mtu == dev->requested_mtu + && common->mtu == common->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 - && eth_addr_equals(dev->hwaddr, dev->requested_hwaddr) - && dev->socket_id == dev->requested_socket_id + && eth_addr_equals(common->hwaddr, dev->requested_hwaddr) + && common->socket_id == common->requested_socket_id && dev->started && !pending_reset) { /* Reconfiguration is unnecessary */ @@ -6400,31 +6344,31 @@ retry: dev->started = false; mp_cfg = (struct dpdk_mp_config){ - .name = dev->up.name, - .mtu = dev->requested_mtu, - .socket_id = dev->requested_socket_id, - .n_rxq = dev->requested_n_rxq, + .name = common->up.name, + .mtu = common->requested_mtu, + .socket_id = common->requested_socket_id, + .n_rxq = common->requested_n_rxq, .rxq_size = dev->requested_rxq_size, - .n_txq = dev->requested_n_txq, + .n_txq = common->requested_n_txq, .txq_size = dev->requested_txq_size, }; - err = netdev_dpdk_mempool_configure(dev, &mp_cfg); + err = netdev_dpdk_mempool_configure(common, &mp_cfg); if (err && err != EEXIST) { 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; + netdev->n_txq = common->requested_n_txq; + netdev->n_rxq = common->requested_n_rxq; dev->rxq_size = dev->requested_rxq_size; dev->txq_size = dev->requested_txq_size; - rte_free(dev->tx_q); - dev->tx_q = NULL; + rte_free(common->tx_q); + common->tx_q = NULL; - if (!eth_addr_equals(dev->hwaddr, dev->requested_hwaddr)) { + if (!eth_addr_equals(common->hwaddr, dev->requested_hwaddr)) { err = netdev_dpdk_eth_set_etheraddr__(dev, dev->requested_hwaddr); if (err) { goto out; @@ -6435,7 +6379,7 @@ retry: if (err) { goto out; } - netdev_dpdk_update_netdev_flags(dev); + netdev_dpdk_common_update_ol_flags(common); /* If both requested and actual hwaddr were previously * unset (initialized to 0), then first device init above @@ -6447,7 +6391,7 @@ retry: * configured by the user, as netdev_dpdk_eth_set_etheraddr__() * will have succeeded to get to this point. */ - dev->requested_hwaddr = dev->hwaddr; + dev->requested_hwaddr = common->hwaddr; if (try_rx_steer) { err = dpdk_rx_steer_configure(dev); @@ -6458,16 +6402,16 @@ retry: * The extra queue must be explicitly removed here to ensure that * it is unconfigured immediately. */ - dev->requested_n_rxq = dev->user_n_rxq; + common->requested_n_rxq = dev->user_n_rxq; goto retry; } } else { - VLOG_INFO("%s: rx-steering: default rss", netdev_get_name(&dev->up)); + VLOG_INFO("%s: rx-steering: default rss", netdev_get_name(netdev)); } dev->rx_steer_flags = dev->requested_rx_steer_flags; - dev->tx_q = netdev_dpdk_alloc_txq(netdev->n_txq); - if (!dev->tx_q) { + common->tx_q = netdev_dpdk_alloc_txq(netdev->n_txq); + if (!common->tx_q) { err = ENOMEM; } @@ -6482,41 +6426,44 @@ static int dpdk_vhost_reconfigure_helper(struct netdev_dpdk *dev) OVS_REQUIRES(dev->mutex) { - dev->up.n_txq = dev->requested_n_txq; - dev->up.n_rxq = dev->requested_n_rxq; + struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); + struct netdev *netdev = &common->up; + + netdev->n_txq = common->requested_n_txq; + netdev->n_rxq = common->requested_n_rxq; /* Always keep RX queue 0 enabled for implementations that won't * report vring states. */ dev->vhost_rxq_enabled[0] = true; /* Enable TX queue 0 by default if it wasn't disabled. */ - if (dev->tx_q[0].map == OVS_VHOST_QUEUE_MAP_UNKNOWN) { - dev->tx_q[0].map = 0; + if (common->tx_q[0].map == OVS_VHOST_QUEUE_MAP_UNKNOWN) { + common->tx_q[0].map = 0; } - rte_spinlock_lock(&dev->stats_lock); - memset(&dev->stats, 0, sizeof dev->stats); - memset(dev->sw_stats, 0, sizeof *dev->sw_stats); - rte_spinlock_unlock(&dev->stats_lock); + rte_spinlock_lock(&common->stats_lock); + memset(&common->stats, 0, sizeof common->stats); + memset(common->sw_stats, 0, sizeof *common->sw_stats); + rte_spinlock_unlock(&common->stats_lock); netdev_dpdk_remap_txqs(dev); if (netdev_dpdk_get_vid(dev) >= 0) { struct dpdk_mp_config mp_cfg = { - .name = dev->up.name, - .mtu = dev->requested_mtu, - .socket_id = dev->requested_socket_id, - .n_rxq = dev->requested_n_rxq, + .name = common->up.name, + .mtu = common->requested_mtu, + .socket_id = common->requested_socket_id, + .n_rxq = common->requested_n_rxq, .rxq_size = NIC_PORT_DEFAULT_RXQ_SIZE, - .n_txq = dev->requested_n_txq, + .n_txq = common->requested_n_txq, .txq_size = NIC_PORT_DEFAULT_TXQ_SIZE, }; int err; - err = netdev_dpdk_mempool_configure(dev, &mp_cfg); + err = netdev_dpdk_mempool_configure(common, &mp_cfg); if (!err) { /* A new mempool was created or re-used. */ - netdev_change_seq_changed(&dev->up); + netdev_change_seq_changed(netdev); } else if (err != EEXIST) { return err; } @@ -6524,11 +6471,11 @@ dpdk_vhost_reconfigure_helper(struct netdev_dpdk *dev) if (dev->vhost_reconfigured == false) { dev->vhost_reconfigured = true; /* Carrier status may need updating. */ - netdev_change_seq_changed(&dev->up); + netdev_change_seq_changed(netdev); } } - netdev_dpdk_update_netdev_flags(dev); + netdev_dpdk_common_update_ol_flags(common); return 0; } @@ -6627,14 +6574,14 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) dev->vhost_driver_flags |= vhost_flags; VLOG_INFO("vHost User device '%s' created in 'client' mode, " "using client socket '%s'", - dev->up.name, dev->vhost_id); + netdev->name, dev->vhost_id); } err = rte_vhost_driver_callback_register(dev->vhost_id, &virtio_net_device_ops); if (err) { VLOG_ERR("rte_vhost_driver_callback_register failed for " - "vhost user client port: %s\n", dev->up.name); + "vhost user client port: %s\n", netdev->name); goto unlock; } @@ -6642,7 +6589,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) virtio_unsup_features = 1ULL << VIRTIO_NET_F_HOST_ECN | 1ULL << VIRTIO_NET_F_HOST_UFO; VLOG_DBG("%s: TSO enabled on vhost port", - netdev_get_name(&dev->up)); + netdev_get_name(netdev)); } else { /* Advertise checksum offloading to the guest, but explicitly * disable TSO and friends. @@ -6657,7 +6604,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) virtio_unsup_features); if (err) { VLOG_ERR("rte_vhost_driver_disable_features failed for " - "vhost user client port: %s\n", dev->up.name); + "vhost user client port: %s\n", netdev->name); goto unlock; } @@ -6668,7 +6615,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) err = rte_vhost_driver_set_max_queue_num(dev->vhost_id, max_qp); if (err) { VLOG_ERR("rte_vhost_driver_set_max_queue_num failed for " - "vhost-user client port: %s\n", dev->up.name); + "vhost-user client port: %s\n", netdev->name); goto unlock; } } @@ -6676,7 +6623,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev) err = rte_vhost_driver_start(dev->vhost_id); if (err) { VLOG_ERR("rte_vhost_driver_start failed for vhost user " - "client port: %s\n", dev->up.name); + "client port: %s\n", netdev->name); goto unlock; } } @@ -6928,14 +6875,14 @@ static const struct netdev_class netdev_dpdk_class = { .dealloc = netdev_dpdk_eth_dealloc, .get_config = netdev_dpdk_eth_get_config, .set_config = netdev_dpdk_eth_set_config, - .get_numa_id = netdev_dpdk_get_numa_id, + .get_numa_id = netdev_dpdk_common_get_numa_id, .set_tx_multiq = netdev_dpdk_eth_set_tx_multiq, .send = netdev_dpdk_eth_send, .set_etheraddr = netdev_dpdk_eth_set_etheraddr, .get_etheraddr = netdev_dpdk_eth_get_etheraddr, - .get_mtu = netdev_dpdk_get_mtu, - .set_mtu = netdev_dpdk_set_mtu, - .get_ifindex = netdev_dpdk_get_ifindex, + .get_mtu = netdev_dpdk_eth_get_mtu, + .set_mtu = netdev_dpdk_eth_set_mtu, + .get_ifindex = netdev_dpdk_eth_get_ifindex, .get_carrier = netdev_dpdk_eth_get_carrier, .get_carrier_resets = netdev_dpdk_eth_get_carrier_resets, .get_stats = netdev_dpdk_eth_get_stats, @@ -6972,13 +6919,13 @@ static const struct netdev_class netdev_dpdk_vhost_class = { .construct = netdev_dpdk_vhost_construct, .destruct = netdev_dpdk_vhost_destruct, .dealloc = netdev_dpdk_vhost_dealloc, - .get_numa_id = netdev_dpdk_get_numa_id, + .get_numa_id = netdev_dpdk_common_get_numa_id, .send = netdev_dpdk_vhost_send, .set_etheraddr = netdev_dpdk_vhost_set_etheraddr, .get_etheraddr = netdev_dpdk_vhost_get_etheraddr, - .get_mtu = netdev_dpdk_get_mtu, - .set_mtu = netdev_dpdk_set_mtu, - .get_ifindex = netdev_dpdk_get_ifindex, + .get_mtu = netdev_dpdk_vhost_get_mtu, + .set_mtu = netdev_dpdk_vhost_set_mtu, + .get_ifindex = netdev_dpdk_vhost_get_ifindex, .get_carrier = netdev_dpdk_vhost_get_carrier, .get_stats = netdev_dpdk_vhost_get_stats, .get_custom_stats = netdev_dpdk_vhost_get_custom_stats, @@ -7014,13 +6961,13 @@ static const struct netdev_class netdev_dpdk_vhost_client_class = { .dealloc = netdev_dpdk_vhost_dealloc, .get_config = netdev_dpdk_vhost_client_get_config, .set_config = netdev_dpdk_vhost_client_set_config, - .get_numa_id = netdev_dpdk_get_numa_id, + .get_numa_id = netdev_dpdk_common_get_numa_id, .send = netdev_dpdk_vhost_send, .set_etheraddr = netdev_dpdk_vhost_set_etheraddr, .get_etheraddr = netdev_dpdk_vhost_get_etheraddr, - .get_mtu = netdev_dpdk_get_mtu, - .set_mtu = netdev_dpdk_set_mtu, - .get_ifindex = netdev_dpdk_get_ifindex, + .get_mtu = netdev_dpdk_vhost_get_mtu, + .set_mtu = netdev_dpdk_vhost_set_mtu, + .get_ifindex = netdev_dpdk_vhost_get_ifindex, .get_carrier = netdev_dpdk_vhost_get_carrier, .get_stats = netdev_dpdk_vhost_get_stats, .get_custom_stats = netdev_dpdk_vhost_get_custom_stats, -- 2.54.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
