From e896b661e65b9efc015818b9a10a25c3f73e5f5b Mon Sep 17 00:00:00 2001 From: Long Li Date: Wed, 21 Oct 2020 17:26:07 -0700 Subject: [PATCH] net/netvsc: allocate contiguous physical memory for RNDIS [ upstream commit b8c3c628aff6defbabf677b4eea14c0529486357 ] When sending data, netvsc assumes the tx_rndis buffer is contiguous and calculates physical addresses based on this assumption. Use memzone to allocate tx_rndis so it's guaranteed that this buffer is physically contiguous. Signed-off-by: Long Li --- drivers/net/netvsc/hn_rxtx.c | 23 ++++++++++++----------- drivers/net/netvsc/hn_var.h | 2 ++ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/net/netvsc/hn_rxtx.c b/drivers/net/netvsc/hn_rxtx.c index 4286b6b463..c0965ab420 100644 --- a/drivers/net/netvsc/hn_rxtx.c +++ b/drivers/net/netvsc/hn_rxtx.c @@ -283,10 +283,15 @@ hn_dev_tx_queue_setup(struct rte_eth_dev *dev, PMD_INIT_LOG(DEBUG, "TX descriptor pool %s n=%u size=%zu", name, nb_desc, sizeof(struct hn_txdesc)); - txq->tx_rndis = rte_calloc("hn_txq_rndis", nb_desc, - HN_RNDIS_PKT_ALIGNED, RTE_CACHE_LINE_SIZE); - if (txq->tx_rndis == NULL) + txq->tx_rndis_mz = rte_memzone_reserve_aligned(name, + nb_desc * HN_RNDIS_PKT_ALIGNED, rte_socket_id(), + RTE_MEMZONE_IOVA_CONTIG, HN_RNDIS_PKT_ALIGNED); + if (!txq->tx_rndis_mz) { + err = -rte_errno; goto error; + } + txq->tx_rndis = txq->tx_rndis_mz->addr; + txq->tx_rndis_iova = txq->tx_rndis_mz->iova; txq->txdesc_pool = rte_mempool_create(name, nb_desc, sizeof(struct hn_txdesc), @@ -315,7 +320,7 @@ hn_dev_tx_queue_setup(struct rte_eth_dev *dev, error: if (txq->txdesc_pool) rte_mempool_free(txq->txdesc_pool); - rte_free(txq->tx_rndis); + rte_memzone_free(txq->tx_rndis_mz); rte_free(txq); return err; } @@ -357,7 +362,7 @@ hn_dev_tx_queue_release(void *arg) if (txq->txdesc_pool) rte_mempool_free(txq->txdesc_pool); - rte_free(txq->tx_rndis); + rte_memzone_free(txq->tx_rndis_mz); rte_free(txq); } @@ -1356,12 +1361,8 @@ static int hn_xmit_sg(struct hn_tx_queue *txq, hn_rndis_dump(txd->rndis_pkt); /* pass IOVA of rndis header in first segment */ - addr = rte_malloc_virt2iova(txq->tx_rndis); - if (unlikely(addr == RTE_BAD_IOVA)) { - PMD_DRV_LOG(ERR, "RNDIS transmit can not get iova"); - return -EINVAL; - } - addr = addr + ((char *)txd->rndis_pkt - (char *)txq->tx_rndis); + addr = txq->tx_rndis_iova + + ((char *)txd->rndis_pkt - (char *)txq->tx_rndis); sg[0].page = addr / PAGE_SIZE; sg[0].ofs = addr & PAGE_MASK; diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h index a4d47abca3..44c9db95a6 100644 --- a/drivers/net/netvsc/hn_var.h +++ b/drivers/net/netvsc/hn_var.h @@ -53,7 +53,9 @@ struct hn_tx_queue { uint16_t queue_id; uint32_t free_thresh; struct rte_mempool *txdesc_pool; + const struct rte_memzone *tx_rndis_mz; void *tx_rndis; + rte_iova_t tx_rndis_iova; /* Applied packet transmission aggregation limits. */ uint32_t agg_szmax;