mempool: store memory chunks in a list
[dpdk.git] / drivers / net / mlx4 / mlx4.c
index f946f08..67851b6 100644 (file)
@@ -1047,14 +1047,20 @@ error:
 static void
 txq_free_elts(struct txq *txq)
 {
-       unsigned int i;
        unsigned int elts_n = txq->elts_n;
+       unsigned int elts_head = txq->elts_head;
+       unsigned int elts_tail = txq->elts_tail;
        struct txq_elt (*elts)[elts_n] = txq->elts;
        linear_t (*elts_linear)[elts_n] = txq->elts_linear;
        struct ibv_mr *mr_linear = txq->mr_linear;
 
        DEBUG("%p: freeing WRs", (void *)txq);
        txq->elts_n = 0;
+       txq->elts_head = 0;
+       txq->elts_tail = 0;
+       txq->elts_comp = 0;
+       txq->elts_comp_cd = 0;
+       txq->elts_comp_cd_init = 0;
        txq->elts = NULL;
        txq->elts_linear = NULL;
        txq->mr_linear = NULL;
@@ -1064,12 +1070,17 @@ txq_free_elts(struct txq *txq)
        rte_free(elts_linear);
        if (elts == NULL)
                return;
-       for (i = 0; (i != elemof(*elts)); ++i) {
-               struct txq_elt *elt = &(*elts)[i];
+       while (elts_tail != elts_head) {
+               struct txq_elt *elt = &(*elts)[elts_tail];
 
-               if (elt->buf == NULL)
-                       continue;
+               assert(elt->buf != NULL);
                rte_pktmbuf_free(elt->buf);
+#ifndef NDEBUG
+               /* Poisoning. */
+               memset(elt, 0x77, sizeof(*elt));
+#endif
+               if (++elts_tail == elts_n)
+                       elts_tail = 0;
        }
        rte_free(elts);
 }
@@ -1206,8 +1217,8 @@ static struct ibv_mr *
 mlx4_mp2mr(struct ibv_pd *pd, const struct rte_mempool *mp)
 {
        const struct rte_memseg *ms = rte_eal_get_physmem_layout();
-       uintptr_t start = mp->elt_va_start;
-       uintptr_t end = mp->elt_va_end;
+       uintptr_t start = (uintptr_t)STAILQ_FIRST(&mp->mem_list)->addr;
+       uintptr_t end = start + STAILQ_FIRST(&mp->mem_list)->len;
        unsigned int i;
 
        DEBUG("mempool %p area start=%p end=%p size=%zu",
@@ -1309,7 +1320,6 @@ txq_mp2mr(struct txq *txq, const struct rte_mempool *mp)
 }
 
 struct txq_mp2mr_mbuf_check_data {
-       const struct rte_mempool *mp;
        int ret;
 };
 
@@ -1317,34 +1327,26 @@ struct txq_mp2mr_mbuf_check_data {
  * Callback function for rte_mempool_obj_iter() to check whether a given
  * mempool object looks like a mbuf.
  *
- * @param[in, out] arg
- *   Context data (struct txq_mp2mr_mbuf_check_data). Contains mempool pointer
- *   and return value.
- * @param[in] start
- *   Object start address.
- * @param[in] end
- *   Object end address.
+ * @param[in] mp
+ *   The mempool pointer
+ * @param[in] arg
+ *   Context data (struct txq_mp2mr_mbuf_check_data). Contains the
+ *   return value.
+ * @param[in] obj
+ *   Object address.
  * @param index
- *   Unused.
- *
- * @return
- *   Nonzero value when object is not a mbuf.
+ *   Object index, unused.
  */
 static void
-txq_mp2mr_mbuf_check(void *arg, void *start, void *end,
-                    uint32_t index __rte_unused)
+txq_mp2mr_mbuf_check(struct rte_mempool *mp, void *arg, void *obj,
+       uint32_t index __rte_unused)
 {
        struct txq_mp2mr_mbuf_check_data *data = arg;
-       struct rte_mbuf *buf =
-               (void *)((uintptr_t)start + data->mp->header_size);
+       struct rte_mbuf *buf = obj;
 
-       (void)index;
        /* Check whether mbuf structure fits element size and whether mempool
         * pointer is valid. */
-       if (((uintptr_t)end >= (uintptr_t)(buf + 1)) &&
-           (buf->pool == data->mp))
-               data->ret = 0;
-       else
+       if (sizeof(*buf) > mp->elt_size || buf->pool != mp)
                data->ret = -1;
 }
 
@@ -1358,28 +1360,16 @@ txq_mp2mr_mbuf_check(void *arg, void *start, void *end,
  *   Pointer to TX queue structure.
  */
 static void
-txq_mp2mr_iter(const struct rte_mempool *mp, void *arg)
+txq_mp2mr_iter(struct rte_mempool *mp, void *arg)
 {
        struct txq *txq = arg;
        struct txq_mp2mr_mbuf_check_data data = {
-               .mp = mp,
-               .ret = -1,
+               .ret = 0,
        };
 
-       /* Discard empty mempools. */
-       if (mp->size == 0)
-               return;
        /* Register mempool only if the first element looks like a mbuf. */
-       rte_mempool_obj_iter((void *)mp->elt_va_start,
-                            1,
-                            mp->header_size + mp->elt_size + mp->trailer_size,
-                            1,
-                            mp->elt_pa,
-                            mp->pg_num,
-                            mp->pg_shift,
-                            txq_mp2mr_mbuf_check,
-                            &data);
-       if (data.ret)
+       if (rte_mempool_obj_iter(mp, txq_mp2mr_mbuf_check, &data) == 0 ||
+                       data.ret == -1)
                return;
        txq_mp2mr(txq, mp);
 }
@@ -1588,6 +1578,10 @@ mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n)
                if (likely(elt->buf != NULL)) {
                        struct rte_mbuf *tmp = elt->buf;
 
+#ifndef NDEBUG
+                       /* Poisoning. */
+                       memset(elt, 0x66, sizeof(*elt));
+#endif
                        /* Faster than rte_pktmbuf_free(). */
                        do {
                                struct rte_mbuf *next = NEXT(tmp);
@@ -3060,7 +3054,7 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
                         * cacheline while allocating rep.
                         */
                        rte_prefetch0(seg);
-                       rep = __rte_mbuf_raw_alloc(rxq->mp);
+                       rep = rte_mbuf_raw_alloc(rxq->mp);
                        if (unlikely(rep == NULL)) {
                                /*
                                 * Unable to allocate a replacement mbuf,
@@ -3259,7 +3253,7 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
                if (ret == 0)
                        break;
                len = ret;
-               rep = __rte_mbuf_raw_alloc(rxq->mp);
+               rep = rte_mbuf_raw_alloc(rxq->mp);
                if (unlikely(rep == NULL)) {
                        /*
                         * Unable to allocate a replacement mbuf,
@@ -4313,6 +4307,12 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
                 0);
        if (priv_get_ifname(priv, &ifname) == 0)
                info->if_index = if_nametoindex(ifname);
+       info->speed_capa =
+                       ETH_LINK_SPEED_1G |
+                       ETH_LINK_SPEED_10G |
+                       ETH_LINK_SPEED_20G |
+                       ETH_LINK_SPEED_40G |
+                       ETH_LINK_SPEED_56G;
        priv_unlock(priv);
 }
 
@@ -4715,6 +4715,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
                dev_link.link_speed = link_speed;
        dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
                                ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+       dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+                       ETH_LINK_SPEED_FIXED);
        if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
                /* Link status changed. */
                dev->data->dev_link = dev_link;