summaryrefslogtreecommitdiff
path: root/drivers/infiniband/hw/mlx5
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-08-13 14:13:29 +0100
committerMark Brown <broonie@kernel.org>2026-08-13 14:13:29 +0100
commit88682fbf8becdf92592f0d82c10c10e46ee33ac3 (patch)
treefb0679a337ae5100b788840c57bdbdd09173425c /drivers/infiniband/hw/mlx5
parenta62802520975e3176a5c89084af47b3c69585404 (diff)
parentd87924b995ab6d33e1c102a705837afdb8fff618 (diff)
downloadlinux-next-88682fbf8becdf92592f0d82c10c10e46ee33ac3.tar.gz
linux-next-88682fbf8becdf92592f0d82c10c10e46ee33ac3.zip
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git
# Conflicts: # drivers/infiniband/hw/irdma/verbs.c
Diffstat (limited to 'drivers/infiniband/hw/mlx5')
-rw-r--r--drivers/infiniband/hw/mlx5/cong.c24
-rw-r--r--drivers/infiniband/hw/mlx5/counters.c11
-rw-r--r--drivers/infiniband/hw/mlx5/main.c16
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h1
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c6
-rw-r--r--drivers/infiniband/hw/mlx5/odp.c6
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c37
-rw-r--r--drivers/infiniband/hw/mlx5/srq.c25
-rw-r--r--drivers/infiniband/hw/mlx5/umr.c13
9 files changed, 84 insertions, 55 deletions
diff --git a/drivers/infiniband/hw/mlx5/cong.c b/drivers/infiniband/hw/mlx5/cong.c
index d0edf83a2f20..a775b4c86e11 100644
--- a/drivers/infiniband/hw/mlx5/cong.c
+++ b/drivers/infiniband/hw/mlx5/cong.c
@@ -361,7 +361,7 @@ static int mlx5_ib_set_cc_params(struct mlx5_ib_dev *dev, u32 port_num,
MLX5_SET(field_select_r_roce_rp, field, field_select_r_roce_rp,
attr_mask);
- err = mlx5_cmd_exec_in(dev->mdev, modify_cong_params, in);
+ err = mlx5_cmd_exec_in(mdev, modify_cong_params, in);
kvfree(in);
alloc_err:
mlx5_ib_put_native_port_mdev(dev, port_num + 1);
@@ -373,22 +373,12 @@ static ssize_t set_param(struct file *filp, const char __user *buf,
{
struct mlx5_ib_dbg_param *param = filp->private_data;
int offset = param->offset;
- char lbuf[11] = { };
u32 var;
int ret;
- if (count > sizeof(lbuf))
- return -EINVAL;
-
- if (copy_from_user(lbuf, buf, count))
- return -EFAULT;
-
- lbuf[sizeof(lbuf) - 1] = '\0';
-
- if (kstrtou32(lbuf, 0, &var))
- return -EINVAL;
-
- ret = mlx5_ib_set_cc_params(param->dev, param->port_num, offset, var);
+ ret = kstrtou32_from_user(buf, count, 0, &var);
+ if (!ret)
+ ret = mlx5_ib_set_cc_params(param->dev, param->port_num, offset, var);
return ret ? ret : count;
}
@@ -399,15 +389,13 @@ static ssize_t get_param(struct file *filp, char __user *buf, size_t count,
int offset = param->offset;
u32 var = 0;
int ret;
- char lbuf[11];
+ char lbuf[12];
ret = mlx5_ib_get_cc_params(param->dev, param->port_num, offset, &var);
if (ret)
return ret;
- ret = snprintf(lbuf, sizeof(lbuf), "%d\n", var);
- if (ret < 0)
- return ret;
+ ret = scnprintf(lbuf, sizeof(lbuf), "%u\n", var);
return simple_read_from_buffer(buf, count, pos, lbuf, ret);
}
diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c
index 5a79e834ddea..2250b195571c 100644
--- a/drivers/infiniband/hw/mlx5/counters.c
+++ b/drivers/infiniband/hw/mlx5/counters.c
@@ -742,11 +742,9 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
names = is_vport ? vport_roce_accl_cnts : roce_accl_cnts;
size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) :
ARRAY_SIZE(roce_accl_cnts);
- if (MLX5_CAP_GEN(dev->mdev, roce_accl)) {
- for (i = 0; i < size; i++, j++) {
- descs[j].name = names[i].name;
- offsets[j] = names[i].offset;
- }
+ for (i = 0; i < size; i++, j++) {
+ descs[j].name = names[i].name;
+ offsets[j] = names[i].offset;
}
if (is_vport)
@@ -826,8 +824,7 @@ static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) :
ARRAY_SIZE(roce_accl_cnts);
- if (MLX5_CAP_GEN(dev->mdev, roce_accl))
- num_counters += size;
+ num_counters += size;
cnts->num_q_counters = num_counters;
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 4ff6cca7e581..a7bcc33587cc 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -969,7 +969,6 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
if (err)
return err;
- memset(props, 0, sizeof(*props));
err = mlx5_query_system_image_guid(ibdev,
&props->sys_image_guid);
if (err)
@@ -4477,6 +4476,7 @@ static const struct uapi_definition mlx5_ib_defs[] = {
UAPI_DEF_CHAIN(mlx5_ib_dm_defs),
UAPI_DEF_CHAIN(mlx5_ib_create_cq_defs),
UAPI_DEF_CHAIN(mlx5_ib_create_qp_defs),
+ UAPI_DEF_CHAIN(mlx5_ib_create_srq_defs),
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_DEVICE, &mlx5_ib_query_context),
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_MR, &mlx5_ib_reg_dmabuf_mr),
@@ -4951,6 +4951,9 @@ static int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev)
if (err)
return err;
+ if (MLX5_CAP_GEN(dev->mdev, qp_latency_sensitive_disable))
+ return 0;
+
err = mlx5_alloc_bfreg(dev->mdev, &dev->fp_bfreg, false, true);
if (err)
mlx5_free_bfreg(dev->mdev, &dev->bfreg);
@@ -4960,7 +4963,8 @@ static int mlx5_ib_stage_bfrag_init(struct mlx5_ib_dev *dev)
static void mlx5_ib_stage_bfrag_cleanup(struct mlx5_ib_dev *dev)
{
- mlx5_free_bfreg(dev->mdev, &dev->fp_bfreg);
+ if (!MLX5_CAP_GEN(dev->mdev, qp_latency_sensitive_disable))
+ mlx5_free_bfreg(dev->mdev, &dev->fp_bfreg);
mlx5_free_bfreg(dev->mdev, &dev->bfreg);
}
@@ -5501,13 +5505,13 @@ static int __init mlx5_ib_init(void)
{
int ret;
- xlt_emergency_page = (void *)__get_free_page(GFP_KERNEL);
+ xlt_emergency_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!xlt_emergency_page)
return -ENOMEM;
mlx5_ib_event_wq = alloc_ordered_workqueue("mlx5_ib_event_wq", 0);
if (!mlx5_ib_event_wq) {
- free_page((unsigned long)xlt_emergency_page);
+ kfree(xlt_emergency_page);
return -ENOMEM;
}
@@ -5542,7 +5546,7 @@ rep_err:
mlx5_ib_qp_event_cleanup();
qp_event_err:
destroy_workqueue(mlx5_ib_event_wq);
- free_page((unsigned long)xlt_emergency_page);
+ kfree(xlt_emergency_page);
return ret;
}
@@ -5556,7 +5560,7 @@ static void __exit mlx5_ib_cleanup(void)
mlx5_ib_qp_event_cleanup();
destroy_workqueue(mlx5_ib_event_wq);
- free_page((unsigned long)xlt_emergency_page);
+ kfree(xlt_emergency_page);
}
module_init(mlx5_ib_init);
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 522984d958bb..e9ddf2e97a76 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -1517,6 +1517,7 @@ extern const struct uapi_definition mlx5_ib_qos_defs[];
extern const struct uapi_definition mlx5_ib_std_types_defs[];
extern const struct uapi_definition mlx5_ib_create_cq_defs[];
extern const struct uapi_definition mlx5_ib_create_qp_defs[];
+extern const struct uapi_definition mlx5_ib_create_srq_defs[];
static inline int is_qp1(enum ib_qp_type qp_type)
{
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index e6b74955d95d..00e13028762a 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -339,7 +339,7 @@ static int mlx5r_build_frmr_key(struct ib_device *device,
return 0;
}
-static struct ib_frmr_pool_ops mlx5r_frmr_pool_ops = {
+static const struct ib_frmr_pool_ops mlx5r_frmr_pool_ops = {
.create_frmrs = mlx5r_create_mkeys,
.destroy_frmrs = mlx5r_destroy_mkeys,
.build_key = mlx5r_build_frmr_key,
@@ -898,8 +898,8 @@ static void mlx5_ib_dmabuf_invalidate_cb(struct dma_buf_attachment *attach)
ib_umem_dmabuf_unmap_pages(umem_dmabuf);
}
-static struct dma_buf_attach_ops mlx5_ib_dmabuf_attach_ops = {
- .allow_peer2peer = 1,
+static const struct dma_buf_attach_ops mlx5_ib_dmabuf_attach_ops = {
+ .allow_peer2peer = true,
.invalidate_mappings = mlx5_ib_dmabuf_invalidate_cb,
};
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index 1badec9bf527..b8618610737a 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -37,6 +37,7 @@
#include <linux/hmm.h>
#include <linux/hmm-dma.h>
#include <linux/pci-p2pdma.h>
+#include <linux/slab.h>
#include "mlx5_ib.h"
#include "cmd.h"
@@ -1414,7 +1415,8 @@ static void mlx5_ib_mr_wqe_pfault_handler(struct mlx5_ib_dev *dev,
goto resolve_page_fault;
}
- wqe_start = (void *)__get_free_page(GFP_KERNEL);
+ /* TODO: switch to "fast and as large as possible" allocation helper */
+ wqe_start = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!wqe_start) {
mlx5_ib_err(dev, "Error allocating memory for IO page fault handling.\n");
goto resolve_page_fault;
@@ -1475,7 +1477,7 @@ resolve_page_fault:
pfault->wqe.wq_num, resume_with_error,
pfault->type);
mlx5_core_res_put(res);
- free_page((unsigned long)wqe_start);
+ kfree(wqe_start);
}
static void mlx5_ib_mr_rdma_pfault_handler(struct mlx5_ib_dev *dev,
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 7ff02d89c31d..0d4f8b109ad2 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -647,6 +647,7 @@ static int set_user_buf_size(struct mlx5_ib_dev *dev,
struct ib_qp_init_attr *attr)
{
int desc_sz = 1 << qp->sq.wqe_shift;
+ int rq_buf_size, sq_buf_size;
if (desc_sz > MLX5_CAP_GEN(dev->mdev, max_wqe_sz_sq)) {
mlx5_ib_warn(dev, "desc_sz %d, max_sq_desc_sz %d\n",
@@ -671,11 +672,21 @@ static int set_user_buf_size(struct mlx5_ib_dev *dev,
if (attr->qp_type == IB_QPT_RAW_PACKET ||
qp->flags & IB_QP_CREATE_SOURCE_QPN) {
- base->ubuffer.buf_size = qp->rq.wqe_cnt << qp->rq.wqe_shift;
- qp->raw_packet_qp.sq.ubuffer.buf_size = qp->sq.wqe_cnt << 6;
+ if (check_shl_overflow(qp->rq.wqe_cnt, qp->rq.wqe_shift,
+ &base->ubuffer.buf_size))
+ return -EINVAL;
+ if (check_shl_overflow(qp->sq.wqe_cnt, 6,
+ &qp->raw_packet_qp.sq.ubuffer.buf_size))
+ return -EINVAL;
} else {
- base->ubuffer.buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
- (qp->sq.wqe_cnt << 6);
+ if (check_shl_overflow(qp->rq.wqe_cnt, qp->rq.wqe_shift,
+ &rq_buf_size))
+ return -EINVAL;
+ if (check_shl_overflow(qp->sq.wqe_cnt, 6, &sq_buf_size))
+ return -EINVAL;
+ if (check_add_overflow(rq_buf_size, sq_buf_size,
+ &base->ubuffer.buf_size))
+ return -EINVAL;
}
return 0;
@@ -1004,7 +1015,11 @@ static int _create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
qp->rq.offset = 0;
qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB);
- qp->sq.offset = qp->rq.wqe_cnt << qp->rq.wqe_shift;
+ if (check_shl_overflow(qp->rq.wqe_cnt, qp->rq.wqe_shift,
+ &qp->sq.offset)) {
+ err = -EINVAL;
+ goto err_bfreg;
+ }
err = set_user_buf_size(dev, qp, ucmd, base, attr);
if (err)
@@ -1123,7 +1138,8 @@ static int _create_kernel_qp(struct mlx5_ib_dev *dev,
void *qpc;
int err;
- if (init_attr->qp_type == MLX5_IB_QPT_REG_UMR)
+ if (init_attr->qp_type == MLX5_IB_QPT_REG_UMR &&
+ !MLX5_CAP_GEN(dev->mdev, qp_latency_sensitive_disable))
qp->bf.bfreg = &dev->fp_bfreg;
else
qp->bf.bfreg = &dev->bfreg;
@@ -2509,11 +2525,12 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
MLX5_SET(qpc, qpc, st, mlx5_st);
MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
- if (attr->qp_type != MLX5_IB_QPT_REG_UMR)
+ if (attr->qp_type == MLX5_IB_QPT_REG_UMR) {
+ if (!MLX5_CAP_GEN(dev->mdev, qp_latency_sensitive_disable))
+ MLX5_SET(qpc, qpc, latency_sensitive, 1);
+ } else {
MLX5_SET(qpc, qpc, pd, to_mpd(pd ? pd : devr->p0)->pdn);
- else
- MLX5_SET(qpc, qpc, latency_sensitive, 1);
-
+ }
if (qp->flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)
MLX5_SET(qpc, qpc, block_lb_mc, 1);
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
index 5bc48fef3744..a973c1b7515f 100644
--- a/drivers/infiniband/hw/mlx5/srq.c
+++ b/drivers/infiniband/hw/mlx5/srq.c
@@ -10,6 +10,9 @@
#include "mlx5_ib.h"
#include "srq.h"
+#define UVERBS_MODULE_NAME mlx5_ib
+#include <rdma/uverbs_named_ioctl.h>
+
static void *get_wqe(struct mlx5_ib_srq *srq, int n)
{
return mlx5_frag_buf_get_wqe(&srq->fbc, n);
@@ -48,6 +51,8 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
struct mlx5_ib_create_srq ucmd;
struct mlx5_ib_ucontext *ucontext = rdma_udata_to_drv_context(
udata, struct mlx5_ib_ucontext, ibucontext);
+ struct uverbs_attr_bundle *attrs =
+ rdma_udata_to_uverbs_attr_bundle(udata);
int err;
u32 uidx = MLX5_IB_DEFAULT_UIDX;
@@ -66,7 +71,9 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
srq->wq_sig = !!(ucmd.flags & MLX5_SRQ_FLAG_SIGNATURE);
- srq->umem = ib_umem_get_va(pd->device, ucmd.buf_addr, buf_size, 0);
+ srq->umem = ib_umem_get_attr_or_va(pd->device, attrs,
+ UVERBS_ATTR_CREATE_SRQ_BUF_UMEM,
+ ucmd.buf_addr, buf_size, 0);
if (IS_ERR(srq->umem)) {
mlx5_ib_dbg(dev, "failed umem get, size %d\n", buf_size);
err = PTR_ERR(srq->umem);
@@ -74,7 +81,9 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
}
in->umem = srq->umem;
- err = mlx5_ib_db_map_user(ucontext, NULL, 0, ucmd.db_addr, &srq->db);
+ err = mlx5_ib_db_map_user(ucontext, attrs,
+ MLX5_IB_ATTR_CREATE_SRQ_DBR_BUF_UMEM,
+ ucmd.db_addr, &srq->db);
if (err) {
mlx5_ib_dbg(dev, "map doorbell failed\n");
goto err_umem;
@@ -462,3 +471,15 @@ out:
return err;
}
+
+ADD_UVERBS_ATTRIBUTES_SIMPLE(
+ mlx5_ib_srq_create,
+ UVERBS_OBJECT_SRQ,
+ UVERBS_METHOD_SRQ_CREATE,
+ UVERBS_ATTR_UMEM(MLX5_IB_ATTR_CREATE_SRQ_DBR_BUF_UMEM,
+ UA_OPTIONAL));
+
+const struct uapi_definition mlx5_ib_create_srq_defs[] = {
+ UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_SRQ, &mlx5_ib_srq_create),
+ {},
+};
diff --git a/drivers/infiniband/hw/mlx5/umr.c b/drivers/infiniband/hw/mlx5/umr.c
index 48cae5cc1c1b..951de1d85632 100644
--- a/drivers/infiniband/hw/mlx5/umr.c
+++ b/drivers/infiniband/hw/mlx5/umr.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. */
+#include <linux/slab.h>
#include <rdma/ib_umem_odp.h>
#include <rdma/iter.h>
#include "mlx5_ib.h"
@@ -517,22 +518,20 @@ static void *mlx5r_umr_alloc_xlt(size_t *nents, size_t ent_size, gfp_t gfp_mask)
size = min_t(size_t, ent_size * ALIGN(*nents, xlt_chunk_align),
MLX5_MAX_UMR_CHUNK);
*nents = size / ent_size;
- res = (void *)__get_free_pages(gfp_mask | __GFP_NOWARN,
- get_order(size));
+ res = kmalloc(PAGE_ALIGN(size), gfp_mask | __GFP_NOWARN);
if (res)
return res;
if (size > MLX5_SPARE_UMR_CHUNK) {
size = MLX5_SPARE_UMR_CHUNK;
*nents = size / ent_size;
- res = (void *)__get_free_pages(gfp_mask | __GFP_NOWARN,
- get_order(size));
+ res = kmalloc(size, gfp_mask | __GFP_NOWARN);
if (res)
return res;
}
*nents = PAGE_SIZE / ent_size;
- res = (void *)__get_free_page(gfp_mask);
+ res = kmalloc(PAGE_SIZE, gfp_mask);
if (res)
return res;
@@ -548,7 +547,7 @@ static void mlx5r_umr_free_xlt(void *xlt, size_t length)
return;
}
- free_pages((unsigned long)xlt, get_order(length));
+ kfree(xlt);
}
static void mlx5r_umr_unmap_free_xlt(struct mlx5_ib_dev *dev, void *xlt,
@@ -978,7 +977,7 @@ static inline int _mlx5r_dmabuf_umr_update_pas(struct mlx5_ib_mr *mr,
start_block, nblocks);
}
-/**
+/*
* This function makes an mkey non-present by zapping the translation entries of
* the mkey by zapping (zeroing out) the first N entries, where N is determined
* by the largest page size supported by the device and the MR length.