net/enic: refactor Tx mbuf recycling
authorJohn Daley <johndale@cisco.com>
Fri, 3 Jun 2016 00:22:52 +0000 (17:22 -0700)
committerBruce Richardson <bruce.richardson@intel.com>
Wed, 15 Jun 2016 15:13:56 +0000 (17:13 +0200)
Mbufs were returned to the pool one at a time. Use rte_mempool_put_bulk
instead. There were multiple function calls for each buffer returned.
Refactor this code into just 2 functions.

Signed-off-by: John Daley <johndale@cisco.com>
drivers/net/enic/base/vnic_wq.h
drivers/net/enic/enic_rxtx.c

index fe46bb4..689b81c 100644 (file)
@@ -177,33 +177,6 @@ buf_idx_incr(uint32_t n_descriptors, uint32_t idx)
        return idx;
 }
 
        return idx;
 }
 
-static inline void vnic_wq_service(struct vnic_wq *wq,
-       struct cq_desc *cq_desc, u16 completed_index,
-       void (*buf_service)(struct vnic_wq *wq,
-       struct cq_desc *cq_desc, struct vnic_wq_buf *buf, void *opaque),
-       void *opaque)
-{
-       struct vnic_wq_buf *buf;
-       unsigned int to_clean = wq->tail_idx;
-
-       buf = &wq->bufs[to_clean];
-       while (1) {
-
-               (*buf_service)(wq, cq_desc, buf, opaque);
-
-               wq->ring.desc_avail++;
-
-
-               to_clean = buf_idx_incr(wq->ring.desc_count, to_clean);
-
-               if (to_clean == completed_index)
-                       break;
-
-               buf = &wq->bufs[to_clean];
-       }
-       wq->tail_idx = to_clean;
-}
-
 void vnic_wq_free(struct vnic_wq *wq);
 int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
        unsigned int desc_count, unsigned int desc_size);
 void vnic_wq_free(struct vnic_wq *wq);
 int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
        unsigned int desc_count, unsigned int desc_size);
index a36ee24..b3f74d5 100644 (file)
@@ -326,33 +326,49 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
        return nb_rx;
 }
 
        return nb_rx;
 }
 
-static void enic_wq_free_buf(struct vnic_wq *wq,
-       __rte_unused struct cq_desc *cq_desc,
-       struct vnic_wq_buf *buf,
-       __rte_unused void *opaque)
+static inline void enic_free_wq_bufs(struct vnic_wq *wq, u16 completed_index)
 {
 {
-       enic_free_wq_buf(wq, buf);
-}
-
-static int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc,
-       __rte_unused u8 type, u16 q_number, u16 completed_index, void *opaque)
-{
-       struct enic *enic = vnic_dev_priv(vdev);
+       struct vnic_wq_buf *buf;
+       struct rte_mbuf *m, *free[ENIC_MAX_WQ_DESCS];
+       unsigned int nb_to_free, nb_free = 0, i;
+       struct rte_mempool *pool;
+       unsigned int tail_idx;
+       unsigned int desc_count = wq->ring.desc_count;
+
+       nb_to_free = enic_ring_sub(desc_count, wq->tail_idx, completed_index)
+                                  + 1;
+       tail_idx = wq->tail_idx;
+       buf = &wq->bufs[tail_idx];
+       pool = ((struct rte_mbuf *)buf->mb)->pool;
+       for (i = 0; i < nb_to_free; i++) {
+               buf = &wq->bufs[tail_idx];
+               m = (struct rte_mbuf *)(buf->mb);
+               if (likely(m->pool == pool)) {
+                       free[nb_free++] = m;
+               } else {
+                       rte_mempool_put_bulk(pool, (void *)free, nb_free);
+                       free[0] = m;
+                       nb_free = 1;
+                       pool = m->pool;
+               }
+               tail_idx = enic_ring_incr(desc_count, tail_idx);
+               buf->mb = NULL;
+       }
 
 
-       vnic_wq_service(&enic->wq[q_number], cq_desc,
-               completed_index, enic_wq_free_buf,
-               opaque);
+       rte_mempool_put_bulk(pool, (void **)free, nb_free);
 
 
-       return 0;
+       wq->tail_idx = tail_idx;
+       wq->ring.desc_avail += nb_to_free;
 }
 
 }
 
-unsigned int enic_cleanup_wq(struct enic *enic, struct vnic_wq *wq)
+unsigned int enic_cleanup_wq(__rte_unused struct enic *enic, struct vnic_wq *wq)
 {
 {
-       u16 completed_index = *((uint32_t *)wq->cqmsg_rz->addr) & 0xffff;
+       u16 completed_index;
+
+       completed_index = *((uint32_t *)wq->cqmsg_rz->addr) & 0xffff;
 
        if (wq->last_completed_index != completed_index) {
 
        if (wq->last_completed_index != completed_index) {
-               enic_wq_service(enic->vdev, NULL, 0, wq->index,
-                               completed_index, NULL);
+               enic_free_wq_bufs(wq, completed_index);
                wq->last_completed_index = completed_index;
        }
        return 0;
                wq->last_completed_index = completed_index;
        }
        return 0;