@@ -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
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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 */
@@ -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,
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 <david.marchand@redhat.com> --- 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