New upstream version 18.11-rc1
[deb_dpdk.git] / drivers / net / ark / ark_ethdev_rx.c
index 16f0d11..300029d 100644 (file)
@@ -25,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 {
@@ -50,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 */
@@ -102,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);
+       }
 }
 
 /* ************************************************************************* */
@@ -196,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);
@@ -446,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) {
@@ -495,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)