Skip to content

Commit d345691

Browse files
Leon Romanovskyjgunthorpe
authored andcommitted
RDMA: Handle AH allocations by IB/core
Simplify drivers by ensuring lifetime of ib_ah object. The changes in .create_ah() go hand in hand with relevant update in .destroy_ah(). We will use this opportunity and convert .destroy_ah() to don't fail, as it was suggested a long time ago, because there is nothing to do in case of failure during destroy. Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent f631603 commit d345691

36 files changed

+229
-330
lines changed

drivers/infiniband/core/device.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2222,6 +2222,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
22222222
SET_DEVICE_OP(dev_ops, set_vf_link_state);
22232223
SET_DEVICE_OP(dev_ops, unmap_fmr);
22242224

2225+
SET_OBJ_SIZE(dev_ops, ib_ah);
22252226
SET_OBJ_SIZE(dev_ops, ib_pd);
22262227
SET_OBJ_SIZE(dev_ops, ib_ucontext);
22272228
}

drivers/infiniband/core/verbs.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -496,25 +496,33 @@ static struct ib_ah *_rdma_create_ah(struct ib_pd *pd,
496496
u32 flags,
497497
struct ib_udata *udata)
498498
{
499+
struct ib_device *device = pd->device;
499500
struct ib_ah *ah;
501+
int ret;
500502

501503
might_sleep_if(flags & RDMA_CREATE_AH_SLEEPABLE);
502504

503-
if (!pd->device->ops.create_ah)
505+
if (!device->ops.create_ah)
504506
return ERR_PTR(-EOPNOTSUPP);
505507

506-
ah = pd->device->ops.create_ah(pd, ah_attr, flags, udata);
508+
ah = rdma_zalloc_drv_obj_gfp(
509+
device, ib_ah,
510+
(flags & RDMA_CREATE_AH_SLEEPABLE) ? GFP_KERNEL : GFP_ATOMIC);
511+
if (!ah)
512+
return ERR_PTR(-ENOMEM);
507513

508-
if (!IS_ERR(ah)) {
509-
ah->device = pd->device;
510-
ah->pd = pd;
511-
ah->uobject = NULL;
512-
ah->type = ah_attr->type;
513-
ah->sgid_attr = rdma_update_sgid_attr(ah_attr, NULL);
514+
ah->device = device;
515+
ah->pd = pd;
516+
ah->type = ah_attr->type;
517+
ah->sgid_attr = rdma_update_sgid_attr(ah_attr, NULL);
514518

515-
atomic_inc(&pd->usecnt);
519+
ret = device->ops.create_ah(ah, ah_attr, flags, udata);
520+
if (ret) {
521+
kfree(ah);
522+
return ERR_PTR(ret);
516523
}
517524

525+
atomic_inc(&pd->usecnt);
518526
return ah;
519527
}
520528

@@ -935,19 +943,18 @@ int rdma_destroy_ah_user(struct ib_ah *ah, u32 flags, struct ib_udata *udata)
935943
{
936944
const struct ib_gid_attr *sgid_attr = ah->sgid_attr;
937945
struct ib_pd *pd;
938-
int ret;
939946

940947
might_sleep_if(flags & RDMA_DESTROY_AH_SLEEPABLE);
941948

942949
pd = ah->pd;
943-
ret = ah->device->ops.destroy_ah(ah, flags, udata);
944-
if (!ret) {
945-
atomic_dec(&pd->usecnt);
946-
if (sgid_attr)
947-
rdma_put_gid_attr(sgid_attr);
948-
}
949950

950-
return ret;
951+
ah->device->ops.destroy_ah(ah, flags);
952+
atomic_dec(&pd->usecnt);
953+
if (sgid_attr)
954+
rdma_put_gid_attr(sgid_attr);
955+
956+
kfree(ah);
957+
return 0;
951958
}
952959
EXPORT_SYMBOL(rdma_destroy_ah_user);
953960

drivers/infiniband/hw/bnxt_re/ib_verbs.c

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -633,20 +633,13 @@ int bnxt_re_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
633633
}
634634

635635
/* Address Handles */
636-
int bnxt_re_destroy_ah(struct ib_ah *ib_ah, u32 flags, struct ib_udata *udata)
636+
void bnxt_re_destroy_ah(struct ib_ah *ib_ah, u32 flags)
637637
{
638638
struct bnxt_re_ah *ah = container_of(ib_ah, struct bnxt_re_ah, ib_ah);
639639
struct bnxt_re_dev *rdev = ah->rdev;
640-
int rc;
641640

642-
rc = bnxt_qplib_destroy_ah(&rdev->qplib_res, &ah->qplib_ah,
643-
!(flags & RDMA_DESTROY_AH_SLEEPABLE));
644-
if (rc) {
645-
dev_err(rdev_to_dev(rdev), "Failed to destroy HW AH");
646-
return rc;
647-
}
648-
kfree(ah);
649-
return 0;
641+
bnxt_qplib_destroy_ah(&rdev->qplib_res, &ah->qplib_ah,
642+
!(flags & RDMA_DESTROY_AH_SLEEPABLE));
650643
}
651644

