Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu
[linux-2.6-block.git] / drivers / infiniband / core / restrack.c
1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /*
3  * Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved.
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 static int rt_xa_alloc_cyclic(struct xarray *xa, u32 *id, void *entry,
17                               u32 *next)
18 {
19         int err;
20
21         *id = *next;
22         if (*next == U32_MAX)
23                 *id = 0;
24
25         xa_lock(xa);
26         err = __xa_alloc(xa, id, U32_MAX, entry, GFP_KERNEL);
27         if (err && *next != U32_MAX) {
28                 *id = 0;
29                 err = __xa_alloc(xa, id, *next, entry, GFP_KERNEL);
30         }
31
32         if (!err)
33                 *next = *id + 1;
34         xa_unlock(xa);
35         return err;
36 }
37
38 /**
39  * rdma_restrack_init() - initialize and allocate resource tracking
40  * @dev:  IB device
41  *
42  * Return: 0 on success
43  */
44 int rdma_restrack_init(struct ib_device *dev)
45 {
46         struct rdma_restrack_root *rt;
47         int i;
48
49         dev->res = kcalloc(RDMA_RESTRACK_MAX, sizeof(*rt), GFP_KERNEL);
50         if (!dev->res)
51                 return -ENOMEM;
52
53         rt = dev->res;
54
55         for (i = 0; i < RDMA_RESTRACK_MAX; i++)
56                 xa_init_flags(&rt[i].xa, XA_FLAGS_ALLOC);
57
58         return 0;
59 }
60
61 static const char *type2str(enum rdma_restrack_type type)
62 {
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",
70         };
71
72         return names[type];
73 };
74
75 /**
76  * rdma_restrack_clean() - clean resource tracking
77  * @dev:  IB device
78  */
79 void rdma_restrack_clean(struct ib_device *dev)
80 {
81         struct rdma_restrack_root *rt = dev->res;
82         struct rdma_restrack_entry *e;
83         char buf[TASK_COMM_LEN];
84         bool found = false;
85         const char *owner;
86         int i;
87
88         for (i = 0 ; i < RDMA_RESTRACK_MAX; i++) {
89                 struct xarray *xa = &dev->res[i].xa;
90
91                 if (!xa_empty(xa)) {
92                         unsigned long index;
93
94                         if (!found) {
95                                 pr_err("restrack: %s", CUT_HERE);
96                                 dev_err(&dev->dev, "BUG: RESTRACK detected leak of resources\n");
97                         }
98                         xa_for_each(xa, index, e) {
99                                 if (rdma_is_kernel_res(e)) {
100                                         owner = e->kern_name;
101                                 } else {
102                                         /*
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().
106                                          */
107                                         get_task_comm(buf, e->task);
108                                         owner = buf;
109                                 }
110
111                                 pr_err("restrack: %s %s object allocated by %s is not freed\n",
112                                        rdma_is_kernel_res(e) ? "Kernel" :
113                                                                "User",
114                                        type2str(e->type), owner);
115                         }
116                         found = true;
117                 }
118                 xa_destroy(xa);
119         }
120         if (found)
121                 pr_err("restrack: %s", CUT_HERE);
122
123         kfree(rt);
124 }
125
126 /**
127  * rdma_restrack_count() - the current usage of specific object
128  * @dev:  IB device
129  * @type: actual type of object to operate
130  * @ns:   PID namespace
131  */
132 int rdma_restrack_count(struct ib_device *dev, enum rdma_restrack_type type,
133                         struct pid_namespace *ns)
134 {
135         struct rdma_restrack_root *rt = &dev->res[type];
136         struct rdma_restrack_entry *e;
137         XA_STATE(xas, &rt->xa, 0);
138         u32 cnt = 0;
139
140         xa_lock(&rt->xa);
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)))
145                         cnt++;
146         }
147         xa_unlock(&rt->xa);
148         return cnt;
149 }
150 EXPORT_SYMBOL(rdma_restrack_count);
151
152 static void set_kern_name(struct rdma_restrack_entry *res)
153 {
154         struct ib_pd *pd;
155
156         switch (res->type) {
157         case RDMA_RESTRACK_QP:
158                 pd = container_of(res, struct ib_qp, res)->pd;
159                 if (!pd) {
160                         WARN_ONCE(true, "XRC QPs are not supported\n");
161                         /* Survive, despite the programmer's error */
162                         res->kern_name = " ";
163                 }
164                 break;
165         case RDMA_RESTRACK_MR:
166                 pd = container_of(res, struct ib_mr, res)->pd;
167                 break;
168         default:
169                 /* Other types set kern_name directly */
170                 pd = NULL;
171                 break;
172         }
173
174         if (pd)
175                 res->kern_name = pd->res.kern_name;
176 }
177
178 static struct ib_device *res_to_dev(struct rdma_restrack_entry *res)
179 {
180         switch (res->type) {
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,
189                                     res)->id.device;
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;
194         default:
195                 WARN_ONCE(true, "Wrong resource tracking type %u\n", res->type);
196                 return NULL;
197         }
198 }
199
200 void rdma_restrack_set_task(struct rdma_restrack_entry *res,
201                             const char *caller)
202 {
203         if (caller) {
204                 res->kern_name = caller;
205                 return;
206         }
207
208         if (res->task)
209                 put_task_struct(res->task);
210         get_task_struct(current);
211         res->task = current;
212 }
213 EXPORT_SYMBOL(rdma_restrack_set_task);
214
215 static void rdma_restrack_add(struct rdma_restrack_entry *res)
216 {
217         struct ib_device *dev = res_to_dev(res);
218         struct rdma_restrack_root *rt;
219         int ret;
220
221         if (!dev)
222                 return;
223
224         rt = &dev->res[res->type];
225
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);
230         else {
231                 /* Special case to ensure that LQPN points to right QP */
232                 struct ib_qp *qp = container_of(res, struct ib_qp, res);
233
234                 ret = xa_insert(&rt->xa, qp->qp_num, res, GFP_KERNEL);
235                 res->id = ret ? 0 : qp->qp_num;
236         }
237
238         if (!ret)
239                 res->valid = true;
240 }
241
242 /**
243  * rdma_restrack_kadd() - add kernel object to the reource tracking database
244  * @res:  resource entry
245  */
246 void rdma_restrack_kadd(struct rdma_restrack_entry *res)
247 {
248         res->task = NULL;
249         set_kern_name(res);
250         res->user = false;
251         rdma_restrack_add(res);
252 }
253 EXPORT_SYMBOL(rdma_restrack_kadd);
254
255 /**
256  * rdma_restrack_uadd() - add user object to the reource tracking database
257  * @res:  resource entry
258  */
259 void rdma_restrack_uadd(struct rdma_restrack_entry *res)
260 {
261         if (res->type != RDMA_RESTRACK_CM_ID)
262                 res->task = NULL;
263
264         if (!res->task)
265                 rdma_restrack_set_task(res, NULL);
266         res->kern_name = NULL;
267
268         res->user = true;
269         rdma_restrack_add(res);
270 }
271 EXPORT_SYMBOL(rdma_restrack_uadd);
272
273 int __must_check rdma_restrack_get(struct rdma_restrack_entry *res)
274 {
275         return kref_get_unless_zero(&res->kref);
276 }
277 EXPORT_SYMBOL(rdma_restrack_get);
278
279 /**
280  * rdma_restrack_get_byid() - translate from ID to restrack object
281  * @dev: IB device
282  * @type: resource track type
283  * @id: ID to take a look
284  *
285  * Return: Pointer to restrack entry or -ENOENT in case of error.
286  */
287 struct rdma_restrack_entry *
288 rdma_restrack_get_byid(struct ib_device *dev,
289                        enum rdma_restrack_type type, u32 id)
290 {
291         struct rdma_restrack_root *rt = &dev->res[type];
292         struct rdma_restrack_entry *res;
293
294         xa_lock(&rt->xa);
295         res = xa_load(&rt->xa, id);
296         if (!res || !rdma_restrack_get(res))
297                 res = ERR_PTR(-ENOENT);
298         xa_unlock(&rt->xa);
299
300         return res;
301 }
302 EXPORT_SYMBOL(rdma_restrack_get_byid);
303
304 static void restrack_release(struct kref *kref)
305 {
306         struct rdma_restrack_entry *res;
307
308         res = container_of(kref, struct rdma_restrack_entry, kref);
309         complete(&res->comp);
310 }
311
312 int rdma_restrack_put(struct rdma_restrack_entry *res)
313 {
314         return kref_put(&res->kref, restrack_release);
315 }
316 EXPORT_SYMBOL(rdma_restrack_put);
317
318 void rdma_restrack_del(struct rdma_restrack_entry *res)
319 {
320         struct rdma_restrack_entry *old;
321         struct rdma_restrack_root *rt;
322         struct ib_device *dev;
323
324         if (!res->valid)
325                 goto out;
326
327         dev = res_to_dev(res);
328         if (WARN_ON(!dev))
329                 return;
330
331         rt = &dev->res[res->type];
332
333         old = xa_erase(&rt->xa, res->id);
334         WARN_ON(old != res);
335         res->valid = false;
336
337         rdma_restrack_put(res);
338         wait_for_completion(&res->comp);
339
340 out:
341         if (res->task) {
342                 put_task_struct(res->task);
343                 res->task = NULL;
344         }
345 }
346 EXPORT_SYMBOL(rdma_restrack_del);