summaryrefslogtreecommitdiff
path: root/drivers/net/mlx4/mlx4.c
diff options
context:
space:
mode:
authorYongseok Koh <yskoh@mellanox.com>2019-04-01 14:15:52 -0700
committerFerruh Yigit <ferruh.yigit@intel.com>2019-04-05 17:45:22 +0200
commit8e493764002285aeec39cde1ce7967841dea45b5 (patch)
tree3d5d7400da3628087c4f85fab17c40c426de5f03 /drivers/net/mlx4/mlx4.c
parent099c2c5376131b3d352d70f8904e586c0e84651e (diff)
downloaddpdk-8e493764002285aeec39cde1ce7967841dea45b5.zip
dpdk-8e493764002285aeec39cde1ce7967841dea45b5.tar.gz
dpdk-8e493764002285aeec39cde1ce7967841dea45b5.tar.xz
net/mlx4: add external allocator for Verbs object
To support secondary process, the memory allocated by library such as completion rings (CQ) and buffer rings (WQ) must be manageable by EAL, in order to share it with secondary processes. With new changes in rdma-core and kernel driver, it is possible to provide an external allocator to the library layer for this purpose. All such resources will now be allocated within DPDK framework. Signed-off-by: Yongseok Koh <yskoh@mellanox.com> Acked-by: Shahaf Shuler <shahafs@mellanox.com>
Diffstat (limited to 'drivers/net/mlx4/mlx4.c')
-rw-r--r--drivers/net/mlx4/mlx4.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index bb6ab8e..0e0b035 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -69,6 +69,62 @@ const char *pmd_mlx4_init_params[] = {
static void mlx4_dev_stop(struct rte_eth_dev *dev);
+#ifdef HAVE_IBV_MLX4_BUF_ALLOCATORS
+/**
+ * Verbs callback to allocate a memory. This function should allocate the space
+ * according to the size provided residing inside a huge page.
+ * Please note that all allocation must respect the alignment from libmlx4
+ * (i.e. currently sysconf(_SC_PAGESIZE)).
+ *
+ * @param[in] size
+ * The size in bytes of the memory to allocate.
+ * @param[in] data
+ * A pointer to the callback data.
+ *
+ * @return
+ * Allocated buffer, NULL otherwise and rte_errno is set.
+ */
+static void *
+mlx4_alloc_verbs_buf(size_t size, void *data)
+{
+ struct mlx4_priv *priv = data;
+ void *ret;
+ size_t alignment = sysconf(_SC_PAGESIZE);
+ unsigned int socket = SOCKET_ID_ANY;
+
+ if (priv->verbs_alloc_ctx.type == MLX4_VERBS_ALLOC_TYPE_TX_QUEUE) {
+ const struct txq *txq = priv->verbs_alloc_ctx.obj;
+
+ socket = txq->socket;
+ } else if (priv->verbs_alloc_ctx.type ==
+ MLX4_VERBS_ALLOC_TYPE_RX_QUEUE) {
+ const struct rxq *rxq = priv->verbs_alloc_ctx.obj;
+
+ socket = rxq->socket;
+ }
+ assert(data != NULL);
+ ret = rte_malloc_socket(__func__, size, alignment, socket);
+ if (!ret && size)
+ rte_errno = ENOMEM;
+ return ret;
+}
+
+/**
+ * Verbs callback to free a memory.
+ *
+ * @param[in] ptr
+ * A pointer to the memory to free.
+ * @param[in] data
+ * A pointer to the callback data.
+ */
+static void
+mlx4_free_verbs_buf(void *ptr, void *data __rte_unused)
+{
+ assert(data != NULL);
+ rte_free(ptr);
+}
+#endif
+
/**
* DPDK callback for Ethernet device configuration.
*
@@ -755,6 +811,17 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
eth_dev->intr_handle = &priv->intr_handle;
priv->dev_data = eth_dev->data;
eth_dev->dev_ops = &mlx4_dev_ops;
+#ifdef HAVE_IBV_MLX4_BUF_ALLOCATORS
+ /* Hint libmlx4 to use PMD allocator for data plane resources */
+ struct mlx4dv_ctx_allocators alctr = {
+ .alloc = &mlx4_alloc_verbs_buf,
+ .free = &mlx4_free_verbs_buf,
+ .data = priv,
+ };
+ mlx4_glue->dv_set_context_attr
+ (ctx, MLX4DV_SET_CTX_ATTR_BUF_ALLOCATORS,
+ (void *)((uintptr_t)&alctr));
+#endif
/* Bring Ethernet device up. */
DEBUG("forcing Ethernet interface up");
mlx4_dev_set_link_up(eth_dev);