652645
static u8 bnxt_re_stack_to_dev_nw_type(enum rdma_network_type ntype)
@@ -667,26 +660,22 @@ static u8 bnxt_re_stack_to_dev_nw_type(enum rdma_network_type ntype)
667660
return nw_type;
668661
}
669662

670-
struct ib_ah *bnxt_re_create_ah(struct ib_pd *ib_pd,
671-
struct rdma_ah_attr *ah_attr,
672-
u32 flags,
673-
struct ib_udata *udata)
663+
int bnxt_re_create_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr,
664+
u32 flags, struct ib_udata *udata)
674665
{
666+
struct ib_pd *ib_pd = ib_ah->pd;
675667
struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
676668
const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
677669
struct bnxt_re_dev *rdev = pd->rdev;
678670
const struct ib_gid_attr *sgid_attr;
679-
struct bnxt_re_ah *ah;
671+
struct bnxt_re_ah *ah = container_of(ib_ah, struct bnxt_re_ah, ib_ah);
680672
u8 nw_type;
681673
int rc;
682674

683675
if (!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) {
684676
dev_err(rdev_to_dev(rdev), "Failed to alloc AH: GRH not set");
685-
return ERR_PTR(-EINVAL);
677+
return -EINVAL;
686678
}
687-
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
688-
if (!ah)
689-
return ERR_PTR(-ENOMEM);
690679

691680
ah->rdev = rdev;
692681
ah->qplib_ah.pd = &pd->qplib_pd;
@@ -716,7 +705,7 @@ struct ib_ah *bnxt_re_create_ah(struct ib_pd *ib_pd,
716705
!(flags & RDMA_CREATE_AH_SLEEPABLE));
717706
if (rc) {
718707
dev_err(rdev_to_dev(rdev), "Failed to allocate HW AH");
719-
goto fail;
708+
return rc;
720709
}
721710

722711
/* Write AVID to shared page. */
@@ -733,11 +722,7 @@ struct ib_ah *bnxt_re_create_ah(struct ib_pd *ib_pd,
733722
spin_unlock_irqrestore(&uctx->sh_lock, flag);
734723
}
735724

736-
return &ah->ib_ah;
737-
738-
fail:
739-
kfree(ah);
740-
return ERR_PTR(rc);
725+
return 0;
741726
}
742727

743728
int bnxt_re_modify_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr)
@@ -810,13 +795,8 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
810795
bnxt_qplib_free_qp_res(&rdev->qplib_res, &qp->qplib_qp);
811796

812797
if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) {
813-
rc = bnxt_qplib_destroy_ah(&rdev->qplib_res,
814-
&rdev->sqp_ah->qplib_ah, false);
815-
if (rc) {
816-
dev_err(rdev_to_dev(rdev),
817-
"Failed to destroy HW AH for shadow QP");
818-
return rc;
819-
}
798+
bnxt_qplib_destroy_ah(&rdev->qplib_res, &rdev->sqp_ah->qplib_ah,
799+
false);
820800

821801
bnxt_qplib_clean_qp(&qp->qplib_qp);
822802
rc = bnxt_qplib_destroy_qp(&rdev->qplib_res,

drivers/infiniband/hw/bnxt_re/ib_verbs.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ struct bnxt_re_pd {
6363
};
6464

6565
struct bnxt_re_ah {
66-
struct bnxt_re_dev *rdev;
6766
struct ib_ah ib_ah;
67+
struct bnxt_re_dev *rdev;
6868
struct bnxt_qplib_ah qplib_ah;
6969
};
7070

@@ -165,13 +165,11 @@ enum rdma_link_layer bnxt_re_get_link_layer(struct ib_device *ibdev,
165165
u8 port_num);
166166
int bnxt_re_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
167167
void bnxt_re_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
168-
struct ib_ah *bnxt_re_create_ah(struct ib_pd *pd,
169-
struct rdma_ah_attr *ah_attr,
170-
u32 flags,
171-
struct ib_udata *udata);
168+
int bnxt_re_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr, u32 flags,
169+
struct ib_udata *udata);
172170
int bnxt_re_modify_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
173171
int bnxt_re_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
174-
int bnxt_re_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata);
172+
void bnxt_re_destroy_ah(struct ib_ah *ah, u32 flags);
175173
struct ib_srq *bnxt_re_create_srq(struct ib_pd *pd,
176174
struct ib_srq_init_attr *srq_init_attr,
177175
struct ib_udata *udata);

drivers/infiniband/hw/bnxt_re/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,7 @@ static const struct ib_device_ops bnxt_re_dev_ops = {
637637
.query_srq = bnxt_re_query_srq,
638638
.reg_user_mr = bnxt_re_reg_user_mr,
639639
.req_notify_cq = bnxt_re_req_notify_cq,
640+
INIT_RDMA_OBJ_SIZE(ib_ah, bnxt_re_ah, ib_ah),
640641
INIT_RDMA_OBJ_SIZE(ib_pd, bnxt_re_pd, ib_pd),
641642
INIT_RDMA_OBJ_SIZE(ib_ucontext, bnxt_re_ucontext, ib_uctx),
642643
};

drivers/infiniband/hw/bnxt_re/qplib_sp.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -532,25 +532,21 @@ int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
532532
return 0;
533533
}
534534

535-
int bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
536-
bool block)
535+
void bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
536+
bool block)
537537
{
538538
struct bnxt_qplib_rcfw *rcfw = res->rcfw;
539539
struct cmdq_destroy_ah req;
540540
struct creq_destroy_ah_resp resp;
541541
u16 cmd_flags = 0;
542-
int rc;
543542

544543
/* Clean up the AH table in the device */
545544
RCFW_CMD_PREP(req, DESTROY_AH, cmd_flags);
546545

547546
req.ah_cid = cpu_to_le32(ah->id);
548547

549-
rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
550-
NULL, block);
551-
if (rc)
552-
return rc;
553-
return 0;
548+
bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp, NULL,
549+
block);
554550
}
555551

556552
/* MRW */

drivers/infiniband/hw/bnxt_re/qplib_sp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,8 @@ int bnxt_qplib_set_func_resources(struct bnxt_qplib_res *res,
243243
struct bnxt_qplib_ctx *ctx);
244244
int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
245245
bool block);
246-
int bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
247-
bool block);
246+
void bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
247+
bool block);
248248
int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res,
249249
struct bnxt_qplib_mrw *mrw);
250250
int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw,

drivers/infiniband/hw/hns/hns_roce_ah.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,17 @@
3939
#define HNS_ROCE_VLAN_SL_BIT_MASK 7
4040
#define HNS_ROCE_VLAN_SL_SHIFT 13
4141

42-
struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
43-
struct rdma_ah_attr *ah_attr,
44-
u32 flags,
45-
struct ib_udata *udata)
42+
int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr,
43+
u32 flags, struct ib_udata *udata)
4644
{
47-
struct hns_roce_dev *hr_dev = to_hr_dev(ibpd->device);
45+
struct hns_roce_dev *hr_dev = to_hr_dev(ibah->device);
4846
const struct ib_gid_attr *gid_attr;
4947
struct device *dev = hr_dev->dev;
50-
struct hns_roce_ah *ah;
48+
struct hns_roce_ah *ah = to_hr_ah(ibah);
5149
u16 vlan_tag = 0xffff;
5250
const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
5351
bool vlan_en = false;
5452

55-
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
56-
if (!ah)
57-
return ERR_PTR(-ENOMEM);
58-
5953
/* Get mac address */
6054
memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN);
6155

@@ -70,7 +64,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
7064
HNS_ROCE_VLAN_SL_BIT_MASK) <<
7165
HNS_ROCE_VLAN_SL_SHIFT;
7266

73-
ah->av.port_pd = cpu_to_le32(to_hr_pd(ibpd)->pdn |
67+
ah->av.port_pd = cpu_to_le32(to_hr_pd(ibah->pd)->pdn |
7468
(rdma_ah_get_port_num(ah_attr) <<
7569
HNS_ROCE_PORT_NUM_SHIFT));
7670
ah->av.gid_index = grh->sgid_index;
@@ -86,7 +80,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
8680
ah->av.sl_tclass_flowlabel = cpu_to_le32(rdma_ah_get_sl(ah_attr) <<
8781
HNS_ROCE_SL_SHIFT);
8882

89-
return &ah->ibah;
83+
return 0;
9084
}
9185

9286
int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
@@ -111,9 +105,7 @@ int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
111105
return 0;
112106
}
113107

114-
int hns_roce_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata)
108+
void hns_roce_destroy_ah(struct ib_ah *ah, u32 flags)
115109
{
116-
kfree(to_hr_ah(ah));
117-
118-
return 0;
110+
return;
119111
}

drivers/infiniband/hw/hns/hns_roce_device.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,12 +1105,10 @@ void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap,
11051105
unsigned long obj, int cnt,
11061106
int rr);
11071107

1108-
struct ib_ah *hns_roce_create_ah(struct ib_pd *pd,
1109-
struct rdma_ah_attr *ah_attr,
1110-
u32 flags,
1111-
struct ib_udata *udata);
1108+
int hns_roce_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr,
1109+
u32 flags, struct ib_udata *udata);
11121110
int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
1113-
int hns_roce_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata);
1111+
void hns_roce_destroy_ah(struct ib_ah *ah, u32 flags);
11141112

11151113
int hns_roce_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
11161114
void hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);

drivers/infiniband/hw/hns/hns_roce_main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,8 @@ static const struct ib_device_ops hns_roce_dev_ops = {
468468
.query_pkey = hns_roce_query_pkey,
469469
.query_port = hns_roce_query_port,
470470
.reg_user_mr = hns_roce_reg_user_mr,
471+
472+
INIT_RDMA_OBJ_SIZE(ib_ah, hns_roce_ah, ibah),
471473
INIT_RDMA_OBJ_SIZE(ib_pd, hns_roce_pd, ibpd),
472474
INIT_RDMA_OBJ_SIZE(ib_ucontext, hns_roce_ucontext, ibucontext),
473475
};

0 commit comments

Comments
 (0)