xref: /linux/kernel/cgroup/rdma.c (revision 1b78070aaef63512688aebfbc82365ef9d6660f1)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * RDMA resource limiting controller for cgroups.
4  *
5  * Used to allow a cgroup hierarchy to stop processes from consuming
6  * additional RDMA resources after a certain limit is reached.
7  *
8  * Copyright (C) 2016 Parav Pandit <pandit.parav@gmail.com>
9  */
10 
11 #include <linux/bitops.h>
12 #include <linux/limits.h>
13 #include <linux/slab.h>
14 #include <linux/seq_file.h>
15 #include <linux/cgroup.h>
16 #include <linux/parser.h>
17 #include <linux/cgroup_rdma.h>
18 
19 #define RDMACG_MAX_STR "max"
20 
21 enum rdmacg_limit_tokens {
22 	RDMACG_DEVICE_INDEX,
23 	RDMACG_HCA_HANDLE_VAL,
24 	RDMACG_HCA_HANDLE_MAX,
25 	RDMACG_HCA_OBJECT_VAL,
26 	RDMACG_HCA_OBJECT_MAX,
27 	NR_RDMACG_LIMIT_TOKENS,
28 };
29 
30 static const match_table_t rdmacg_limit_tokens = {
31 	{ RDMACG_DEVICE_INDEX,		"index=%u"	},
32 	{ RDMACG_HCA_HANDLE_VAL,	"hca_handle=%d"	},
33 	{ RDMACG_HCA_HANDLE_MAX,	"hca_handle=max"	},
34 	{ RDMACG_HCA_OBJECT_VAL,	"hca_object=%d"	},
35 	{ RDMACG_HCA_OBJECT_MAX,	"hca_object=max"	},
36 	{ NR_RDMACG_LIMIT_TOKENS,	NULL			},
37 };
38 
39 /*
40  * Protects list of resource pools maintained on per cgroup basis
41  * and rdma device list.
42  */
43 static DEFINE_MUTEX(rdmacg_mutex);
44 static LIST_HEAD(rdmacg_devices);
45 
46 enum rdmacg_file_type {
47 	RDMACG_RESOURCE_TYPE_MAX,
48 	RDMACG_RESOURCE_TYPE_STAT,
49 	RDMACG_RESOURCE_TYPE_PEAK,
50 };
51 
52 /*
53  * resource table definition as to be seen by the user.
54  * Need to add entries to it when more resources are
55  * added/defined at IB verb/core layer.
56  */
57 static char const *rdmacg_resource_names[] = {
58 	[RDMACG_RESOURCE_HCA_HANDLE]	= "hca_handle",
59 	[RDMACG_RESOURCE_HCA_OBJECT]	= "hca_object",
60 };
61 
62 /* resource tracker for each resource of rdma cgroup */
63 struct rdmacg_resource {
64 	int max;
65 	int usage;
66 	int peak;
67 };
68 
69 /*
70  * resource pool object which represents per cgroup, per device
71  * resources. There are multiple instances of this object per cgroup,
72  * therefore it cannot be embedded within rdma_cgroup structure. It
73  * is maintained as list.
74  */
75 struct rdmacg_resource_pool {
76 	struct rdmacg_device	*device;
77 	struct rdmacg_resource	resources[RDMACG_RESOURCE_MAX];
78 
79 	struct list_head	cg_node;
80 	struct list_head	dev_node;
81 
82 	/* count active user tasks of this pool */
83 	u64			usage_sum;
84 	/* total number counts which are set to max */
85 	int			num_max_cnt;
86 
87 	/* per-resource event counters */
88 	u64			events_max[RDMACG_RESOURCE_MAX];
89 	u64			events_alloc_fail[RDMACG_RESOURCE_MAX];
90 	u64			events_local_max[RDMACG_RESOURCE_MAX];
91 	u64			events_local_alloc_fail[RDMACG_RESOURCE_MAX];
92 };
93 
94 static struct rdma_cgroup *css_rdmacg(struct cgroup_subsys_state *css)
95 {
96 	return container_of(css, struct rdma_cgroup, css);
97 }
98 
99 static struct rdma_cgroup *parent_rdmacg(struct rdma_cgroup *cg)
100 {
101 	return css_rdmacg(cg->css.parent);
102 }
103 
104 static inline struct rdma_cgroup *get_current_rdmacg(void)
105 {
106 	return css_rdmacg(task_get_css(current, rdma_cgrp_id));
107 }
108 
109 static void set_resource_limit(struct rdmacg_resource_pool *rpool,
110 			       int index, int new_max)
111 {
112 	if (new_max == S32_MAX) {
113 		if (rpool->resources[index].max != S32_MAX)
114 			rpool->num_max_cnt++;
115 	} else {
116 		if (rpool->resources[index].max == S32_MAX)
117 			rpool->num_max_cnt--;
118 	}
119 	rpool->resources[index].max = new_max;
120 }
121 
122 static void set_all_resource_max_limit(struct rdmacg_resource_pool *rpool)
123 {
124 	int i;
125 
126 	for (i = 0; i < RDMACG_RESOURCE_MAX; i++)
127 		set_resource_limit(rpool, i, S32_MAX);
128 }
129 
130 static void free_cg_rpool_locked(struct rdmacg_resource_pool *rpool)
131 {
132 	lockdep_assert_held(&rdmacg_mutex);
133 
134 	list_del(&rpool->cg_node);
135 	list_del(&rpool->dev_node);
136 	kfree(rpool);
137 }
138 
139 static bool rpool_has_persistent_state(struct rdmacg_resource_pool *rpool)
140 {
141 	int i;
142 
143 	/*
144 	 * Keep the rpool alive if any peak value is non-zero,
145 	 * so that rdma.peak persists as a historical high-
146 	 * watermark even after all resources are freed.
147 	 */
148 	for (i = 0; i < RDMACG_RESOURCE_MAX; i++) {
149 		if (rpool->resources[i].peak ||
150 		    rpool->events_max[i] ||
151 		    rpool->events_local_max[i] ||
152 		    rpool->events_alloc_fail[i] ||
153 		    rpool->events_local_alloc_fail[i])
154 			return true;
155 	}
156 	return false;
157 }
158 
159 static struct rdmacg_resource_pool *
160 find_cg_rpool_locked(struct rdma_cgroup *cg,
161 		     struct rdmacg_device *device)
162 
163 {
164 	struct rdmacg_resource_pool *pool;
165 
166 	lockdep_assert_held(&rdmacg_mutex);
167 
168 	list_for_each_entry(pool, &cg->rpools, cg_node)
169 		if (pool->device == device)
170 			return pool;
171 
172 	return NULL;
173 }
174 
175 static struct rdmacg_resource_pool *
176 get_cg_rpool_locked(struct rdma_cgroup *cg, struct rdmacg_device *device)
177 {
178 	struct rdmacg_resource_pool *rpool;
179 
180 	rpool = find_cg_rpool_locked(cg, device);
181 	if (rpool)
182 		return rpool;
183 
184 	rpool = kzalloc_obj(*rpool);
185 	if (!rpool)
186 		return ERR_PTR(-ENOMEM);
187 
188 	rpool->device = device;
189 	set_all_resource_max_limit(rpool);
190 
191 	INIT_LIST_HEAD(&rpool->cg_node);
192 	INIT_LIST_HEAD(&rpool->dev_node);
193 	list_add_tail(&rpool->cg_node, &cg->rpools);
194 	list_add_tail(&rpool->dev_node, &device->rpools);
195 	return rpool;
196 }
197 
198 /**
199  * uncharge_cg_locked - uncharge resource for rdma cgroup
200  * @cg: pointer to cg to uncharge and all parents in hierarchy
201  * @device: pointer to rdmacg device
202  * @index: index of the resource to uncharge in cg (resource pool)
203  *
204  * It also frees the resource pool which was created as part of
205  * charging operation when there are no resources attached to
206  * resource pool.
207  */
208 static void
209 uncharge_cg_locked(struct rdma_cgroup *cg,
210 		   struct rdmacg_device *device,
211 		   enum rdmacg_resource_type index)
212 {
213 	struct rdmacg_resource_pool *rpool;
214 
215 	rpool = find_cg_rpool_locked(cg, device);
216 
217 	/*
218 	 * rpool cannot be null at this stage. Let kernel operate in case
219 	 * if there a bug in IB stack or rdma controller, instead of crashing
220 	 * the system.
221 	 */
222 	if (unlikely(!rpool)) {
223 		pr_warn("Invalid device %p or rdma cgroup %p\n", device, cg);
224 		return;
225 	}
226 
227 	rpool->resources[index].usage--;
228 
229 	/*
230 	 * A negative count (or overflow) is invalid,
231 	 * it indicates a bug in the rdma controller.
232 	 */
233 	WARN_ON_ONCE(rpool->resources[index].usage < 0);
234 	rpool->usage_sum--;
235 	if (rpool->usage_sum == 0 &&
236 	    rpool->num_max_cnt == RDMACG_RESOURCE_MAX) {
237 		if (!rpool_has_persistent_state(rpool)) {
238 			/*
239 			 * No user of the rpool and all entries are set to max, so
240 			 * safe to delete this rpool.
241 			 */
242 			free_cg_rpool_locked(rpool);
243 		}
244 	}
245 }
246 
247 /**
248  * rdmacg_event_locked - fire event when resource allocation exceeds limit
249  * @cg: requesting cgroup
250  * @over_cg: cgroup whose limit was exceeded
251  * @device: rdma device
252  * @index: resource type index
253  *
254  * Must be called under rdmacg_mutex. Updates event counters in the
255  * resource pools of @cg and @over_cg, propagates hierarchical max
256  * events from @over_cg (including itself) upward, and notifies
257  * userspace via cgroup_file_notify().
258  */
259 static void rdmacg_event_locked(struct rdma_cgroup *cg,
260 				struct rdma_cgroup *over_cg,
261 				struct rdmacg_device *device,
262 				enum rdmacg_resource_type index)
263 {
264 	struct rdmacg_resource_pool *rpool;
265 	struct rdma_cgroup *p;
266 
267 	lockdep_assert_held(&rdmacg_mutex);
268 
269 	/* Increment local alloc_fail in requesting cgroup */
270 	rpool = find_cg_rpool_locked(cg, device);
271 	if (rpool) {
272 		rpool->events_local_alloc_fail[index]++;
273 		cgroup_file_notify(&cg->events_local_file);
274 	}
275 
276 	/* Increment local max in the over-limit cgroup */
277 	rpool = find_cg_rpool_locked(over_cg, device);
278 	if (rpool) {
279 		rpool->events_local_max[index]++;
280 		cgroup_file_notify(&over_cg->events_local_file);
281 	}
282 
283 	/* Propagate hierarchical max events upward */
284 	for (p = over_cg; parent_rdmacg(p); p = parent_rdmacg(p)) {
285 		rpool = get_cg_rpool_locked(p, device);
286 		if (!IS_ERR(rpool)) {
287 			rpool->events_max[index]++;
288 			cgroup_file_notify(&p->events_file);
289 		}
290 	}
291 	/* Propagate hierarchical alloc_fail from requesting cgroup upward */
292 	for (p = cg; parent_rdmacg(p); p = parent_rdmacg(p)) {
293 		rpool = get_cg_rpool_locked(p, device);
294 		if (!IS_ERR(rpool)) {
295 			rpool->events_alloc_fail[index]++;
296 			cgroup_file_notify(&p->events_file);
297 		}
298 	}
299 }
300 
301 /**
302  * rdmacg_uncharge_hierarchy - hierarchically uncharge rdma resource count
303  * @cg: pointer to cg to uncharge and all parents in hierarchy
304  * @device: pointer to rdmacg device
305  * @stop_cg: while traversing hirerchy, when meet with stop_cg cgroup
306  *           stop uncharging
307  * @index: index of the resource to uncharge in cg in given resource pool
308  */
309 static void rdmacg_uncharge_hierarchy(struct rdma_cgroup *cg,
310 				     struct rdmacg_device *device,
311 				     struct rdma_cgroup *stop_cg,
312 				     enum rdmacg_resource_type index)
313 {
314 	struct rdma_cgroup *p;
315 
316 	mutex_lock(&rdmacg_mutex);
317 
318 	for (p = cg; p != stop_cg; p = parent_rdmacg(p))
319 		uncharge_cg_locked(p, device, index);
320 
321 	mutex_unlock(&rdmacg_mutex);
322 
323 	css_put(&cg->css);
324 }
325 
326 /**
327  * rdmacg_uncharge - hierarchically uncharge rdma resource count
328  * @cg: pointer to cg to uncharge and all parents in hierarchy
329  * @device: pointer to rdmacg device
330  * @index: index of the resource to uncharge in cgroup in given resource pool
331  */
332 void rdmacg_uncharge(struct rdma_cgroup *cg,
333 		     struct rdmacg_device *device,
334 		     enum rdmacg_resource_type index)
335 {
336 	if (index >= RDMACG_RESOURCE_MAX)
337 		return;
338 
339 	rdmacg_uncharge_hierarchy(cg, device, NULL, index);
340 }
341 EXPORT_SYMBOL(rdmacg_uncharge);
342 
343 /**
344  * rdmacg_try_charge - hierarchically try to charge the rdma resource
345  * @rdmacg: pointer to rdma cgroup which will own this resource
346  * @device: pointer to rdmacg device
347  * @index: index of the resource to charge in cgroup (resource pool)
348  *
349  * This function follows charging resource in hierarchical way.
350  * It will fail if the charge would cause the new value to exceed the
351  * hierarchical limit.
352  * Returns 0 if the charge succeeded, otherwise -EAGAIN, -ENOMEM or -EINVAL.
353  * Returns pointer to rdmacg for this resource when charging is successful.
354  *
355  * Charger needs to account resources on two criteria.
356  * (a) per cgroup & (b) per device resource usage.
357  * Per cgroup resource usage ensures that tasks of cgroup doesn't cross
358  * the configured limits. Per device provides granular configuration
359  * in multi device usage. It allocates resource pool in the hierarchy
360  * for each parent it come across for first resource. Later on resource
361  * pool will be available. Therefore it will be much faster thereon
362  * to charge/uncharge.
363  */
364 int rdmacg_try_charge(struct rdma_cgroup **rdmacg,
365 		      struct rdmacg_device *device,
366 		      enum rdmacg_resource_type index)
367 {
368 	struct rdma_cgroup *cg, *p;
369 	struct rdmacg_resource_pool *rpool;
370 	s64 new;
371 	int ret = 0;
372 
373 	if (index >= RDMACG_RESOURCE_MAX)
374 		return -EINVAL;
375 
376 	/*
377 	 * hold on to css, as cgroup can be removed but resource
378 	 * accounting happens on css.
379 	 */
380 	cg = get_current_rdmacg();
381 
382 	mutex_lock(&rdmacg_mutex);
383 	for (p = cg; p; p = parent_rdmacg(p)) {
384 		rpool = get_cg_rpool_locked(p, device);
385 		if (IS_ERR(rpool)) {
386 			ret = PTR_ERR(rpool);
387 			goto err;
388 		} else {
389 			new = (s64)rpool->resources[index].usage + 1;
390 			if (new > rpool->resources[index].max) {
391 				ret = -EAGAIN;
392 				goto err;
393 			} else {
394 				rpool->resources[index].usage = new;
395 				rpool->usage_sum++;
396 			}
397 		}
398 	}
399 	/* Update peak only after all charges succeed */
400 	for (p = cg; p; p = parent_rdmacg(p)) {
401 		rpool = find_cg_rpool_locked(p, device);
402 		if (rpool && rpool->resources[index].usage > rpool->resources[index].peak)
403 			rpool->resources[index].peak = rpool->resources[index].usage;
404 	}
405 	mutex_unlock(&rdmacg_mutex);
406 
407 	*rdmacg = cg;
408 	return 0;
409 
410 err:
411 	if (ret == -EAGAIN)
412 		rdmacg_event_locked(cg, p, device, index);
413 	mutex_unlock(&rdmacg_mutex);
414 	rdmacg_uncharge_hierarchy(cg, device, p, index);
415 	return ret;
416 }
417 EXPORT_SYMBOL(rdmacg_try_charge);
418 
419 /**
420  * rdmacg_register_device - register rdmacg device to rdma controller.
421  * @device: pointer to rdmacg device whose resources need to be accounted.
422  *
423  * If IB stack wish a device to participate in rdma cgroup resource
424  * tracking, it must invoke this API to register with rdma cgroup before
425  * any user space application can start using the RDMA resources.
426  */
427 void rdmacg_register_device(struct rdmacg_device *device)
428 {
429 	INIT_LIST_HEAD(&device->dev_node);
430 	INIT_LIST_HEAD(&device->rpools);
431 
432 	mutex_lock(&rdmacg_mutex);
433 	list_add_tail(&device->dev_node, &rdmacg_devices);
434 	mutex_unlock(&rdmacg_mutex);
435 }
436 EXPORT_SYMBOL(rdmacg_register_device);
437 
438 /**
439  * rdmacg_unregister_device - unregister rdmacg device from rdma controller.
440  * @device: pointer to rdmacg device which was previously registered with rdma
441  *          controller using rdmacg_register_device().
442  *
443  * IB stack must invoke this after all the resources of the IB device
444  * are destroyed and after ensuring that no more resources will be created
445  * when this API is invoked.
446  */
447 void rdmacg_unregister_device(struct rdmacg_device *device)
448 {
449 	struct rdmacg_resource_pool *rpool, *tmp;
450 
451 	/*
452 	 * Synchronize with any active resource settings,
453 	 * usage query happening via configfs.
454 	 */
455 	mutex_lock(&rdmacg_mutex);
456 	list_del_init(&device->dev_node);
457 
458 	/*
459 	 * Now that this device is off the cgroup list, its safe to free
460 	 * all the rpool resources.
461 	 */
462 	list_for_each_entry_safe(rpool, tmp, &device->rpools, dev_node)
463 		free_cg_rpool_locked(rpool);
464 
465 	mutex_unlock(&rdmacg_mutex);
466 }
467 EXPORT_SYMBOL(rdmacg_unregister_device);
468 
469 static struct rdmacg_device *
470 rdmacg_get_device_locked(const char *name, bool has_index, u32 index)
471 {
472 	struct rdmacg_device *match = NULL;
473 	struct rdmacg_device *device;
474 
475 	lockdep_assert_held(&rdmacg_mutex);
476 
477 	list_for_each_entry(device, &rdmacg_devices, dev_node) {
478 		if (strcmp(name, device->name))
479 			continue;
480 
481 		if (has_index) {
482 			if (device->index == index)
483 				return device;
484 			continue;
485 		}
486 
487 		if (match)
488 			return ERR_PTR(-ENOTUNIQ);
489 		match = device;
490 	}
491 
492 	return match ?: ERR_PTR(-ENODEV);
493 }
494 
495 static bool
496 rdmacg_device_name_unique_locked(const struct rdmacg_device *device)
497 {
498 	struct rdmacg_device *other;
499 
500 	lockdep_assert_held(&rdmacg_mutex);
501 
502 	list_for_each_entry(other, &rdmacg_devices, dev_node)
503 		if (other != device && !strcmp(other->name, device->name))
504 			return false;
505 
506 	return true;
507 }
508 
509 static void rdmacg_print_device_key(struct seq_file *sf,
510 				    const struct rdmacg_device *device)
511 {
512 	seq_puts(sf, device->name);
513 	if (!rdmacg_device_name_unique_locked(device))
514 		seq_printf(sf, " index=%u", device->index);
515 	seq_putc(sf, ' ');
516 }
517 
518 static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
519 				       char *buf, size_t nbytes, loff_t off)
520 {
521 	struct rdma_cgroup *cg = css_rdmacg(of_css(of));
522 	const char *dev_name;
523 	struct rdmacg_resource_pool *rpool;
524 	struct rdmacg_device *device;
525 	char *options = strstrip(buf);
526 	char *p;
527 	int *new_limits;
528 	unsigned long enables = 0;
529 	u32 dev_index = 0;
530 	bool has_index = false;
531 	int i = 0, ret = 0;
532 
533 	/* extract the device name first */
534 	dev_name = strsep(&options, " ");
535 	if (!dev_name) {
536 		ret = -EINVAL;
537 		goto err;
538 	}
539 
540 	new_limits = kzalloc_objs(int, RDMACG_RESOURCE_MAX);
541 	if (!new_limits) {
542 		ret = -ENOMEM;
543 		goto err;
544 	}
545 
546 	/* parse the optional device index and resource limit tokens */
547 	while ((p = strsep(&options, " \t\n"))) {
548 		substring_t args[MAX_OPT_ARGS];
549 		int tok, intval;
550 
551 		if (!*p)
552 			continue;
553 
554 		tok = match_token(p, rdmacg_limit_tokens, args);
555 		switch (tok) {
556 		case RDMACG_DEVICE_INDEX:
557 			if (has_index || match_uint(&args[0], &dev_index)) {
558 				ret = -EINVAL;
559 				goto parse_err;
560 			}
561 			has_index = true;
562 			break;
563 		case RDMACG_HCA_HANDLE_VAL:
564 			if (match_int(&args[0], &intval) || intval < 0) {
565 				ret = -EINVAL;
566 				goto parse_err;
567 			}
568 			new_limits[RDMACG_RESOURCE_HCA_HANDLE] = intval;
569 			enables |= BIT(RDMACG_RESOURCE_HCA_HANDLE);
570 			break;
571 		case RDMACG_HCA_HANDLE_MAX:
572 			new_limits[RDMACG_RESOURCE_HCA_HANDLE] = S32_MAX;
573 			enables |= BIT(RDMACG_RESOURCE_HCA_HANDLE);
574 			break;
575 		case RDMACG_HCA_OBJECT_VAL:
576 			if (match_int(&args[0], &intval) || intval < 0) {
577 				ret = -EINVAL;
578 				goto parse_err;
579 			}
580 			new_limits[RDMACG_RESOURCE_HCA_OBJECT] = intval;
581 			enables |= BIT(RDMACG_RESOURCE_HCA_OBJECT);
582 			break;
583 		case RDMACG_HCA_OBJECT_MAX:
584 			new_limits[RDMACG_RESOURCE_HCA_OBJECT] = S32_MAX;
585 			enables |= BIT(RDMACG_RESOURCE_HCA_OBJECT);
586 			break;
587 		default:
588 			ret = -EINVAL;
589 			goto parse_err;
590 		}
591 	}
592 
593 	/* acquire lock to synchronize with hot plug devices */
594 	mutex_lock(&rdmacg_mutex);
595 
596 	device = rdmacg_get_device_locked(dev_name, has_index, dev_index);
597 	if (IS_ERR(device)) {
598 		ret = PTR_ERR(device);
599 		goto dev_err;
600 	}
601 
602 	rpool = get_cg_rpool_locked(cg, device);
603 	if (IS_ERR(rpool)) {
604 		ret = PTR_ERR(rpool);
605 		goto dev_err;
606 	}
607 
608 	/* now set the new limits of the rpool */
609 	for_each_set_bit(i, &enables, RDMACG_RESOURCE_MAX)
610 		set_resource_limit(rpool, i, new_limits[i]);
611 
612 	if (rpool->usage_sum == 0 &&
613 	    rpool->num_max_cnt == RDMACG_RESOURCE_MAX) {
614 		if (!rpool_has_persistent_state(rpool)) {
615 			/*
616 			 * No user of the rpool and all entries are set to max, so
617 			 * safe to delete this rpool.
618 			 */
619 			free_cg_rpool_locked(rpool);
620 		}
621 	}
622 
623 dev_err:
624 	mutex_unlock(&rdmacg_mutex);
625 
626 parse_err:
627 	kfree(new_limits);
628 
629 err:
630 	return ret ?: nbytes;
631 }
632 
633 static void print_rpool_values(struct seq_file *sf,
634 			       struct rdmacg_resource_pool *rpool)
635 {
636 	enum rdmacg_file_type sf_type;
637 	int i;
638 	u32 value;
639 
640 	sf_type = seq_cft(sf)->private;
641 
642 	for (i = 0; i < RDMACG_RESOURCE_MAX; i++) {
643 		seq_puts(sf, rdmacg_resource_names[i]);
644 		seq_putc(sf, '=');
645 		if (sf_type == RDMACG_RESOURCE_TYPE_MAX) {
646 			if (rpool)
647 				value = rpool->resources[i].max;
648 			else
649 				value = S32_MAX;
650 		} else if (sf_type == RDMACG_RESOURCE_TYPE_PEAK) {
651 			value = rpool ? rpool->resources[i].peak : 0;
652 		} else {
653 			if (rpool)
654 				value = rpool->resources[i].usage;
655 			else
656 				value = 0;
657 		}
658 
659 		if (value == S32_MAX)
660 			seq_puts(sf, RDMACG_MAX_STR);
661 		else
662 			seq_printf(sf, "%d", value);
663 		seq_putc(sf, ' ');
664 	}
665 }
666 
667 static int rdmacg_resource_read(struct seq_file *sf, void *v)
668 {
669 	struct rdmacg_device *device;
670 	struct rdmacg_resource_pool *rpool;
671 	struct rdma_cgroup *cg = css_rdmacg(seq_css(sf));
672 
673 	mutex_lock(&rdmacg_mutex);
674 
675 	list_for_each_entry(device, &rdmacg_devices, dev_node) {
676 		rdmacg_print_device_key(sf, device);
677 
678 		rpool = find_cg_rpool_locked(cg, device);
679 		print_rpool_values(sf, rpool);
680 
681 		seq_putc(sf, '\n');
682 	}
683 
684 	mutex_unlock(&rdmacg_mutex);
685 	return 0;
686 }
687 
688 static int rdmacg_events_show(struct seq_file *sf, void *v)
689 {
690 	struct rdma_cgroup *cg = css_rdmacg(seq_css(sf));
691 	struct rdmacg_resource_pool *rpool;
692 	struct rdmacg_device *device;
693 	int i;
694 
695 	mutex_lock(&rdmacg_mutex);
696 
697 	list_for_each_entry(device, &rdmacg_devices, dev_node) {
698 		rpool = find_cg_rpool_locked(cg, device);
699 
700 		rdmacg_print_device_key(sf, device);
701 		for (i = 0; i < RDMACG_RESOURCE_MAX; i++) {
702 			seq_printf(sf, "%s.max=%llu %s.alloc_fail=%llu",
703 				   rdmacg_resource_names[i],
704 				   rpool ? rpool->events_max[i] : 0ULL,
705 				   rdmacg_resource_names[i],
706 				   rpool ? rpool->events_alloc_fail[i] : 0ULL);
707 			if (i < RDMACG_RESOURCE_MAX - 1)
708 				seq_putc(sf, ' ');
709 		}
710 		seq_putc(sf, '\n');
711 	}
712 
713 	mutex_unlock(&rdmacg_mutex);
714 	return 0;
715 }
716 
717 static int rdmacg_events_local_show(struct seq_file *sf, void *v)
718 {
719 	struct rdma_cgroup *cg = css_rdmacg(seq_css(sf));
720 	struct rdmacg_resource_pool *rpool;
721 	struct rdmacg_device *device;
722 	int i;
723 
724 	mutex_lock(&rdmacg_mutex);
725 
726 	list_for_each_entry(device, &rdmacg_devices, dev_node) {
727 		rpool = find_cg_rpool_locked(cg, device);
728 
729 		rdmacg_print_device_key(sf, device);
730 		for (i = 0; i < RDMACG_RESOURCE_MAX; i++) {
731 			seq_printf(sf, "%s.max=%llu %s.alloc_fail=%llu",
732 				   rdmacg_resource_names[i],
733 				   rpool ? rpool->events_local_max[i] : 0ULL,
734 				   rdmacg_resource_names[i],
735 				   rpool ? rpool->events_local_alloc_fail[i] : 0ULL);
736 			if (i < RDMACG_RESOURCE_MAX - 1)
737 				seq_putc(sf, ' ');
738 		}
739 		seq_putc(sf, '\n');
740 	}
741 
742 	mutex_unlock(&rdmacg_mutex);
743 	return 0;
744 }
745 
746 static struct cftype rdmacg_files[] = {
747 	{
748 		.name = "max",
749 		.write = rdmacg_resource_set_max,
750 		.seq_show = rdmacg_resource_read,
751 		.private = RDMACG_RESOURCE_TYPE_MAX,
752 		.flags = CFTYPE_NOT_ON_ROOT,
753 	},
754 	{
755 		.name = "current",
756 		.seq_show = rdmacg_resource_read,
757 		.private = RDMACG_RESOURCE_TYPE_STAT,
758 		.flags = CFTYPE_NOT_ON_ROOT,
759 	},
760 	{
761 		.name = "peak",
762 		.seq_show = rdmacg_resource_read,
763 		.private = RDMACG_RESOURCE_TYPE_PEAK,
764 		.flags = CFTYPE_NOT_ON_ROOT,
765 	},
766 	{
767 		.name = "events",
768 		.seq_show = rdmacg_events_show,
769 		.file_offset = offsetof(struct rdma_cgroup, events_file),
770 		.flags = CFTYPE_NOT_ON_ROOT,
771 	},
772 	{
773 		.name = "events.local",
774 		.seq_show = rdmacg_events_local_show,
775 		.file_offset = offsetof(struct rdma_cgroup, events_local_file),
776 		.flags = CFTYPE_NOT_ON_ROOT,
777 	},
778 	{ }	/* terminate */
779 };
780 
781 static struct cgroup_subsys_state *
782 rdmacg_css_alloc(struct cgroup_subsys_state *parent)
783 {
784 	struct rdma_cgroup *cg;
785 
786 	cg = kzalloc_obj(*cg);
787 	if (!cg)
788 		return ERR_PTR(-ENOMEM);
789 
790 	INIT_LIST_HEAD(&cg->rpools);
791 	return &cg->css;
792 }
793 
794 static void rdmacg_css_free(struct cgroup_subsys_state *css)
795 {
796 	struct rdma_cgroup *cg = css_rdmacg(css);
797 	struct rdmacg_resource_pool *rpool, *tmp;
798 
799 	/* Clean up rpools kept alive by non-zero peak values */
800 	mutex_lock(&rdmacg_mutex);
801 	list_for_each_entry_safe(rpool, tmp, &cg->rpools, cg_node)
802 		free_cg_rpool_locked(rpool);
803 	mutex_unlock(&rdmacg_mutex);
804 
805 	kfree(cg);
806 }
807 
808 /**
809  * rdmacg_css_offline - cgroup css_offline callback
810  * @css: css of interest
811  *
812  * This function is called when @css is about to go away and responsible
813  * for shooting down all rdmacg associated with @css. As part of that it
814  * marks all the resource pool entries to max value, so that when resources are
815  * uncharged, associated resource pool can be freed as well.
816  */
817 static void rdmacg_css_offline(struct cgroup_subsys_state *css)
818 {
819 	struct rdma_cgroup *cg = css_rdmacg(css);
820 	struct rdmacg_resource_pool *rpool;
821 
822 	mutex_lock(&rdmacg_mutex);
823 
824 	list_for_each_entry(rpool, &cg->rpools, cg_node)
825 		set_all_resource_max_limit(rpool);
826 
827 	mutex_unlock(&rdmacg_mutex);
828 }
829 
830 struct cgroup_subsys rdma_cgrp_subsys = {
831 	.css_alloc	= rdmacg_css_alloc,
832 	.css_free	= rdmacg_css_free,
833 	.css_offline	= rdmacg_css_offline,
834 	.legacy_cftypes	= rdmacg_files,
835 	.dfl_cftypes	= rdmacg_files,
836 };
837