1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
3 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
4 * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
9 #define RXE_POOL_TIMEOUT (200)
10 #define RXE_POOL_ALIGN (16)
12 static const struct rxe_type_info {
16 void (*cleanup)(struct rxe_pool_elem *elem);
20 } rxe_type_info[RXE_NUM_TYPES] = {
23 .size = sizeof(struct rxe_ucontext),
24 .elem_offset = offsetof(struct rxe_ucontext, elem),
26 .max_index = RXE_MAX_UCONTEXT,
27 .max_elem = RXE_MAX_UCONTEXT,
31 .size = sizeof(struct rxe_pd),
32 .elem_offset = offsetof(struct rxe_pd, elem),
34 .max_index = RXE_MAX_PD,
35 .max_elem = RXE_MAX_PD,
39 .size = sizeof(struct rxe_ah),
40 .elem_offset = offsetof(struct rxe_ah, elem),
41 .min_index = RXE_MIN_AH_INDEX,
42 .max_index = RXE_MAX_AH_INDEX,
43 .max_elem = RXE_MAX_AH,
47 .size = sizeof(struct rxe_srq),
48 .elem_offset = offsetof(struct rxe_srq, elem),
49 .cleanup = rxe_srq_cleanup,
50 .min_index = RXE_MIN_SRQ_INDEX,
51 .max_index = RXE_MAX_SRQ_INDEX,
52 .max_elem = RXE_MAX_SRQ,
56 .size = sizeof(struct rxe_qp),
57 .elem_offset = offsetof(struct rxe_qp, elem),
58 .cleanup = rxe_qp_cleanup,
59 .min_index = RXE_MIN_QP_INDEX,
60 .max_index = RXE_MAX_QP_INDEX,
61 .max_elem = RXE_MAX_QP,
65 .size = sizeof(struct rxe_cq),
66 .elem_offset = offsetof(struct rxe_cq, elem),
67 .cleanup = rxe_cq_cleanup,
69 .max_index = RXE_MAX_CQ,
70 .max_elem = RXE_MAX_CQ,
74 .size = sizeof(struct rxe_mr),
75 .elem_offset = offsetof(struct rxe_mr, elem),
76 .cleanup = rxe_mr_cleanup,
77 .min_index = RXE_MIN_MR_INDEX,
78 .max_index = RXE_MAX_MR_INDEX,
79 .max_elem = RXE_MAX_MR,
83 .size = sizeof(struct rxe_mw),
84 .elem_offset = offsetof(struct rxe_mw, elem),
85 .cleanup = rxe_mw_cleanup,
86 .min_index = RXE_MIN_MW_INDEX,
87 .max_index = RXE_MAX_MW_INDEX,
88 .max_elem = RXE_MAX_MW,
92 void rxe_pool_init(struct rxe_dev *rxe, struct rxe_pool *pool,
93 enum rxe_elem_type type)
95 const struct rxe_type_info *info = &rxe_type_info[type];
97 memset(pool, 0, sizeof(*pool));
100 pool->name = info->name;
102 pool->max_elem = info->max_elem;
103 pool->elem_size = ALIGN(info->size, RXE_POOL_ALIGN);
104 pool->elem_offset = info->elem_offset;
105 pool->cleanup = info->cleanup;
107 atomic_set(&pool->num_elem, 0);
109 xa_init_flags(&pool->xa, XA_FLAGS_ALLOC);
110 pool->limit.min = info->min_index;
111 pool->limit.max = info->max_index;
114 void rxe_pool_cleanup(struct rxe_pool *pool)
116 WARN_ON(!xa_empty(&pool->xa));
119 void *rxe_alloc(struct rxe_pool *pool)
121 struct rxe_pool_elem *elem;
125 if (WARN_ON(!(pool->type == RXE_TYPE_MR)))
128 if (atomic_inc_return(&pool->num_elem) > pool->max_elem)
131 obj = kzalloc(pool->elem_size, GFP_KERNEL);
135 elem = (struct rxe_pool_elem *)((u8 *)obj + pool->elem_offset);
139 kref_init(&elem->ref_cnt);
140 init_completion(&elem->complete);
142 /* allocate index in array but leave pointer as NULL so it
143 * can't be looked up until rxe_finalize() is called
145 err = xa_alloc_cyclic(&pool->xa, &elem->index, NULL, pool->limit,
146 &pool->next, GFP_KERNEL);
155 atomic_dec(&pool->num_elem);
159 int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem,
165 if (WARN_ON(pool->type == RXE_TYPE_MR))
168 if (atomic_inc_return(&pool->num_elem) > pool->max_elem)
172 elem->obj = (u8 *)elem - pool->elem_offset;
173 kref_init(&elem->ref_cnt);
174 init_completion(&elem->complete);
176 /* AH objects are unique in that the create_ah verb
177 * can be called in atomic context. If the create_ah
178 * call is not sleepable use GFP_ATOMIC.
180 gfp_flags = sleepable ? GFP_KERNEL : GFP_ATOMIC;
184 err = xa_alloc_cyclic(&pool->xa, &elem->index, NULL, pool->limit,
185 &pool->next, gfp_flags);
192 atomic_dec(&pool->num_elem);
196 void *rxe_pool_get_index(struct rxe_pool *pool, u32 index)
198 struct rxe_pool_elem *elem;
199 struct xarray *xa = &pool->xa;
203 elem = xa_load(xa, index);
204 if (elem && kref_get_unless_zero(&elem->ref_cnt))
213 static void rxe_elem_release(struct kref *kref)
215 struct rxe_pool_elem *elem = container_of(kref, typeof(*elem), ref_cnt);
217 complete(&elem->complete);
220 int __rxe_cleanup(struct rxe_pool_elem *elem, bool sleepable)
222 struct rxe_pool *pool = elem->pool;
223 struct xarray *xa = &pool->xa;
224 static int timeout = RXE_POOL_TIMEOUT;
231 /* erase xarray entry to prevent looking up
232 * the pool elem from its index
234 xa_ret = xa_erase(xa, elem->index);
235 WARN_ON(xa_err(xa_ret));
237 /* if this is the last call to rxe_put complete the
238 * object. It is safe to touch obj->elem after this since
243 /* wait until all references to the object have been
244 * dropped before final object specific cleanup and
245 * return to rdma-core
248 if (!completion_done(&elem->complete) && timeout) {
249 ret = wait_for_completion_timeout(&elem->complete,
252 /* Shouldn't happen. There are still references to
253 * the object but, rather than deadlock, free the
254 * object or pass back to rdma-core.
260 unsigned long until = jiffies + timeout;
262 /* AH objects are unique in that the destroy_ah verb
263 * can be called in atomic context. This delay
264 * replaces the wait_for_completion call above
265 * when the destroy_ah call is not sleepable
267 while (!completion_done(&elem->complete) &&
268 time_before(jiffies, until))
271 if (WARN_ON(!completion_done(&elem->complete)))
278 if (pool->type == RXE_TYPE_MR)
279 kfree_rcu(elem->obj);
281 atomic_dec(&pool->num_elem);
286 int __rxe_get(struct rxe_pool_elem *elem)
288 return kref_get_unless_zero(&elem->ref_cnt);
291 int __rxe_put(struct rxe_pool_elem *elem)
293 return kref_put(&elem->ref_cnt, rxe_elem_release);
296 void __rxe_finalize(struct rxe_pool_elem *elem)
300 xa_ret = xa_store(&elem->pool->xa, elem->index, elem, GFP_KERNEL);
301 WARN_ON(xa_err(xa_ret));