* [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct
@ 2026-10-08 13:28 Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 01/10] net/mlx5: Log the data direct to PF device mapping Tariq Toukan
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing
Hi,
This patch series by Dragos adds data direct support for netdev devices,
allowing a mlx5 netdev to issue DMA commands through multiple paths.
This feature is critical for improving performance and reaching line
rate in certain environments where issuing PCI transactions over one
path may be significantly faster than over another. These differences
can arise from various PCI generations in the system or the specific
system topology.
Data direct for netdev will work with devmem by returning the data
direct DMA device instead of the DMA device of the NIC. Each PF netdev
registers its own data direct device and support for RX and TX datapath
is added. The feature is selected through a new data direct priv flag.
The feature is enabled though a ethtool private flag. When this flag
is enabled, the driver will return the data direct device in the
ndo_queue_get_dma_dev op.
During data_direct device unbind, a re-creation of the channels is
triggered.
A note about the unbind: it does not does not tear down dmabuf bindings
attached to the data direct device; the recreated channels will still
pick up the binding via rxq->mp_params and post DMA addresses from the
data direct IOMMU domain to the PF, causing IOMMU faults. A devmem
revoke hook is needed to close those bindings before the switch. This is
out of scope for this series.
A note about io_uring support: currently io_uring rejects the
configuration where the dmabuf dev != page_pool dev.
Regards,
Tariq
[1] https://lore.kernel.org/all/cover.1722512548.git.leon@kernel.org/
Dragos Tatulea (10):
net/mlx5: Log the data direct to PF device mapping
net/mlx5e: Register supported netdevs as data direct users
net/mlx5e: Pre-calculate UMR padding and entry size
net/mlx5e: Add data direct ethtool private flag
net/mlx5e: Add data direct RX infrastructure
net/mlx5e: Add data direct TX infrastructure
net/mlx5e: Use the correct DMA dev when data_direct pdev enabled
net/mlx5e: Recreate netdev channels on data direct device unbind
net: devmem: add netdev_has_dmabuf_binding() helper
net/mlx5e: Enable the data direct netdev feature
.../ethernet/mellanox/mlx5/core/data_direct.c | 5 +
drivers/net/ethernet/mellanox/mlx5/core/en.h | 13 ++
.../ethernet/mellanox/mlx5/core/en/params.c | 5 +
.../ethernet/mellanox/mlx5/core/en/params.h | 2 +
.../mellanox/mlx5/core/en/reporter_rx.c | 1 +
.../mellanox/mlx5/core/en/reporter_tx.c | 1 +
.../ethernet/mellanox/mlx5/core/en_common.c | 38 +++-
.../ethernet/mellanox/mlx5/core/en_ethtool.c | 40 ++++
.../net/ethernet/mellanox/mlx5/core/en_main.c | 173 +++++++++++++++++-
.../net/ethernet/mellanox/mlx5/core/en_rx.c | 28 +--
.../net/ethernet/mellanox/mlx5/core/en_tx.c | 4 +-
include/linux/mlx5/driver.h | 1 +
include/net/netmem.h | 23 +++
net/core/devmem.c | 30 +++
net/core/devmem.h | 2 +
15 files changed, 342 insertions(+), 24 deletions(-)
base-commit: 8df0638138d3e0344fd1fb36cf2d1ca1cf5028f0
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 01/10] net/mlx5: Log the data direct to PF device mapping
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
@ 2026-10-08 13:28 ` Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 02/10] net/mlx5e: Register supported netdevs as data direct users Tariq Toukan
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing
From: Dragos Tatulea <dtatulea@nvidia.com>
Emit an informational message when a data direct device is bound to a
PF, showing the data direct BDF alongside the PF BDF (the mlx5_core log
prefix), to make the mapping observable from dmesg.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/data_direct.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/data_direct.c b/drivers/net/ethernet/mellanox/mlx5/core/data_direct.c
index 5afb11a2a9f0..7db94b8a5b79 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/data_direct.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/data_direct.c
@@ -21,6 +21,7 @@ static LIST_HEAD(mlx5_data_direct_reg_list);
static DEFINE_MUTEX(mlx5_data_direct_mutex);
struct mlx5_data_direct_registration {
+ struct mlx5_core_dev *mdev;
char vuid[MLX5_ST_SZ_BYTES(array1024_auto) + 1];
struct list_head list;
struct blocking_notifier_head users;
@@ -189,6 +190,9 @@ static void mlx5_data_direct_bind(struct mlx5_data_direct_registration *reg,
struct mlx5_data_direct_dev *dev)
{
WRITE_ONCE(reg->dd.dev, dev);
+
+ mlx5_core_info(reg->mdev, "bound data direct device %s\n",
+ pci_name(dev->pdev));
}
static void
@@ -212,6 +216,7 @@ int mlx5_data_direct_init(struct mlx5_core_dev *mdev)
if (!reg)
return -ENOMEM;
+ reg->mdev = mdev;
BLOCKING_INIT_NOTIFIER_HEAD(®->users);
err = mlx5_data_direct_query_vuid(mdev, reg->vuid);
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 02/10] net/mlx5e: Register supported netdevs as data direct users
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 01/10] net/mlx5: Log the data direct to PF device mapping Tariq Toukan
@ 2026-10-08 13:28 ` Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 03/10] net/mlx5e: Pre-calculate UMR padding and entry size Tariq Toukan
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing
From: Dragos Tatulea <dtatulea@nvidia.com>
Register the netdev as a data direct user so it is notified when the
affiliated data direct device is unbound.
Register during NIC enable and unregister during disable so suspend
and resume follow the data direct registration lifetime in mlx5_core.
The notifier callback only traces the unbind event for now; tearing down
the data direct datapath is wired up together with that datapath in
later patches.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 +
.../net/ethernet/mellanox/mlx5/core/en_main.c | 21 +++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index a3945195f454..78cf6aedd04d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -984,6 +984,7 @@ struct mlx5e_priv {
struct mlx5e_mqprio_rl *mqprio_rl;
struct dentry *dfs_root;
struct mlx5_devcom_comp_dev *devcom;
+ struct notifier_block data_direct_nb;
};
static inline u16 mlx5e_stats_nch_read(const struct mlx5e_priv *priv)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index f90b5a34e097..a2b3ac3011c9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -33,6 +33,7 @@
#include <linux/dim.h>
#include <net/tc_act/tc_gact.h>
#include <linux/mlx5/fs.h>
+#include <linux/mlx5/data_direct.h>
#include <net/vxlan.h>
#include <net/geneve.h>
#include <linux/bpf.h>
@@ -6023,6 +6024,18 @@ void mlx5e_destroy_q_counters(struct mlx5e_priv *priv)
}
}
+static int mlx5e_data_direct_event(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv,
+ data_direct_nb);
+
+ if (action == MLX5_DATA_DIRECT_UNBIND)
+ mlx5_core_dbg(priv->mdev, "data direct device unbound\n");
+
+ return NOTIFY_OK;
+}
+
static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
struct net_device *netdev)
{
@@ -6225,6 +6238,12 @@ static int mlx5e_nic_enable(struct mlx5e_priv *priv)
mlx5e_pcie_cong_event_init(priv);
mlx5e_hv_vhca_stats_create(priv);
+
+ if (mlx5_data_direct_supported(mdev)) {
+ priv->data_direct_nb.notifier_call = mlx5e_data_direct_event;
+ mlx5_data_direct_register(mdev, &priv->data_direct_nb);
+ }
+
if (netdev->reg_state != NETREG_REGISTERED)
return 0;
mlx5e_dcbnl_init_app(priv);
@@ -6251,6 +6270,8 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv)
{
struct mlx5_core_dev *mdev = priv->mdev;
+ mlx5_data_direct_unregister(mdev, &priv->data_direct_nb);
+
if (priv->netdev->reg_state == NETREG_REGISTERED)
mlx5e_dcbnl_delete_app(priv);
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 03/10] net/mlx5e: Pre-calculate UMR padding and entry size
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 01/10] net/mlx5: Log the data direct to PF device mapping Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 02/10] net/mlx5e: Register supported netdevs as data direct users Tariq Toukan
@ 2026-10-08 13:28 ` Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 04/10] net/mlx5e: Add data direct ethtool private flag Tariq Toukan
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing
From: Dragos Tatulea <dtatulea@nvidia.com>
A future patch will add KSM UMRs alongside MTT UMRs for data direct. To
avoid having additional ifs in the datapath, pre-calculate the UMR
padding and entry size based on the type of mkey used for UMR type used.
An additional side benefit is that the padding check from
mlx5e_alloc_rx_mpwqe() is no longer needed.
This patch doesn't introduce any functional changes. The mlx5e_rq struct
doesn't grow because the new members were added in a hole.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 +++
.../net/ethernet/mellanox/mlx5/core/en_main.c | 11 +++++++++++
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 16 ++++++----------
3 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 78cf6aedd04d..000493f42912 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -696,6 +696,9 @@ struct mlx5e_rq {
u8 umr_wqebbs;
u8 mtts_per_wqe;
u8 umr_mode;
+ u8 umr_entry_size;
+ u8 umr_pad_bytes;
+ u16 umr_pad_offset;
struct mlx5e_mpw_linear_info *linear_info;
struct mlx5e_shampo_hd *shampo;
} mpwqe;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index a2b3ac3011c9..b86c7b52774a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -901,6 +901,7 @@ static int mlx5e_alloc_rq(struct mlx5e_params *params,
void *rqc_wq = MLX5_ADDR_OF(rqc, rq_param->rqc, wq);
struct mlx5_core_dev *mdev = rq->mdev;
u32 pool_order = 0;
+ u16 entries_bytes;
u32 pool_size;
int wq_sz;
int err;
@@ -947,6 +948,16 @@ static int mlx5e_alloc_rq(struct mlx5e_params *params,
mlx5e_mpwrq_mtts_per_wqe(mdev, rq->mpwqe.page_shift,
rq->mpwqe.umr_mode);
+ rq->mpwqe.umr_entry_size =
+ mlx5e_mpwrq_umr_entry_size(rq->mpwqe.umr_mode);
+ entries_bytes = rq->mpwqe.pages_per_wqe *
+ rq->mpwqe.umr_entry_size;
+ rq->mpwqe.umr_pad_offset = entries_bytes;
+ /* padding can be 0 when no padding is needed */
+ rq->mpwqe.umr_pad_bytes =
+ ALIGN(entries_bytes, MLX5_UMR_FLEX_ALIGNMENT) -
+ entries_bytes;
+
pool_size = rq->mpwqe.pages_per_wqe <<
mlx5e_mpwqe_get_log_rq_size(mdev, params, rqo);
pool_order = rq->mpwqe.page_shift - PAGE_SHIFT;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index e3f915beebe1..9e1224930e06 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -674,16 +674,11 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
};
}
- /* Pad if needed, in case the value set to ucseg->xlt_octowords
- * in mlx5e_build_umr_wqe() needed alignment.
+ /* Pad when the value set to ucseg->xlt_octowords in
+ * mlx5e_build_umr_wqe() needed alignment.
*/
- if (rq->mpwqe.pages_per_wqe & (MLX5_UMR_MTT_NUM_ENTRIES_ALIGNMENT - 1)) {
- int pad = ALIGN(rq->mpwqe.pages_per_wqe, MLX5_UMR_MTT_NUM_ENTRIES_ALIGNMENT) -
- rq->mpwqe.pages_per_wqe;
-
- memset(&umr_wqe->inline_mtts[rq->mpwqe.pages_per_wqe], 0,
- sizeof(*umr_wqe->inline_mtts) * pad);
- }
+ memset((u8 *)umr_wqe->inline_mtts + rq->mpwqe.umr_pad_offset, 0,
+ rq->mpwqe.umr_pad_bytes);
bitmap_zero(wi->skip_release_bitmap, rq->mpwqe.pages_per_wqe);
wi->consumed_strides = 0;
@@ -692,7 +687,8 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
cpu_to_be32((sq->pc << MLX5_WQE_CTRL_WQE_INDEX_SHIFT) |
MLX5_OPCODE_UMR);
- offset = (ix * rq->mpwqe.mtts_per_wqe) * sizeof(struct mlx5_mtt) / MLX5_OCTWORD;
+ offset = ix * rq->mpwqe.mtts_per_wqe *
+ rq->mpwqe.umr_entry_size / MLX5_OCTWORD;
umr_wqe->hdr.uctrl.xlt_offset = cpu_to_be16(offset);
sq->db.wqe_info[pi] = (struct mlx5e_icosq_wqe_info) {
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 04/10] net/mlx5e: Add data direct ethtool private flag
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
` (2 preceding siblings ...)
2026-10-08 13:28 ` [PATCH net-next 03/10] net/mlx5e: Pre-calculate UMR padding and entry size Tariq Toukan
@ 2026-10-08 13:28 ` Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 05/10] net/mlx5e: Add data direct RX infrastructure Tariq Toukan
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing
From: Dragos Tatulea <dtatulea@nvidia.com>
This patch adds the data direct private flag infrastructure.
The MLX5E_PFLAG_DATA_DIRECT flag is needed in the follow-up patches to
detect the configuration of data direct from the user side.
For now the flag can't be actually set. This will be implemented in a
follow-up patch once all pieces are put together.
This patch doesn't introduce any functional changes.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 +
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 6 ++++++
2 files changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 000493f42912..c5bbe5adea45 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -264,6 +264,7 @@ enum mlx5e_priv_flag {
MLX5E_PFLAG_XDP_TX_MPWQE,
MLX5E_PFLAG_SKB_TX_MPWQE,
MLX5E_PFLAG_TX_PORT_TS,
+ MLX5E_PFLAG_DATA_DIRECT,
MLX5E_NUM_PFLAGS, /* Keep last */
};
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 261c466a4d36..b3eced1dd43f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -2400,6 +2400,11 @@ static int set_pflag_tx_port_ts(struct net_device *netdev, bool enable)
return err;
}
+static int set_pflag_data_direct(struct net_device *netdev, bool enable)
+{
+ return -EOPNOTSUPP;
+}
+
static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS] = {
{ "rx_cqe_moder", set_pflag_rx_cqe_based_moder },
{ "tx_cqe_moder", set_pflag_tx_cqe_based_moder },
@@ -2409,6 +2414,7 @@ static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS] = {
{ "xdp_tx_mpwqe", set_pflag_xdp_tx_mpwqe },
{ "skb_tx_mpwqe", set_pflag_skb_tx_mpwqe },
{ "tx_port_ts", set_pflag_tx_port_ts },
+ { "data_direct", set_pflag_data_direct },
};
static int mlx5e_handle_pflag(struct net_device *netdev,
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 05/10] net/mlx5e: Add data direct RX infrastructure
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
` (3 preceding siblings ...)
2026-10-08 13:28 ` [PATCH net-next 04/10] net/mlx5e: Add data direct ethtool private flag Tariq Toukan
@ 2026-10-08 13:28 ` Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 06/10] net/mlx5e: Add data direct TX infrastructure Tariq Toukan
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing
From: Dragos Tatulea <dtatulea@nvidia.com>
Data direct is a HW feature that allows a type of peer-to-peer DMA
between the NIC and another device (e.g. GPU) going through a specific
PCIe topology.
For data direct to work on the RX path, the RQ will use a KSM mkey whose
entries will point to the crossed mkey. This is necessary to enable DMA
from the NIC to the other device.
This commit adds the necessary infrastructure on RX side:
- New RQ state flag for the data direct state.
- Create crossing mkey.
- Create KSM mkey and in data direct PD and make it point to the
crossed mkey.
This commit has no functional changes. data direct mode will be
enabled in a subsequent commit and mlx5e_queue_get_dma_dev() will then
point to the right device.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 6 ++
.../ethernet/mellanox/mlx5/core/en/params.c | 5 +
.../ethernet/mellanox/mlx5/core/en/params.h | 2 +
.../mellanox/mlx5/core/en/reporter_rx.c | 1 +
.../net/ethernet/mellanox/mlx5/core/en_main.c | 101 ++++++++++++++++--
.../net/ethernet/mellanox/mlx5/core/en_rx.c | 12 ++-
6 files changed, 118 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index c5bbe5adea45..d716e70c6d47 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -342,6 +342,7 @@ enum {
MLX5E_RQ_STATE_SHAMPO, /* set when SHAMPO cap is used */
MLX5E_RQ_STATE_MINI_CQE_ENHANCED, /* set when enhanced mini_cqe_cap is used */
MLX5E_RQ_STATE_XSK, /* set to indicate an xsk rq */
+ MLX5E_RQ_STATE_DATA_DIRECT, /* set when the rq maps data through data direct */
MLX5E_NUM_RQ_STATES, /* Must be kept last */
};
@@ -685,6 +686,8 @@ struct mlx5e_rq {
struct mlx5e_mpw_info *info;
mlx5e_fp_skb_from_cqe_mpwrq skb_from_cqe_mpwrq;
__be32 umr_mkey_be;
+ __be32 ksm_child_mkey_be;
+ u32 crossing_mkey;
u16 num_strides;
u16 actual_wq_head;
u8 log_stride_sz;
@@ -1202,6 +1205,9 @@ static inline bool mlx5_tx_swp_supported(struct mlx5_core_dev *mdev)
extern const struct ethtool_ops mlx5e_ethtool_ops;
int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn, u32 *mkey);
+int mlx5e_create_crossing_vhca_mkey(struct mlx5_core_dev *mdev,
+ u32 crossed_mkey, u64 crossed_len,
+ u32 *crossing_mkey);
int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises);
void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev);
int mlx5e_modify_tirs_lb(struct mlx5_core_dev *mdev, bool enable_uc_lb,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
index 5caf7820a136..88b4cd5497d8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
@@ -62,6 +62,9 @@ mlx5e_mpwrq_umr_mode(struct mlx5_core_dev *mdev,
bool unaligned = xsk ? xsk->unaligned : false;
bool oversized = false;
+ if (rqo && rqo->data_direct)
+ return MLX5E_MPWRQ_UMR_MODE_UNALIGNED;
+
if (xsk) {
oversized = xsk->chunk_size < (1 << page_shift);
WARN_ON_ONCE(xsk->chunk_size > (1 << page_shift));
@@ -1296,12 +1299,14 @@ void mlx5e_build_xdpsq_param(struct mlx5_core_dev *mdev,
int mlx5e_build_channel_param(struct mlx5_core_dev *mdev,
struct mlx5e_params *params,
struct netdev_queue_config *qcfg,
+ bool data_direct,
struct mlx5e_channel_param *cparam)
{
u8 icosq_log_wq_sz, async_icosq_log_wq_sz;
int err;
cparam->rq_opt.qcfg = qcfg;
+ cparam->rq_opt.data_direct = data_direct;
err = mlx5e_build_rq_param(mdev, params, &cparam->rq_opt, &cparam->rq);
if (err)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.h b/drivers/net/ethernet/mellanox/mlx5/core/en/params.h
index 275f9be53a34..43332015f445 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.h
@@ -15,6 +15,7 @@ struct mlx5e_xsk_param {
struct mlx5e_rq_opt_param {
struct mlx5e_xsk_param *xsk;
struct netdev_queue_config *qcfg;
+ bool data_direct;
};
struct mlx5e_cq_param {
@@ -146,6 +147,7 @@ void mlx5e_build_xdpsq_param(struct mlx5_core_dev *mdev,
int mlx5e_build_channel_param(struct mlx5_core_dev *mdev,
struct mlx5e_params *params,
struct netdev_queue_config *qcfg,
+ bool data_direct,
struct mlx5e_channel_param *cparam);
void mlx5e_build_xsk_channel_param(struct mlx5_core_dev *mdev,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
index 6efb626b5506..f9fce1d0e9e7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
@@ -21,6 +21,7 @@ static const char * const rq_sw_state_type_name[] = {
[MLX5E_RQ_STATE_SHAMPO] = "shampo",
[MLX5E_RQ_STATE_MINI_CQE_ENHANCED] = "mini_cqe_enhanced",
[MLX5E_RQ_STATE_XSK] = "xsk",
+ [MLX5E_RQ_STATE_DATA_DIRECT] = "data_direct",
};
static int mlx5e_query_rq_state(struct mlx5_core_dev *dev, u32 rqn, u8 *state)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index b86c7b52774a..e0d46e067c72 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -425,7 +425,7 @@ static u8 mlx5e_mpwrq_access_mode(enum mlx5e_mpwrq_umr_mode umr_mode)
static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
u32 npages, u8 page_shift, u32 *umr_mkey,
dma_addr_t filler_addr,
- enum mlx5e_mpwrq_umr_mode umr_mode,
+ enum mlx5e_mpwrq_umr_mode umr_mode, u32 pdn,
u32 xsk_chunk_size)
{
struct mlx5_mtt *mtt;
@@ -465,7 +465,7 @@ static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
MLX5_SET(mkc, mkc, access_mode_1_0, mlx5e_mpwrq_access_mode(umr_mode));
mlx5e_mkey_set_relaxed_ordering(mdev, mkc);
MLX5_SET(mkc, mkc, qpn, 0xffffff);
- MLX5_SET(mkc, mkc, pd, mdev->mlx5e_res.hw_objs.pdn);
+ MLX5_SET(mkc, mkc, pd, pdn);
MLX5_SET64(mkc, mkc, len, npages << page_shift);
MLX5_SET(mkc, mkc, translations_octword_size, octwords);
if (umr_mode == MLX5E_MPWRQ_UMR_MODE_TRIPLE)
@@ -531,9 +531,11 @@ static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
static int mlx5e_create_rq_umr_mkey(struct mlx5_core_dev *mdev, struct mlx5e_rq *rq)
{
u32 xsk_chunk_size = rq->xsk_pool ? rq->xsk_pool->chunk_size : 0;
+ bool dd = test_bit(MLX5E_RQ_STATE_DATA_DIRECT, &rq->state);
u32 wq_size = mlx5_wq_ll_get_size(&rq->mpwqe.wq);
u32 num_entries, max_num_entries;
u32 umr_mkey;
+ u32 pdn;
int err;
max_num_entries = mlx5e_mpwrq_max_num_entries(mdev, rq->mpwqe.umr_mode);
@@ -546,13 +548,80 @@ static int mlx5e_create_rq_umr_mkey(struct mlx5_core_dev *mdev, struct mlx5e_rq
__func__, wq_size, rq->mpwqe.mtts_per_wqe,
max_num_entries);
+ pdn = dd ? mdev->data_direct->pdn : mdev->mlx5e_res.hw_objs.pdn;
err = mlx5e_create_umr_mkey(mdev, num_entries, rq->mpwqe.page_shift,
&umr_mkey, rq->wqe_overflow.addr,
- rq->mpwqe.umr_mode, xsk_chunk_size);
+ rq->mpwqe.umr_mode, pdn,
+ xsk_chunk_size);
rq->mpwqe.umr_mkey_be = cpu_to_be32(umr_mkey);
return err;
}
+int mlx5e_create_crossing_vhca_mkey(struct mlx5_core_dev *mdev,
+ u32 crossed_mkey, u64 crossed_len,
+ u32 *crossing_mkey)
+{
+ int inlen = MLX5_ST_SZ_BYTES(create_mkey_in);
+ int access_mode = MLX5_MKC_ACCESS_MODE_CROSSING;
+ void *mkc;
+ u32 *in;
+ int err;
+
+ if (!MLX5_CAP_GEN(mdev, crossing_vhca_mkey))
+ return -EOPNOTSUPP;
+
+ in = kvzalloc(inlen, GFP_KERNEL);
+ if (!in)
+ return -ENOMEM;
+
+ mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
+ MLX5_SET(mkc, mkc, access_mode_1_0, access_mode & 0x3);
+ MLX5_SET(mkc, mkc, access_mode_4_2, (access_mode >> 2) & 0x7);
+ MLX5_SET(mkc, mkc, crossing_target_vhca_id,
+ MLX5_CAP_GEN(mdev, vhca_id));
+ MLX5_SET(mkc, mkc, translations_octword_size, crossed_mkey);
+ MLX5_SET(mkc, mkc, pd, mdev->mlx5e_res.hw_objs.pdn);
+ MLX5_SET(mkc, mkc, qpn, 0xffffff);
+ MLX5_SET(mkc, mkc, lr, 1);
+ MLX5_SET(mkc, mkc, lw, 1);
+ MLX5_SET64(mkc, mkc, start_addr, 0);
+ MLX5_SET64(mkc, mkc, len, crossed_len);
+
+ err = mlx5_core_create_mkey(mdev, crossing_mkey, in, inlen);
+ kvfree(in);
+ return err;
+}
+
+static int mlx5e_rq_alloc_data_direct_mkey(struct mlx5e_rq *rq)
+{
+ struct mlx5_core_dev *mdev = rq->mdev;
+ u32 umr_mkey;
+ u64 umr_len;
+ int wq_sz;
+
+ if (!test_bit(MLX5E_RQ_STATE_DATA_DIRECT, &rq->state))
+ return 0;
+
+ wq_sz = mlx5_wq_ll_get_size(&rq->mpwqe.wq);
+ umr_mkey = be32_to_cpu(rq->mpwqe.umr_mkey_be);
+ umr_len = (u64)wq_sz * rq->mpwqe.mtts_per_wqe << rq->mpwqe.page_shift;
+
+ rq->mpwqe.ksm_child_mkey_be =
+ cpu_to_be32(mdev->data_direct->mkey_ro_valid ?
+ mdev->data_direct->mkey_ro :
+ mdev->data_direct->mkey);
+
+ return mlx5e_create_crossing_vhca_mkey(mdev, umr_mkey,
+ umr_len,
+ &rq->mpwqe.crossing_mkey);
+}
+
+static void mlx5e_rq_free_data_direct_mkey(struct mlx5e_rq *rq)
+{
+ if (test_bit(MLX5E_RQ_STATE_DATA_DIRECT, &rq->state))
+ mlx5_core_destroy_mkey(rq->mdev, rq->mpwqe.crossing_mkey);
+}
+
static void mlx5e_init_frags_partition(struct mlx5e_rq *rq)
{
struct mlx5e_wqe_frag_info next_frag = {};
@@ -900,6 +969,7 @@ static int mlx5e_alloc_rq(struct mlx5e_params *params,
{
void *rqc_wq = MLX5_ADDR_OF(rqc, rq_param->rqc, wq);
struct mlx5_core_dev *mdev = rq->mdev;
+ bool data_direct = false;
u32 pool_order = 0;
u16 entries_bytes;
u32 pool_size;
@@ -937,6 +1007,11 @@ static int mlx5e_alloc_rq(struct mlx5e_params *params,
if (err)
goto err_rq_wq_destroy;
+ data_direct = rqo && rqo->data_direct;
+
+ if (data_direct)
+ set_bit(MLX5E_RQ_STATE_DATA_DIRECT, &rq->state);
+
rq->mpwqe.umr_mode = mlx5e_mpwrq_umr_mode(mdev, rqo);
rq->mpwqe.pages_per_wqe =
mlx5e_mpwrq_pages_per_wqe(mdev, rq->mpwqe.page_shift,
@@ -975,10 +1050,14 @@ static int mlx5e_alloc_rq(struct mlx5e_params *params,
if (err)
goto err_rq_drop_page;
- err = mlx5e_rq_alloc_mpwqe_info(rq, node);
+ err = mlx5e_rq_alloc_data_direct_mkey(rq);
if (err)
goto err_rq_mkey;
+ err = mlx5e_rq_alloc_mpwqe_info(rq, node);
+ if (err)
+ goto err_rq_free_dd_mkey;
+
err = mlx5e_rq_alloc_mpwqe_linear_info(rq, node, params, rqo);
if (err)
goto err_free_mpwqe_info;
@@ -1071,7 +1150,9 @@ static int mlx5e_alloc_rq(struct mlx5e_params *params,
wqe->data[0].addr = cpu_to_be64(dma_offset + headroom);
wqe->data[0].byte_count = cpu_to_be32(byte_count);
- wqe->data[0].lkey = rq->mpwqe.umr_mkey_be;
+ wqe->data[0].lkey = data_direct ?
+ cpu_to_be32(rq->mpwqe.crossing_mkey) :
+ rq->mpwqe.umr_mkey_be;
} else {
struct mlx5e_rx_wqe_cyc *wqe =
mlx5_wq_cyc_get_wqe(&rq->wqe.wq, i);
@@ -1105,6 +1186,8 @@ static int mlx5e_alloc_rq(struct mlx5e_params *params,
kvfree(rq->mpwqe.linear_info);
err_free_mpwqe_info:
kvfree(rq->mpwqe.info);
+err_rq_free_dd_mkey:
+ mlx5e_rq_free_data_direct_mkey(rq);
err_rq_mkey:
mlx5_core_destroy_mkey(mdev, be32_to_cpu(rq->mpwqe.umr_mkey_be));
err_rq_drop_page:
@@ -1132,6 +1215,7 @@ static void mlx5e_free_rq(struct mlx5e_rq *rq)
mlx5e_rq_free_shampo(rq);
kvfree(rq->mpwqe.linear_info);
kvfree(rq->mpwqe.info);
+ mlx5e_rq_free_data_direct_mkey(rq);
mlx5_core_destroy_mkey(rq->mdev, be32_to_cpu(rq->mpwqe.umr_mkey_be));
mlx5e_free_mpwqe_rq_drop_page(rq);
break;
@@ -2849,6 +2933,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
struct mlx5e_xsk_param xsk;
bool async_icosq_needed;
struct mlx5e_channel *c;
+ bool data_direct;
unsigned int irq;
int vec_ix;
int cpu;
@@ -2873,7 +2958,11 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
goto err_free;
}
- err = mlx5e_build_channel_param(mdev, params, qcfg, cparam);
+ data_direct = MLX5E_GET_PFLAG(params, MLX5E_PFLAG_DATA_DIRECT) &&
+ netif_rxq_has_unreadable_mp(netdev, ix);
+
+ err = mlx5e_build_channel_param(mdev, params, qcfg, data_direct,
+ cparam);
if (err)
goto err_free;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 9e1224930e06..c992da08caae 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -669,9 +669,15 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
goto err_unmap;
addr = page_pool_get_dma_addr_netmem(frag_page->netmem);
- umr_wqe->inline_mtts[i] = (struct mlx5_mtt) {
- .ptag = cpu_to_be64(addr | MLX5_EN_WR),
- };
+ if (test_bit(MLX5E_RQ_STATE_DATA_DIRECT, &rq->state))
+ umr_wqe->inline_ksms[i] = (struct mlx5_ksm) {
+ .key = rq->mpwqe.ksm_child_mkey_be,
+ .va = cpu_to_be64(addr),
+ };
+ else
+ umr_wqe->inline_mtts[i] = (struct mlx5_mtt) {
+ .ptag = cpu_to_be64(addr | MLX5_EN_WR),
+ };
}
/* Pad when the value set to ucseg->xlt_octowords in
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 06/10] net/mlx5e: Add data direct TX infrastructure
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
` (4 preceding siblings ...)
2026-10-08 13:28 ` [PATCH net-next 05/10] net/mlx5e: Add data direct RX infrastructure Tariq Toukan
@ 2026-10-08 13:28 ` Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 07/10] net/mlx5e: Use the correct DMA dev when data_direct pdev enabled Tariq Toukan
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing
From: Dragos Tatulea <dtatulea@nvidia.com>
Data direct is a HW feature that allows a type of peer-to-peer DMA
between the NIC and another device (e.g. GPU) going through a specific
PCIe topology.
For data direct to work on the TX path, a crossing mkey is necessary
which is created as a mlx5e resource. This mkey is used by all SQs.
For simplicity always create this resource and link it to the SQ
if data direct is supported.
An SQ state flag is added as well to signal to the TX data path that
data direct is enabled.
This commit has no functional changes. data direct mode will be
enabled in a subsequent commit and mlx5e_queue_get_dma_dev() will then
point to the right device.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +
.../mellanox/mlx5/core/en/reporter_tx.c | 1 +
.../ethernet/mellanox/mlx5/core/en_common.c | 38 ++++++++++++++++++-
.../net/ethernet/mellanox/mlx5/core/en_main.c | 6 +++
.../net/ethernet/mellanox/mlx5/core/en_tx.c | 4 +-
include/linux/mlx5/driver.h | 1 +
6 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index d716e70c6d47..23e45e87cdee 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -397,6 +397,7 @@ enum {
MLX5E_SQ_STATE_PENDING_XSK_TX,
MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC,
MLX5E_SQ_STATE_LOCK_NEEDED,
+ MLX5E_SQ_STATE_DATA_DIRECT, /* set when the sq maps net_iov frags through data direct */
MLX5E_NUM_SQ_STATES, /* Must be kept last */
};
@@ -453,6 +454,7 @@ struct mlx5e_txqsq {
u8 min_inline_mode;
struct device *pdev;
__be32 mkey_be;
+ __be32 crossing_mkey_be;
unsigned long state;
unsigned int hw_mtu;
struct mlx5_clock *clock;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
index 8409ae73768f..b4a4ff877bbc 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
@@ -18,6 +18,7 @@ static const char * const sq_sw_state_type_name[] = {
[MLX5E_SQ_STATE_PENDING_XSK_TX] = "pending_xsk_tx",
[MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC] = "pending_tls_rx_resync",
[MLX5E_SQ_STATE_LOCK_NEEDED] = "lock_needed",
+ [MLX5E_SQ_STATE_DATA_DIRECT] = "data_direct",
};
static int mlx5e_wait_for_sq_flush(struct mlx5e_txqsq *sq)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
index c2d4bae533de..c1d3b2ba1864 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c
@@ -30,6 +30,8 @@
* SOFTWARE.
*/
+#include <linux/mlx5/data_direct.h>
+
#include "devlink.h"
#include "en.h"
#include "lib/crypto.h"
@@ -153,6 +155,30 @@ mlx5e_get_devlink_param_num_doorbells(struct mlx5_core_dev *dev)
return err ? MLX5_DEFAULT_NUM_DOORBELLS : val.vu32;
}
+static int mlx5e_create_data_direct_crossing_mkey(struct mlx5_core_dev *mdev)
+{
+ struct mlx5e_hw_objs *res = &mdev->mlx5e_res.hw_objs;
+
+ if (!mdev->data_direct ||
+ !MLX5_CAP_GEN(mdev, crossing_vhca_mkey))
+ return 0;
+
+ return mlx5e_create_crossing_vhca_mkey(mdev, mdev->data_direct->mkey,
+ U64_MAX,
+ &res->data_direct_crossing_mkey);
+}
+
+static void mlx5e_destroy_data_direct_crossing_mkey(struct mlx5_core_dev *mdev)
+{
+ struct mlx5e_hw_objs *res = &mdev->mlx5e_res.hw_objs;
+
+ if (!mdev->data_direct ||
+ !MLX5_CAP_GEN(mdev, crossing_vhca_mkey))
+ return;
+
+ mlx5_core_destroy_mkey(mdev, res->data_direct_crossing_mkey);
+}
+
int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises)
{
struct mlx5e_hw_objs *res = &mdev->mlx5e_res.hw_objs;
@@ -177,12 +203,19 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises)
goto err_dealloc_transport_domain;
}
+ err = mlx5e_create_data_direct_crossing_mkey(mdev);
+ if (err) {
+ mlx5_core_err(mdev, "create data direct crossing mkey failed, %d\n",
+ err);
+ goto err_destroy_mkey;
+ }
+
num_doorbells = min(mlx5e_get_devlink_param_num_doorbells(mdev),
mlx5e_get_max_num_channels(mdev));
res->bfregs = kzalloc_objs(*res->bfregs, num_doorbells);
if (!res->bfregs) {
err = -ENOMEM;
- goto err_destroy_mkey;
+ goto err_destroy_crossing_mkey;
}
for (i = 0; i < num_doorbells; i++) {
@@ -221,6 +254,8 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises)
for (i = 0; i < res->num_bfregs; i++)
mlx5_free_bfreg(mdev, res->bfregs + i);
kfree(res->bfregs);
+err_destroy_crossing_mkey:
+ mlx5e_destroy_data_direct_crossing_mkey(mdev);
err_destroy_mkey:
mlx5_core_destroy_mkey(mdev, res->mkey);
err_dealloc_transport_domain:
@@ -241,6 +276,7 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev)
for (unsigned int i = 0; i < res->num_bfregs; i++)
mlx5_free_bfreg(mdev, res->bfregs + i);
kfree(res->bfregs);
+ mlx5e_destroy_data_direct_crossing_mkey(mdev);
mlx5_core_destroy_mkey(mdev, res->mkey);
mlx5_core_dealloc_transport_domain(mdev, res->td.tdn);
mlx5_core_dealloc_pd(mdev, res->pdn);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index e0d46e067c72..d5282a301621 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1825,6 +1825,12 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state);
if (param->is_mpw)
set_bit(MLX5E_SQ_STATE_MPWQE, &sq->state);
+ if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_DATA_DIRECT)) {
+ u32 mkey = mdev->mlx5e_res.hw_objs.data_direct_crossing_mkey;
+
+ sq->crossing_mkey_be = cpu_to_be32(mkey);
+ set_bit(MLX5E_SQ_STATE_DATA_DIRECT, &sq->state);
+ }
sq->stop_room = param->stop_room;
sq->ptp_cyc2time = mlx5_sq_ts_translator(mdev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
index 14479da98f42..62ffb41a64df 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
@@ -182,6 +182,7 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb,
unsigned char *skb_data, u16 headlen,
struct mlx5_wqe_data_seg *dseg)
{
+ bool dd = test_bit(MLX5E_SQ_STATE_DATA_DIRECT, &sq->state);
dma_addr_t dma_addr = 0;
u8 num_dma = 0;
int i;
@@ -211,7 +212,8 @@ mlx5e_txwqe_build_dsegs(struct mlx5e_txqsq *sq, struct sk_buff *skb,
goto dma_unmap_wqe_err;
dseg->addr = cpu_to_be64(dma_addr);
- dseg->lkey = sq->mkey_be;
+ dseg->lkey = dd && skb_frag_is_net_iov(frag) ?
+ sq->crossing_mkey_be : sq->mkey_be;
dseg->byte_count = cpu_to_be32(fsz);
mlx5e_dma_push_netmem(sq, skb_frag_netmem(frag), dma_addr, fsz);
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index abb99371ff13..4c8b447337f1 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -678,6 +678,7 @@ struct mlx5e_resources {
u32 pdn;
struct mlx5_td td;
u32 mkey;
+ u32 data_direct_crossing_mkey;
struct mlx5_sq_bfreg *bfregs;
unsigned int num_bfregs;
#define MLX5_MAX_NUM_TC 8
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 07/10] net/mlx5e: Use the correct DMA dev when data_direct pdev enabled
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
` (5 preceding siblings ...)
2026-10-08 13:28 ` [PATCH net-next 06/10] net/mlx5e: Add data direct TX infrastructure Tariq Toukan
@ 2026-10-08 13:28 ` Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 08/10] net/mlx5e: Recreate netdev channels on data direct device unbind Tariq Toukan
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing
From: Dragos Tatulea <dtatulea@nvidia.com>
When the private flag is set, always return the data direct
PCI device instead of the NIC PF PCI device in .ndo_queue_get_dma_dev.
Rename netdev argument to netdev because there are too many confusing
"dev"-based names in this function.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index d5282a301621..6476baf71bde 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -5897,10 +5897,10 @@ static int mlx5e_queue_start(struct net_device *dev,
return 0;
}
-static struct device *mlx5e_queue_get_dma_dev(struct net_device *dev,
+static struct device *mlx5e_queue_get_dma_dev(struct net_device *netdev,
int queue_index)
{
- struct mlx5e_priv *priv = netdev_priv(dev);
+ struct mlx5e_priv *priv = netdev_priv(netdev);
struct mlx5e_channels *channels;
struct device *pdev = NULL;
struct mlx5e_channel *ch;
@@ -5913,7 +5913,16 @@ static struct device *mlx5e_queue_get_dma_dev(struct net_device *dev,
goto out;
ch = channels->c[queue_index];
- pdev = ch->pdev;
+ if (MLX5E_GET_PFLAG(&channels->params, MLX5E_PFLAG_DATA_DIRECT)) {
+ struct mlx5_core_dev *mdev = ch->mdev;
+ struct mlx5_data_direct_dev *dd_dev;
+
+ dd_dev = mlx5_data_direct_get_dev(mdev->data_direct);
+ if (dd_dev)
+ pdev = &dd_dev->pdev->dev;
+ } else {
+ pdev = ch->pdev;
+ }
out:
mutex_unlock(&priv->state_lock);
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 08/10] net/mlx5e: Recreate netdev channels on data direct device unbind
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
` (6 preceding siblings ...)
2026-10-08 13:28 ` [PATCH net-next 07/10] net/mlx5e: Use the correct DMA dev when data_direct pdev enabled Tariq Toukan
@ 2026-10-08 13:28 ` Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 09/10] net: devmem: add netdev_has_dmabuf_binding() helper Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 10/10] net/mlx5e: Enable the data direct netdev feature Tariq Toukan
9 siblings, 0 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing
From: Dragos Tatulea <dtatulea@nvidia.com>
To prevent queues from using data direct resources, disable the data
direct private flag and trigger channel re-creation for each netdev that
is registered to a data direct device in the unbind callback.
Channels will be re-created without the data direct flag.
Note that this does not tear down dmabuf bindings attached to the data
direct device; the recreated channels will still pick up the binding via
rxq->mp_params and post DMA addresses from the data direct IOMMU domain
to the PF, causing IOMMU faults. A devmem revoke hook is needed to close
those bindings before the switch.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
.../net/ethernet/mellanox/mlx5/core/en_main.c | 23 +++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 6476baf71bde..fb3e0bd00f04 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -6144,9 +6144,28 @@ static int mlx5e_data_direct_event(struct notifier_block *nb,
{
struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv,
data_direct_nb);
+ struct mlx5e_params new_params;
+
+ if (action != MLX5_DATA_DIRECT_UNBIND)
+ return NOTIFY_DONE;
+
+ rtnl_lock();
+ netdev_lock(priv->netdev);
+ mutex_lock(&priv->state_lock);
- if (action == MLX5_DATA_DIRECT_UNBIND)
- mlx5_core_dbg(priv->mdev, "data direct device unbound\n");
+ if (!MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_DATA_DIRECT))
+ goto out;
+
+ new_params = priv->channels.params;
+ MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_DATA_DIRECT, false);
+ mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
+ netdev_info(priv->netdev,
+ "data_direct device unbound, disabled data_direct\n");
+
+out:
+ mutex_unlock(&priv->state_lock);
+ netdev_unlock(priv->netdev);
+ rtnl_unlock();
return NOTIFY_OK;
}
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 09/10] net: devmem: add netdev_has_dmabuf_binding() helper
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
` (7 preceding siblings ...)
2026-10-08 13:28 ` [PATCH net-next 08/10] net/mlx5e: Recreate netdev channels on data direct device unbind Tariq Toukan
@ 2026-10-08 13:28 ` Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 10/10] net/mlx5e: Enable the data direct netdev feature Tariq Toukan
9 siblings, 0 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing, Bobby Eshleman
From: Dragos Tatulea <dtatulea@nvidia.com>
Currently there is no way to check whether a dmabuf is bound on a TX
queue. RX side has netif_rxq_has_unreadable_mp() which gives a hint
of it.
To help with that, add a helper to check whether a devmem dmabuf
binding may still be in use on a given netdev, optionally filtered by
the DMA device the dmabuf was mapped against.
A binding can outlive its xarray slot: it can still be referenced by
in-flight TX skbs, whose DMA mappings are only valid for the device the
dmabuf was attached to. Reporting such a binding as gone would let a
driver swap the DMA device out from under those skbs. For this reason,
track bindings for their whole lifetime on a new list.
This API is necessary for the upcoming support of data direct in mlx5e.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Cc: Bobby Eshleman <bobbyeshleman@gmail.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
include/net/netmem.h | 23 +++++++++++++++++++++++
net/core/devmem.c | 30 ++++++++++++++++++++++++++++++
net/core/devmem.h | 2 ++
3 files changed, 55 insertions(+)
diff --git a/include/net/netmem.h b/include/net/netmem.h
index 0cc8572f62ca..8bcf44f43d17 100644
--- a/include/net/netmem.h
+++ b/include/net/netmem.h
@@ -387,16 +387,39 @@ static inline unsigned long netmem_get_dma_addr(netmem_ref netmem)
return netmem_to_nmdesc(netmem)->dma_addr;
}
+struct net_device;
+
#if defined(CONFIG_NET_DEVMEM)
static inline bool net_is_devmem_iov(const struct net_iov *niov)
{
return niov->type == NET_IOV_DMABUF;
}
+
+/**
+ * netdev_has_dmabuf_binding - is there a dmabuf binding for a
+ * given @dev and @dma_dev
+ *
+ * @dev: netdev to check bindings
+ * @dma_dev: dma device to check, when NULL it will not be checked
+ *
+ * A binding is reported until its last reference is dropped, which can be
+ * long after the user unbound it: net_iovs of a TX binding can still be
+ * queued in flight, with DMA mappings that are only valid for @dma_dev.
+ *
+ * Return: true if a binding is found under @dev and possibly @dma_dev
+ */
+bool netdev_has_dmabuf_binding(struct net_device *dev, struct device *dma_dev);
#else
static inline bool net_is_devmem_iov(const struct net_iov *niov)
{
return false;
}
+
+static inline bool netdev_has_dmabuf_binding(struct net_device *dev,
+ struct device *dma_dev)
+{
+ return false;
+}
#endif
void __get_netmem(netmem_ref netmem);
diff --git a/net/core/devmem.c b/net/core/devmem.c
index 07c62e2e3088..173d66d1cb6e 100644
--- a/net/core/devmem.c
+++ b/net/core/devmem.c
@@ -25,6 +25,9 @@
static DEFINE_XARRAY_FLAGS(net_devmem_dmabuf_bindings, XA_FLAGS_ALLOC1);
+static DEFINE_SPINLOCK(net_devmem_live_bindings_lock);
+static LIST_HEAD(net_devmem_live_bindings);
+
static const struct memory_provider_ops dmabuf_devmem_ops;
static struct net_iov *net_iov_free_pop(struct net_iov_area *area,
@@ -63,6 +66,10 @@ void __net_devmem_dmabuf_binding_free(struct work_struct *wq)
{
struct net_devmem_dmabuf_binding *binding = container_of(wq, typeof(*binding), unbind_w);
+ spin_lock(&net_devmem_live_bindings_lock);
+ list_del(&binding->live_list);
+ spin_unlock(&net_devmem_live_bindings_lock);
+
if (binding->freelist)
WARN(binding->free_count != binding->area.num_niovs,
"destroying dmabuf binding with outstanding net_iovs: total=%zu, free=%u",
@@ -321,6 +328,10 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
list_add(&binding->list, &priv->bindings);
+ spin_lock(&net_devmem_live_bindings_lock);
+ list_add(&binding->live_list, &net_devmem_live_bindings);
+ spin_unlock(&net_devmem_live_bindings_lock);
+
return binding;
err_free_niovs:
@@ -357,6 +368,25 @@ struct net_devmem_dmabuf_binding *net_devmem_lookup_dmabuf(u32 id)
return binding;
}
+bool netdev_has_dmabuf_binding(struct net_device *dev, struct device *dma_dev)
+{
+ struct net_devmem_dmabuf_binding *binding;
+ bool found = false;
+
+ spin_lock(&net_devmem_live_bindings_lock);
+ list_for_each_entry(binding, &net_devmem_live_bindings, live_list) {
+ if (dev == READ_ONCE(binding->dev) &&
+ (!dma_dev || binding->attachment->dev == dma_dev)) {
+ found = true;
+ break;
+ }
+ }
+ spin_unlock(&net_devmem_live_bindings_lock);
+
+ return found;
+}
+EXPORT_SYMBOL_GPL(netdev_has_dmabuf_binding);
+
void net_devmem_get_net_iov(struct net_iov *niov)
{
net_devmem_dmabuf_binding_get(net_devmem_iov_binding(niov));
diff --git a/net/core/devmem.h b/net/core/devmem.h
index 1cec10f0257c..eadf6df38687 100644
--- a/net/core/devmem.h
+++ b/net/core/devmem.h
@@ -54,6 +54,8 @@ struct net_devmem_dmabuf_binding {
*/
struct list_head list;
+ struct list_head live_list;
+
/* rxq's this binding is active on. */
struct xarray bound_rxqs;
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next 10/10] net/mlx5e: Enable the data direct netdev feature
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
` (8 preceding siblings ...)
2026-10-08 13:28 ` [PATCH net-next 09/10] net: devmem: add netdev_has_dmabuf_binding() helper Tariq Toukan
@ 2026-10-08 13:28 ` Tariq Toukan
9 siblings, 0 replies; 11+ messages in thread
From: Tariq Toukan @ 2026-10-08 13:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Bobby Eshleman, Byungchul Park, Carolina Jubran, Cosmin Ratiu,
Dragos Tatulea, Gal Pressman, Jacob Keller, Kees Cook,
Leon Romanovsky, open list, linux-rdma, Mark Bloch, Matt Fleming,
Mina Almasry, Nikolay Aleksandrov, Saeed Mahameed, Shivaji Kant,
Simon Horman, Stanislav Fomichev, Stanislav Fomichev,
Tariq Toukan, William Tu, Yue Haibing
From: Dragos Tatulea <dtatulea@nvidia.com>
Add the implementation of the data direct private flag.
This enables the feature altogether.
Do not allow state changes while dmabufs are still bound
to the netdev.
Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
.../ethernet/mellanox/mlx5/core/en_ethtool.c | 36 ++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index b3eced1dd43f..8ab1150ce3f2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -32,6 +32,7 @@
#include <linux/dim.h>
#include <linux/ethtool_netlink.h>
+#include <linux/mlx5/data_direct.h>
#include <net/netdev_queues.h>
#include "en.h"
@@ -2402,7 +2403,40 @@ static int set_pflag_tx_port_ts(struct net_device *netdev, bool enable)
static int set_pflag_data_direct(struct net_device *netdev, bool enable)
{
- return -EOPNOTSUPP;
+ struct mlx5e_priv *priv = netdev_priv(netdev);
+ struct mlx5_core_dev *mdev = priv->mdev;
+ struct mlx5e_params new_params;
+
+ if (enable) {
+ if (!mlx5_data_direct_supported(mdev) ||
+ !MLX5_CAP_GEN(mdev, crossing_vhca_mkey)) {
+ netdev_err(netdev, "data_direct is not supported by the device\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (!MLX5_CAP_GEN(mdev, shampo)) {
+ netdev_err(netdev, "data_direct requires SHAMPO (Header-Data Split) support\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (!mlx5_data_direct_get_dev(mdev->data_direct)) {
+ netdev_err(netdev, "data_direct device not bound\n");
+ return -ENODEV;
+ }
+ }
+
+ /* Changing the flag reopens the channels with a different DMA device,
+ * which would break any dmabuf currently bound to this netdev.
+ */
+ if (netdev_has_dmabuf_binding(netdev, NULL)) {
+ netdev_err(netdev, "Can't change data_direct while dmabufs are bound\n");
+ return -EBUSY;
+ }
+
+ new_params = priv->channels.params;
+ MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_DATA_DIRECT, enable);
+
+ return mlx5e_safe_switch_params(priv, &new_params, NULL, NULL, true);
}
static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS] = {
--
2.44.0
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-10-08 13:30 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-08 13:28 [PATCH net-next 00/10] net/mlx5e: Add netdev support for data direct Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 01/10] net/mlx5: Log the data direct to PF device mapping Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 02/10] net/mlx5e: Register supported netdevs as data direct users Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 03/10] net/mlx5e: Pre-calculate UMR padding and entry size Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 04/10] net/mlx5e: Add data direct ethtool private flag Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 05/10] net/mlx5e: Add data direct RX infrastructure Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 06/10] net/mlx5e: Add data direct TX infrastructure Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 07/10] net/mlx5e: Use the correct DMA dev when data_direct pdev enabled Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 08/10] net/mlx5e: Recreate netdev channels on data direct device unbind Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 09/10] net: devmem: add netdev_has_dmabuf_binding() helper Tariq Toukan
2026-10-08 13:28 ` [PATCH net-next 10/10] net/mlx5e: Enable the data direct netdev feature Tariq Toukan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®