ethdev: make stats and xstats reset callbacks return int
[dpdk.git] / drivers / net / af_xdp / rte_eth_af_xdp.c
index c638d92..f9686c2 100644 (file)
@@ -5,6 +5,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <poll.h>
 #include <netinet/in.h>
 #include <net/if.h>
 #include <sys/socket.h>
@@ -55,7 +56,7 @@ static int af_xdp_logtype;
        rte_log(RTE_LOG_ ## level, af_xdp_logtype,      \
                "%s(): " fmt, __func__, ##args)
 
-#define ETH_AF_XDP_FRAME_SIZE          XSK_UMEM__DEFAULT_FRAME_SIZE
+#define ETH_AF_XDP_FRAME_SIZE          2048
 #define ETH_AF_XDP_NUM_BUFFERS         4096
 #define ETH_AF_XDP_DATA_HEADROOM       0
 #define ETH_AF_XDP_DFLT_NUM_DESCS      XSK_RING_CONS__DEFAULT_NUM_DESCS
@@ -90,12 +91,12 @@ struct pkt_rx_queue {
        struct rx_stats stats;
 
        struct pkt_tx_queue *pair;
+       struct pollfd fds[1];
        int xsk_queue_idx;
 };
 
 struct tx_stats {
        uint64_t tx_pkts;
-       uint64_t err_pkts;
        uint64_t tx_bytes;
 };
 
@@ -206,8 +207,14 @@ eth_af_xdp_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
                return 0;
 
        rcvd = xsk_ring_cons__peek(rx, nb_pkts, &idx_rx);
-       if (rcvd == 0)
+       if (rcvd == 0) {
+#if defined(XDP_USE_NEED_WAKEUP)
+               if (xsk_ring_prod__needs_wakeup(fq))
+                       (void)poll(rxq->fds, 1, 1000);
+#endif
+
                goto out;
+       }
 
        if (xsk_prod_nb_free(fq, free_thresh) >= free_thresh)
                (void)reserve_fill_queue(umem, ETH_AF_XDP_RX_BATCH_SIZE);
@@ -279,16 +286,19 @@ kick_tx(struct pkt_tx_queue *txq)
 {
        struct xsk_umem_info *umem = txq->pair->umem;
 
-       while (send(xsk_socket__fd(txq->pair->xsk), NULL,
-                     0, MSG_DONTWAIT) < 0) {
-               /* some thing unexpected */
-               if (errno != EBUSY && errno != EAGAIN && errno != EINTR)
-                       break;
-
-               /* pull from completion queue to leave more space */
-               if (errno == EAGAIN)
-                       pull_umem_cq(umem, ETH_AF_XDP_TX_BATCH_SIZE);
-       }
+#if defined(XDP_USE_NEED_WAKEUP)
+       if (xsk_ring_prod__needs_wakeup(&txq->tx))
+#endif
+               while (send(xsk_socket__fd(txq->pair->xsk), NULL,
+                           0, MSG_DONTWAIT) < 0) {
+                       /* some thing unexpected */
+                       if (errno != EBUSY && errno != EAGAIN && errno != EINTR)
+                               break;
+
+                       /* pull from completion queue to leave more space */
+                       if (errno == EAGAIN)
+                               pull_umem_cq(umem, ETH_AF_XDP_TX_BATCH_SIZE);
+               }
        pull_umem_cq(umem, ETH_AF_XDP_TX_BATCH_SIZE);
 }
 
@@ -393,7 +403,7 @@ eth_dev_configure(struct rte_eth_dev *dev)
        return 0;
 }
 
-static void
+static int
 eth_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
        struct pmd_internals *internals = dev->data->dev_private;
@@ -411,6 +421,8 @@ eth_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        dev_info->default_txportconf.nb_queues = 1;
        dev_info->default_rxportconf.ring_size = ETH_AF_XDP_DFLT_NUM_DESCS;
        dev_info->default_txportconf.ring_size = ETH_AF_XDP_DFLT_NUM_DESCS;
