From: Jan Medala Date: Thu, 30 Jun 2016 15:04:57 +0000 (+0200) Subject: net/ena: make coherent memory allocation NUMA-aware X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=3d3edc265fc8;p=dpdk.git net/ena: make coherent memory allocation NUMA-aware While allocating (coherent) memory, get information about calling node Id and pass that as parameter when reserving a memzone. Signed-off-by: Alexander Matushevsky Signed-off-by: Jakub Palider Signed-off-by: Jan Medala --- diff --git a/drivers/net/ena/base/ena_com.c b/drivers/net/ena/base/ena_com.c index b5b8cd9951..a3649d8bb0 100644 --- a/drivers/net/ena/base/ena_com.c +++ b/drivers/net/ena/base/ena_com.c @@ -329,6 +329,7 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev, struct ena_com_io_sq *io_sq) { size_t size; + int dev_node; ENA_TOUCH(ctx); @@ -341,15 +342,29 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev, size = io_sq->desc_entry_size * io_sq->q_depth; - if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) - ENA_MEM_ALLOC_COHERENT(ena_dev->dmadev, - size, - io_sq->desc_addr.virt_addr, - io_sq->desc_addr.phys_addr, - io_sq->desc_addr.mem_handle); - else - io_sq->desc_addr.virt_addr = - ENA_MEM_ALLOC(ena_dev->dmadev, size); + if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) { + ENA_MEM_ALLOC_COHERENT_NODE(ena_dev->dmadev, + size, + io_sq->desc_addr.virt_addr, + io_sq->desc_addr.phys_addr, + ctx->numa_node, + dev_node); + if (!io_sq->desc_addr.virt_addr) + ENA_MEM_ALLOC_COHERENT(ena_dev->dmadev, + size, + io_sq->desc_addr.virt_addr, + io_sq->desc_addr.phys_addr, + io_sq->desc_addr.mem_handle); + } else { + ENA_MEM_ALLOC_NODE(ena_dev->dmadev, + size, + io_sq->desc_addr.virt_addr, + ctx->numa_node, + dev_node); + if (!io_sq->desc_addr.virt_addr) + io_sq->desc_addr.virt_addr = + ENA_MEM_ALLOC(ena_dev->dmadev, size); + } if (!io_sq->desc_addr.virt_addr) { ena_trc_err("memory allocation failed"); @@ -368,6 +383,7 @@ static int ena_com_init_io_cq(struct ena_com_dev *ena_dev, struct ena_com_io_cq *io_cq) { size_t size; + int prev_node; ENA_TOUCH(ctx); memset(&io_cq->cdesc_addr, 0x0, sizeof(struct ena_com_io_desc_addr)); @@ -380,11 +396,18 @@ static int ena_com_init_io_cq(struct ena_com_dev *ena_dev, size = io_cq->cdesc_entry_size_in_bytes * io_cq->q_depth; - ENA_MEM_ALLOC_COHERENT(ena_dev->dmadev, - size, - io_cq->cdesc_addr.virt_addr, - io_cq->cdesc_addr.phys_addr, - io_cq->cdesc_addr.mem_handle); + ENA_MEM_ALLOC_COHERENT_NODE(ena_dev->dmadev, + size, + io_cq->cdesc_addr.virt_addr, + io_cq->cdesc_addr.phys_addr, + ctx->numa_node, + prev_node); + if (!io_cq->cdesc_addr.virt_addr) + ENA_MEM_ALLOC_COHERENT(ena_dev->dmadev, + size, + io_cq->cdesc_addr.virt_addr, + io_cq->cdesc_addr.phys_addr, + io_cq->cdesc_addr.mem_handle); if (!io_cq->cdesc_addr.virt_addr) { ena_trc_err("memory allocation failed"); diff --git a/drivers/net/ena/base/ena_plat_dpdk.h b/drivers/net/ena/base/ena_plat_dpdk.h index 3c0203fa1d..b1ed80c702 100644 --- a/drivers/net/ena/base/ena_plat_dpdk.h +++ b/drivers/net/ena/base/ena_plat_dpdk.h @@ -196,6 +196,29 @@ typedef uint64_t dma_addr_t; ENA_TOUCH(dmadev); \ rte_free(virt); }) +#define ENA_MEM_ALLOC_COHERENT_NODE(dmadev, size, virt, phys, node, dev_node) \ + do { \ + const struct rte_memzone *mz; \ + char z_name[RTE_MEMZONE_NAMESIZE]; \ + ENA_TOUCH(dmadev); ENA_TOUCH(dev_node); \ + snprintf(z_name, sizeof(z_name), \ + "ena_alloc_%d", ena_alloc_cnt++); \ + mz = rte_memzone_reserve(z_name, size, node, 0); \ + virt = mz->addr; \ + phys = mz->phys_addr; \ + } while (0) + +#define ENA_MEM_ALLOC_NODE(dmadev, size, virt, node, dev_node) \ + do { \ + const struct rte_memzone *mz; \ + char z_name[RTE_MEMZONE_NAMESIZE]; \ + ENA_TOUCH(dmadev); ENA_TOUCH(dev_node); \ + snprintf(z_name, sizeof(z_name), \ + "ena_alloc_%d", ena_alloc_cnt++); \ + mz = rte_memzone_reserve(z_name, size, node, 0); \ + virt = mz->addr; \ + } while (0) + #define ENA_MEM_ALLOC(dmadev, size) rte_zmalloc(NULL, size, 1) #define ENA_MEM_FREE(dmadev, ptr) ({ENA_TOUCH(dmadev); rte_free(ptr); }) diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c index 11e7d8e56c..c56c654c1b 100644 --- a/drivers/net/ena/ena_ethdev.c +++ b/drivers/net/ena/ena_ethdev.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "ena_ethdev.h" #include "ena_logs.h" @@ -232,6 +233,18 @@ static struct eth_dev_ops ena_dev_ops = { .reta_query = ena_rss_reta_query, }; +#define NUMA_NO_NODE SOCKET_ID_ANY + +static inline int ena_cpu_to_node(int cpu) +{ + struct rte_config *config = rte_eal_get_configuration(); + + if (likely(cpu < RTE_MAX_MEMZONE)) + return config->mem_config->memzone[cpu].socket_id; + + return NUMA_NO_NODE; +} + static inline void ena_rx_mbuf_prepare(struct rte_mbuf *mbuf, struct ena_com_rx_ctx *ena_rx_ctx) { @@ -962,6 +975,7 @@ static int ena_tx_queue_setup(struct rte_eth_dev *dev, ctx.msix_vector = -1; /* admin interrupts not used */ ctx.mem_queue_type = ena_dev->tx_mem_queue_type; ctx.queue_size = adapter->tx_ring_size; + ctx.numa_node = ena_cpu_to_node(queue_idx); rc = ena_com_create_io_queue(ena_dev, &ctx); if (rc) { @@ -1055,6 +1069,7 @@ static int ena_rx_queue_setup(struct rte_eth_dev *dev, ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; ctx.msix_vector = -1; /* admin interrupts not used */ ctx.queue_size = adapter->rx_ring_size; + ctx.numa_node = ena_cpu_to_node(queue_idx); rc = ena_com_create_io_queue(ena_dev, &ctx); if (rc)