]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/seastar/dpdk/drivers/net/ark/ark_ethdev_rx.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / seastar / dpdk / drivers / net / ark / ark_ethdev_rx.c
index f39e6f68ac9fe225e0020363cffcc61403f8a7e7..300029d6b86ebdd154bb9e7e98ffe9e523021687 100644 (file)
@@ -1,34 +1,5 @@
-/*-
- * BSD LICENSE
- *
- * Copyright (c) 2015-2017 Atomic Rules LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of copyright holder nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
 #include <unistd.h>
@@ -36,7 +7,6 @@
 #include "ark_ethdev_rx.h"
 #include "ark_global.h"
 #include "ark_logs.h"
-#include "ark_ethdev.h"
 #include "ark_mpu.h"
 #include "ark_udm.h"
 
@@ -55,6 +25,9 @@ static uint32_t eth_ark_rx_jumbo(struct ark_rx_queue *queue,
                                 struct rte_mbuf *mbuf0,
                                 uint32_t cons_index);
 static inline int eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue);
+static int eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
+                                   uint32_t *pnb,
+                                   struct rte_mbuf **mbufs);
 
 /* ************************************************************************* */
 struct ark_rx_queue {
@@ -62,7 +35,7 @@ struct ark_rx_queue {
        struct rte_mbuf **reserve_q;
        /* array of physical addresses of the mbuf data pointer */
        /* This point is a virtual address */
-       phys_addr_t *paddress_q;
+       rte_iova_t *paddress_q;
        struct rte_mempool *mb_pool;
 
        struct ark_udm_t *udm;
@@ -80,7 +53,7 @@ struct ark_rx_queue {
        /* The queue Index is used within the dpdk device structures */
        uint16_t queue_index;
 
-       uint32_t pad1;
+       uint32_t last_cons;
 
        /* separate cache line */
        /* second cache line - fields only used in slow path */
@@ -96,18 +69,18 @@ eth_ark_rx_hw_setup(struct rte_eth_dev *dev,
                    struct ark_rx_queue *queue,
                    uint16_t rx_queue_id __rte_unused, uint16_t rx_queue_idx)
 {
-       phys_addr_t queue_base;
-       phys_addr_t phys_addr_q_base;
-       phys_addr_t phys_addr_prod_index;
+       rte_iova_t queue_base;
+       rte_iova_t phys_addr_q_base;
+       rte_iova_t phys_addr_prod_index;
 
-       queue_base = rte_malloc_virt2phy(queue);
+       queue_base = rte_malloc_virt2iova(queue);
        phys_addr_prod_index = queue_base +
                offsetof(struct ark_rx_queue, prod_index);
 
-       phys_addr_q_base = rte_malloc_virt2phy(queue->paddress_q);
+       phys_addr_q_base = rte_malloc_virt2iova(queue->paddress_q);
 
        /* Verify HW */
-       if (ark_mpu_verify(queue->mpu, sizeof(phys_addr_t))) {
+       if (ark_mpu_verify(queue->mpu, sizeof(rte_iova_t))) {
                PMD_DRV_LOG(ERR, "Illegal configuration rx queue\n");
                return -1;
        }
@@ -132,7 +105,10 @@ eth_ark_rx_update_cons_index(struct ark_rx_queue *queue, uint32_t cons_index)
 {
        queue->cons_index = cons_index;
        eth_ark_rx_seed_mbufs(queue);
-       ark_mpu_set_producer(queue->mpu, queue->seed_index);
+       if (((cons_index - queue->last_cons) >= 64U)) {
+               queue->last_cons = cons_index;
+               ark_mpu_set_producer(queue->mpu, queue->seed_index);
+       }
 }
 
 /* ************************************************************************* */
@@ -205,7 +181,7 @@ eth_ark_dev_rx_queue_setup(struct rte_eth_dev *dev,
                                   socket_id);
        queue->paddress_q =
                rte_zmalloc_socket("Ark_rx_queue paddr",
-                                  nb_desc * sizeof(phys_addr_t),
+                                  nb_desc * sizeof(rte_iova_t),
                                   64,
                                   socket_id);
 
@@ -226,20 +202,25 @@ eth_ark_dev_rx_queue_setup(struct rte_eth_dev *dev,
        /* populate mbuf reserve */
        status = eth_ark_rx_seed_mbufs(queue);
 
+       if (queue->seed_index != nb_desc) {
+               PMD_DRV_LOG(ERR, "ARK: Failed to allocate %u mbufs for RX queue %d\n",
+                           nb_desc, qidx);
+               status = -1;
+       }
        /* MPU Setup */
        if (status == 0)
                status = eth_ark_rx_hw_setup(dev, queue, qidx, queue_idx);
 
        if (unlikely(status != 0)) {
-               struct rte_mbuf *mbuf;
+               struct rte_mbuf **mbuf;
 
                PMD_DRV_LOG(ERR, "Failed to initialize RX queue %d %s\n",
                            qidx,
                            __func__);
                /* Free the mbufs allocated */
-               for (i = 0, mbuf = queue->reserve_q[0];
-                    i < nb_desc; ++i, mbuf++) {
-                       rte_pktmbuf_free(mbuf);
+               for (i = 0, mbuf = queue->reserve_q;
+                    i < queue->seed_index; ++i, mbuf++) {
+                       rte_pktmbuf_free(*mbuf);
                }
                rte_free(queue->reserve_q);
                rte_free(queue->paddress_q);
@@ -357,7 +338,7 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 
        uint16_t remaining;
        uint16_t data_len;
-       uint8_t segments;
+       uint16_t segments;
 
        /* first buf populated by called */
        mbuf_prev = mbuf0;
@@ -476,8 +457,13 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
        struct rte_mbuf **mbufs = &queue->reserve_q[seed_m];
        int status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, nb);
 
-       if (unlikely(status != 0))
-               return -1;
+       if (unlikely(status != 0)) {
+               /* Try to recover from lack of mbufs in pool */
+               status = eth_ark_rx_seed_recovery(queue, &nb, mbufs);
+               if (unlikely(status != 0)) {
+                       return -1;
+               }
+       }
 
        if (ARK_RX_DEBUG) {             /* DEBUG */
                while (count != nb) {
@@ -500,22 +486,22 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
        case 0:
                while (count != nb) {
                        queue->paddress_q[seed_m++] =
-                               (*mbufs++)->buf_physaddr;
+                               (*mbufs++)->buf_iova;
                        count++;
                /* FALLTHROUGH */
        case 3:
                queue->paddress_q[seed_m++] =
-                       (*mbufs++)->buf_physaddr;
+                       (*mbufs++)->buf_iova;
                count++;
                /* FALLTHROUGH */
        case 2:
                queue->paddress_q[seed_m++] =
-                       (*mbufs++)->buf_physaddr;
+                       (*mbufs++)->buf_iova;
                count++;
                /* FALLTHROUGH */
        case 1:
                queue->paddress_q[seed_m++] =
-                       (*mbufs++)->buf_physaddr;
+                       (*mbufs++)->buf_iova;
                count++;
                /* FALLTHROUGH */
 
@@ -525,6 +511,29 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
        return 0;
 }
 
+int
+eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
+                        uint32_t *pnb,
+                        struct rte_mbuf **mbufs)
+{
+       int status = -1;
+
+       /* Ignore small allocation failures */
+       if (*pnb <= 64)
+               return -1;
+
+       *pnb = 64U;
+       status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, *pnb);
+       if (status != 0) {
+               PMD_DRV_LOG(ERR,
+                           "ARK: Could not allocate %u mbufs from pool for RX queue %u;"
+                           " %u free buffers remaining in queue\n",
+                           *pnb, queue->queue_index,
+                           queue->seed_index - queue->cons_index);
+       }
+       return status;
+}
+
 void
 eth_ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id,
                      const char *msg)