From: Tariq Toukan <tariqt@nvidia.com>
To: Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>
Cc: Saeed Mahameed <saeedm@nvidia.com>,
Leon Romanovsky <leon@kernel.org>,
Tariq Toukan <tariqt@nvidia.com>, Mark Bloch <mbloch@nvidia.com>,
"Moshe Shemesh" <moshe@nvidia.com>,
Akiva Goldberger <agoldberger@nvidia.com>,
<netdev@vger.kernel.org>, <linux-rdma@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, Gal Pressman <gal@nvidia.com>,
Dragos Tatulea <dtatulea@nvidia.com>
Subject: [PATCH net-next 3/3] net/mlx5: Add VHCA_ID page management mode support
Date: Fri, 1 May 2026 07:41:56 +0300 [thread overview]
Message-ID: <20260501044156.260875-4-tariqt@nvidia.com> (raw)
In-Reply-To: <20260501044156.260875-1-tariqt@nvidia.com>
From: Moshe Shemesh <moshe@nvidia.com>
Add support for VHCA_ID-based page management mode. When the device
firmware advertises the icm_mng_function_id_mode capability with
MLX5_ID_MODE_FUNCTION_VHCA_ID, page management operations between the
driver and firmware may use vhca_id instead of function_id as the
effective function identifier, and the ec_function field is ignored.
Update page management commands to conditionally set ec_function field
only in FUNC_ID mode. Boot page allocation always uses FUNC_ID mode
semantics for backward compatibility, as the capability bit is only
available after set_hca_cap(). If after set_hca_cap() VHCA_ID mode was
set, modify the tracking of the boot pages in page_root_xa to use
vhca_id too.
Add mlx5_esw_vhca_id_to_func_type() to resolve the function type via
vport lookup in VHCA_ID mode, enabling per-type debugfs counters.
Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
.../net/ethernet/mellanox/mlx5/core/eswitch.c | 42 ++++
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 7 +
.../net/ethernet/mellanox/mlx5/core/main.c | 3 +
.../ethernet/mellanox/mlx5/core/pagealloc.c | 226 ++++++++++++++----
include/linux/mlx5/driver.h | 7 +
5 files changed, 235 insertions(+), 50 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index e0eafcf0c52a..d3eaefc5c0e0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -852,6 +852,48 @@ bool mlx5_esw_vport_vhca_id(struct mlx5_eswitch *esw, u16 vportn, u16 *vhca_id)
return true;
}
+u16 mlx5_esw_vhca_id_to_func_type(struct mlx5_core_dev *dev, u16 vhca_id)
+{
+ struct mlx5_eswitch *esw = dev->priv.eswitch;
+ struct mlx5_vport *vport;
+ unsigned long i;
+ u16 type;
+
+ if (vhca_id == MLX5_CAP_GEN(dev, vhca_id))
+ return MLX5_SELF;
+
+ if (!esw)
+ return MLX5_FUNC_TYPE_NONE;
+
+ mutex_lock(&esw->state_lock);
+ mlx5_esw_for_each_vport(esw, i, vport) {
+ if (vport->vhca_id != vhca_id)
+ continue;
+
+ if (vport->vport == MLX5_VPORT_HOST_PF) {
+ type = MLX5_HOST_PF;
+ goto unlock;
+ }
+
+ if (xa_get_mark(&esw->vports, i, MLX5_ESW_VPT_SF)) {
+ type = MLX5_SF;
+ goto unlock;
+ }
+
+ if (xa_get_mark(&esw->vports, i, MLX5_ESW_VPT_VF)) {
+ type = MLX5_VF;
+ goto unlock;
+ }
+
+ type = MLX5_EC_VF;
+ goto unlock;
+ }
+ type = MLX5_FUNC_TYPE_NONE;
+unlock:
+ mutex_unlock(&esw->state_lock);
+ return type;
+}
+
static int esw_vport_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
{
bool vst_mode_steering = esw_vst_mode_is_steering(esw);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 2fd601bd102f..5940b4cbfd77 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -863,6 +863,7 @@ void mlx5_esw_vport_vhca_id_unmap(struct mlx5_eswitch *esw,
struct mlx5_vport *vport);
int mlx5_eswitch_vhca_id_to_vport(struct mlx5_eswitch *esw, u16 vhca_id, u16 *vport_num);
bool mlx5_esw_vport_vhca_id(struct mlx5_eswitch *esw, u16 vportn, u16 *vhca_id);
+u16 mlx5_esw_vhca_id_to_func_type(struct mlx5_core_dev *dev, u16 vhca_id);
void mlx5_esw_offloads_rep_remove(struct mlx5_eswitch *esw,
const struct mlx5_vport *vport);
@@ -1034,6 +1035,12 @@ mlx5_esw_vport_vhca_id(struct mlx5_eswitch *esw, u16 vportn, u16 *vhca_id)
return false;
}
+static inline u16
+mlx5_esw_vhca_id_to_func_type(struct mlx5_core_dev *dev, u16 vhca_id)
+{
+ return MLX5_FUNC_TYPE_NONE;
+}
+
static inline void
mlx5_eswitch_safe_aux_devs_remove(struct mlx5_core_dev *dev) {}
static inline struct mlx5_flow_handle *
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index a242053f3a58..52cf341ad6b3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -597,6 +597,9 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
if (MLX5_CAP_GEN_MAX(dev, release_all_pages))
MLX5_SET(cmd_hca_cap, set_hca_cap, release_all_pages, 1);
+ if (MLX5_CAP_GEN_MAX(dev, icm_mng_function_id_mode))
+ MLX5_SET(cmd_hca_cap, set_hca_cap, icm_mng_function_id_mode, 1);
+
if (MLX5_CAP_GEN_MAX(dev, mkey_by_name))
MLX5_SET(cmd_hca_cap, set_hca_cap, mkey_by_name, 1);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
index 77ffa31cc505..7ebe88aa3b3e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
@@ -38,6 +38,7 @@
#include "mlx5_core.h"
#include "lib/eq.h"
#include "lib/tout.h"
+#include "eswitch.h"
enum {
MLX5_PAGES_CANT_GIVE = 0,
@@ -69,9 +70,24 @@ enum {
MLX5_NUM_4K_IN_PAGE = PAGE_SIZE / MLX5_ADAPTER_PAGE_SIZE,
};
-static u32 get_function(u16 func_id, bool ec_function)
+static bool mlx5_page_mgt_mode_is_vhca_id(const struct mlx5_core_dev *dev)
{
- return (u32)func_id | (ec_function << 16);
+ return dev->priv.page_mgt_mode == MLX5_PAGE_MGT_MODE_VHCA_ID;
+}
+
+static void mlx5_page_mgt_mode_set(struct mlx5_core_dev *dev,
+ enum mlx5_page_mgt_mode mode)
+{
+ dev->priv.page_mgt_mode = mode;
+}
+
+static u32 get_function_key(struct mlx5_core_dev *dev, u16 func_vhca_id,
+ bool ec_function)
+{
+ if (mlx5_page_mgt_mode_is_vhca_id(dev))
+ return (u32)func_vhca_id;
+
+ return (u32)func_vhca_id | (ec_function << 16);
}
static u16 func_id_to_type(struct mlx5_core_dev *dev, u16 func_id, bool ec_function)
@@ -89,12 +105,21 @@ static u16 func_id_to_type(struct mlx5_core_dev *dev, u16 func_id, bool ec_funct
return MLX5_SF;
}
+static u16 func_vhca_id_to_type(struct mlx5_core_dev *dev, u16 func_vhca_id,
+ bool ec_function)
+{
+ if (mlx5_page_mgt_mode_is_vhca_id(dev))
+ return mlx5_esw_vhca_id_to_func_type(dev, func_vhca_id);
+
+ return func_id_to_type(dev, func_vhca_id, ec_function);
+}
+
static u32 mlx5_get_ec_function(u32 function)
{
return function >> 16;
}
-static u32 mlx5_get_func_id(u32 function)
+static u32 mlx5_get_func_vhca_id(u32 function)
{
return function & 0xffff;
}
@@ -196,7 +221,7 @@ static struct fw_page *find_fw_page(struct mlx5_core_dev *dev, u64 addr,
return result;
}
-static int mlx5_cmd_query_pages(struct mlx5_core_dev *dev, u16 *func_id,
+static int mlx5_cmd_query_pages(struct mlx5_core_dev *dev, u16 *func_vhca_id,
s32 *npages, int boot)
{
u32 out[MLX5_ST_SZ_DW(query_pages_out)] = {};
@@ -207,14 +232,20 @@ static int mlx5_cmd_query_pages(struct mlx5_core_dev *dev, u16 *func_id,
MLX5_SET(query_pages_in, in, op_mod, boot ?
MLX5_QUERY_PAGES_IN_OP_MOD_BOOT_PAGES :
MLX5_QUERY_PAGES_IN_OP_MOD_INIT_PAGES);
- MLX5_SET(query_pages_in, in, embedded_cpu_function, mlx5_core_is_ecpf(dev));
+
+ if (mlx5_page_mgt_mode_is_vhca_id(dev))
+ MLX5_SET(query_pages_in, in, function_id,
+ MLX5_CAP_GEN(dev, vhca_id));
+ else
+ MLX5_SET(query_pages_in, in, embedded_cpu_function,
+ mlx5_core_is_ecpf(dev));
err = mlx5_cmd_exec_inout(dev, query_pages, in, out);
if (err)
return err;
*npages = MLX5_GET(query_pages_out, out, num_pages);
- *func_id = MLX5_GET(query_pages_out, out, function_id);
+ *func_vhca_id = MLX5_GET(query_pages_out, out, function_id);
return err;
}
@@ -334,7 +365,7 @@ static int alloc_system_page(struct mlx5_core_dev *dev, u32 function)
return err;
}
-static void page_notify_fail(struct mlx5_core_dev *dev, u16 func_id,
+static void page_notify_fail(struct mlx5_core_dev *dev, u16 func_vhca_id,
bool ec_function)
{
u32 in[MLX5_ST_SZ_DW(manage_pages_in)] = {};
@@ -342,19 +373,23 @@ static void page_notify_fail(struct mlx5_core_dev *dev, u16 func_id,
MLX5_SET(manage_pages_in, in, opcode, MLX5_CMD_OP_MANAGE_PAGES);
MLX5_SET(manage_pages_in, in, op_mod, MLX5_PAGES_CANT_GIVE);
- MLX5_SET(manage_pages_in, in, function_id, func_id);
- MLX5_SET(manage_pages_in, in, embedded_cpu_function, ec_function);
+ MLX5_SET(manage_pages_in, in, function_id, func_vhca_id);
+
+ if (!mlx5_page_mgt_mode_is_vhca_id(dev))
+ MLX5_SET(manage_pages_in, in, embedded_cpu_function,
+ ec_function);
err = mlx5_cmd_exec_in(dev, manage_pages, in);
if (err)
- mlx5_core_warn(dev, "page notify failed func_id(%d) err(%d)\n",
- func_id, err);
+ mlx5_core_warn(dev,
+ "page notify failed func_vhca_id(%d) err(%d)\n",
+ func_vhca_id, err);
}
-static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
+static int give_pages(struct mlx5_core_dev *dev, u16 func_vhca_id, int npages,
int event, bool ec_function)
{
- u32 function = get_function(func_id, ec_function);
+ u32 function = get_function_key(dev, func_vhca_id, ec_function);
u32 out[MLX5_ST_SZ_DW(manage_pages_out)] = {0};
int inlen = MLX5_ST_SZ_BYTES(manage_pages_in);
int notify_fail = event;
@@ -390,9 +425,12 @@ static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
MLX5_SET(manage_pages_in, in, opcode, MLX5_CMD_OP_MANAGE_PAGES);
MLX5_SET(manage_pages_in, in, op_mod, MLX5_PAGES_GIVE);
- MLX5_SET(manage_pages_in, in, function_id, func_id);
+ MLX5_SET(manage_pages_in, in, function_id, func_vhca_id);
MLX5_SET(manage_pages_in, in, input_num_entries, npages);
- MLX5_SET(manage_pages_in, in, embedded_cpu_function, ec_function);
+
+ if (!mlx5_page_mgt_mode_is_vhca_id(dev))
+ MLX5_SET(manage_pages_in, in, embedded_cpu_function,
+ ec_function);
err = mlx5_cmd_do(dev, in, inlen, out, sizeof(out));
if (err == -EREMOTEIO) {
@@ -405,17 +443,20 @@ static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
}
err = mlx5_cmd_check(dev, err, in, out);
if (err) {
- mlx5_core_warn(dev, "func_id 0x%x, npages %d, err %d\n",
- func_id, npages, err);
+ mlx5_core_warn(dev, "func_vhca_id 0x%x, npages %d, err %d\n",
+ func_vhca_id, npages, err);
goto out_dropped;
}
- func_type = func_id_to_type(dev, func_id, ec_function);
- dev->priv.page_counters[func_type] += npages;
+ func_type = func_vhca_id_to_type(dev, func_vhca_id, ec_function);
+ if (func_type != MLX5_FUNC_TYPE_NONE)
+ dev->priv.page_counters[func_type] += npages;
dev->priv.fw_pages += npages;
- mlx5_core_dbg(dev, "npages %d, ec_function %d, func_id 0x%x, err %d\n",
- npages, ec_function, func_id, err);
+ mlx5_core_dbg(dev,
+ "npages %d, ec_function %d, func 0x%x, mode %d, err %d\n",
+ npages, ec_function, func_vhca_id,
+ mlx5_page_mgt_mode_is_vhca_id(dev), err);
kvfree(in);
return 0;
@@ -428,14 +469,14 @@ static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
out_free:
kvfree(in);
if (notify_fail)
- page_notify_fail(dev, func_id, ec_function);
+ page_notify_fail(dev, func_vhca_id, ec_function);
return err;
}
-static void release_all_pages(struct mlx5_core_dev *dev, u16 func_id,
+static void release_all_pages(struct mlx5_core_dev *dev, u16 func_vhca_id,
bool ec_function)
{
- u32 function = get_function(func_id, ec_function);
+ u32 function = get_function_key(dev, func_vhca_id, ec_function);
struct rb_root *root;
struct rb_node *p;
int npages = 0;
@@ -454,12 +495,14 @@ static void release_all_pages(struct mlx5_core_dev *dev, u16 func_id,
free_fwp(dev, fwp, fwp->free_count);
}
- func_type = func_id_to_type(dev, func_id, ec_function);
- dev->priv.page_counters[func_type] -= npages;
+ func_type = func_vhca_id_to_type(dev, func_vhca_id, ec_function);
+ if (func_type != MLX5_FUNC_TYPE_NONE)
+ dev->priv.page_counters[func_type] -= npages;
dev->priv.fw_pages -= npages;
- mlx5_core_dbg(dev, "npages %d, ec_function %d, func_id 0x%x\n",
- npages, ec_function, func_id);
+ mlx5_core_dbg(dev, "npages %d, ec_function %d, func 0x%x, mode %d\n",
+ npages, ec_function, func_vhca_id,
+ mlx5_page_mgt_mode_is_vhca_id(dev));
}
static u32 fwp_fill_manage_pages_out(struct fw_page *fwp, u32 *out, u32 index,
@@ -487,7 +530,7 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
struct fw_page *fwp;
struct rb_node *p;
bool ec_function;
- u32 func_id;
+ u32 func_vhca_id;
u32 npages;
u32 i = 0;
int err;
@@ -499,10 +542,11 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
/* No hard feelings, we want our pages back! */
npages = MLX5_GET(manage_pages_in, in, input_num_entries);
- func_id = MLX5_GET(manage_pages_in, in, function_id);
+ func_vhca_id = MLX5_GET(manage_pages_in, in, function_id);
ec_function = MLX5_GET(manage_pages_in, in, embedded_cpu_function);
- root = xa_load(&dev->priv.page_root_xa, get_function(func_id, ec_function));
+ root = xa_load(&dev->priv.page_root_xa,
+ get_function_key(dev, func_vhca_id, ec_function));
if (WARN_ON_ONCE(!root))
return -EEXIST;
@@ -518,10 +562,11 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev,
return 0;
}
-static int reclaim_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
- int *nclaimed, bool event, bool ec_function)
+static int reclaim_pages(struct mlx5_core_dev *dev, u16 func_vhca_id,
+ int npages, int *nclaimed, bool event,
+ bool ec_function)
{
- u32 function = get_function(func_id, ec_function);
+ u32 function = get_function_key(dev, func_vhca_id, ec_function);
int outlen = MLX5_ST_SZ_BYTES(manage_pages_out);
u32 in[MLX5_ST_SZ_DW(manage_pages_in)] = {};
int num_claimed;
@@ -540,12 +585,16 @@ static int reclaim_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
MLX5_SET(manage_pages_in, in, opcode, MLX5_CMD_OP_MANAGE_PAGES);
MLX5_SET(manage_pages_in, in, op_mod, MLX5_PAGES_TAKE);
- MLX5_SET(manage_pages_in, in, function_id, func_id);
+ MLX5_SET(manage_pages_in, in, function_id, func_vhca_id);
MLX5_SET(manage_pages_in, in, input_num_entries, npages);
- MLX5_SET(manage_pages_in, in, embedded_cpu_function, ec_function);
- mlx5_core_dbg(dev, "func 0x%x, npages %d, outlen %d\n",
- func_id, npages, outlen);
+ if (!mlx5_page_mgt_mode_is_vhca_id(dev))
+ MLX5_SET(manage_pages_in, in, embedded_cpu_function,
+ ec_function);
+
+ mlx5_core_dbg(dev, "func 0x%x, npages %d, outlen %d mode %d\n",
+ func_vhca_id, npages, outlen,
+ mlx5_page_mgt_mode_is_vhca_id(dev));
err = reclaim_pages_cmd(dev, in, sizeof(in), out, outlen);
if (err) {
npages = MLX5_GET(manage_pages_in, in, input_num_entries);
@@ -577,8 +626,9 @@ static int reclaim_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
if (nclaimed)
*nclaimed = num_claimed;
- func_type = func_id_to_type(dev, func_id, ec_function);
- dev->priv.page_counters[func_type] -= num_claimed;
+ func_type = func_vhca_id_to_type(dev, func_vhca_id, ec_function);
+ if (func_type != MLX5_FUNC_TYPE_NONE)
+ dev->priv.page_counters[func_type] -= num_claimed;
dev->priv.fw_pages -= num_claimed;
out_free:
@@ -658,30 +708,101 @@ static int req_pages_handler(struct notifier_block *nb,
* req->npages (and not min ()).
*/
req->npages = max_t(s32, npages, MAX_RECLAIM_NPAGES);
- req->ec_function = ec_function;
+ if (!mlx5_page_mgt_mode_is_vhca_id(dev))
+ req->ec_function = ec_function;
req->release_all = release_all;
INIT_WORK(&req->work, pages_work_handler);
queue_work(dev->priv.pg_wq, &req->work);
return NOTIFY_OK;
}
+/*
+ * After set_hca_cap(), the second satisfy_startup_pages(dev, 0) may see
+ * VHCA_ID mode. If page_root_xa already has the PF entry from the first
+ * (boot) call under FUNC_ID keys 0 or (ec_function << 16), migrate that
+ * entry to the device vhca_id key so lookups use VHCA_ID semantics.
+ */
+static int mlx5_pagealloc_migrate_pf_to_vhca_id(struct mlx5_core_dev *dev)
+{
+ u32 vhca_id_key, old_key;
+ struct rb_root *root;
+ struct fw_page *fwp;
+ struct rb_node *p;
+ bool ec_function;
+ int err;
+
+ if (xa_empty(&dev->priv.page_root_xa))
+ return 0;
+
+ vhca_id_key = MLX5_CAP_GEN(dev, vhca_id);
+ ec_function = mlx5_core_is_ecpf(dev);
+
+ old_key = ec_function ? (1U << 16) : 0;
+ root = xa_load(&dev->priv.page_root_xa, old_key);
+ if (!root)
+ return 0;
+
+ if (old_key == vhca_id_key)
+ return 0;
+
+ err = xa_insert(&dev->priv.page_root_xa, vhca_id_key, root, GFP_KERNEL);
+ if (err) {
+ mlx5_core_warn(dev,
+ "failed to migrate page root key 0x%x to vhca_id 0x%x\n",
+ old_key, vhca_id_key);
+ return err;
+ }
+
+ xa_erase(&dev->priv.page_root_xa, old_key);
+
+ for (p = rb_first(root); p; p = rb_next(p)) {
+ fwp = rb_entry(p, struct fw_page, rb_node);
+ fwp->function = vhca_id_key;
+ }
+
+ return 0;
+}
+
int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev, int boot)
{
- u16 func_id;
+ bool ec_function = false;
+ u16 func_vhca_id;
s32 npages;
int err;
- err = mlx5_cmd_query_pages(dev, &func_id, &npages, boot);
+ /* When boot flag is set, the icm_mng_function_id_mode capability is
+ * not yet set (only set after set_hca_cap()), so use FUNC_ID mode
+ * for backward compatibility. When boot is false, set mode from
+ * cap (set_hca_cap has run successfully).
+ */
+ if (boot) {
+ mlx5_page_mgt_mode_set(dev, MLX5_PAGE_MGT_MODE_FUNC_ID);
+ } else {
+ if (MLX5_CAP_GEN_MAX(dev, icm_mng_function_id_mode) ==
+ MLX5_ID_MODE_FUNCTION_VHCA_ID) {
+ err = mlx5_pagealloc_migrate_pf_to_vhca_id(dev);
+ if (err)
+ return err;
+ mlx5_page_mgt_mode_set(dev, MLX5_PAGE_MGT_MODE_VHCA_ID);
+ }
+ }
+
+ err = mlx5_cmd_query_pages(dev, &func_vhca_id, &npages, boot);
if (err)
return err;
- mlx5_core_dbg(dev, "requested %d %s pages for func_id 0x%x\n",
- npages, boot ? "boot" : "init", func_id);
+ mlx5_core_dbg(dev,
+ "requested %d %s pages for func_vhca_id 0x%x\n",
+ npages, boot ? "boot" : "init", func_vhca_id);
if (!npages)
return 0;
- return give_pages(dev, func_id, npages, 0, mlx5_core_is_ecpf(dev));
+ /* In VHCA_ID mode, ec_function remains false (not used). */
+ if (!mlx5_page_mgt_mode_is_vhca_id(dev))
+ ec_function = mlx5_core_is_ecpf(dev);
+
+ return give_pages(dev, func_vhca_id, npages, 0, ec_function);
}
enum {
@@ -709,15 +830,17 @@ static int mlx5_reclaim_root_pages(struct mlx5_core_dev *dev,
while (!RB_EMPTY_ROOT(root)) {
u32 ec_function = mlx5_get_ec_function(function);
- u32 function_id = mlx5_get_func_id(function);
+ u32 func_vhca_id = mlx5_get_func_vhca_id(function);
int nclaimed;
int err;
- err = reclaim_pages(dev, function_id, optimal_reclaimed_pages(),
+ err = reclaim_pages(dev, func_vhca_id,
+ optimal_reclaimed_pages(),
&nclaimed, false, ec_function);
if (err) {
- mlx5_core_warn(dev, "reclaim_pages err (%d) func_id=0x%x ec_func=0x%x\n",
- err, function_id, ec_function);
+ mlx5_core_warn(dev,
+ "reclaim_pages err (%d) func_vhca_id=0x%x ec_func=0x%x\n",
+ err, func_vhca_id, ec_function);
return err;
}
@@ -751,6 +874,9 @@ int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev)
WARN(dev->priv.fw_pages,
"FW pages counter is %d after reclaiming all pages\n",
dev->priv.fw_pages);
+ if (mlx5_page_mgt_mode_is_vhca_id(dev) && !dev->priv.eswitch)
+ return 0;
+
WARN(dev->priv.page_counters[MLX5_VF],
"VFs FW pages counter is %d after reclaiming all pages\n",
dev->priv.page_counters[MLX5_VF]);
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index b460b3bae195..8e22ea662644 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -556,6 +556,12 @@ enum mlx5_func_type {
MLX5_HOST_PF,
MLX5_EC_VF,
MLX5_FUNC_TYPE_NUM,
+ MLX5_FUNC_TYPE_NONE = MLX5_FUNC_TYPE_NUM,
+};
+
+enum mlx5_page_mgt_mode {
+ MLX5_PAGE_MGT_MODE_FUNC_ID,
+ MLX5_PAGE_MGT_MODE_VHCA_ID,
};
struct mlx5_ft_pool;
@@ -575,6 +581,7 @@ struct mlx5_priv {
u32 fw_pages_alloc_failed;
u32 give_pages_dropped;
u32 reclaim_pages_discard;
+ enum mlx5_page_mgt_mode page_mgt_mode;
struct mlx5_core_health health;
struct list_head traps;
--
2.44.0
next prev parent reply other threads:[~2026-05-01 4:42 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-01 4:41 [PATCH net-next 0/3] net/mlx5: ICM page management in VHCA_ID mode Tariq Toukan
2026-05-01 4:41 ` [PATCH net-next 1/3] net/mlx5: Relax capability check for eswitch query paths Tariq Toukan
2026-05-01 4:41 ` [PATCH net-next 2/3] net/mlx5: Make debugfs page counters by function type dynamic Tariq Toukan
2026-05-01 4:41 ` Tariq Toukan [this message]
2026-05-03 1:45 ` [PATCH net-next 3/3] net/mlx5: Add VHCA_ID page management mode support Jakub Kicinski
2026-05-04 11:33 ` Moshe Shemesh
2026-05-03 1:45 ` Jakub Kicinski
2026-05-04 11:41 ` Moshe Shemesh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260501044156.260875-4-tariqt@nvidia.com \
--to=tariqt@nvidia.com \
--cc=agoldberger@nvidia.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=dtatulea@nvidia.com \
--cc=edumazet@google.com \
--cc=gal@nvidia.com \
--cc=kuba@kernel.org \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=mbloch@nvidia.com \
--cc=moshe@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=saeedm@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.