mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-04 15:55:59 -04:00
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma fixes from Jason Gunthorpe:
"Seems bigger than usual, a number of things were posted near/during
the merg window:
- Fix some compilation regressions related to the new DMABUF code
- Close a race with ib_register_device() vs netdev events that causes
GID table corruption
- Compilation warnings with some compilers in bng_re
- Correct error unwind in bng_re and the umem pinned dmabuf
- Avoid NULL pointer crash in ionic during query_port()
- Check the size for uAPI validation checks in EFA
- Several system call stack leaks in drivers found with AI
- Fix the new restricted_node_type so it works with wildcard listens
too"
* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
RDMA/uverbs: Import DMA-BUF module in uverbs_std_types_dmabuf file
RDMA/umem: Fix double dma_buf_unpin in failure path
RDMA/core: Check id_priv->restricted_node_type in cma_listen_on_dev()
RDMA/ionic: Fix kernel stack leak in ionic_create_cq()
RDMA/irdma: Fix kernel stack leak in irdma_create_user_ah()
IB/mthca: Add missed mthca_unmap_user_db() for mthca_create_srq()
RDMA/efa: Fix typo in efa_alloc_mr()
RDMA/ionic: Fix potential NULL pointer dereference in ionic_query_port
RDMA/bng_re: Unwind bng_re_dev_init properly
RDMA/bng_re: Remove unnessary validity checks
RDMA/core: Fix stale RoCE GIDs during netdev events at registration
RDMA/uverbs: select CONFIG_DMA_SHARED_BUFFER
This commit is contained in:
@@ -6,6 +6,7 @@ menuconfig INFINIBAND
|
||||
depends on INET
|
||||
depends on m || IPV6 != m
|
||||
depends on !ALPHA
|
||||
select DMA_SHARED_BUFFER
|
||||
select IRQ_POLL
|
||||
select DIMLIB
|
||||
help
|
||||
|
||||
@@ -926,6 +926,13 @@ static int gid_table_setup_one(struct ib_device *ib_dev)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* Mark the device as ready for GID cache updates. This allows netdev
|
||||
* event handlers to update the GID cache even before the device is
|
||||
* fully registered.
|
||||
*/
|
||||
ib_device_enable_gid_updates(ib_dev);
|
||||
|
||||
rdma_roce_rescan_device(ib_dev);
|
||||
|
||||
return err;
|
||||
@@ -1637,6 +1644,12 @@ void ib_cache_release_one(struct ib_device *device)
|
||||
|
||||
void ib_cache_cleanup_one(struct ib_device *device)
|
||||
{
|
||||
/*
|
||||
* Clear the GID updates mark first to prevent event handlers from
|
||||
* accessing the device while it's being torn down.
|
||||
*/
|
||||
ib_device_disable_gid_updates(device);
|
||||
|
||||
/* The cleanup function waits for all in-progress workqueue
|
||||
* elements and cleans up the GID cache. This function should be
|
||||
* called after the device was removed from the devices list and
|
||||
|
||||
@@ -2729,6 +2729,9 @@ static int cma_listen_on_dev(struct rdma_id_private *id_priv,
|
||||
*to_destroy = NULL;
|
||||
if (cma_family(id_priv) == AF_IB && !rdma_cap_ib_cm(cma_dev->device, 1))
|
||||
return 0;
|
||||
if (id_priv->restricted_node_type != RDMA_NODE_UNSPECIFIED &&
|
||||
id_priv->restricted_node_type != cma_dev->device->node_type)
|
||||
return 0;
|
||||
|
||||
dev_id_priv =
|
||||
__rdma_create_id(net, cma_listen_handler, id_priv,
|
||||
@@ -2736,6 +2739,7 @@ static int cma_listen_on_dev(struct rdma_id_private *id_priv,
|
||||
if (IS_ERR(dev_id_priv))
|
||||
return PTR_ERR(dev_id_priv);
|
||||
|
||||
dev_id_priv->restricted_node_type = id_priv->restricted_node_type;
|
||||
dev_id_priv->state = RDMA_CM_ADDR_BOUND;
|
||||
memcpy(cma_src_addr(dev_id_priv), cma_src_addr(id_priv),
|
||||
rdma_addr_size(cma_src_addr(id_priv)));
|
||||
@@ -4194,7 +4198,7 @@ int rdma_restrict_node_type(struct rdma_cm_id *id, u8 node_type)
|
||||
}
|
||||
|
||||
mutex_lock(&lock);
|
||||
if (id_priv->cma_dev)
|
||||
if (READ_ONCE(id_priv->state) != RDMA_CM_IDLE)
|
||||
ret = -EALREADY;
|
||||
else
|
||||
id_priv->restricted_node_type = node_type;
|
||||
|
||||
@@ -100,6 +100,9 @@ void ib_enum_all_roce_netdevs(roce_netdev_filter filter,
|
||||
roce_netdev_callback cb,
|
||||
void *cookie);
|
||||
|
||||
void ib_device_enable_gid_updates(struct ib_device *device);
|
||||
void ib_device_disable_gid_updates(struct ib_device *device);
|
||||
|
||||
typedef int (*nldev_callback)(struct ib_device *device,
|
||||
struct sk_buff *skb,
|
||||
struct netlink_callback *cb,
|
||||
|
||||
@@ -93,6 +93,7 @@ static struct workqueue_struct *ib_unreg_wq;
|
||||
static DEFINE_XARRAY_FLAGS(devices, XA_FLAGS_ALLOC);
|
||||
static DECLARE_RWSEM(devices_rwsem);
|
||||
#define DEVICE_REGISTERED XA_MARK_1
|
||||
#define DEVICE_GID_UPDATES XA_MARK_2
|
||||
|
||||
static u32 highest_client_id;
|
||||
#define CLIENT_REGISTERED XA_MARK_1
|
||||
@@ -2412,11 +2413,42 @@ void ib_enum_all_roce_netdevs(roce_netdev_filter filter,
|
||||
unsigned long index;
|
||||
|
||||
down_read(&devices_rwsem);
|
||||
xa_for_each_marked (&devices, index, dev, DEVICE_REGISTERED)
|
||||
xa_for_each_marked(&devices, index, dev, DEVICE_GID_UPDATES)
|
||||
ib_enum_roce_netdev(dev, filter, filter_cookie, cb, cookie);
|
||||
up_read(&devices_rwsem);
|
||||
}
|
||||
|
||||
/**
|
||||
* ib_device_enable_gid_updates - Mark device as ready for GID cache updates
|
||||
* @device: Device to mark
|
||||
*
|
||||
* Called after GID table is allocated and initialized. After this mark is set,
|
||||
* netdevice event handlers can update the device's GID cache. This allows
|
||||
* events that arrive during device registration to be processed, avoiding
|
||||
* stale GID entries when netdev properties change during the device
|
||||
* registration process.
|
||||
*/
|
||||
void ib_device_enable_gid_updates(struct ib_device *device)
|
||||
{
|
||||
down_write(&devices_rwsem);
|
||||
xa_set_mark(&devices, device->index, DEVICE_GID_UPDATES);
|
||||
up_write(&devices_rwsem);
|
||||
}
|
||||
|
||||
/**
|
||||
* ib_device_disable_gid_updates - Clear the GID updates mark
|
||||
* @device: Device to unmark
|
||||
*
|
||||
* Called before GID table cleanup to prevent event handlers from accessing
|
||||
* the device while it's being torn down.
|
||||
*/
|
||||
void ib_device_disable_gid_updates(struct ib_device *device)
|
||||
{
|
||||
down_write(&devices_rwsem);
|
||||
xa_clear_mark(&devices, device->index, DEVICE_GID_UPDATES);
|
||||
up_write(&devices_rwsem);
|
||||
}
|
||||
|
||||
/*
|
||||
* ib_enum_all_devs - enumerate all ib_devices
|
||||
* @cb: Callback to call for each found ib_device
|
||||
|
||||
@@ -218,13 +218,11 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,
|
||||
|
||||
err = ib_umem_dmabuf_map_pages(umem_dmabuf);
|
||||
if (err)
|
||||
goto err_unpin;
|
||||
goto err_release;
|
||||
dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv);
|
||||
|
||||
return umem_dmabuf;
|
||||
|
||||
err_unpin:
|
||||
dma_buf_unpin(umem_dmabuf->attach);
|
||||
err_release:
|
||||
dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv);
|
||||
ib_umem_release(&umem_dmabuf->umem);
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "rdma_core.h"
|
||||
#include "uverbs.h"
|
||||
|
||||
MODULE_IMPORT_NS("DMA_BUF");
|
||||
|
||||
static int uverbs_dmabuf_attach(struct dma_buf *dmabuf,
|
||||
struct dma_buf_attachment *attachment)
|
||||
{
|
||||
|
||||
@@ -54,9 +54,6 @@ static void bng_re_destroy_chip_ctx(struct bng_re_dev *rdev)
|
||||
{
|
||||
struct bng_re_chip_ctx *chip_ctx;
|
||||
|
||||
if (!rdev->chip_ctx)
|
||||
return;
|
||||
|
||||
kfree(rdev->dev_attr);
|
||||
rdev->dev_attr = NULL;
|
||||
|
||||
@@ -124,12 +121,6 @@ static int bng_re_net_ring_free(struct bng_re_dev *rdev,
|
||||
struct bnge_fw_msg fw_msg = {};
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (!rdev)
|
||||
return rc;
|
||||
|
||||
if (!aux_dev)
|
||||
return rc;
|
||||
|
||||
bng_re_init_hwrm_hdr((void *)&req, HWRM_RING_FREE);
|
||||
req.ring_type = type;
|
||||
req.ring_id = cpu_to_le16(fw_ring_id);
|
||||
@@ -150,10 +141,7 @@ static int bng_re_net_ring_alloc(struct bng_re_dev *rdev,
|
||||
struct hwrm_ring_alloc_input req = {};
|
||||
struct hwrm_ring_alloc_output resp;
|
||||
struct bnge_fw_msg fw_msg = {};
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (!aux_dev)
|
||||
return rc;
|
||||
int rc;
|
||||
|
||||
bng_re_init_hwrm_hdr((void *)&req, HWRM_RING_ALLOC);
|
||||
req.enables = 0;
|
||||
@@ -184,10 +172,7 @@ static int bng_re_stats_ctx_free(struct bng_re_dev *rdev)
|
||||
struct hwrm_stat_ctx_free_input req = {};
|
||||
struct hwrm_stat_ctx_free_output resp = {};
|
||||
struct bnge_fw_msg fw_msg = {};
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (!aux_dev)
|
||||
return rc;
|
||||
int rc;
|
||||
|
||||
bng_re_init_hwrm_hdr((void *)&req, HWRM_STAT_CTX_FREE);
|
||||
req.stat_ctx_id = cpu_to_le32(rdev->stats_ctx.fw_id);
|
||||
@@ -208,13 +193,10 @@ static int bng_re_stats_ctx_alloc(struct bng_re_dev *rdev)
|
||||
struct hwrm_stat_ctx_alloc_output resp = {};
|
||||
struct hwrm_stat_ctx_alloc_input req = {};
|
||||
struct bnge_fw_msg fw_msg = {};
|
||||
int rc = -EINVAL;
|
||||
int rc;
|
||||
|
||||
stats->fw_id = BNGE_INVALID_STATS_CTX_ID;
|
||||
|
||||
if (!aux_dev)
|
||||
return rc;
|
||||
|
||||
bng_re_init_hwrm_hdr((void *)&req, HWRM_STAT_CTX_ALLOC);
|
||||
req.update_period_ms = cpu_to_le32(1000);
|
||||
req.stats_dma_addr = cpu_to_le64(stats->dma_map);
|
||||
@@ -303,7 +285,7 @@ static int bng_re_dev_init(struct bng_re_dev *rdev)
|
||||
if (rc) {
|
||||
ibdev_err(&rdev->ibdev,
|
||||
"Failed to register with netedev: %#x\n", rc);
|
||||
return -EINVAL;
|
||||
goto reg_netdev_fail;
|
||||
}
|
||||
|
||||
set_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
|
||||
@@ -312,19 +294,16 @@ static int bng_re_dev_init(struct bng_re_dev *rdev)
|
||||
ibdev_err(&rdev->ibdev,
|
||||
"RoCE requires minimum 2 MSI-X vectors, but only %d reserved\n",
|
||||
rdev->aux_dev->auxr_info->msix_requested);
|
||||
bnge_unregister_dev(rdev->aux_dev);
|
||||
clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto msix_ctx_fail;
|
||||
}
|
||||
ibdev_dbg(&rdev->ibdev, "Got %d MSI-X vectors\n",
|
||||
rdev->aux_dev->auxr_info->msix_requested);
|
||||
|
||||
rc = bng_re_setup_chip_ctx(rdev);
|
||||
if (rc) {
|
||||
bnge_unregister_dev(rdev->aux_dev);
|
||||
clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
|
||||
ibdev_err(&rdev->ibdev, "Failed to get chip context\n");
|
||||
return -EINVAL;
|
||||
goto msix_ctx_fail;
|
||||
}
|
||||
|
||||
bng_re_query_hwrm_version(rdev);
|
||||
@@ -333,16 +312,14 @@ static int bng_re_dev_init(struct bng_re_dev *rdev)
|
||||
if (rc) {
|
||||
ibdev_err(&rdev->ibdev,
|
||||
"Failed to allocate RCFW Channel: %#x\n", rc);
|
||||
goto fail;
|
||||
goto alloc_fw_chl_fail;
|
||||
}
|
||||
|
||||
/* Allocate nq record memory */
|
||||
rdev->nqr = kzalloc_obj(*rdev->nqr);
|
||||
if (!rdev->nqr) {
|
||||
bng_re_destroy_chip_ctx(rdev);
|
||||
bnge_unregister_dev(rdev->aux_dev);
|
||||
clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
|
||||
return -ENOMEM;
|
||||
rc = -ENOMEM;
|
||||
goto nq_alloc_fail;
|
||||
}
|
||||
|
||||
rdev->nqr->num_msix = rdev->aux_dev->auxr_info->msix_requested;
|
||||
@@ -411,9 +388,15 @@ static int bng_re_dev_init(struct bng_re_dev *rdev)
|
||||
free_ring:
|
||||
bng_re_net_ring_free(rdev, rdev->rcfw.creq.ring_id, type);
|
||||
free_rcfw:
|
||||
kfree(rdev->nqr);
|
||||
nq_alloc_fail:
|
||||
bng_re_free_rcfw_channel(&rdev->rcfw);
|
||||
fail:
|
||||
bng_re_dev_uninit(rdev);
|
||||
alloc_fw_chl_fail:
|
||||
bng_re_destroy_chip_ctx(rdev);
|
||||
msix_ctx_fail:
|
||||
bnge_unregister_dev(rdev->aux_dev);
|
||||
clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
|
||||
reg_netdev_fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -486,8 +469,7 @@ static void bng_re_remove(struct auxiliary_device *adev)
|
||||
|
||||
rdev = dev_info->rdev;
|
||||
|
||||
if (rdev)
|
||||
bng_re_remove_device(rdev, adev);
|
||||
bng_re_remove_device(rdev, adev);
|
||||
kfree(dev_info);
|
||||
}
|
||||
|
||||
|
||||
@@ -1661,7 +1661,7 @@ static struct efa_mr *efa_alloc_mr(struct ib_pd *ibpd, int access_flags,
|
||||
struct efa_mr *mr;
|
||||
|
||||
if (udata && udata->inlen &&
|
||||
!ib_is_udata_cleared(udata, 0, sizeof(udata->inlen))) {
|
||||
!ib_is_udata_cleared(udata, 0, udata->inlen)) {
|
||||
ibdev_dbg(&dev->ibdev,
|
||||
"Incompatible ABI params, udata not cleared\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
@@ -1218,7 +1218,7 @@ int ionic_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
rdma_udata_to_drv_context(udata, struct ionic_ctx, ibctx);
|
||||
struct ionic_vcq *vcq = to_ionic_vcq(ibcq);
|
||||
struct ionic_tbl_buf buf = {};
|
||||
struct ionic_cq_resp resp;
|
||||
struct ionic_cq_resp resp = {};
|
||||
struct ionic_cq_req req;
|
||||
int udma_idx = 0, rc;
|
||||
|
||||
|
||||
@@ -81,6 +81,8 @@ static int ionic_query_port(struct ib_device *ibdev, u32 port,
|
||||
return -EINVAL;
|
||||
|
||||
ndev = ib_device_get_netdev(ibdev, port);
|
||||
if (!ndev)
|
||||
return -ENODEV;
|
||||
|
||||
if (netif_running(ndev) && netif_carrier_ok(ndev)) {
|
||||
attr->state = IB_PORT_ACTIVE;
|
||||
|
||||
@@ -5212,7 +5212,7 @@ static int irdma_create_user_ah(struct ib_ah *ibah,
|
||||
#define IRDMA_CREATE_AH_MIN_RESP_LEN offsetofend(struct irdma_create_ah_resp, rsvd)
|
||||
struct irdma_ah *ah = container_of(ibah, struct irdma_ah, ibah);
|
||||
struct irdma_device *iwdev = to_iwdev(ibah->pd->device);
|
||||
struct irdma_create_ah_resp uresp;
|
||||
struct irdma_create_ah_resp uresp = {};
|
||||
struct irdma_ah *parent_ah;
|
||||
int err;
|
||||
|
||||
|
||||
@@ -428,6 +428,8 @@ static int mthca_create_srq(struct ib_srq *ibsrq,
|
||||
|
||||
if (context && ib_copy_to_udata(udata, &srq->srqn, sizeof(__u32))) {
|
||||
mthca_free_srq(to_mdev(ibsrq->device), srq);
|
||||
mthca_unmap_user_db(to_mdev(ibsrq->device), &context->uar,
|
||||
context->db_tab, ucmd.db_index);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@@ -436,6 +438,7 @@ static int mthca_create_srq(struct ib_srq *ibsrq,
|
||||
|
||||
static int mthca_destroy_srq(struct ib_srq *srq, struct ib_udata *udata)
|
||||
{
|
||||
mthca_free_srq(to_mdev(srq->device), to_msrq(srq));
|
||||
if (udata) {
|
||||
struct mthca_ucontext *context =
|
||||
rdma_udata_to_drv_context(
|
||||
@@ -446,8 +449,6 @@ static int mthca_destroy_srq(struct ib_srq *srq, struct ib_udata *udata)
|
||||
mthca_unmap_user_db(to_mdev(srq->device), &context->uar,
|
||||
context->db_tab, to_msrq(srq)->db_index);
|
||||
}
|
||||
|
||||
mthca_free_srq(to_mdev(srq->device), to_msrq(srq));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ void rdma_destroy_id(struct rdma_cm_id *id);
|
||||
*
|
||||
* It needs to be called before the RDMA identifier is bound
|
||||
* to an device, which mean it should be called before
|
||||
* rdma_bind_addr(), rdma_bind_addr() and rdma_listen().
|
||||
* rdma_bind_addr(), rdma_resolve_addr() and rdma_listen().
|
||||
*/
|
||||
int rdma_restrict_node_type(struct rdma_cm_id *id, u8 node_type);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user