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 <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:

committed by
Jason Gunthorpe

parent
f6316032fd
commit
d345691471
@@ -89,36 +89,29 @@ EXPORT_SYMBOL(rvt_check_ah);
|
||||
|
||||
/**
|
||||
* rvt_create_ah - create an address handle
|
||||
* @pd: the protection domain
|
||||
* @ibah: the IB address handle
|
||||
* @ah_attr: the attributes of the AH
|
||||
* @create_flags: create address handle flags (see enum rdma_create_ah_flags)
|
||||
* @udata: pointer to user's input output buffer information.
|
||||
*
|
||||
* 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,
|
||||
struct rdma_ah_attr *ah_attr,
|
||||
u32 create_flags,
|
||||
struct ib_udata *udata)
|
||||
int rvt_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr,
|
||||
u32 create_flags, struct ib_udata *udata)
|
||||
{
|
||||
struct rvt_ah *ah;
|
||||
struct rvt_dev_info *dev = ib_to_rvt(pd->device);
|
||||
struct rvt_ah *ah = ibah_to_rvtah(ibah);
|
||||
struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
|
||||
unsigned long flags;
|
||||
|
||||
if (rvt_check_ah(pd->device, ah_attr))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
ah = kmalloc(sizeof(*ah), GFP_ATOMIC);
|
||||
if (!ah)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (rvt_check_ah(ibah->device, ah_attr))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&dev->n_ahs_lock, flags);
|
||||
if (dev->n_ahs_allocated == dev->dparms.props.max_ah) {
|
||||
spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
|
||||
kfree(ah);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev->n_ahs_allocated++;
|
||||
@@ -129,9 +122,9 @@ struct ib_ah *rvt_create_ah(struct ib_pd *pd,
|
||||
atomic_set(&ah->refcount, 0);
|
||||
|
||||
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,
|
||||
*
|
||||
* Return: 0 on success
|
||||
*/
|
||||
int rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags,
|
||||
struct ib_udata *udata)
|
||||
void rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags)
|
||||
{
|
||||
struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
|
||||
struct rvt_ah *ah = ibah_to_rvtah(ibah);
|
||||
unsigned long flags;
|
||||
|
||||
if (atomic_read(&ah->refcount) != 0)
|
||||
return -EBUSY;
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&dev->n_ahs_lock, flags);
|
||||
dev->n_ahs_allocated--;
|
||||
spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
|
||||
|
||||
rdma_destroy_ah_attr(&ah->attr);
|
||||
kfree(ah);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user