forked from Minki/linux
RDMA/rdmavt: Decouple QP and SGE lists allocations
The rdmavt QP has fields that are both needed for the control and data path. Such mixed declaration caused to the very specific allocation flow with kzalloc_node and SGE list embedded into the struct rvt_qp. This patch separates QP creation to two: regular memory allocation for the control path and specific code for the SGE list, while the access to the later is performed through derefenced pointer. Such pointer and its context are expected to be in the cache, so performance difference is expected to be negligible, if any exists. Link: https://lore.kernel.org/r/f66c1e20ccefba0db3c69c58ca9c897f062b4d1c.1627040189.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
parent
0dc0da15ed
commit
44da3730e0
@ -1078,7 +1078,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
|
|||||||
int err;
|
int err;
|
||||||
struct rvt_swqe *swq = NULL;
|
struct rvt_swqe *swq = NULL;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
size_t sg_list_sz;
|
size_t sg_list_sz = 0;
|
||||||
struct ib_qp *ret = ERR_PTR(-ENOMEM);
|
struct ib_qp *ret = ERR_PTR(-ENOMEM);
|
||||||
struct rvt_dev_info *rdi = ib_to_rvt(ibpd->device);
|
struct rvt_dev_info *rdi = ib_to_rvt(ibpd->device);
|
||||||
void *priv = NULL;
|
void *priv = NULL;
|
||||||
@ -1126,8 +1126,6 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
|
|||||||
if (!swq)
|
if (!swq)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
sz = sizeof(*qp);
|
|
||||||
sg_list_sz = 0;
|
|
||||||
if (init_attr->srq) {
|
if (init_attr->srq) {
|
||||||
struct rvt_srq *srq = ibsrq_to_rvtsrq(init_attr->srq);
|
struct rvt_srq *srq = ibsrq_to_rvtsrq(init_attr->srq);
|
||||||
|
|
||||||
@ -1137,10 +1135,13 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
|
|||||||
} else if (init_attr->cap.max_recv_sge > 1)
|
} else if (init_attr->cap.max_recv_sge > 1)
|
||||||
sg_list_sz = sizeof(*qp->r_sg_list) *
|
sg_list_sz = sizeof(*qp->r_sg_list) *
|
||||||
(init_attr->cap.max_recv_sge - 1);
|
(init_attr->cap.max_recv_sge - 1);
|
||||||
qp = kzalloc_node(sz + sg_list_sz, GFP_KERNEL,
|
qp = kzalloc_node(sizeof(*qp), GFP_KERNEL, rdi->dparms.node);
|
||||||
rdi->dparms.node);
|
|
||||||
if (!qp)
|
if (!qp)
|
||||||
goto bail_swq;
|
goto bail_swq;
|
||||||
|
qp->r_sg_list =
|
||||||
|
kzalloc_node(sg_list_sz, GFP_KERNEL, rdi->dparms.node);
|
||||||
|
if (!qp->r_sg_list)
|
||||||
|
goto bail_qp;
|
||||||
qp->allowed_ops = get_allowed_ops(init_attr->qp_type);
|
qp->allowed_ops = get_allowed_ops(init_attr->qp_type);
|
||||||
|
|
||||||
RCU_INIT_POINTER(qp->next, NULL);
|
RCU_INIT_POINTER(qp->next, NULL);
|
||||||
@ -1328,6 +1329,7 @@ bail_driver_priv:
|
|||||||
|
|
||||||
bail_qp:
|
bail_qp:
|
||||||
kfree(qp->s_ack_queue);
|
kfree(qp->s_ack_queue);
|
||||||
|
kfree(qp->r_sg_list);
|
||||||
kfree(qp);
|
kfree(qp);
|
||||||
|
|
||||||
bail_swq:
|
bail_swq:
|
||||||
@ -1762,6 +1764,7 @@ int rvt_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
|
|||||||
kvfree(qp->r_rq.kwq);
|
kvfree(qp->r_rq.kwq);
|
||||||
rdi->driver_f.qp_priv_free(rdi, qp);
|
rdi->driver_f.qp_priv_free(rdi, qp);
|
||||||
kfree(qp->s_ack_queue);
|
kfree(qp->s_ack_queue);
|
||||||
|
kfree(qp->r_sg_list);
|
||||||
rdma_destroy_ah_attr(&qp->remote_ah_attr);
|
rdma_destroy_ah_attr(&qp->remote_ah_attr);
|
||||||
rdma_destroy_ah_attr(&qp->alt_ah_attr);
|
rdma_destroy_ah_attr(&qp->alt_ah_attr);
|
||||||
free_ud_wq_attr(qp);
|
free_ud_wq_attr(qp);
|
||||||
|
@ -444,7 +444,7 @@ struct rvt_qp {
|
|||||||
/*
|
/*
|
||||||
* This sge list MUST be last. Do not add anything below here.
|
* This sge list MUST be last. Do not add anything below here.
|
||||||
*/
|
*/
|
||||||
struct rvt_sge r_sg_list[] /* verified SGEs */
|
struct rvt_sge *r_sg_list /* verified SGEs */
|
||||||
____cacheline_aligned_in_smp;
|
____cacheline_aligned_in_smp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user