net/mlx5: fix mark enabling for Rx
[dpdk.git] / drivers / net / af_xdp / rte_eth_af_xdp.c
index 917e0bb..b3ed704 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/ethtool.h>
 #include <linux/sockios.h>
 #include "af_xdp_deps.h"
+#include <bpf/bpf.h>
 #include <bpf/xsk.h>
 
 #include <rte_ethdev.h>
@@ -139,7 +140,7 @@ struct pmd_internals {
        bool shared_umem;
        char prog_path[PATH_MAX];
        bool custom_prog_configured;
-       bool use_bpf_link;
+       struct bpf_map *map;
 
        struct rte_ether_addr eth_addr;
 
@@ -696,67 +697,6 @@ find_internal_resource(struct pmd_internals *port_int)
        return list;
 }
 
-/* Check if the netdev,qid context already exists */
-static inline bool
-ctx_exists(struct pkt_rx_queue *rxq, const char *ifname,
-               struct pkt_rx_queue *list_rxq, const char *list_ifname)
-{
-       bool exists = false;
-
-       if (rxq->xsk_queue_idx == list_rxq->xsk_queue_idx &&
-                       !strncmp(ifname, list_ifname, IFNAMSIZ)) {
-               AF_XDP_LOG(ERR, "ctx %s,%i already exists, cannot share umem\n",
-                                       ifname, rxq->xsk_queue_idx);
-               exists = true;
-       }
-
-       return exists;
-}
-
-/* Get a pointer to an existing UMEM which overlays the rxq's mb_pool */
-static inline int
-get_shared_umem(struct pkt_rx_queue *rxq, const char *ifname,
-                       struct xsk_umem_info **umem)
-{
-       struct internal_list *list;
-       struct pmd_internals *internals;
-       int i = 0, ret = 0;
-       struct rte_mempool *mb_pool = rxq->mb_pool;
-
-       if (mb_pool == NULL)
-               return ret;
-
-       pthread_mutex_lock(&internal_list_lock);
-
-       TAILQ_FOREACH(list, &internal_list, next) {
-               internals = list->eth_dev->data->dev_private;
-               for (i = 0; i < internals->queue_cnt; i++) {
-                       struct pkt_rx_queue *list_rxq =
-                                               &internals->rx_queues[i];
-                       if (rxq == list_rxq)
-                               continue;
-                       if (mb_pool == internals->rx_queues[i].mb_pool) {
-                               if (ctx_exists(rxq, ifname, list_rxq,
-                                               internals->if_name)) {
-                                       ret = -1;
-                                       goto out;
-                               }
-                               if (__atomic_load_n(
-                                       &internals->rx_queues[i].umem->refcnt,
-                                                       __ATOMIC_ACQUIRE)) {
-                                       *umem = internals->rx_queues[i].umem;
-                                       goto out;
-                               }
-                       }
-               }
-       }
-
-out:
-       pthread_mutex_unlock(&internal_list_lock);
-
-       return ret;
-}
-
 static int
 eth_dev_configure(struct rte_eth_dev *dev)
 {
@@ -973,8 +913,7 @@ eth_dev_close(struct rte_eth_dev *dev)
         */
        dev->data->mac_addrs = NULL;
 
-       if (!internals->use_bpf_link)
-               remove_xdp_program(internals);
+       remove_xdp_program(internals);
 
        if (internals->shared_umem) {
                struct internal_list *list;
@@ -1013,6 +952,66 @@ static inline uintptr_t get_base_addr(struct rte_mempool *mp, uint64_t *align)
        return aligned_addr;
 }
 
+/* Check if the netdev,qid context already exists */
+static inline bool
+ctx_exists(struct pkt_rx_queue *rxq, const char *ifname,
+               struct pkt_rx_queue *list_rxq, const char *list_ifname)
+{
+       bool exists = false;
+
+       if (rxq->xsk_queue_idx == list_rxq->xsk_queue_idx &&
+                       !strncmp(ifname, list_ifname, IFNAMSIZ)) {
+               AF_XDP_LOG(ERR, "ctx %s,%i already exists, cannot share umem\n",
+                                       ifname, rxq->xsk_queue_idx);
+               exists = true;
+       }
+
+       return exists;
+}
+
+/* Get a pointer to an existing UMEM which overlays the rxq's mb_pool */
+static inline int
+get_shared_umem(struct pkt_rx_queue *rxq, const char *ifname,
+                       struct xsk_umem_info **umem)
+{
+       struct internal_list *list;
+       struct pmd_internals *internals;
+       int i = 0, ret = 0;
+       struct rte_mempool *mb_pool = rxq->mb_pool;
+
+       if (mb_pool == NULL)
+               return ret;
+
+       pthread_mutex_lock(&internal_list_lock);
+
+       TAILQ_FOREACH(list, &internal_list, next) {
+               internals = list->eth_dev->data->dev_private;
+               for (i = 0; i < internals->queue_cnt; i++) {
+                       struct pkt_rx_queue *list_rxq =
+                                               &internals->rx_queues[i];
+                       if (rxq == list_rxq)
+                               continue;
+                       if (mb_pool == internals->rx_queues[i].mb_pool) {
+                               if (ctx_exists(rxq, ifname, list_rxq,
+                                               internals->if_name)) {
+                                       ret = -1;
+                                       goto out;
+                               }
+                               if (__atomic_load_n(&internals->rx_queues[i].umem->refcnt,
+                                                   __ATOMIC_ACQUIRE)) {
+                                       *umem = internals->rx_queues[i].umem;
+                                       goto out;
+                               }
+                       }
+               }
+       }
+
+out:
+       pthread_mutex_unlock(&internal_list_lock);
+
+       return ret;
+}
+
 static struct
 xsk_umem_info *xdp_umem_configure(struct pmd_internals *internals,
                                  struct pkt_rx_queue *rxq)
@@ -1149,11 +1148,10 @@ err:
 }
 
 static int
