0001
0002
0003
0004
0005
0006 #include <rdma/rdma_cm.h>
0007 #include <rdma/ib_verbs.h>
0008 #include <rdma/restrack.h>
0009 #include <rdma/rdma_counter.h>
0010 #include <linux/mutex.h>
0011 #include <linux/sched/task.h>
0012 #include <linux/pid_namespace.h>
0013
0014 #include "cma_priv.h"
0015 #include "restrack.h"
0016
0017
0018
0019
0020
0021
0022
0023 int rdma_restrack_init(struct ib_device *dev)
0024 {
0025 struct rdma_restrack_root *rt;
0026 int i;
0027
0028 dev->res = kcalloc(RDMA_RESTRACK_MAX, sizeof(*rt), GFP_KERNEL);
0029 if (!dev->res)
0030 return -ENOMEM;
0031
0032 rt = dev->res;
0033
0034 for (i = 0; i < RDMA_RESTRACK_MAX; i++)
0035 xa_init_flags(&rt[i].xa, XA_FLAGS_ALLOC);
0036
0037 return 0;
0038 }
0039
0040 static const char *type2str(enum rdma_restrack_type type)
0041 {
0042 static const char * const names[RDMA_RESTRACK_MAX] = {
0043 [RDMA_RESTRACK_PD] = "PD",
0044 [RDMA_RESTRACK_CQ] = "CQ",
0045 [RDMA_RESTRACK_QP] = "QP",
0046 [RDMA_RESTRACK_CM_ID] = "CM_ID",
0047 [RDMA_RESTRACK_MR] = "MR",
0048 [RDMA_RESTRACK_CTX] = "CTX",
0049 [RDMA_RESTRACK_COUNTER] = "COUNTER",
0050 [RDMA_RESTRACK_SRQ] = "SRQ",
0051 };
0052
0053 return names[type];
0054 };
0055
0056
0057
0058
0059
0060 void rdma_restrack_clean(struct ib_device *dev)
0061 {
0062 struct rdma_restrack_root *rt = dev->res;
0063 struct rdma_restrack_entry *e;
0064 char buf[TASK_COMM_LEN];
0065 bool found = false;
0066 const char *owner;
0067 int i;
0068
0069 for (i = 0 ; i < RDMA_RESTRACK_MAX; i++) {
0070 struct xarray *xa = &dev->res[i].xa;
0071
0072 if (!xa_empty(xa)) {
0073 unsigned long index;
0074
0075 if (!found) {
0076 pr_err("restrack: %s", CUT_HERE);
0077 dev_err(&dev->dev, "BUG: RESTRACK detected leak of resources\n");
0078 }
0079 xa_for_each(xa, index, e) {
0080 if (rdma_is_kernel_res(e)) {
0081 owner = e->kern_name;
0082 } else {
0083
0084
0085
0086
0087
0088 get_task_comm(buf, e->task);
0089 owner = buf;
0090 }
0091
0092 pr_err("restrack: %s %s object allocated by %s is not freed\n",
0093 rdma_is_kernel_res(e) ? "Kernel" :
0094 "User",
0095 type2str(e->type), owner);
0096 }
0097 found = true;
0098 }
0099 xa_destroy(xa);
0100 }
0101 if (found)
0102 pr_err("restrack: %s", CUT_HERE);
0103
0104 kfree(rt);
0105 }
0106
0107
0108
0109
0110
0111
0112 int rdma_restrack_count(struct ib_device *dev, enum rdma_restrack_type type)
0113 {
0114 struct rdma_restrack_root *rt = &dev->res[type];
0115 struct rdma_restrack_entry *e;
0116 XA_STATE(xas, &rt->xa, 0);
0117 u32 cnt = 0;
0118
0119 xa_lock(&rt->xa);
0120 xas_for_each(&xas, e, U32_MAX)
0121 cnt++;
0122 xa_unlock(&rt->xa);
0123 return cnt;
0124 }
0125 EXPORT_SYMBOL(rdma_restrack_count);
0126
0127 static struct ib_device *res_to_dev(struct rdma_restrack_entry *res)
0128 {
0129 switch (res->type) {
0130 case RDMA_RESTRACK_PD:
0131 return container_of(res, struct ib_pd, res)->device;
0132 case RDMA_RESTRACK_CQ:
0133 return container_of(res, struct ib_cq, res)->device;
0134 case RDMA_RESTRACK_QP:
0135 return container_of(res, struct ib_qp, res)->device;
0136 case RDMA_RESTRACK_CM_ID:
0137 return container_of(res, struct rdma_id_private,
0138 res)->id.device;
0139 case RDMA_RESTRACK_MR:
0140 return container_of(res, struct ib_mr, res)->device;
0141 case RDMA_RESTRACK_CTX:
0142 return container_of(res, struct ib_ucontext, res)->device;
0143 case RDMA_RESTRACK_COUNTER:
0144 return container_of(res, struct rdma_counter, res)->device;
0145 case RDMA_RESTRACK_SRQ:
0146 return container_of(res, struct ib_srq, res)->device;
0147 default:
0148 WARN_ONCE(true, "Wrong resource tracking type %u\n", res->type);
0149 return NULL;
0150 }
0151 }
0152
0153
0154
0155
0156
0157
0158
0159 static void rdma_restrack_attach_task(struct rdma_restrack_entry *res,
0160 struct task_struct *task)
0161 {
0162 if (WARN_ON_ONCE(!task))
0163 return;
0164
0165 if (res->task)
0166 put_task_struct(res->task);
0167 get_task_struct(task);
0168 res->task = task;
0169 res->user = true;
0170 }
0171
0172
0173
0174
0175
0176
0177 void rdma_restrack_set_name(struct rdma_restrack_entry *res, const char *caller)
0178 {
0179 if (caller) {
0180 res->kern_name = caller;
0181 return;
0182 }
0183
0184 rdma_restrack_attach_task(res, current);
0185 }
0186 EXPORT_SYMBOL(rdma_restrack_set_name);
0187
0188
0189
0190
0191
0192
0193
0194 void rdma_restrack_parent_name(struct rdma_restrack_entry *dst,
0195 const struct rdma_restrack_entry *parent)
0196 {
0197 if (rdma_is_kernel_res(parent))
0198 dst->kern_name = parent->kern_name;
0199 else
0200 rdma_restrack_attach_task(dst, parent->task);
0201 }
0202 EXPORT_SYMBOL(rdma_restrack_parent_name);
0203
0204
0205
0206
0207
0208
0209
0210 void rdma_restrack_new(struct rdma_restrack_entry *res,
0211 enum rdma_restrack_type type)
0212 {
0213 kref_init(&res->kref);
0214 init_completion(&res->comp);
0215 res->type = type;
0216 }
0217 EXPORT_SYMBOL(rdma_restrack_new);
0218
0219
0220
0221
0222
0223 void rdma_restrack_add(struct rdma_restrack_entry *res)
0224 {
0225 struct ib_device *dev = res_to_dev(res);
0226 struct rdma_restrack_root *rt;
0227 int ret = 0;
0228
0229 if (!dev)
0230 return;
0231
0232 if (res->no_track)
0233 goto out;
0234
0235 rt = &dev->res[res->type];
0236
0237 if (res->type == RDMA_RESTRACK_QP) {
0238
0239 struct ib_qp *qp = container_of(res, struct ib_qp, res);
0240
0241 WARN_ONCE(qp->qp_num >> 24 || qp->port >> 8,
0242 "QP number 0x%0X and port 0x%0X", qp->qp_num,
0243 qp->port);
0244 res->id = qp->qp_num;
0245 if (qp->qp_type == IB_QPT_SMI || qp->qp_type == IB_QPT_GSI)
0246 res->id |= qp->port << 24;
0247 ret = xa_insert(&rt->xa, res->id, res, GFP_KERNEL);
0248 if (ret)
0249 res->id = 0;
0250 } else if (res->type == RDMA_RESTRACK_COUNTER) {
0251
0252 struct rdma_counter *counter;
0253
0254 counter = container_of(res, struct rdma_counter, res);
0255 ret = xa_insert(&rt->xa, counter->id, res, GFP_KERNEL);
0256 res->id = ret ? 0 : counter->id;
0257 } else {
0258 ret = xa_alloc_cyclic(&rt->xa, &res->id, res, xa_limit_32b,
0259 &rt->next_id, GFP_KERNEL);
0260 ret = (ret < 0) ? ret : 0;
0261 }
0262
0263 out:
0264 if (!ret)
0265 res->valid = true;
0266 }
0267 EXPORT_SYMBOL(rdma_restrack_add);
0268
0269 int __must_check rdma_restrack_get(struct rdma_restrack_entry *res)
0270 {
0271 return kref_get_unless_zero(&res->kref);
0272 }
0273 EXPORT_SYMBOL(rdma_restrack_get);
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 struct rdma_restrack_entry *
0284 rdma_restrack_get_byid(struct ib_device *dev,
0285 enum rdma_restrack_type type, u32 id)
0286 {
0287 struct rdma_restrack_root *rt = &dev->res[type];
0288 struct rdma_restrack_entry *res;
0289
0290 xa_lock(&rt->xa);
0291 res = xa_load(&rt->xa, id);
0292 if (!res || !rdma_restrack_get(res))
0293 res = ERR_PTR(-ENOENT);
0294 xa_unlock(&rt->xa);
0295
0296 return res;
0297 }
0298 EXPORT_SYMBOL(rdma_restrack_get_byid);
0299
0300 static void restrack_release(struct kref *kref)
0301 {
0302 struct rdma_restrack_entry *res;
0303
0304 res = container_of(kref, struct rdma_restrack_entry, kref);
0305 if (res->task) {
0306 put_task_struct(res->task);
0307 res->task = NULL;
0308 }
0309 complete(&res->comp);
0310 }
0311
0312 int rdma_restrack_put(struct rdma_restrack_entry *res)
0313 {
0314 return kref_put(&res->kref, restrack_release);
0315 }
0316 EXPORT_SYMBOL(rdma_restrack_put);
0317
0318
0319
0320
0321
0322 void rdma_restrack_del(struct rdma_restrack_entry *res)
0323 {
0324 struct rdma_restrack_entry *old;
0325 struct rdma_restrack_root *rt;
0326 struct ib_device *dev;
0327
0328 if (!res->valid) {
0329 if (res->task) {
0330 put_task_struct(res->task);
0331 res->task = NULL;
0332 }
0333 return;
0334 }
0335
0336 if (res->no_track)
0337 goto out;
0338
0339 dev = res_to_dev(res);
0340 if (WARN_ON(!dev))
0341 return;
0342
0343 rt = &dev->res[res->type];
0344
0345 old = xa_erase(&rt->xa, res->id);
0346 if (res->type == RDMA_RESTRACK_MR)
0347 return;
0348 WARN_ON(old != res);
0349
0350 out:
0351 res->valid = false;
0352 rdma_restrack_put(res);
0353 wait_for_completion(&res->comp);
0354 }
0355 EXPORT_SYMBOL(rdma_restrack_del);