mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
Merge rdma branch 'for-rc' into 'for-next'
These did not seem worth sending as a dedicated rc PR during the last week of the cycle. * ko-rdma/for-rc: RDMA/ipoib: Drain RCU callbacks during module teardown RDMA/mlx5: Drain RCU callbacks during module teardown RDMA/core: Wait for RCU callbacks before unloading ib_core RDMA/irdma: Prevent overflows in memory contiguity checks RDMA/siw: publish QP after initialization RDMA/hns: Fix potential integer overflow in mhop hem cleanup RDMA/core: Fix memory leak in __ib_create_cq() on invalid cqe RDMA/mana_ib: initialize err for empty send WR lists RDMA/erdma: initialize ret for empty receive WR lists RDMA/irdma: Prevent user-triggered null deref on QP create RDMA/irdma: Prevent rereg_mr for non-mem regions RDMA/cma: Fix hardware address comparison length in netevent callback RDMa/mlx5: Avoid frame overflow warning IB/mad: Drop unmatched RMPP responses before reassembly Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
commit
fab939caf8
|
|
@ -5272,7 +5272,7 @@ static int cma_netevent_callback(struct notifier_block *self,
|
|||
|
||||
list_for_each_entry(current_id, &ips_node->id_list, id_list_entry) {
|
||||
if (!memcmp(current_id->id.route.addr.dev_addr.dst_dev_addr,
|
||||
neigh->ha, ETH_ALEN))
|
||||
neigh->ha, neigh->dev->addr_len))
|
||||
continue;
|
||||
cma_id_get(current_id);
|
||||
if (!queue_work(cma_wq, ¤t_id->id.net_work))
|
||||
|
|
|
|||
|
|
@ -3332,6 +3332,7 @@ static void __exit ib_core_cleanup(void)
|
|||
/* Make sure that any pending umem accounting work is done. */
|
||||
destroy_workqueue(ib_wq);
|
||||
destroy_workqueue(ib_unreg_wq);
|
||||
rcu_barrier();
|
||||
WARN_ON(!xa_empty(&clients));
|
||||
WARN_ON(!xa_empty(&devices));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2031,6 +2031,24 @@ void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)
|
|||
change_mad_state(mad_send_wr, IB_MAD_STATE_EARLY_RESP);
|
||||
}
|
||||
|
||||
static bool is_kernel_rmpp_data_response(struct ib_mad_agent_private *agent,
|
||||
struct ib_mad_recv_wc *mad_recv_wc)
|
||||
{
|
||||
const struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
|
||||
struct ib_rmpp_mad *rmpp_mad;
|
||||
|
||||
if (!ib_mad_kernel_rmpp_agent(&agent->agent) ||
|
||||
!ib_response_mad(mad_hdr) ||
|
||||
!ib_is_mad_class_rmpp(mad_hdr->mgmt_class))
|
||||
return false;
|
||||
|
||||
rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
|
||||
|
||||
return (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
|
||||
IB_MGMT_RMPP_FLAG_ACTIVE) &&
|
||||
rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA;
|
||||
}
|
||||
|
||||
static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
|
||||
struct ib_mad_recv_wc *mad_recv_wc)
|
||||
{
|
||||
|
|
@ -2050,6 +2068,18 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
|
|||
}
|
||||
|
||||
list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
|
||||
if (is_kernel_rmpp_data_response(mad_agent_priv, mad_recv_wc)) {
|
||||
spin_lock_irqsave(&mad_agent_priv->lock, flags);
|
||||
mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
|
||||
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
|
||||
|
||||
if (!mad_send_wr) {
|
||||
ib_free_recv_mad(mad_recv_wc);
|
||||
deref_mad_agent(mad_agent_priv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) {
|
||||
mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
|
||||
mad_recv_wc);
|
||||
|
|
|
|||
|
|
@ -2214,13 +2214,13 @@ struct ib_cq *__ib_create_cq(struct ib_device *device,
|
|||
struct ib_cq *cq;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON_ONCE(!cq_attr->cqe))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
cq = rdma_zalloc_drv_obj(device, ib_cq);
|
||||
if (!cq)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (WARN_ON_ONCE(!cq_attr->cqe))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
cq->device = device;
|
||||
cq->comp_handler = comp_handler;
|
||||
cq->event_handler = event_handler;
|
||||
|
|
|
|||
|
|
@ -734,7 +734,7 @@ int erdma_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *recv_wr,
|
|||
const struct ib_recv_wr *wr = recv_wr;
|
||||
struct erdma_qp *qp = to_eqp(ibqp);
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_irqsave(&qp->lock, flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -836,7 +836,7 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
|
|||
mhop.bt_chunk_size;
|
||||
|
||||
for (i = 0; i < table->num_hem; ++i) {
|
||||
obj = i * buf_chunk_size / table->obj_size;
|
||||
obj = (u64)i * buf_chunk_size / table->obj_size;
|
||||
if (table->hem[i])
|
||||
hns_roce_table_mhop_put(hr_dev, table, obj, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2902,7 +2902,7 @@ static bool irdma_check_mem_contiguous(u64 *arr, u32 npages, u32 pg_size)
|
|||
u32 pg_idx;
|
||||
|
||||
for (pg_idx = 0; pg_idx < npages; pg_idx++) {
|
||||
if ((*arr + (pg_size * pg_idx)) != arr[pg_idx])
|
||||
if ((*arr + ((u64)pg_size * pg_idx)) != arr[pg_idx])
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2935,7 +2935,7 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
|
|||
|
||||
for (i = 0; i < lvl2->leaf_cnt; i++, leaf++) {
|
||||
arr = leaf->addr;
|
||||
if ((*start_addr + (i * pg_size * PBLE_PER_PAGE)) != *arr)
|
||||
if ((*start_addr + ((u64)i * pg_size * PBLE_PER_PAGE)) != *arr)
|
||||
return false;
|
||||
ret = irdma_check_mem_contiguous(arr, leaf->cnt, pg_size);
|
||||
if (!ret)
|
||||
|
|
@ -3897,6 +3897,9 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags,
|
|||
if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
if (iwmr->type != IRDMA_MEMREG_TYPE_MEM)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
ret = ib_umem_check_rereg(iwmr->region, flags, new_access);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ static int mana_ib_post_send_ud(struct mana_ib_qp *qp, const struct ib_ud_wr *wr
|
|||
int mana_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
|
||||
const struct ib_send_wr **bad_wr)
|
||||
{
|
||||
int err;
|
||||
int err = 0;
|
||||
struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp);
|
||||
|
||||
for (; wr; wr = wr->next) {
|
||||
|
|
|
|||
|
|
@ -5542,6 +5542,7 @@ static int __init mlx5_ib_init(void)
|
|||
dd_err:
|
||||
mlx5r_rep_cleanup();
|
||||
rep_err:
|
||||
rcu_barrier();
|
||||
mlx5_ib_qp_event_cleanup();
|
||||
qp_event_err:
|
||||
destroy_workqueue(mlx5_ib_event_wq);
|
||||
|
|
@ -5555,6 +5556,7 @@ static void __exit mlx5_ib_cleanup(void)
|
|||
auxiliary_driver_unregister(&mlx5r_driver);
|
||||
auxiliary_driver_unregister(&mlx5r_mp_driver);
|
||||
mlx5r_rep_cleanup();
|
||||
rcu_barrier();
|
||||
|
||||
mlx5_ib_qp_event_cleanup();
|
||||
destroy_workqueue(mlx5_ib_event_wq);
|
||||
|
|
|
|||
|
|
@ -840,13 +840,15 @@ static int handle_psv(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int handle_reg_mr_integrity(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_ib_qp *qp,
|
||||
const struct ib_send_wr *wr,
|
||||
struct mlx5_wqe_ctrl_seg **ctrl, void **seg,
|
||||
int *size, void **cur_edge,
|
||||
unsigned int *idx, int nreq, u8 fence,
|
||||
u8 next_fence)
|
||||
static noinline_for_stack int handle_reg_mr_integrity(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_ib_qp *qp,
|
||||
const struct ib_send_wr *wr,
|
||||
struct mlx5_wqe_ctrl_seg **ctrl,
|
||||
void **seg,
|
||||
int *size, void **cur_edge,
|
||||
unsigned int *idx, int nreq,
|
||||
u8 fence,
|
||||
u8 next_fence)
|
||||
{
|
||||
struct mlx5_ib_mr *mr;
|
||||
struct mlx5_ib_mr *pi_mr;
|
||||
|
|
|
|||
|
|
@ -316,6 +316,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
|
|||
struct siw_ucontext *uctx =
|
||||
rdma_udata_to_drv_context(udata, struct siw_ucontext,
|
||||
base_ucontext);
|
||||
struct siw_uresp_create_qp uresp = {};
|
||||
unsigned long flags;
|
||||
int num_sqe, num_rqe, rv = 0;
|
||||
size_t length;
|
||||
|
|
@ -369,11 +370,6 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
|
|||
spin_lock_init(&qp->rq_lock);
|
||||
spin_lock_init(&qp->orq_lock);
|
||||
|
||||
rv = siw_qp_add(sdev, qp);
|
||||
if (rv)
|
||||
goto err_atomic;
|
||||
|
||||
|
||||
/* All queue indices are derived from modulo operations
|
||||
* on a free running 'get' (consumer) and 'put' (producer)
|
||||
* unsigned counter. Having queue sizes at power of two
|
||||
|
|
@ -391,14 +387,14 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
|
|||
|
||||
if (qp->sendq == NULL) {
|
||||
rv = -ENOMEM;
|
||||
goto err_out_xa;
|
||||
goto err_out;
|
||||
}
|
||||
if (attrs->sq_sig_type != IB_SIGNAL_REQ_WR) {
|
||||
if (attrs->sq_sig_type == IB_SIGNAL_ALL_WR)
|
||||
qp->attrs.flags |= SIW_SIGNAL_ALL_WR;
|
||||
else {
|
||||
rv = -EINVAL;
|
||||
goto err_out_xa;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
qp->pd = pd;
|
||||
|
|
@ -424,7 +420,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
|
|||
|
||||
if (qp->recvq == NULL) {
|
||||
rv = -ENOMEM;
|
||||
goto err_out_xa;
|
||||
goto err_out;
|
||||
}
|
||||
qp->attrs.rq_size = num_rqe;
|
||||
}
|
||||
|
|
@ -439,11 +435,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
|
|||
qp->attrs.state = SIW_QP_STATE_IDLE;
|
||||
|
||||
if (udata) {
|
||||
struct siw_uresp_create_qp uresp = {};
|
||||
|
||||
uresp.num_sqe = num_sqe;
|
||||
uresp.num_rqe = num_rqe;
|
||||
uresp.qp_id = qp_id(qp);
|
||||
|
||||
if (qp->sendq) {
|
||||
length = num_sqe * sizeof(struct siw_sqe);
|
||||
|
|
@ -452,7 +445,7 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
|
|||
length, &uresp.sq_key);
|
||||
if (!qp->sq_entry) {
|
||||
rv = -ENOMEM;
|
||||
goto err_out_xa;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -464,9 +457,23 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
|
|||
if (!qp->rq_entry) {
|
||||
uresp.sq_key = SIW_INVAL_UOBJ_KEY;
|
||||
rv = -ENOMEM;
|
||||
goto err_out_xa;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
qp->tx_cpu = siw_get_tx_cpu(sdev);
|
||||
if (qp->tx_cpu < 0) {
|
||||
rv = -EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
init_completion(&qp->qp_free);
|
||||
|
||||
rv = siw_qp_add(sdev, qp);
|
||||
if (rv)
|
||||
goto err_out_tx;
|
||||
|
||||
if (udata) {
|
||||
uresp.qp_id = qp_id(qp);
|
||||
|
||||
if (udata->outlen < sizeof(uresp)) {
|
||||
rv = -EINVAL;
|
||||
|
|
@ -476,22 +483,19 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
|
|||
if (rv)
|
||||
goto err_out_xa;
|
||||
}
|
||||
qp->tx_cpu = siw_get_tx_cpu(sdev);
|
||||
if (qp->tx_cpu < 0) {
|
||||
rv = -EINVAL;
|
||||
goto err_out_xa;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&qp->devq);
|
||||
spin_lock_irqsave(&sdev->lock, flags);
|
||||
list_add_tail(&qp->devq, &sdev->qp_list);
|
||||
spin_unlock_irqrestore(&sdev->lock, flags);
|
||||
|
||||
init_completion(&qp->qp_free);
|
||||
|
||||
return 0;
|
||||
|
||||
err_out_xa:
|
||||
xa_erase(&sdev->qp_xa, qp_id(qp));
|
||||
err_out_tx:
|
||||
siw_put_tx_cpu(qp->tx_cpu);
|
||||
err_out:
|
||||
if (uctx) {
|
||||
rdma_user_mmap_entry_remove(qp->sq_entry);
|
||||
rdma_user_mmap_entry_remove(qp->rq_entry);
|
||||
|
|
|
|||
|
|
@ -2783,6 +2783,7 @@ static int __init ipoib_init_module(void)
|
|||
err_sa:
|
||||
ib_sa_unregister_client(&ipoib_sa_client);
|
||||
destroy_workqueue(ipoib_workqueue);
|
||||
rcu_barrier();
|
||||
|
||||
err_fs:
|
||||
ipoib_unregister_debugfs();
|
||||
|
|
@ -2800,6 +2801,7 @@ static void __exit ipoib_cleanup_module(void)
|
|||
ib_sa_unregister_client(&ipoib_sa_client);
|
||||
ipoib_unregister_debugfs();
|
||||
destroy_workqueue(ipoib_workqueue);
|
||||
rcu_barrier();
|
||||
}
|
||||
|
||||
module_init(ipoib_init_module);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user