1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
3 * Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved.
6 #include <rdma/rdma_cm.h>
7 #include <rdma/ib_verbs.h>
8 #include <rdma/restrack.h>
9 #include <linux/mutex.h>
10 #include <linux/sched/task.h>
11 #include <linux/pid_namespace.h>
16 static int rt_xa_alloc_cyclic(struct xarray *xa, u32 *id, void *entry,
26 err = __xa_alloc(xa, id, U32_MAX, entry, GFP_KERNEL);
27 if (err && *next != U32_MAX) {
29 err = __xa_alloc(xa, id, *next, entry, GFP_KERNEL);
39 * rdma_restrack_init() - initialize and allocate resource tracking
42 * Return: 0 on success
44 int rdma_restrack_init(struct ib_device *dev)
46 struct rdma_restrack_root *rt;
49 dev->res = kcalloc(RDMA_RESTRACK_MAX, sizeof(*rt), GFP_KERNEL);
55 for (i = 0; i < RDMA_RESTRACK_MAX; i++)
56 xa_init_flags(&rt[i].xa, XA_FLAGS_ALLOC);
61 static const char *type2str(enum rdma_restrack_type type)
63 static const char * const names[RDMA_RESTRACK_MAX] = {
64 [RDMA_RESTRACK_PD] = "PD",
65 [RDMA_RESTRACK_CQ] = "CQ",
66 [RDMA_RESTRACK_QP] = "QP",
67 [RDMA_RESTRACK_CM_ID] = "CM_ID",
68 [RDMA_RESTRACK_MR] = "MR",
69 [RDMA_RESTRACK_CTX] = "CTX",
76 * rdma_restrack_clean() - clean resource tracking
79 void rdma_restrack_clean(struct ib_device *dev)
81 struct rdma_restrack_root *rt = dev->res;
82 struct rdma_restrack_entry *e;
83 char buf[TASK_COMM_LEN];
88 for (i = 0 ; i < RDMA_RESTRACK_MAX; i++) {
89 struct xarray *xa = &dev->res[i].xa;
95 pr_err("restrack: %s", CUT_HERE);
96 dev_err(&dev->dev, "BUG: RESTRACK detected leak of resources\n");
98 xa_for_each(xa, index, e) {
99 if (rdma_is_kernel_res(e)) {
100 owner = e->kern_name;
103 * There is no need to call get_task_struct here,
104 * because we can be here only if there are more
105 * get_task_struct() call than put_task_struct().
107 get_task_comm(buf, e->task);
111 pr_err("restrack: %s %s object allocated by %s is not freed\n",
112 rdma_is_kernel_res(e) ? "Kernel" :
114 type2str(e->type), owner);
121 pr_err("restrack: %s", CUT_HERE);
127 * rdma_restrack_count() - the current usage of specific object
129 * @type: actual type of object to operate
132 int rdma_restrack_count(struct ib_device *dev, enum rdma_restrack_type type,
133 struct pid_namespace *ns)
135 struct rdma_restrack_root *rt = &dev->res[type];
136 struct rdma_restrack_entry *e;
137 XA_STATE(xas, &rt->xa, 0);
141 xas_for_each(&xas, e, U32_MAX) {
142 if (ns == &init_pid_ns ||
143 (!rdma_is_kernel_res(e) &&
144 ns == task_active_pid_ns(e->task)))
150 EXPORT_SYMBOL(rdma_restrack_count);
152 static void set_kern_name(struct rdma_restrack_entry *res)
157 case RDMA_RESTRACK_QP:
158 pd = container_of(res, struct ib_qp, res)->pd;
160 WARN_ONCE(true, "XRC QPs are not supported\n");
161 /* Survive, despite the programmer's error */
162 res->kern_name = " ";
165 case RDMA_RESTRACK_MR:
166 pd = container_of(res, struct ib_mr, res)->pd;
169 /* Other types set kern_name directly */
175 res->kern_name = pd->res.kern_name;
178 static struct ib_device *res_to_dev(struct rdma_restrack_entry *res)
181 case RDMA_RESTRACK_PD:
182 return container_of(res, struct ib_pd, res)->device;
183 case RDMA_RESTRACK_CQ:
184 return container_of(res, struct ib_cq, res)->device;
185 case RDMA_RESTRACK_QP:
186 return container_of(res, struct ib_qp, res)->device;
187 case RDMA_RESTRACK_CM_ID:
188 return container_of(res, struct rdma_id_private,
190 case RDMA_RESTRACK_MR:
191 return container_of(res, struct ib_mr, res)->device;
192 case RDMA_RESTRACK_CTX:
193 return container_of(res, struct ib_ucontext, res)->device;
195 WARN_ONCE(true, "Wrong resource tracking type %u\n", res->type);
200 void rdma_restrack_set_task(struct rdma_restrack_entry *res,
204 res->kern_name = caller;
209 put_task_struct(res->task);
210 get_task_struct(current);
213 EXPORT_SYMBOL(rdma_restrack_set_task);
215 static void rdma_restrack_add(struct rdma_restrack_entry *res)
217 struct ib_device *dev = res_to_dev(res);
218 struct rdma_restrack_root *rt;
224 rt = &dev->res[res->type];
226 kref_init(&res->kref);
227 init_completion(&res->comp);
228 if (res->type != RDMA_RESTRACK_QP)
229 ret = rt_xa_alloc_cyclic(&rt->xa, &res->id, res, &rt->next_id);
231 /* Special case to ensure that LQPN points to right QP */
232 struct ib_qp *qp = container_of(res, struct ib_qp, res);
234 ret = xa_insert(&rt->xa, qp->qp_num, res, GFP_KERNEL);
235 res->id = ret ? 0 : qp->qp_num;
243 * rdma_restrack_kadd() - add kernel object to the reource tracking database
244 * @res: resource entry
246 void rdma_restrack_kadd(struct rdma_restrack_entry *res)
251 rdma_restrack_add(res);
253 EXPORT_SYMBOL(rdma_restrack_kadd);
256 * rdma_restrack_uadd() - add user object to the reource tracking database
257 * @res: resource entry
259 void rdma_restrack_uadd(struct rdma_restrack_entry *res)
261 if (res->type != RDMA_RESTRACK_CM_ID)
265 rdma_restrack_set_task(res, NULL);
266 res->kern_name = NULL;
269 rdma_restrack_add(res);
271 EXPORT_SYMBOL(rdma_restrack_uadd);
273 int __must_check rdma_restrack_get(struct rdma_restrack_entry *res)
275 return kref_get_unless_zero(&res->kref);
277 EXPORT_SYMBOL(rdma_restrack_get);
280 * rdma_restrack_get_byid() - translate from ID to restrack object
282 * @type: resource track type
283 * @id: ID to take a look
285 * Return: Pointer to restrack entry or -ENOENT in case of error.
287 struct rdma_restrack_entry *
288 rdma_restrack_get_byid(struct ib_device *dev,
289 enum rdma_restrack_type type, u32 id)
291 struct rdma_restrack_root *rt = &dev->res[type];
292 struct rdma_restrack_entry *res;
295 res = xa_load(&rt->xa, id);
296 if (!res || !rdma_restrack_get(res))
297 res = ERR_PTR(-ENOENT);
302 EXPORT_SYMBOL(rdma_restrack_get_byid);
304 static void restrack_release(struct kref *kref)
306 struct rdma_restrack_entry *res;
308 res = container_of(kref, struct rdma_restrack_entry, kref);
309 complete(&res->comp);
312 int rdma_restrack_put(struct rdma_restrack_entry *res)
314 return kref_put(&res->kref, restrack_release);
316 EXPORT_SYMBOL(rdma_restrack_put);
318 void rdma_restrack_del(struct rdma_restrack_entry *res)
320 struct rdma_restrack_entry *old;
321 struct rdma_restrack_root *rt;
322 struct ib_device *dev;
327 dev = res_to_dev(res);
331 rt = &dev->res[res->type];
333 old = xa_erase(&rt->xa, res->id);
337 rdma_restrack_put(res);
338 wait_for_completion(&res->comp);
342 put_task_struct(res->task);
346 EXPORT_SYMBOL(rdma_restrack_del);