+
+       return 0;
 }
 
 static int
@@ -445,14 +457,13 @@ eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
                stats->imissed += xdp_stats.rx_dropped;
 
                stats->opackets += stats->q_opackets[i];
-               stats->oerrors += txq->stats.err_pkts;
                stats->obytes += stats->q_obytes[i];
        }
 
        return 0;
 }
 
-static void
+static int
 eth_stats_reset(struct rte_eth_dev *dev)
 {
        struct pmd_internals *internals = dev->data->dev_private;
@@ -464,6 +475,8 @@ eth_stats_reset(struct rte_eth_dev *dev)
                memset(&internals->tx_queues[i].stats, 0,
                                        sizeof(struct tx_stats));
        }
+
+       return 0;
 }
 
 static void
@@ -622,6 +635,11 @@ xsk_configure(struct pmd_internals *internals, struct pkt_rx_queue *rxq,
        cfg.libbpf_flags = 0;
        cfg.xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
        cfg.bind_flags = 0;
+
+#if defined(XDP_USE_NEED_WAKEUP)
+       cfg.bind_flags |= XDP_USE_NEED_WAKEUP;
+#endif
+
        ret = xsk_socket__create(&rxq->xsk, internals->if_name,
                        rxq->xsk_queue_idx, rxq->umem->umem, &rxq->rx,
                        &txq->tx, &cfg);
@@ -683,6 +701,9 @@ eth_rx_queue_setup(struct rte_eth_dev *dev,
                goto err;
        }
 
+       rxq->fds[0].fd = xsk_socket__fd(rxq->xsk);
+       rxq->fds[0].events = POLLIN;
+
        rxq->umem->pmd_zc = internals->pmd_zc;
 
        dev->data->rx_queues[rx_queue_id] = rxq;
@@ -727,41 +748,47 @@ eth_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
        return (ret < 0) ? -errno : 0;
 }
 
-static void
+static int
 eth_dev_change_flags(char *if_name, uint32_t flags, uint32_t mask)
 {
        struct ifreq ifr;
+       int ret = 0;
        int s;
 
        s = socket(PF_INET, SOCK_DGRAM, 0);
        if (s < 0)
-               return;
+               return -errno;
 
        strlcpy(ifr.ifr_name, if_name, IFNAMSIZ);
-       if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
+       if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
+               ret = -errno;
                goto out;
+       }
        ifr.ifr_flags &= mask;
        ifr.ifr_flags |= flags;
-       if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0)
+       if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) {
+               ret = -errno;
                goto out;
+       }
 out:
        close(s);
+       return ret;
 }
 
-static void
+static int
 eth_dev_promiscuous_enable(struct rte_eth_dev *dev)
 {
        struct pmd_internals *internals = dev->data->dev_private;
 
-       eth_dev_change_flags(internals->if_name, IFF_PROMISC, ~0);
+       return eth_dev_change_flags(internals->if_name, IFF_PROMISC, ~0);
 }
 
-static void
+static int
 eth_dev_promiscuous_disable(struct rte_eth_dev *dev)
 {
        struct pmd_internals *internals = dev->data->dev_private;
 
-       eth_dev_change_flags(internals->if_name, 0, ~IFF_PROMISC);
+       return eth_dev_change_flags(internals->if_name, 0, ~IFF_PROMISC);
 }
 
 static const struct eth_dev_ops ops = {
@@ -833,9 +860,13 @@ xdp_get_channels_info(const char *if_name, int *max_queues,
        ifr.ifr_data = (void *)&channels;
        strncpy(ifr.ifr_name, if_name, IFNAMSIZ);
        ret = ioctl(fd, SIOCETHTOOL, &ifr);
-       if (ret && errno != EOPNOTSUPP) {
-               ret = -errno;
-               goto out;
+       if (ret) {
+               if (errno == EOPNOTSUPP) {
+                       ret = 0;
+               } else {
+                       ret = -errno;
+                       goto out;
+               }
        }
 
        if (channels.max_combined == 0 || errno == EOPNOTSUPP) {