-load_custom_xdp_prog(const char *prog_path, int if_index, bool use_bpf_link)
+load_custom_xdp_prog(const char *prog_path, int if_index, struct bpf_map **map)
 {
        int ret, prog_fd = -1;
        struct bpf_object *obj;
-       struct bpf_map *map;
 
        ret = bpf_prog_load(prog_path, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
        if (ret) {
@@ -1163,17 +1161,17 @@ load_custom_xdp_prog(const char *prog_path, int if_index, bool use_bpf_link)
 
        /*
         * The loaded program must provision for a map of xsks, such that some
-        * traffic can be redirected to userspace. When the xsk is created,
-        * libbpf inserts it into the map.
+        * traffic can be redirected to userspace.
         */
-       map = bpf_object__find_map_by_name(obj, "xsks_map");
-       if (!map) {
+       *map = bpf_object__find_map_by_name(obj, "xsks_map");
+       if (!*map) {
                AF_XDP_LOG(ERR, "Failed to find xsks_map in %s\n", prog_path);
                return -1;
        }
 
        /* Link the program with the given network device */
-       ret = link_xdp_program(if_index, prog_fd, use_bpf_link);
+       ret = bpf_set_link_xdp_fd(if_index, prog_fd,
+                                       XDP_FLAGS_UPDATE_IF_NOEXIST);
        if (ret) {
                AF_XDP_LOG(ERR, "Failed to set prog fd %d on interface\n",
                                prog_fd);
@@ -1274,13 +1272,14 @@ xsk_configure(struct pmd_internals *internals, struct pkt_rx_queue *rxq,
                                !internals->custom_prog_configured) {
                ret = load_custom_xdp_prog(internals->prog_path,
                                           internals->if_index,
-                                          internals->use_bpf_link);
+                                          &internals->map);
                if (ret) {
                        AF_XDP_LOG(ERR, "Failed to load custom XDP program %s\n",
                                        internals->prog_path);
                        goto err;
                }
                internals->custom_prog_configured = 1;
+               cfg.libbpf_flags = XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD;
        }
 
        if (internals->shared_umem)
@@ -1297,6 +1296,19 @@ xsk_configure(struct pmd_internals *internals, struct pkt_rx_queue *rxq,
                goto err;
        }
 
+       /* insert the xsk into the xsks_map */
+       if (internals->custom_prog_configured) {
+               int err, fd;
+
+               fd = xsk_socket__fd(rxq->xsk);
+               err = bpf_map_update_elem(bpf_map__fd(internals->map),
+                                         &rxq->xsk_queue_idx, &fd, 0);
+               if (err) {
+                       AF_XDP_LOG(ERR, "Failed to insert xsk in map.\n");
+                       goto err;
+               }
+       }
+
 #if defined(XDP_UMEM_UNALIGNED_CHUNK_FLAG)
        ret = rte_pktmbuf_alloc_bulk(rxq->umem->mb_pool, fq_bufs, reserve_size);
        if (ret) {
@@ -1691,7 +1703,6 @@ init_internals(struct rte_vdev_device *dev, const char *if_name,
        strlcpy(internals->if_name, if_name, IFNAMSIZ);
        strlcpy(internals->prog_path, prog_path, PATH_MAX);
        internals->custom_prog_configured = 0;
-       internals->use_bpf_link = probe_bpf_link();
 
 #ifndef ETH_AF_XDP_SHARED_UMEM
        if (shared_umem) {