The patch adds support for using DPDK's AF_XDP PMD.
Base on DPDK 19.08-rc0:
commit c6a53a6bcd0ae52afe0a6d58b059af577c9408b3
Author: Thomas Monjalon <[email protected]>
Date: Tue May 14 18:04:37 2019 +0200
version: 19.08-rc0
An AF_XDP PMD can be created by:
$ ovs-vsctl add-port br0 afxdp-p0 -- set int afxdp-p0 type=dpdk \
options:dpdk-devargs=net_af_xdp,iface=enp2s0,queue=0
$ ovs-vsctl show
Port "afxdp-p0"
Interface "afxdp-p0"
type: dpdk
options: {dpdk-devargs="net_af_xdp,iface=enp2s0,queue=0"}
The performance of physical device loopback shows around 7Mpps with 64B pkt.
$ ovs-ofctl add-flow br0 "in_port=afxdp-p0, \
actions=set_field:14->in_port,set_field:a0:36:9f:33:b1:40->dl_src,afxdp-p0"
Note: I have to set e_RTE_METER_GREEN to 0 to pass compile.
Signed-off-by: William Tu <[email protected]>
---
lib/netdev-dpdk.c | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 47153dc60148..99697bc896ca 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -380,6 +380,8 @@ struct netdev_dpdk {
/* If true, device was attached by rte_eth_dev_attach(). */
bool attached;
+ /* If true, device was hop plugged by rte_eal_hotplug_add(). */
+ bool hotplugged;
/* If true, rte_eth_dev_start() was successfully called */
bool started;
struct eth_addr hwaddr;
@@ -1376,6 +1378,14 @@ netdev_dpdk_destruct(struct netdev *netdev)
rte_eth_dev_stop(dev->port_id);
dev->started = false;
+ if (dev->hotplugged) {
+ int ret;
+ ret = rte_eal_hotplug_remove("vdev", "net_af_xdp");
+ if (ret) {
+ VLOG_ERR("%s unplugged error %d", __func__, ret);
+ }
+ }
+
if (dev->attached) {
/* Retrieve eth device data before closing it.
* FIXME: avoid direct access to DPDK internal array rte_eth_devices.
@@ -1648,6 +1658,26 @@ netdev_dpdk_lookup_by_port_id(dpdk_port_t port_id)
}
static dpdk_port_t
+netdev_dpdk_get_af_xdp_port(const char *vdev_args)
+{
+ const char vdev_name[] = "net_af_xdp";
+ dpdk_port_t port_id;
+
+ if (rte_eal_hotplug_add("vdev", vdev_name, vdev_args) < 0) {
+ VLOG_WARN("Cannot hotplug AF_XDP device: %s\n", vdev_args);
+ return DPDK_ETH_PORT_ID_INVALID;
+ }
+
+ if (rte_eth_dev_get_port_by_name(vdev_name, &port_id) != 0) {
+ rte_eal_hotplug_remove("vdev", vdev_name);
+ VLOG_WARN("Cannot get AF_XDP port_id, device: %s\n", vdev_args);
+ return DPDK_ETH_PORT_ID_INVALID;
+ }
+
+ return port_id;
+}
+
+static dpdk_port_t
netdev_dpdk_get_port_by_mac(const char *mac_str)
{
dpdk_port_t port_id;
@@ -1705,7 +1735,11 @@ netdev_dpdk_process_devargs(struct netdev_dpdk *dev,
{
dpdk_port_t new_port_id;
- if (strncmp(devargs, "class=eth,mac=", 14) == 0) {
+ if (strncmp(devargs, "net_af_xdp", 10) == 0) {
+ new_port_id = netdev_dpdk_get_af_xdp_port(&devargs[11]);
+ dev->hotplugged = true;
+ VLOG_INFO("Device '%s' hotplugged to DPDK", devargs);
+ } else if (strncmp(devargs, "class=eth,mac=", 14) == 0) {
new_port_id = netdev_dpdk_get_port_by_mac(&devargs[14]);
} else {
new_port_id = netdev_dpdk_get_port_by_devargs(devargs);
@@ -2031,7 +2065,7 @@ netdev_dpdk_policer_pkt_handle(struct rte_meter_srtcm
*meter,
uint32_t pkt_len = rte_pktmbuf_pkt_len(pkt) - sizeof(struct ether_hdr);
return rte_meter_srtcm_color_blind_check(meter, profile, time, pkt_len) ==
- e_RTE_METER_GREEN;
+ 0; /* e_RTE_METER_GREEN */
}
static int
--
2.7.4
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev