Commit d3456914 authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Jason Gunthorpe

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: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent f6316032
...@@ -2222,6 +2222,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops) ...@@ -2222,6 +2222,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
SET_DEVICE_OP(dev_ops, set_vf_link_state); SET_DEVICE_OP(dev_ops, set_vf_link_state);
SET_DEVICE_OP(dev_ops, unmap_fmr); SET_DEVICE_OP(dev_ops, unmap_fmr);
SET_OBJ_SIZE(dev_ops, ib_ah);
SET_OBJ_SIZE(dev_ops, ib_pd); SET_OBJ_SIZE(dev_ops, ib_pd);
SET_OBJ_SIZE(dev_ops, ib_ucontext); SET_OBJ_SIZE(dev_ops, ib_ucontext);
} }
......
...@@ -496,25 +496,33 @@ static struct ib_ah *_rdma_create_ah(struct ib_pd *pd, ...@@ -496,25 +496,33 @@ static struct ib_ah *_rdma_create_ah(struct ib_pd *pd,
u32 flags, u32 flags,
struct ib_udata *udata) struct ib_udata *udata)
{ {
struct ib_device *device = pd->device;
struct ib_ah *ah; struct ib_ah *ah;
int ret;
might_sleep_if(flags & RDMA_CREATE_AH_SLEEPABLE); might_sleep_if(flags & RDMA_CREATE_AH_SLEEPABLE);
if (!pd->device->ops.create_ah) if (!device->ops.create_ah)
return ERR_PTR(-EOPNOTSUPP); return ERR_PTR(-EOPNOTSUPP);
ah = pd->device->ops.create_ah(pd, ah_attr, flags, udata); ah = rdma_zalloc_drv_obj_gfp(
device, ib_ah,
(flags & RDMA_CREATE_AH_SLEEPABLE) ? GFP_KERNEL : GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
if (!IS_ERR(ah)) { ah->device = device;
ah->device = pd->device;
ah->pd = pd; ah->pd = pd;
ah->uobject = NULL;
ah->type = ah_attr->type; ah->type = ah_attr->type;
ah->sgid_attr = rdma_update_sgid_attr(ah_attr, NULL); ah->sgid_attr = rdma_update_sgid_attr(ah_attr, NULL);
atomic_inc(&pd->usecnt); ret = device->ops.create_ah(ah, ah_attr, flags, udata);
if (ret) {
kfree(ah);
return ERR_PTR(ret);
} }
atomic_inc(&pd->usecnt);
return ah; return ah;
} }
...@@ -935,19 +943,18 @@ int rdma_destroy_ah_user(struct ib_ah *ah, u32 flags, struct ib_udata *udata) ...@@ -935,19 +943,18 @@ int rdma_destroy_ah_user(struct ib_ah *ah, u32 flags, struct ib_udata *udata)
{ {
const struct ib_gid_attr *sgid_attr = ah->sgid_attr; const struct ib_gid_attr *sgid_attr = ah->sgid_attr;
struct ib_pd *pd; struct ib_pd *pd;
int ret;
might_sleep_if(flags & RDMA_DESTROY_AH_SLEEPABLE); might_sleep_if(flags & RDMA_DESTROY_AH_SLEEPABLE);
pd = ah->pd; pd = ah->pd;
ret = ah->device->ops.destroy_ah(ah, flags, udata);
if (!ret) { ah->device->ops.destroy_ah(ah, flags);
atomic_dec(&pd->usecnt); atomic_dec(&pd->usecnt);
if (sgid_attr) if (sgid_attr)
rdma_put_gid_attr(sgid_attr); rdma_put_gid_attr(sgid_attr);
}
return ret; kfree(ah);
return 0;
} }
EXPORT_SYMBOL(rdma_destroy_ah_user); EXPORT_SYMBOL(rdma_destroy_ah_user);
......
...@@ -633,20 +633,13 @@ int bnxt_re_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) ...@@ -633,20 +633,13 @@ int bnxt_re_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
} }
/* Address Handles */ /* Address Handles */
int bnxt_re_destroy_ah(struct ib_ah *ib_ah, u32 flags, struct ib_udata *udata) void bnxt_re_destroy_ah(struct ib_ah *ib_ah, u32 flags)
{ {
struct bnxt_re_ah *ah = container_of(ib_ah, struct bnxt_re_ah, ib_ah); struct bnxt_re_ah *ah = container_of(ib_ah, struct bnxt_re_ah, ib_ah);
struct bnxt_re_dev *rdev = ah->rdev; struct bnxt_re_dev *rdev = ah->rdev;
int rc;
rc = bnxt_qplib_destroy_ah(&rdev->qplib_res, &ah->qplib_ah, bnxt_qplib_destroy_ah(&rdev->qplib_res, &ah->qplib_ah,
!(flags & RDMA_DESTROY_AH_SLEEPABLE)); !(flags & RDMA_DESTROY_AH_SLEEPABLE));
if (rc) {
dev_err(rdev_to_dev(rdev), "Failed to destroy HW AH");
return rc;
}
kfree(ah);
return 0;
} }
static u8 bnxt_re_stack_to_dev_nw_type(enum rdma_network_type ntype) 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) ...@@ -667,26 +660,22 @@ static u8 bnxt_re_stack_to_dev_nw_type(enum rdma_network_type ntype)
return nw_type; return nw_type;
} }
struct ib_ah *bnxt_re_create_ah(struct ib_pd *ib_pd, int bnxt_re_create_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr,
struct rdma_ah_attr *ah_attr, u32 flags, struct ib_udata *udata)
u32 flags,
struct ib_udata *udata)
{ {
struct ib_pd *ib_pd = ib_ah->pd;
struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd); struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr); const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
struct bnxt_re_dev *rdev = pd->rdev; struct bnxt_re_dev *rdev = pd->rdev;
const struct ib_gid_attr *sgid_attr; const struct ib_gid_attr *sgid_attr;
struct bnxt_re_ah *ah; struct bnxt_re_ah *ah = container_of(ib_ah, struct bnxt_re_ah, ib_ah);
u8 nw_type; u8 nw_type;
int rc; int rc;
if (!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) { if (!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) {
dev_err(rdev_to_dev(rdev), "Failed to alloc AH: GRH not set"); dev_err(rdev_to_dev(rdev), "Failed to alloc AH: GRH not set");
return ERR_PTR(-EINVAL); return -EINVAL;
} }
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
ah->rdev = rdev; ah->rdev = rdev;
ah->qplib_ah.pd = &pd->qplib_pd; ah->qplib_ah.pd = &pd->qplib_pd;
...@@ -716,7 +705,7 @@ struct ib_ah *bnxt_re_create_ah(struct ib_pd *ib_pd, ...@@ -716,7 +705,7 @@ struct ib_ah *bnxt_re_create_ah(struct ib_pd *ib_pd,
!(flags & RDMA_CREATE_AH_SLEEPABLE)); !(flags & RDMA_CREATE_AH_SLEEPABLE));
if (rc) { if (rc) {
dev_err(rdev_to_dev(rdev), "Failed to allocate HW AH"); dev_err(rdev_to_dev(rdev), "Failed to allocate HW AH");
goto fail; return rc;
} }
/* Write AVID to shared page. */ /* Write AVID to shared page. */
...@@ -733,11 +722,7 @@ struct ib_ah *bnxt_re_create_ah(struct ib_pd *ib_pd, ...@@ -733,11 +722,7 @@ struct ib_ah *bnxt_re_create_ah(struct ib_pd *ib_pd,
spin_unlock_irqrestore(&uctx->sh_lock, flag); spin_unlock_irqrestore(&uctx->sh_lock, flag);
} }
return &ah->ib_ah; return 0;
fail:
kfree(ah);
return ERR_PTR(rc);
} }
int bnxt_re_modify_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr) 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) ...@@ -810,13 +795,8 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
bnxt_qplib_free_qp_res(&rdev->qplib_res, &qp->qplib_qp); bnxt_qplib_free_qp_res(&rdev->qplib_res, &qp->qplib_qp);
if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) { if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) {
rc = bnxt_qplib_destroy_ah(&rdev->qplib_res, bnxt_qplib_destroy_ah(&rdev->qplib_res, &rdev->sqp_ah->qplib_ah,
&rdev->sqp_ah->qplib_ah, false); false);
if (rc) {
dev_err(rdev_to_dev(rdev),
"Failed to destroy HW AH for shadow QP");
return rc;
}
bnxt_qplib_clean_qp(&qp->qplib_qp); bnxt_qplib_clean_qp(&qp->qplib_qp);
rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, rc = bnxt_qplib_destroy_qp(&rdev->qplib_res,
......
...@@ -63,8 +63,8 @@ struct bnxt_re_pd { ...@@ -63,8 +63,8 @@ struct bnxt_re_pd {
}; };
struct bnxt_re_ah { struct bnxt_re_ah {
struct bnxt_re_dev *rdev;
struct ib_ah ib_ah; struct ib_ah ib_ah;
struct bnxt_re_dev *rdev;
struct bnxt_qplib_ah qplib_ah; struct bnxt_qplib_ah qplib_ah;
}; };
...@@ -165,13 +165,11 @@ enum rdma_link_layer bnxt_re_get_link_layer(struct ib_device *ibdev, ...@@ -165,13 +165,11 @@ enum rdma_link_layer bnxt_re_get_link_layer(struct ib_device *ibdev,
u8 port_num); u8 port_num);
int bnxt_re_alloc_pd(struct ib_pd *pd, struct ib_udata *udata); int bnxt_re_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
void bnxt_re_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata); void bnxt_re_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
struct ib_ah *bnxt_re_create_ah(struct ib_pd *pd, int bnxt_re_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr, u32 flags,
struct rdma_ah_attr *ah_attr,
u32 flags,
struct ib_udata *udata); struct ib_udata *udata);
int bnxt_re_modify_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr); int bnxt_re_modify_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
int bnxt_re_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr); int bnxt_re_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
int bnxt_re_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata); void bnxt_re_destroy_ah(struct ib_ah *ah, u32 flags);
struct ib_srq *bnxt_re_create_srq(struct ib_pd *pd, struct ib_srq *bnxt_re_create_srq(struct ib_pd *pd,
struct ib_srq_init_attr *srq_init_attr, struct ib_srq_init_attr *srq_init_attr,
struct ib_udata *udata); struct ib_udata *udata);
......
...@@ -637,6 +637,7 @@ static const struct ib_device_ops bnxt_re_dev_ops = { ...@@ -637,6 +637,7 @@ static const struct ib_device_ops bnxt_re_dev_ops = {
.query_srq = bnxt_re_query_srq, .query_srq = bnxt_re_query_srq,
.reg_user_mr = bnxt_re_reg_user_mr, .reg_user_mr = bnxt_re_reg_user_mr,
.req_notify_cq = bnxt_re_req_notify_cq, .req_notify_cq = bnxt_re_req_notify_cq,
INIT_RDMA_OBJ_SIZE(ib_ah, bnxt_re_ah, ib_ah),
INIT_RDMA_OBJ_SIZE(ib_pd, bnxt_re_pd, ib_pd), INIT_RDMA_OBJ_SIZE(ib_pd, bnxt_re_pd, ib_pd),
INIT_RDMA_OBJ_SIZE(ib_ucontext, bnxt_re_ucontext, ib_uctx), INIT_RDMA_OBJ_SIZE(ib_ucontext, bnxt_re_ucontext, ib_uctx),
}; };
......
...@@ -532,25 +532,21 @@ int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah, ...@@ -532,25 +532,21 @@ int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
return 0; return 0;
} }
int bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah, void bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
bool block) bool block)
{ {
struct bnxt_qplib_rcfw *rcfw = res->rcfw; struct bnxt_qplib_rcfw *rcfw = res->rcfw;
struct cmdq_destroy_ah req; struct cmdq_destroy_ah req;
struct creq_destroy_ah_resp resp; struct creq_destroy_ah_resp resp;
u16 cmd_flags = 0; u16 cmd_flags = 0;
int rc;
/* Clean up the AH table in the device */ /* Clean up the AH table in the device */
RCFW_CMD_PREP(req, DESTROY_AH, cmd_flags); RCFW_CMD_PREP(req, DESTROY_AH, cmd_flags);
req.ah_cid = cpu_to_le32(ah->id); req.ah_cid = cpu_to_le32(ah->id);
rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp, bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp, NULL,
NULL, block); block);
if (rc)
return rc;
return 0;
} }
/* MRW */ /* MRW */
......
...@@ -243,7 +243,7 @@ int bnxt_qplib_set_func_resources(struct bnxt_qplib_res *res, ...@@ -243,7 +243,7 @@ int bnxt_qplib_set_func_resources(struct bnxt_qplib_res *res,
struct bnxt_qplib_ctx *ctx); struct bnxt_qplib_ctx *ctx);
int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah, int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
bool block); bool block);
int bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah, void bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah,
bool block); bool block);
int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res, int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res,
struct bnxt_qplib_mrw *mrw); struct bnxt_qplib_mrw *mrw);
......
...@@ -39,23 +39,17 @@ ...@@ -39,23 +39,17 @@
#define HNS_ROCE_VLAN_SL_BIT_MASK 7 #define HNS_ROCE_VLAN_SL_BIT_MASK 7
#define HNS_ROCE_VLAN_SL_SHIFT 13 #define HNS_ROCE_VLAN_SL_SHIFT 13
struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr,
struct rdma_ah_attr *ah_attr, u32 flags, struct ib_udata *udata)
u32 flags,
struct ib_udata *udata)
{ {
struct hns_roce_dev *hr_dev = to_hr_dev(ibpd->device); struct hns_roce_dev *hr_dev = to_hr_dev(ibah->device);
const struct ib_gid_attr *gid_attr; const struct ib_gid_attr *gid_attr;
struct device *dev = hr_dev->dev; struct device *dev = hr_dev->dev;
struct hns_roce_ah *ah; struct hns_roce_ah *ah = to_hr_ah(ibah);
u16 vlan_tag = 0xffff; u16 vlan_tag = 0xffff;
const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr); const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
bool vlan_en = false; bool vlan_en = false;
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
/* Get mac address */ /* Get mac address */
memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN); memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN);
...@@ -70,7 +64,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, ...@@ -70,7 +64,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
HNS_ROCE_VLAN_SL_BIT_MASK) << HNS_ROCE_VLAN_SL_BIT_MASK) <<
HNS_ROCE_VLAN_SL_SHIFT; HNS_ROCE_VLAN_SL_SHIFT;
ah->av.port_pd = cpu_to_le32(to_hr_pd(ibpd)->pdn | ah->av.port_pd = cpu_to_le32(to_hr_pd(ibah->pd)->pdn |
(rdma_ah_get_port_num(ah_attr) << (rdma_ah_get_port_num(ah_attr) <<
HNS_ROCE_PORT_NUM_SHIFT)); HNS_ROCE_PORT_NUM_SHIFT));
ah->av.gid_index = grh->sgid_index; ah->av.gid_index = grh->sgid_index;
...@@ -86,7 +80,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, ...@@ -86,7 +80,7 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd,
ah->av.sl_tclass_flowlabel = cpu_to_le32(rdma_ah_get_sl(ah_attr) << ah->av.sl_tclass_flowlabel = cpu_to_le32(rdma_ah_get_sl(ah_attr) <<
HNS_ROCE_SL_SHIFT); HNS_ROCE_SL_SHIFT);
return &ah->ibah; return 0;
} }
int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) 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) ...@@ -111,9 +105,7 @@ int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
return 0; return 0;
} }
int hns_roce_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata) void hns_roce_destroy_ah(struct ib_ah *ah, u32 flags)
{ {
kfree(to_hr_ah(ah)); return;
return 0;
} }
...@@ -1105,12 +1105,10 @@ void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap, ...@@ -1105,12 +1105,10 @@ void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap,
unsigned long obj, int cnt, unsigned long obj, int cnt,
int rr); int rr);
struct ib_ah *hns_roce_create_ah(struct ib_pd *pd, int hns_roce_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr,
struct rdma_ah_attr *ah_attr, u32 flags, struct ib_udata *udata);
u32 flags,
struct ib_udata *udata);
int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr); int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
int hns_roce_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata); void hns_roce_destroy_ah(struct ib_ah *ah, u32 flags);
int hns_roce_alloc_pd(struct ib_pd *pd, struct ib_udata *udata); int hns_roce_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
void hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata); void hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
......
...@@ -468,6 +468,8 @@ static const struct ib_device_ops hns_roce_dev_ops = { ...@@ -468,6 +468,8 @@ static const struct ib_device_ops hns_roce_dev_ops = {
.query_pkey = hns_roce_query_pkey, .query_pkey = hns_roce_query_pkey,
.query_port = hns_roce_query_port, .query_port = hns_roce_query_port,
.reg_user_mr = hns_roce_reg_user_mr, .reg_user_mr = hns_roce_reg_user_mr,
INIT_RDMA_OBJ_SIZE(ib_ah, hns_roce_ah, ibah),
INIT_RDMA_OBJ_SIZE(ib_pd, hns_roce_pd, ibpd), INIT_RDMA_OBJ_SIZE(ib_pd, hns_roce_pd, ibpd),
INIT_RDMA_OBJ_SIZE(ib_ucontext, hns_roce_ucontext, ibucontext), INIT_RDMA_OBJ_SIZE(ib_ucontext, hns_roce_ucontext, ibucontext),
}; };
......
...@@ -40,13 +40,12 @@ ...@@ -40,13 +40,12 @@
#include "mlx4_ib.h" #include "mlx4_ib.h"
static struct ib_ah *create_ib_ah(struct ib_pd *pd, static void create_ib_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr)
struct rdma_ah_attr *ah_attr,
struct mlx4_ib_ah *ah)
{ {
struct mlx4_dev *dev = to_mdev(pd->device)->dev; struct mlx4_ib_ah *ah = to_mah(ib_ah);
struct mlx4_dev *dev = to_mdev(ib_ah->device)->dev;
ah->av.ib.port_pd = cpu_to_be32(to_mpd(pd)->pdn | ah->av.ib.port_pd = cpu_to_be32(to_mpd(ib_ah->pd)->pdn |
(rdma_ah_get_port_num(ah_attr) << 24)); (rdma_ah_get_port_num(ah_attr) << 24));
ah->av.ib.g_slid = rdma_ah_get_path_bits(ah_attr); ah->av.ib.g_slid = rdma_ah_get_path_bits(ah_attr);
ah->av.ib.sl_tclass_flowlabel = ah->av.ib.sl_tclass_flowlabel =
...@@ -73,15 +72,12 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd, ...@@ -73,15 +72,12 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd,
--static_rate; --static_rate;
ah->av.ib.stat_rate = static_rate; ah->av.ib.stat_rate = static_rate;
} }
return &ah->ibah;
} }
static struct ib_ah *create_iboe_ah(struct ib_pd *pd, static int create_iboe_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr)
struct rdma_ah_attr *ah_attr,
struct mlx4_ib_ah *ah)
{ {
struct mlx4_ib_dev *ibdev = to_mdev(pd->device); struct mlx4_ib_dev *ibdev = to_mdev(ib_ah->device);
struct mlx4_ib_ah *ah = to_mah(ib_ah);
const struct ib_gid_attr *gid_attr; const struct ib_gid_attr *gid_attr;
struct mlx4_dev *dev = ibdev->dev; struct mlx4_dev *dev = ibdev->dev;
int is_mcast = 0; int is_mcast = 0;
...@@ -108,7 +104,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, ...@@ -108,7 +104,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd,
memcpy(ah->av.eth.s_mac, gid_attr->ndev->dev_addr, ETH_ALEN); memcpy(ah->av.eth.s_mac, gid_attr->ndev->dev_addr, ETH_ALEN);
ret = mlx4_ib_gid_index_to_real_index(ibdev, gid_attr); ret = mlx4_ib_gid_index_to_real_index(ibdev, gid_attr);
if (ret < 0) if (ret < 0)
return ERR_PTR(ret); return ret;
ah->av.eth.gid_index = ret; ah->av.eth.gid_index = ret;
} else { } else {
/* mlx4_ib_create_ah_slave fills in the s_mac and the vlan */ /* mlx4_ib_create_ah_slave fills in the s_mac and the vlan */
...@@ -117,7 +113,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, ...@@ -117,7 +113,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd,
if (vlan_tag < 0x1000) if (vlan_tag < 0x1000)
vlan_tag |= (rdma_ah_get_sl(ah_attr) & 7) << 13; vlan_tag |= (rdma_ah_get_sl(ah_attr) & 7) << 13;
ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | ah->av.eth.port_pd = cpu_to_be32(to_mpd(ib_ah->pd)->pdn |
(rdma_ah_get_port_num(ah_attr) << 24)); (rdma_ah_get_port_num(ah_attr) << 24));
ah->av.eth.vlan = cpu_to_be16(vlan_tag); ah->av.eth.vlan = cpu_to_be16(vlan_tag);
ah->av.eth.hop_limit = grh->hop_limit; ah->av.eth.hop_limit = grh->hop_limit;
...@@ -140,24 +136,16 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, ...@@ -140,24 +136,16 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd,
memcpy(ah->av.eth.dgid, grh->dgid.raw, 16); memcpy(ah->av.eth.dgid, grh->dgid.raw, 16);
ah->av.eth.sl_tclass_flowlabel |= cpu_to_be32(rdma_ah_get_sl(ah_attr) ah->av.eth.sl_tclass_flowlabel |= cpu_to_be32(rdma_ah_get_sl(ah_attr)
<< 29); << 29);
return &ah->ibah; return 0;
} }
struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, int mlx4_ib_create_ah(struct ib_ah *ib_ah, struct rdma_ah_attr *ah_attr,
u32 flags, struct ib_udata *udata) u32 flags, struct ib_udata *udata)
{ {
struct mlx4_ib_ah *ah;
struct ib_ah *ret;
ah = kzalloc(sizeof *ah, GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
if (ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) { if (ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) {
if (!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) { if (!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH))
ret = ERR_PTR(-EINVAL); return -EINVAL;
} else {
/* /*
* TBD: need to handle the case when we get * TBD: need to handle the case when we get
* called in an atomic context and there we * called in an atomic context and there we
...@@ -166,37 +154,27 @@ struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, ...@@ -166,37 +154,27 @@ struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
* local addresses which we can translate * local addresses which we can translate
* without going to sleep. * without going to sleep.
*/ */
ret = create_iboe_ah(pd, ah_attr, ah); return create_iboe_ah(ib_ah, ah_attr);
} }
if (IS_ERR(ret)) create_ib_ah(ib_ah, ah_attr);
kfree(ah); return 0;
return ret;
} else
return create_ib_ah(pd, ah_attr, ah); /* never fails */
} }
/* AH's created via this call must be free'd by mlx4_ib_destroy_ah. */ int mlx4_ib_create_ah_slave(struct ib_ah *ah, struct rdma_ah_attr *ah_attr,
struct ib_ah *mlx4_ib_create_ah_slave(struct ib_pd *pd, int slave_sgid_index, u8 *s_mac, u16 vlan_tag)
struct rdma_ah_attr *ah_attr,
int slave_sgid_index, u8 *s_mac,
u16 vlan_tag)
{ {
struct rdma_ah_attr slave_attr = *ah_attr; struct rdma_ah_attr slave_attr = *ah_attr;
struct mlx4_ib_ah *mah; struct mlx4_ib_ah *mah = to_mah(ah);
struct ib_ah *ah; int ret;
slave_attr.grh.sgid_attr = NULL; slave_attr.grh.sgid_attr = NULL;
slave_attr.grh.sgid_index = slave_sgid_index; slave_attr.grh.sgid_index = slave_sgid_index;
ah = mlx4_ib_create_ah(pd, &slave_attr, 0, NULL); ret = mlx4_ib_create_ah(ah, &slave_attr, 0, NULL);
if (IS_ERR(ah)) if (ret)
return ah; return ret;
ah->device = pd->device;
ah->pd = pd;
ah->type = ah_attr->type; ah->type = ah_attr->type;
mah = to_mah(ah);
/* get rid of force-loopback bit */ /* get rid of force-loopback bit */
mah->av.ib.port_pd &= cpu_to_be32(0x7FFFFFFF); mah->av.ib.port_pd &= cpu_to_be32(0x7FFFFFFF);
...@@ -208,7 +186,7 @@ struct ib_ah *mlx4_ib_create_ah_slave(struct ib_pd *pd, ...@@ -208,7 +186,7 @@ struct ib_ah *mlx4_ib_create_ah_slave(struct ib_pd *pd,
vlan_tag |= (rdma_ah_get_sl(ah_attr) & 7) << 13; vlan_tag |= (rdma_ah_get_sl(ah_attr) & 7) << 13;
mah->av.eth.vlan = cpu_to_be16(vlan_tag); mah->av.eth.vlan = cpu_to_be16(vlan_tag);
return ah; return 0;
} }
int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
...@@ -250,8 +228,7 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) ...@@ -250,8 +228,7 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
return 0; return 0;
} }
int mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata) void mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags)
{ {
kfree(to_mah(ah)); return;
return 0;
} }
...@@ -1371,9 +1371,9 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port, ...@@ -1371,9 +1371,9 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
struct ib_ah *ah; struct ib_ah *ah;
struct ib_qp *send_qp = NULL; struct ib_qp *send_qp = NULL;
unsigned wire_tx_ix = 0; unsigned wire_tx_ix = 0;
int ret = 0;
u16 wire_pkey_ix; u16 wire_pkey_ix;
int src_qpnum; int src_qpnum;
int ret;
sqp_ctx = dev->sriov.sqps[port-1]; sqp_ctx = dev->sriov.sqps[port-1];
...@@ -1393,12 +1393,20 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port, ...@@ -1393,12 +1393,20 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
send_qp = sqp->qp; send_qp = sqp->qp;
ah = rdma_zalloc_drv_obj(sqp_ctx->pd->device, ib_ah);
if (!ah)
return -ENOMEM;
ah->device = sqp_ctx->pd->device;
ah->pd = sqp_ctx->pd;
/* create ah */ /* create ah */
ah = mlx4_ib_create_ah_slave(sqp_ctx->pd, attr, ret = mlx4_ib_create_ah_slave(ah, attr,
rdma_ah_retrieve_grh(attr)->sgid_index, rdma_ah_retrieve_grh(attr)->sgid_index,
s_mac, vlan_id); s_mac, vlan_id);
if (IS_ERR(ah)) if (ret)
return -ENOMEM; goto out;
spin_lock(&sqp->tx_lock); spin_lock(&sqp->tx_lock);
if (sqp->tx_ix_head - sqp->tx_ix_tail >= if (sqp->tx_ix_head - sqp->tx_ix_tail >=
(MLX4_NUM_TUNNEL_BUFS - 1)) (MLX4_NUM_TUNNEL_BUFS - 1))
...@@ -1410,8 +1418,7 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port, ...@@ -1410,8 +1418,7 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
goto out; goto out;
sqp_mad = (struct mlx4_mad_snd_buf *) (sqp->tx_ring[wire_tx_ix].buf.addr); sqp_mad = (struct mlx4_mad_snd_buf *) (sqp->tx_ring[wire_tx_ix].buf.addr);
if (sqp->tx_ring[wire_tx_ix].ah) kfree(sqp->tx_ring[wire_tx_ix].ah);
mlx4_ib_destroy_ah(sqp->tx_ring[wire_tx_ix].ah, 0, NULL);
sqp->tx_ring[wire_tx_ix].ah = ah; sqp->tx_ring[wire_tx_ix].ah = ah;
ib_dma_sync_single_for_cpu(&dev->ib_dev, ib_dma_sync_single_for_cpu(&dev->ib_dev,
sqp->tx_ring[wire_tx_ix].buf.map, sqp->tx_ring[wire_tx_ix].buf.map,
...@@ -1450,7 +1457,7 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port, ...@@ -1450,7 +1457,7 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
spin_unlock(&sqp->tx_lock); spin_unlock(&sqp->tx_lock);
sqp->tx_ring[wire_tx_ix].ah = NULL; sqp->tx_ring[wire_tx_ix].ah = NULL;
out: out:
mlx4_ib_destroy_ah(ah, 0, NULL); kfree(ah);
return ret; return ret;
} }
...@@ -1902,9 +1909,8 @@ static void mlx4_ib_sqp_comp_worker(struct work_struct *work) ...@@ -1902,9 +1909,8 @@ static void mlx4_ib_sqp_comp_worker(struct work_struct *work)
if (wc.status == IB_WC_SUCCESS) { if (wc.status == IB_WC_SUCCESS) {
switch (wc.opcode) { switch (wc.opcode) {
case IB_WC_SEND: case IB_WC_SEND:
mlx4_ib_destroy_ah(sqp->tx_ring[wc.wr_id & kfree(sqp->tx_ring[wc.wr_id &
(MLX4_NUM_TUNNEL_BUFS - 1)].ah, (MLX4_NUM_TUNNEL_BUFS - 1)].ah);
0, NULL);
sqp->tx_ring[wc.wr_id & (MLX4_NUM_TUNNEL_BUFS - 1)].ah sqp->tx_ring[wc.wr_id & (MLX4_NUM_TUNNEL_BUFS - 1)].ah
= NULL; = NULL;
spin_lock(&sqp->tx_lock); spin_lock(&sqp->tx_lock);
...@@ -1932,9 +1938,8 @@ static void mlx4_ib_sqp_comp_worker(struct work_struct *work) ...@@ -1932,9 +1938,8 @@ static void mlx4_ib_sqp_comp_worker(struct work_struct *work)
" status = %d, wrid = 0x%llx\n", " status = %d, wrid = 0x%llx\n",
ctx->slave, wc.status, wc.wr_id); ctx->slave, wc.status, wc.wr_id);
if (!MLX4_TUN_IS_RECV(wc.wr_id)) { if (!MLX4_TUN_IS_RECV(wc.wr_id)) {
mlx4_ib_destroy_ah(sqp->tx_ring[wc.wr_id & kfree(sqp->tx_ring[wc.wr_id &
(MLX4_NUM_TUNNEL_BUFS - 1)].ah, (MLX4_NUM_TUNNEL_BUFS - 1)].ah);
0, NULL);
sqp->tx_ring[wc.wr_id & (MLX4_NUM_TUNNEL_BUFS - 1)].ah sqp->tx_ring[wc.wr_id & (MLX4_NUM_TUNNEL_BUFS - 1)].ah
= NULL; = NULL;
spin_lock(&sqp->tx_lock); spin_lock(&sqp->tx_lock);
......
...@@ -2558,6 +2558,8 @@ static const struct ib_device_ops mlx4_ib_dev_ops = { ...@@ -2558,6 +2558,8 @@ static const struct ib_device_ops mlx4_ib_dev_ops = {
.req_notify_cq = mlx4_ib_arm_cq, .req_notify_cq = mlx4_ib_arm_cq,
.rereg_user_mr = mlx4_ib_rereg_user_mr, .rereg_user_mr = mlx4_ib_rereg_user_mr,
.resize_cq = mlx4_ib_resize_cq, .resize_cq = mlx4_ib_resize_cq,
INIT_RDMA_OBJ_SIZE(ib_ah, mlx4_ib_ah, ibah),
INIT_RDMA_OBJ_SIZE(ib_pd, mlx4_ib_pd, ibpd), INIT_RDMA_OBJ_SIZE(ib_pd, mlx4_ib_pd, ibpd),
INIT_RDMA_OBJ_SIZE(ib_ucontext, mlx4_ib_ucontext, ibucontext), INIT_RDMA_OBJ_SIZE(ib_ucontext, mlx4_ib_ucontext, ibucontext),
}; };
......
...@@ -752,14 +752,12 @@ int mlx4_ib_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags); ...@@ -752,14 +752,12 @@ int mlx4_ib_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq); void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
void mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq); void mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, int mlx4_ib_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr, u32 flags,
u32 flags, struct ib_udata *udata); struct ib_udata *udata);
struct ib_ah *mlx4_ib_create_ah_slave(struct ib_pd *pd, int mlx4_ib_create_ah_slave(struct ib_ah *ah, struct rdma_ah_attr *ah_attr,
struct rdma_ah_attr *ah_attr, int slave_sgid_index, u8 *s_mac, u16 vlan_tag);
int slave_sgid_index, u8 *s_mac,
u16 vlan_tag);
int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr); int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
int mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata); void mlx4_ib_destroy_ah(struct ib_ah *ah, u32 flags);
struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd, struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
struct ib_srq_init_attr *init_attr, struct ib_srq_init_attr *init_attr,
......
...@@ -32,8 +32,7 @@ ...@@ -32,8 +32,7 @@
#include "mlx5_ib.h" #include "mlx5_ib.h"
static struct ib_ah *create_ib_ah(struct mlx5_ib_dev *dev, static void create_ib_ah(struct mlx5_ib_dev *dev, struct mlx5_ib_ah *ah,
struct mlx5_ib_ah *ah,
struct rdma_ah_attr *ah_attr) struct rdma_ah_attr *ah_attr)
{ {
enum ib_gid_type gid_type; enum ib_gid_type gid_type;
...@@ -67,21 +66,19 @@ static struct ib_ah *create_ib_ah(struct mlx5_ib_dev *dev, ...@@ -67,21 +66,19 @@ static struct ib_ah *create_ib_ah(struct mlx5_ib_dev *dev,
ah->av.fl_mlid = rdma_ah_get_path_bits(ah_attr) & 0x7f; ah->av.fl_mlid = rdma_ah_get_path_bits(ah_attr) & 0x7f;
ah->av.stat_rate_sl |= (rdma_ah_get_sl(ah_attr) & 0xf); ah->av.stat_rate_sl |= (rdma_ah_get_sl(ah_attr) & 0xf);
} }
return &ah->ibah;
} }
struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, int mlx5_ib_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr,
u32 flags, struct ib_udata *udata) u32 flags, struct ib_udata *udata)
{ {
struct mlx5_ib_ah *ah; struct mlx5_ib_ah *ah = to_mah(ibah);
struct mlx5_ib_dev *dev = to_mdev(pd->device); struct mlx5_ib_dev *dev = to_mdev(ibah->device);
enum rdma_ah_attr_type ah_type = ah_attr->type; enum rdma_ah_attr_type ah_type = ah_attr->type;
if ((ah_type == RDMA_AH_ATTR_TYPE_ROCE) && if ((ah_type == RDMA_AH_ATTR_TYPE_ROCE) &&
!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) !(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH))
return ERR_PTR(-EINVAL); return -EINVAL;
if (ah_type == RDMA_AH_ATTR_TYPE_ROCE && udata) { if (ah_type == RDMA_AH_ATTR_TYPE_ROCE && udata) {
int err; int err;
...@@ -90,21 +87,18 @@ struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, ...@@ -90,21 +87,18 @@ struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
sizeof(resp.dmac); sizeof(resp.dmac);
if (udata->outlen < min_resp_len) if (udata->outlen < min_resp_len)
return ERR_PTR(-EINVAL); return -EINVAL;
resp.response_length = min_resp_len; resp.response_length = min_resp_len;
memcpy(resp.dmac, ah_attr->roce.dmac, ETH_ALEN); memcpy(resp.dmac, ah_attr->roce.dmac, ETH_ALEN);
err = ib_copy_to_udata(udata, &resp, resp.response_length); err = ib_copy_to_udata(udata, &resp, resp.response_length);
if (err) if (err)
return ERR_PTR(err); return err;
} }
ah = kzalloc(sizeof(*ah), GFP_ATOMIC); create_ib_ah(dev, ah, ah_attr);
if (!ah) return 0;
return ERR_PTR(-ENOMEM);
return create_ib_ah(dev, ah, ah_attr); /* never fails */
} }
int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
...@@ -131,8 +125,7 @@ int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) ...@@ -131,8 +125,7 @@ int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
return 0; return 0;
} }
int mlx5_ib_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata) void mlx5_ib_destroy_ah(struct ib_ah *ah, u32 flags)
{ {
kfree(to_mah(ah)); return;
return 0;
} }
...@@ -5986,6 +5986,8 @@ static const struct ib_device_ops mlx5_ib_dev_ops = { ...@@ -5986,6 +5986,8 @@ static const struct ib_device_ops mlx5_ib_dev_ops = {
.req_notify_cq = mlx5_ib_arm_cq, .req_notify_cq = mlx5_ib_arm_cq,
.rereg_user_mr = mlx5_ib_rereg_user_mr, .rereg_user_mr = mlx5_ib_rereg_user_mr,
.resize_cq = mlx5_ib_resize_cq, .resize_cq = mlx5_ib_resize_cq,
INIT_RDMA_OBJ_SIZE(ib_ah, mlx5_ib_ah, ibah),
INIT_RDMA_OBJ_SIZE(ib_pd, mlx5_ib_pd, ibpd), INIT_RDMA_OBJ_SIZE(ib_pd, mlx5_ib_pd, ibpd),
INIT_RDMA_OBJ_SIZE(ib_ucontext, mlx5_ib_ucontext, ibucontext), INIT_RDMA_OBJ_SIZE(ib_ucontext, mlx5_ib_ucontext, ibucontext),
}; };
......
...@@ -1054,10 +1054,10 @@ void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db) ...@@ -1054,10 +1054,10 @@ void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db)
void __mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq); void __mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq);
void mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq); void mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq);
void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index); void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index);
struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, int mlx5_ib_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr, u32 flags,
u32 flags, struct ib_udata *udata); struct ib_udata *udata);
int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr); int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
int mlx5_ib_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata); void mlx5_ib_destroy_ah(struct ib_ah *ah, u32 flags);
struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd, struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
struct ib_srq_init_attr *init_attr, struct ib_srq_init_attr *init_attr,
struct ib_udata *udata); struct ib_udata *udata);
......
...@@ -388,34 +388,19 @@ static void mthca_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata) ...@@ -388,34 +388,19 @@ static void mthca_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
mthca_pd_free(to_mdev(pd->device), to_mpd(pd)); mthca_pd_free(to_mdev(pd->device), to_mpd(pd));
} }
static struct ib_ah *mthca_ah_create(struct ib_pd *pd, static int mthca_ah_create(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr,
struct rdma_ah_attr *ah_attr, u32 flags, struct ib_udata *udata)
u32 flags,
struct ib_udata *udata)
{ {
int err; struct mthca_ah *ah = to_mah(ibah);
struct mthca_ah *ah;
ah = kmalloc(sizeof *ah, GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
err = mthca_create_ah(to_mdev(pd->device), to_mpd(pd), ah_attr, ah); return mthca_create_ah(to_mdev(ibah->device), to_mpd(ibah->pd), ah_attr,
if (err) { ah);
kfree(ah);
return ERR_PTR(err);
}
return &ah->ibah;
} }
static int mthca_ah_destroy(struct ib_ah *ah, u32 flags, struct ib_udata *udata) static void mthca_ah_destroy(struct ib_ah *ah, u32 flags)
{ {
mthca_destroy_ah(to_mdev(ah->device), to_mah(ah)); mthca_destroy_ah(to_mdev(ah->device), to_mah(ah));
kfree(ah);
return 0;
} }
static struct ib_srq *mthca_create_srq(struct ib_pd *pd, static struct ib_srq *mthca_create_srq(struct ib_pd *pd,
...@@ -1213,6 +1198,8 @@ static const struct ib_device_ops mthca_dev_ops = { ...@@ -1213,6 +1198,8 @@ static const struct ib_device_ops mthca_dev_ops = {
.query_qp = mthca_query_qp, .query_qp = mthca_query_qp,
.reg_user_mr = mthca_reg_user_mr, .reg_user_mr = mthca_reg_user_mr,
.resize_cq = mthca_resize_cq, .resize_cq = mthca_resize_cq,
INIT_RDMA_OBJ_SIZE(ib_ah, mthca_ah, ibah),
INIT_RDMA_OBJ_SIZE(ib_pd, mthca_pd, ibpd), INIT_RDMA_OBJ_SIZE(ib_pd, mthca_pd, ibpd),
INIT_RDMA_OBJ_SIZE(ib_ucontext, mthca_ucontext, ibucontext), INIT_RDMA_OBJ_SIZE(ib_ucontext, mthca_ucontext, ibucontext),
}; };
......
...@@ -156,29 +156,25 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, ...@@ -156,29 +156,25 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
return status; return status;
} }
struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct rdma_ah_attr *attr, int ocrdma_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr, u32 flags,
u32 flags, struct ib_udata *udata) struct ib_udata *udata)
{ {
u32 *ahid_addr; u32 *ahid_addr;
int status; int status;
struct ocrdma_ah *ah; struct ocrdma_ah *ah = get_ocrdma_ah(ibah);
bool isvlan = false; bool isvlan = false;
u16 vlan_tag = 0xffff; u16 vlan_tag = 0xffff;
const struct ib_gid_attr *sgid_attr; const struct ib_gid_attr *sgid_attr;
struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); struct ocrdma_pd *pd = get_ocrdma_pd(ibah->pd);
struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device); struct ocrdma_dev *dev = get_ocrdma_dev(ibah->device);
if ((attr->type != RDMA_AH_ATTR_TYPE_ROCE) || if ((attr->type != RDMA_AH_ATTR_TYPE_ROCE) ||
!(rdma_ah_get_ah_flags(attr) & IB_AH_GRH)) !(rdma_ah_get_ah_flags(attr) & IB_AH_GRH))
return ERR_PTR(-EINVAL); return -EINVAL;
if (atomic_cmpxchg(&dev->update_sl, 1, 0)) if (atomic_cmpxchg(&dev->update_sl, 1, 0))
ocrdma_init_service_level(dev); ocrdma_init_service_level(dev);
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
status = ocrdma_alloc_av(dev, ah); status = ocrdma_alloc_av(dev, ah);
if (status) if (status)
goto av_err; goto av_err;
...@@ -210,23 +206,20 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct rdma_ah_attr *attr, ...@@ -210,23 +206,20 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct rdma_ah_attr *attr,
OCRDMA_AH_VLAN_VALID_SHIFT); OCRDMA_AH_VLAN_VALID_SHIFT);
} }
return &ah->ibah; return 0;
av_conf_err: av_conf_err:
ocrdma_free_av(dev, ah); ocrdma_free_av(dev, ah);
av_err: av_err:
kfree(ah); return status;
return ERR_PTR(status);
} }
int ocrdma_destroy_ah(struct ib_ah *ibah, u32 flags, struct ib_udata *udata) void ocrdma_destroy_ah(struct ib_ah *ibah, u32 flags)
{ {
struct ocrdma_ah *ah = get_ocrdma_ah(ibah); struct ocrdma_ah *ah = get_ocrdma_ah(ibah);
struct ocrdma_dev *dev = get_ocrdma_dev(ibah->device); struct ocrdma_dev *dev = get_ocrdma_dev(ibah->device);
ocrdma_free_av(dev, ah); ocrdma_free_av(dev, ah);
kfree(ah);
return 0;
} }
int ocrdma_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) int ocrdma_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
......
...@@ -51,9 +51,9 @@ enum { ...@@ -51,9 +51,9 @@ enum {
OCRDMA_AH_L3_TYPE_SHIFT = 0x1D /* 29 bits */ OCRDMA_AH_L3_TYPE_SHIFT = 0x1D /* 29 bits */
}; };
struct ib_ah *ocrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, int ocrdma_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr, u32 flags,
u32 flags, struct ib_udata *udata); struct ib_udata *udata);
int ocrdma_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata); void ocrdma_destroy_ah(struct ib_ah *ah, u32 flags);
int ocrdma_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr); int ocrdma_query_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
int ocrdma_process_mad(struct ib_device *, int ocrdma_process_mad(struct ib_device *,
......
...@@ -3067,13 +3067,12 @@ int ocrdma_alloc_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah) ...@@ -3067,13 +3067,12 @@ int ocrdma_alloc_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah)
return status; return status;
} }
int ocrdma_free_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah) void ocrdma_free_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&dev->av_tbl.lock, flags); spin_lock_irqsave(&dev->av_tbl.lock, flags);
ah->av->valid = 0; ah->av->valid = 0;
spin_unlock_irqrestore(&dev->av_tbl.lock, flags); spin_unlock_irqrestore(&dev->av_tbl.lock, flags);
return 0;
} }
static int ocrdma_create_eqs(struct ocrdma_dev *dev) static int ocrdma_create_eqs(struct ocrdma_dev *dev)
......
...@@ -139,8 +139,8 @@ int ocrdma_mbx_modify_srq(struct ocrdma_srq *, struct ib_srq_attr *); ...@@ -139,8 +139,8 @@ int ocrdma_mbx_modify_srq(struct ocrdma_srq *, struct ib_srq_attr *);
int ocrdma_mbx_query_srq(struct ocrdma_srq *, struct ib_srq_attr *); int ocrdma_mbx_query_srq(struct ocrdma_srq *, struct ib_srq_attr *);
int ocrdma_mbx_destroy_srq(struct ocrdma_dev *, struct ocrdma_srq *); int ocrdma_mbx_destroy_srq(struct ocrdma_dev *, struct ocrdma_srq *);
int ocrdma_alloc_av(struct ocrdma_dev *, struct ocrdma_ah *); int ocrdma_alloc_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah);
int ocrdma_free_av(struct ocrdma_dev *, struct ocrdma_ah *); void ocrdma_free_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah);
int ocrdma_qp_state_change(struct ocrdma_qp *, enum ib_qp_state new_state, int ocrdma_qp_state_change(struct ocrdma_qp *, enum ib_qp_state new_state,
enum ib_qp_state *old_ib_state); enum ib_qp_state *old_ib_state);
......
...@@ -179,6 +179,8 @@ static const struct ib_device_ops ocrdma_dev_ops = { ...@@ -179,6 +179,8 @@ static const struct ib_device_ops ocrdma_dev_ops = {
.reg_user_mr = ocrdma_reg_user_mr, .reg_user_mr = ocrdma_reg_user_mr,
.req_notify_cq = ocrdma_arm_cq, .req_notify_cq = ocrdma_arm_cq,
.resize_cq = ocrdma_resize_cq, .resize_cq = ocrdma_resize_cq,
INIT_RDMA_OBJ_SIZE(ib_ah, ocrdma_ah, ibah),
INIT_RDMA_OBJ_SIZE(ib_pd, ocrdma_pd, ibpd), INIT_RDMA_OBJ_SIZE(ib_pd, ocrdma_pd, ibpd),
INIT_RDMA_OBJ_SIZE(ib_ucontext, ocrdma_ucontext, ibucontext), INIT_RDMA_OBJ_SIZE(ib_ucontext, ocrdma_ucontext, ibucontext),
}; };
......
...@@ -238,6 +238,8 @@ static const struct ib_device_ops qedr_dev_ops = { ...@@ -238,6 +238,8 @@ static const struct ib_device_ops qedr_dev_ops = {
.reg_user_mr = qedr_reg_user_mr, .reg_user_mr = qedr_reg_user_mr,
.req_notify_cq = qedr_arm_cq, .req_notify_cq = qedr_arm_cq,
.resize_cq = qedr_resize_cq, .resize_cq = qedr_resize_cq,
INIT_RDMA_OBJ_SIZE(ib_ah, qedr_ah, ibah),
INIT_RDMA_OBJ_SIZE(ib_pd, qedr_pd, ibpd), INIT_RDMA_OBJ_SIZE(ib_pd, qedr_pd, ibpd),
INIT_RDMA_OBJ_SIZE(ib_ucontext, qedr_ucontext, ibucontext), INIT_RDMA_OBJ_SIZE(ib_ucontext, qedr_ucontext, ibucontext),
}; };
......
...@@ -2546,27 +2546,21 @@ int qedr_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) ...@@ -2546,27 +2546,21 @@ int qedr_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
return rc; return rc;
} }
struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct rdma_ah_attr *attr, int qedr_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr, u32 flags,
u32 flags, struct ib_udata *udata) struct ib_udata *udata)
{ {
struct qedr_ah *ah; struct qedr_ah *ah = get_qedr_ah(ibah);
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
rdma_copy_ah_attr(&ah->attr, attr); rdma_copy_ah_attr(&ah->attr, attr);
return &ah->ibah; return 0;
} }
int qedr_destroy_ah(struct ib_ah *ibah, u32 flags, struct ib_udata *udata) void qedr_destroy_ah(struct ib_ah *ibah, u32 flags)
{ {
struct qedr_ah *ah = get_qedr_ah(ibah); struct qedr_ah *ah = get_qedr_ah(ibah);
rdma_destroy_ah_attr(&ah->attr); rdma_destroy_ah_attr(&ah->attr);
kfree(ah);
return 0;
} }
static void free_mr_info(struct qedr_dev *dev, struct mr_info *info) static void free_mr_info(struct qedr_dev *dev, struct mr_info *info)
......
...@@ -73,9 +73,9 @@ int qedr_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr); ...@@ -73,9 +73,9 @@ int qedr_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr);
int qedr_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata); int qedr_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata);
int qedr_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr, int qedr_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
const struct ib_recv_wr **bad_recv_wr); const struct ib_recv_wr **bad_recv_wr);
struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct rdma_ah_attr *attr, int qedr_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr, u32 flags,
u32 flags, struct ib_udata *udata); struct ib_udata *udata);
int qedr_destroy_ah(struct ib_ah *ibah, u32 flags, struct ib_udata *udata); void qedr_destroy_ah(struct ib_ah *ibah, u32 flags);
int qedr_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata); int qedr_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
struct ib_mr *qedr_get_dma_mr(struct ib_pd *, int acc); struct ib_mr *qedr_get_dma_mr(struct ib_pd *, int acc);
......
...@@ -195,6 +195,8 @@ static const struct ib_device_ops pvrdma_dev_ops = { ...@@ -195,6 +195,8 @@ static const struct ib_device_ops pvrdma_dev_ops = {
.query_qp = pvrdma_query_qp, .query_qp = pvrdma_query_qp,
.reg_user_mr = pvrdma_reg_user_mr, .reg_user_mr = pvrdma_reg_user_mr,
.req_notify_cq = pvrdma_req_notify_cq, .req_notify_cq = pvrdma_req_notify_cq,
INIT_RDMA_OBJ_SIZE(ib_ah, pvrdma_ah, ibah),
INIT_RDMA_OBJ_SIZE(ib_pd, pvrdma_pd, ibpd), INIT_RDMA_OBJ_SIZE(ib_pd, pvrdma_pd, ibpd),
INIT_RDMA_OBJ_SIZE(ib_ucontext, pvrdma_ucontext, ibucontext), INIT_RDMA_OBJ_SIZE(ib_ucontext, pvrdma_ucontext, ibucontext),
}; };
......
...@@ -507,34 +507,28 @@ void pvrdma_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata) ...@@ -507,34 +507,28 @@ void pvrdma_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
* @udata: user data blob * @udata: user data blob
* @flags: create address handle flags (see enum rdma_create_ah_flags) * @flags: create address handle flags (see enum rdma_create_ah_flags)
* *
* @return: the ib_ah pointer on success, otherwise errno. * @return: 0 on success, otherwise errno.
*/ */
struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, int pvrdma_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr,
u32 flags, struct ib_udata *udata) u32 flags, struct ib_udata *udata)
{ {
struct pvrdma_dev *dev = to_vdev(pd->device); struct pvrdma_dev *dev = to_vdev(ibah->device);
struct pvrdma_ah *ah; struct pvrdma_ah *ah = to_vah(ibah);
const struct ib_global_route *grh; const struct ib_global_route *grh;
u8 port_num = rdma_ah_get_port_num(ah_attr); u8 port_num = rdma_ah_get_port_num(ah_attr);
if (!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) if (!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH))
return ERR_PTR(-EINVAL); return -EINVAL;
grh = rdma_ah_read_grh(ah_attr); grh = rdma_ah_read_grh(ah_attr);
if ((ah_attr->type != RDMA_AH_ATTR_TYPE_ROCE) || if ((ah_attr->type != RDMA_AH_ATTR_TYPE_ROCE) ||
rdma_is_multicast_addr((struct in6_addr *)grh->dgid.raw)) rdma_is_multicast_addr((struct in6_addr *)grh->dgid.raw))
return ERR_PTR(-EINVAL); return -EINVAL;
if (!atomic_add_unless(&dev->num_ahs, 1, dev->dsr->caps.max_ah)) if (!atomic_add_unless(&dev->num_ahs, 1, dev->dsr->caps.max_ah))
return ERR_PTR(-ENOMEM); return -ENOMEM;
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
if (!ah) {
atomic_dec(&dev->num_ahs);
return ERR_PTR(-ENOMEM);
}
ah->av.port_pd = to_vpd(pd)->pd_handle | (port_num << 24); ah->av.port_pd = to_vpd(ibah->pd)->pd_handle | (port_num << 24);
ah->av.src_path_bits = rdma_ah_get_path_bits(ah_attr); ah->av.src_path_bits = rdma_ah_get_path_bits(ah_attr);
ah->av.src_path_bits |= 0x80; ah->av.src_path_bits |= 0x80;
ah->av.gid_index = grh->sgid_index; ah->av.gid_index = grh->sgid_index;
...@@ -544,11 +538,7 @@ struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, ...@@ -544,11 +538,7 @@ struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
memcpy(ah->av.dgid, grh->dgid.raw, 16); memcpy(ah->av.dgid, grh->dgid.raw, 16);
memcpy(ah->av.dmac, ah_attr->roce.dmac, ETH_ALEN); memcpy(ah->av.dmac, ah_attr->roce.dmac, ETH_ALEN);
ah->ibah.device = pd->device; return 0;
ah->ibah.pd = pd;
ah->ibah.uobject = NULL;
return &ah->ibah;
} }
/** /**
...@@ -556,14 +546,10 @@ struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, ...@@ -556,14 +546,10 @@ struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
* @ah: the address handle to destroyed * @ah: the address handle to destroyed
* @flags: destroy address handle flags (see enum rdma_destroy_ah_flags) * @flags: destroy address handle flags (see enum rdma_destroy_ah_flags)
* *
* @return: 0 on success.
*/ */
int pvrdma_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata) void pvrdma_destroy_ah(struct ib_ah *ah, u32 flags)
{ {
struct pvrdma_dev *dev = to_vdev(ah->device); struct pvrdma_dev *dev = to_vdev(ah->device);
kfree(to_vah(ah));
atomic_dec(&dev->num_ahs); atomic_dec(&dev->num_ahs);
return 0;
} }
...@@ -415,9 +415,9 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev, ...@@ -415,9 +415,9 @@ struct ib_cq *pvrdma_create_cq(struct ib_device *ibdev,
int pvrdma_destroy_cq(struct ib_cq *cq, struct ib_udata *udata); int pvrdma_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
int pvrdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc); int pvrdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
int pvrdma_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags); int pvrdma_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, int pvrdma_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr, u32 flags,
u32 flags, struct ib_udata *udata); struct ib_udata *udata);
int pvrdma_destroy_ah(struct ib_ah *ah, u32 flags, struct ib_udata *udata); void pvrdma_destroy_ah(struct ib_ah *ah, u32 flags);
struct ib_srq *pvrdma_create_srq(struct ib_pd *pd, struct ib_srq *pvrdma_create_srq(struct ib_pd *pd,
struct ib_srq_init_attr *init_attr, struct ib_srq_init_attr *init_attr,
......
...@@ -89,36 +89,29 @@ EXPORT_SYMBOL(rvt_check_ah); ...@@ -89,36 +89,29 @@ EXPORT_SYMBOL(rvt_check_ah);
/** /**
* rvt_create_ah - create an address handle * rvt_create_ah - create an address handle
* @pd: the protection domain * @ibah: the IB address handle
* @ah_attr: the attributes of the AH * @ah_attr: the attributes of the AH
* @create_flags: create address handle flags (see enum rdma_create_ah_flags) * @create_flags: create address handle flags (see enum rdma_create_ah_flags)
* @udata: pointer to user's input output buffer information. * @udata: pointer to user's input output buffer information.
* *
* This may be called from interrupt context. * This may be called from interrupt context.
* *
* Return: newly allocated ah * Return: 0 on success
*/ */
struct ib_ah *rvt_create_ah(struct ib_pd *pd, int rvt_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr,
struct rdma_ah_attr *ah_attr, u32 create_flags, struct ib_udata *udata)
u32 create_flags,
struct ib_udata *udata)
{ {
struct rvt_ah *ah; struct rvt_ah *ah = ibah_to_rvtah(ibah);
struct rvt_dev_info *dev = ib_to_rvt(pd->device); struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
unsigned long flags; unsigned long flags;
if (rvt_check_ah(pd->device, ah_attr)) if (rvt_check_ah(ibah->device, ah_attr))
return ERR_PTR(-EINVAL); return -EINVAL;
ah = kmalloc(sizeof(*ah), GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
spin_lock_irqsave(&dev->n_ahs_lock, flags); spin_lock_irqsave(&dev->n_ahs_lock, flags);
if (dev->n_ahs_allocated == dev->dparms.props.max_ah) { if (dev->n_ahs_allocated == dev->dparms.props.max_ah) {
spin_unlock_irqrestore(&dev->n_ahs_lock, flags); spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
kfree(ah); return -ENOMEM;
return ERR_PTR(-ENOMEM);
} }
dev->n_ahs_allocated++; dev->n_ahs_allocated++;
...@@ -129,9 +122,9 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd, ...@@ -129,9 +122,9 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd,
atomic_set(&ah->refcount, 0); atomic_set(&ah->refcount, 0);
if (dev->driver_f.notify_new_ah) if (dev->driver_f.notify_new_ah)
dev->driver_f.notify_new_ah(pd->device, ah_attr, ah); dev->driver_f.notify_new_ah(ibah->device, ah_attr, ah);
return &ah->ibah; return 0;
} }
/** /**
...@@ -142,24 +135,20 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd, ...@@ -142,24 +135,20 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd,
* *
* Return: 0 on success * Return: 0 on success
*/ */
int rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags, void rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags)
struct ib_udata *udata)
{ {
struct rvt_dev_info *dev = ib_to_rvt(ibah->device); struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
struct rvt_ah *ah = ibah_to_rvtah(ibah); struct rvt_ah *ah = ibah_to_rvtah(ibah);
unsigned long flags; unsigned long flags;
if (atomic_read(&ah->refcount) != 0) if (atomic_read(&ah->refcount) != 0)
return -EBUSY; return;
spin_lock_irqsave(&dev->n_ahs_lock, flags); spin_lock_irqsave(&dev->n_ahs_lock, flags);
dev->n_ahs_allocated--; dev->n_ahs_allocated--;
spin_unlock_irqrestore(&dev->n_ahs_lock, flags); spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
rdma_destroy_ah_attr(&ah->attr); rdma_destroy_ah_attr(&ah->attr);
kfree(ah);
return 0;
} }
/** /**
......
...@@ -50,12 +50,9 @@ ...@@ -50,12 +50,9 @@
#include <rdma/rdma_vt.h> #include <rdma/rdma_vt.h>
struct ib_ah *rvt_create_ah(struct ib_pd *pd, int rvt_create_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr,
struct rdma_ah_attr *ah_attr, u32 create_flags, struct ib_udata *udata);
u32 create_flags, void rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags);
struct ib_udata *udata);
int rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags,
struct ib_udata *udata);
int rvt_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr); int rvt_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
int rvt_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr); int rvt_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
......
...@@ -425,6 +425,8 @@ static const struct ib_device_ops rvt_dev_ops = { ...@@ -425,6 +425,8 @@ static const struct ib_device_ops rvt_dev_ops = {
.req_notify_cq = rvt_req_notify_cq, .req_notify_cq = rvt_req_notify_cq,
.resize_cq = rvt_resize_cq, .resize_cq = rvt_resize_cq,
.unmap_fmr = rvt_unmap_fmr, .unmap_fmr = rvt_unmap_fmr,
INIT_RDMA_OBJ_SIZE(ib_ah, rvt_ah, ibah),
INIT_RDMA_OBJ_SIZE(ib_pd, rvt_pd, ibpd), INIT_RDMA_OBJ_SIZE(ib_pd, rvt_pd, ibpd),
INIT_RDMA_OBJ_SIZE(ib_ucontext, rvt_ucontext, ibucontext), INIT_RDMA_OBJ_SIZE(ib_ucontext, rvt_ucontext, ibucontext),
}; };
......
...@@ -52,7 +52,7 @@ struct rxe_type_info rxe_type_info[RXE_NUM_TYPES] = { ...@@ -52,7 +52,7 @@ struct rxe_type_info rxe_type_info[RXE_NUM_TYPES] = {
[RXE_TYPE_AH] = { [RXE_TYPE_AH] = {
.name = "rxe-ah", .name = "rxe-ah",
.size = sizeof(struct rxe_ah), .size = sizeof(struct rxe_ah),
.flags = RXE_POOL_ATOMIC, .flags = RXE_POOL_ATOMIC | RXE_POOL_NO_ALLOC,
}, },
[RXE_TYPE_SRQ] = { [RXE_TYPE_SRQ] = {
.name = "rxe-srq", .name = "rxe-srq",
......
...@@ -191,30 +191,24 @@ static void rxe_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) ...@@ -191,30 +191,24 @@ static void rxe_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
rxe_drop_ref(pd); rxe_drop_ref(pd);
} }
static struct ib_ah *rxe_create_ah(struct ib_pd *ibpd, static int rxe_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr,
struct rdma_ah_attr *attr, u32 flags, struct ib_udata *udata)
u32 flags,
struct ib_udata *udata)
{ {
int err; int err;
struct rxe_dev *rxe = to_rdev(ibpd->device); struct rxe_dev *rxe = to_rdev(ibah->device);
struct rxe_pd *pd = to_rpd(ibpd); struct rxe_ah *ah = to_rah(ibah);
struct rxe_ah *ah;
err = rxe_av_chk_attr(rxe, attr); err = rxe_av_chk_attr(rxe, attr);
if (err) if (err)
return ERR_PTR(err); return err;
ah = rxe_alloc(&rxe->ah_pool);
if (!ah)
return ERR_PTR(-ENOMEM);
rxe_add_ref(pd); err = rxe_add_to_pool(&rxe->ah_pool, &ah->pelem);
ah->pd = pd; if (err)
return err;
rxe_init_av(attr, &ah->av); rxe_init_av(attr, &ah->av);
return &ah->ibah; return 0;
} }
static int rxe_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) static int rxe_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
...@@ -241,13 +235,11 @@ static int rxe_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) ...@@ -241,13 +235,11 @@ static int rxe_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
return 0; return 0;
} }
static int rxe_destroy_ah(struct ib_ah *ibah, u32 flags, struct ib_udata *udata) static void rxe_destroy_ah(struct ib_ah *ibah, u32 flags)
{ {
struct rxe_ah *ah = to_rah(ibah); struct rxe_ah *ah = to_rah(ibah);
rxe_drop_ref(ah->pd);
rxe_drop_ref(ah); rxe_drop_ref(ah);
return 0;
} }
static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr) static int post_one_recv(struct rxe_rq *rq, const struct ib_recv_wr *ibwr)
...@@ -1171,6 +1163,8 @@ static const struct ib_device_ops rxe_dev_ops = { ...@@ -1171,6 +1163,8 @@ static const struct ib_device_ops rxe_dev_ops = {
.reg_user_mr = rxe_reg_user_mr, .reg_user_mr = rxe_reg_user_mr,
.req_notify_cq = rxe_req_notify_cq, .req_notify_cq = rxe_req_notify_cq,
.resize_cq = rxe_resize_cq, .resize_cq = rxe_resize_cq,
INIT_RDMA_OBJ_SIZE(ib_ah, rxe_ah, ibah),
INIT_RDMA_OBJ_SIZE(ib_pd, rxe_pd, ibpd), INIT_RDMA_OBJ_SIZE(ib_pd, rxe_pd, ibpd),
INIT_RDMA_OBJ_SIZE(ib_ucontext, rxe_ucontext, ibuc), INIT_RDMA_OBJ_SIZE(ib_ucontext, rxe_ucontext, ibuc),
}; };
......
...@@ -71,8 +71,8 @@ struct rxe_pd { ...@@ -71,8 +71,8 @@ struct rxe_pd {
}; };
struct rxe_ah { struct rxe_ah {
struct rxe_pool_entry pelem;
struct ib_ah ibah; struct ib_ah ibah;
struct rxe_pool_entry pelem;
struct rxe_pd *pd; struct rxe_pd *pd;
struct rxe_av av; struct rxe_av av;
}; };
......
...@@ -2401,12 +2401,11 @@ struct ib_device_ops { ...@@ -2401,12 +2401,11 @@ struct ib_device_ops {
void (*disassociate_ucontext)(struct ib_ucontext *ibcontext); void (*disassociate_ucontext)(struct ib_ucontext *ibcontext);
int (*alloc_pd)(struct ib_pd *pd, struct ib_udata *udata); int (*alloc_pd)(struct ib_pd *pd, struct ib_udata *udata);
void (*dealloc_pd)(struct ib_pd *pd, struct ib_udata *udata); void (*dealloc_pd)(struct ib_pd *pd, struct ib_udata *udata);
struct ib_ah *(*create_ah)(struct ib_pd *pd, int (*create_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr,
struct rdma_ah_attr *ah_attr, u32 flags, u32 flags, struct ib_udata *udata);
struct ib_udata *udata);
int (*modify_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr); int (*modify_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
int (*query_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr); int (*query_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
int (*destroy_ah)(struct ib_ah *ah, u32 flags, struct ib_udata *udata); void (*destroy_ah)(struct ib_ah *ah, u32 flags);
struct ib_srq *(*create_srq)(struct ib_pd *pd, struct ib_srq *(*create_srq)(struct ib_pd *pd,
struct ib_srq_init_attr *srq_init_attr, struct ib_srq_init_attr *srq_init_attr,
struct ib_udata *udata); struct ib_udata *udata);
...@@ -2552,6 +2551,7 @@ struct ib_device_ops { ...@@ -2552,6 +2551,7 @@ struct ib_device_ops {
*/ */
void (*dealloc_driver)(struct ib_device *dev); void (*dealloc_driver)(struct ib_device *dev);
DECLARE_RDMA_OBJ_SIZE(ib_ah);
DECLARE_RDMA_OBJ_SIZE(ib_pd); DECLARE_RDMA_OBJ_SIZE(ib_pd);
DECLARE_RDMA_OBJ_SIZE(ib_ucontext); DECLARE_RDMA_OBJ_SIZE(ib_ucontext);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment