1
2
3
4
5
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>
12
13#include "cma_priv.h"
14#include "restrack.h"
15
16
17
18
19
20
21
22int rdma_restrack_init(struct ib_device *dev)
23{
24 struct rdma_restrack_root *rt;
25 int i;
26
27 dev->res = kcalloc(RDMA_RESTRACK_MAX, sizeof(*rt), GFP_KERNEL);
28 if (!dev->res)
29 return -ENOMEM;
30
31 rt = dev->res;
32
33 for (i = 0; i < RDMA_RESTRACK_MAX; i++)
34 xa_init_flags(&rt[i].xa, XA_FLAGS_ALLOC);
35
36 return 0;
37}
38
39static const char *type2str(enum rdma_restrack_type type)
40{
41 static const char * const names[RDMA_RESTRACK_MAX] = {
42 [RDMA_RESTRACK_PD] = "PD",
43 [RDMA_RESTRACK_CQ] = "CQ",
44 [RDMA_RESTRACK_QP] = "QP",
45 [RDMA_RESTRACK_CM_ID] = "CM_ID",
46 [RDMA_RESTRACK_MR] = "MR",
47 [RDMA_RESTRACK_CTX] = "CTX",
48 };
49
50 return names[type];
51};
52
53
54
55
56
57void rdma_restrack_clean(struct ib_device *dev)
58{
59 struct rdma_restrack_root *rt = dev->res;
60 struct rdma_restrack_entry *e;
61 char buf[TASK_COMM_LEN];
62 bool found = false;
63 const char *owner;
64 int i;
65
66 for (i = 0 ; i < RDMA_RESTRACK_MAX; i++) {
67 struct xarray *xa = &dev->res[i].xa;
68
69 if (!xa_empty(xa)) {
70 unsigned long index;
71
72 if (!found) {
73 pr_err("restrack: %s", CUT_HERE);
74 dev_err(&dev->dev, "BUG: RESTRACK detected leak of resources\n");
75 }
76 xa_for_each(xa, index, e) {
77 if (rdma_is_kernel_res(e)) {
78 owner = e->kern_name;
79 } else {
80
81
82
83
84
85 get_task_comm(buf, e->task);
86 owner = buf;
87 }
88
89 pr_err("restrack: %s %s object allocated by %s is not freed\n",
90 rdma_is_kernel_res(e) ? "Kernel" :
91 "User",
92 type2str(e->type), owner);
93 }
94 found = true;
95 }
96 xa_destroy(xa);
97 }
98 if (found)
99 pr_err("restrack: %s", CUT_HERE);
100
101 kfree(rt);
102}
103
104
105
106
107
108
109
110int rdma_restrack_count(struct ib_device *dev, enum rdma_restrack_type type,
111 struct pid_namespace *ns)
112{
113 struct rdma_restrack_root *rt = &dev->res[type];
114 struct rdma_restrack_entry *e;
115 XA_STATE(xas, &rt->xa, 0);
116 u32 cnt = 0;
117
118 xa_lock(&rt->xa);
119 xas_for_each(&xas, e, U32_MAX) {
120 if (ns == &init_pid_ns ||
121 (!rdma_is_kernel_res(e) &&
122 ns == task_active_pid_ns(e->task)))
123 cnt++;
124 }
125 xa_unlock(&rt->xa);
126 return cnt;
127}
128EXPORT_SYMBOL(rdma_restrack_count);
129
130static void set_kern_name(struct rdma_restrack_entry *res)
131{
132 struct ib_pd *pd;
133
134 switch (res->type) {
135 case RDMA_RESTRACK_QP:
136 pd = container_of(res, struct ib_qp, res)->pd;
137 if (!pd) {
138 WARN_ONCE(true, "XRC QPs are not supported\n");
139
140 res->kern_name = " ";
141 }
142 break;
143 case RDMA_RESTRACK_MR:
144 pd = container_of(res, struct ib_mr, res)->pd;
145 break;
146 default:
147
148 pd = NULL;
149 break;
150 }
151
152 if (pd)
153 res->kern_name = pd->res.kern_name;
154}
155
156static struct ib_device *res_to_dev(struct rdma_restrack_entry *res)
157{
158 switch (res->type) {
159 case RDMA_RESTRACK_PD:
160 return container_of(res, struct ib_pd, res)->device;
161 case RDMA_RESTRACK_CQ:
162 return container_of(res, struct ib_cq, res)->device;
163 case RDMA_RESTRACK_QP:
164 return container_of(res, struct ib_qp, res)->device;
165 case RDMA_RESTRACK_CM_ID:
166 return container_of(res, struct rdma_id_private,
167 res)->id.device;
168 case RDMA_RESTRACK_MR:
169 return container_of(res, struct ib_mr, res)->device;
170 case RDMA_RESTRACK_CTX:
171 return container_of(res, struct ib_ucontext, res)->device;
172 default:
173 WARN_ONCE(true, "Wrong resource tracking type %u\n", res->type);
174 return NULL;
175 }
176}
177
178void rdma_restrack_set_task(struct rdma_restrack_entry *res,
179 const char *caller)
180{
181 if (caller) {
182 res->kern_name = caller;
183 return;
184 }
185
186 if (res->task)
187 put_task_struct(res->task);
188 get_task_struct(current);
189 res->task = current;
190}
191EXPORT_SYMBOL(rdma_restrack_set_task);
192
193static void rdma_restrack_add(struct rdma_restrack_entry *res)
194{
195 struct ib_device *dev = res_to_dev(res);
196 struct rdma_restrack_root *rt;
197 int ret;
198
199 if (!dev)
200 return;
201
202 rt = &dev->res[res->type];
203
204 kref_init(&res->kref);
205 init_completion(&res->comp);
206 if (res->type != RDMA_RESTRACK_QP)
207 ret = xa_alloc_cyclic(&rt->xa, &res->id, res, xa_limit_32b,
208 &rt->next_id, GFP_KERNEL);
209 else {
210
211 struct ib_qp *qp = container_of(res, struct ib_qp, res);
212
213 ret = xa_insert(&rt->xa, qp->qp_num, res, GFP_KERNEL);
214 res->id = ret ? 0 : qp->qp_num;
215 }
216
217 if (!ret)
218 res->valid = true;
219}
220
221
222
223
224
225void rdma_restrack_kadd(struct rdma_restrack_entry *res)
226{
227 res->task = NULL;
228 set_kern_name(res);
229 res->user = false;
230 rdma_restrack_add(res);
231}
232EXPORT_SYMBOL(rdma_restrack_kadd);
233
234
235
236
237
238void rdma_restrack_uadd(struct rdma_restrack_entry *res)
239{
240 if (res->type != RDMA_RESTRACK_CM_ID)
241 res->task = NULL;
242
243 if (!res->task)
244 rdma_restrack_set_task(res, NULL);
245 res->kern_name = NULL;
246
247 res->user = true;
248 rdma_restrack_add(res);
249}
250EXPORT_SYMBOL(rdma_restrack_uadd);
251
252int __must_check rdma_restrack_get(struct rdma_restrack_entry *res)
253{
254 return kref_get_unless_zero(&res->kref);
255}
256EXPORT_SYMBOL(rdma_restrack_get);
257
258
259
260
261
262
263
264
265
266struct rdma_restrack_entry *
267rdma_restrack_get_byid(struct ib_device *dev,
268 enum rdma_restrack_type type, u32 id)
269{
270 struct rdma_restrack_root *rt = &dev->res[type];
271 struct rdma_restrack_entry *res;
272
273 xa_lock(&rt->xa);
274 res = xa_load(&rt->xa, id);
275 if (!res || !rdma_restrack_get(res))
276 res = ERR_PTR(-ENOENT);
277 xa_unlock(&rt->xa);
278
279 return res;
280}
281EXPORT_SYMBOL(rdma_restrack_get_byid);
282
283static void restrack_release(struct kref *kref)
284{
285 struct rdma_restrack_entry *res;
286
287 res = container_of(kref, struct rdma_restrack_entry, kref);
288 complete(&res->comp);
289}
290
291int rdma_restrack_put(struct rdma_restrack_entry *res)
292{
293 return kref_put(&res->kref, restrack_release);
294}
295EXPORT_SYMBOL(rdma_restrack_put);
296
297void rdma_restrack_del(struct rdma_restrack_entry *res)
298{
299 struct rdma_restrack_entry *old;
300 struct rdma_restrack_root *rt;
301 struct ib_device *dev;
302
303 if (!res->valid)
304 goto out;
305
306 dev = res_to_dev(res);
307 if (WARN_ON(!dev))
308 return;
309
310 rt = &dev->res[res->type];
311
312 old = xa_erase(&rt->xa, res->id);
313 WARN_ON(old != res);
314 res->valid = false;
315
316 rdma_restrack_put(res);
317 wait_for_completion(&res->comp);
318
319out:
320 if (res->task) {
321 put_task_struct(res->task);
322 res->task = NULL;
323 }
324}
325EXPORT_SYMBOL(rdma_restrack_del);
326