RDMA: Handle PD allocations by IB/core
The PD allocations in IB/core allows us to simplify drivers and their error flows in their .alloc_pd() paths. The changes in .alloc_pd() go hand in had with relevant update in .dealloc_pd(). We will use this opportunity and convert .dealloc_pd() to don't fail, as it was suggested a long time ago, failures are not happening as we have never seen a WARN_ON print. 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
30471d4b20
commit
21a428a019
@@ -46,6 +46,7 @@ struct rxe_type_info rxe_type_info[RXE_NUM_TYPES] = {
|
||||
[RXE_TYPE_PD] = {
|
||||
.name = "rxe-pd",
|
||||
.size = sizeof(struct rxe_pd),
|
||||
.flags = RXE_POOL_NO_ALLOC,
|
||||
},
|
||||
[RXE_TYPE_AH] = {
|
||||
.name = "rxe-ah",
|
||||
@@ -119,8 +120,10 @@ static void rxe_cache_clean(size_t cnt)
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
type = &rxe_type_info[i];
|
||||
kmem_cache_destroy(type->cache);
|
||||
type->cache = NULL;
|
||||
if (!(type->flags & RXE_POOL_NO_ALLOC)) {
|
||||
kmem_cache_destroy(type->cache);
|
||||
type->cache = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,14 +137,17 @@ int rxe_cache_init(void)
|
||||
for (i = 0; i < RXE_NUM_TYPES; i++) {
|
||||
type = &rxe_type_info[i];
|
||||
size = ALIGN(type->size, RXE_POOL_ALIGN);
|
||||
type->cache = kmem_cache_create(type->name, size,
|
||||
RXE_POOL_ALIGN,
|
||||
RXE_POOL_CACHE_FLAGS, NULL);
|
||||
if (!type->cache) {
|
||||
pr_err("Unable to init kmem cache for %s\n",
|
||||
type->name);
|
||||
err = -ENOMEM;
|
||||
goto err1;
|
||||
if (!(type->flags & RXE_POOL_NO_ALLOC)) {
|
||||
type->cache =
|
||||
kmem_cache_create(type->name, size,
|
||||
RXE_POOL_ALIGN,
|
||||
RXE_POOL_CACHE_FLAGS, NULL);
|
||||
if (!type->cache) {
|
||||
pr_err("Unable to init kmem cache for %s\n",
|
||||
type->name);
|
||||
err = -ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,6 +421,37 @@ out_put_pool:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_entry *elem)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
might_sleep_if(!(pool->flags & RXE_POOL_ATOMIC));
|
||||
|
||||
read_lock_irqsave(&pool->pool_lock, flags);
|
||||
if (pool->state != RXE_POOL_STATE_VALID) {
|
||||
read_unlock_irqrestore(&pool->pool_lock, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
kref_get(&pool->ref_cnt);
|
||||
read_unlock_irqrestore(&pool->pool_lock, flags);
|
||||
|
||||
kref_get(&pool->rxe->ref_cnt);
|
||||
|
||||
if (atomic_inc_return(&pool->num_elem) > pool->max_elem)
|
||||
goto out_put_pool;
|
||||
|
||||
elem->pool = pool;
|
||||
kref_init(&elem->ref_cnt);
|
||||
|
||||
return 0;
|
||||
|
||||
out_put_pool:
|
||||
atomic_dec(&pool->num_elem);
|
||||
rxe_dev_put(pool->rxe);
|
||||
rxe_pool_put(pool);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void rxe_elem_release(struct kref *kref)
|
||||
{
|
||||
struct rxe_pool_entry *elem =
|
||||
@@ -424,7 +461,8 @@ void rxe_elem_release(struct kref *kref)
|
||||
if (pool->cleanup)
|
||||
pool->cleanup(elem);
|
||||
|
||||
kmem_cache_free(pool_cache(pool), elem);
|
||||
if (!(pool->flags & RXE_POOL_NO_ALLOC))
|
||||
kmem_cache_free(pool_cache(pool), elem);
|
||||
atomic_dec(&pool->num_elem);
|
||||
rxe_dev_put(pool->rxe);
|
||||
rxe_pool_put(pool);
|
||||
|
@@ -41,6 +41,7 @@ enum rxe_pool_flags {
|
||||
RXE_POOL_ATOMIC = BIT(0),
|
||||
RXE_POOL_INDEX = BIT(1),
|
||||
RXE_POOL_KEY = BIT(2),
|
||||
RXE_POOL_NO_ALLOC = BIT(4),
|
||||
};
|
||||
|
||||
enum rxe_elem_type {
|
||||
@@ -131,6 +132,9 @@ void rxe_pool_cleanup(struct rxe_pool *pool);
|
||||
/* allocate an object from pool */
|
||||
void *rxe_alloc(struct rxe_pool *pool);
|
||||
|
||||
/* connect already allocated object to pool */
|
||||
int rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_entry *elem);
|
||||
|
||||
/* assign an index to an indexed object and insert object into
|
||||
* pool's rb tree
|
||||
*/
|
||||
|
@@ -191,23 +191,20 @@ static int rxe_port_immutable(struct ib_device *dev, u8 port_num,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ib_pd *rxe_alloc_pd(struct ib_device *dev,
|
||||
struct ib_ucontext *context,
|
||||
struct ib_udata *udata)
|
||||
static int rxe_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
struct rxe_dev *rxe = to_rdev(dev);
|
||||
struct rxe_pd *pd;
|
||||
struct rxe_dev *rxe = to_rdev(ibpd->device);
|
||||
struct rxe_pd *pd = to_rpd(ibpd);
|
||||
|
||||
pd = rxe_alloc(&rxe->pd_pool);
|
||||
return pd ? &pd->ibpd : ERR_PTR(-ENOMEM);
|
||||
return rxe_add_to_pool(&rxe->pd_pool, &pd->pelem);
|
||||
}
|
||||
|
||||
static int rxe_dealloc_pd(struct ib_pd *ibpd)
|
||||
static void rxe_dealloc_pd(struct ib_pd *ibpd)
|
||||
{
|
||||
struct rxe_pd *pd = to_rpd(ibpd);
|
||||
|
||||
rxe_drop_ref(pd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ib_ah *rxe_create_ah(struct ib_pd *ibpd,
|
||||
@@ -1183,6 +1180,7 @@ static const struct ib_device_ops rxe_dev_ops = {
|
||||
.reg_user_mr = rxe_reg_user_mr,
|
||||
.req_notify_cq = rxe_req_notify_cq,
|
||||
.resize_cq = rxe_resize_cq,
|
||||
INIT_RDMA_OBJ_SIZE(ib_pd, rxe_pd, ibpd),
|
||||
};
|
||||
|
||||
int rxe_register_device(struct rxe_dev *rxe)
|
||||
|
@@ -66,8 +66,8 @@ struct rxe_ucontext {
|
||||
};
|
||||
|
||||
struct rxe_pd {
|
||||
struct ib_pd ibpd;
|
||||
struct rxe_pool_entry pelem;
|
||||
struct ib_pd ibpd;
|
||||
};
|
||||
|
||||
struct rxe_ah {
|
||||
|
Reference in New Issue
Block a user