12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/types.h>
17 #include <linux/string.h>
18 #include <linux/errno.h>
30 #define PRIOIDX_SZ 128
36 static inline struct cgroup_netprio_state *cgrp_netprio_state(
struct cgroup *cgrp)
38 return container_of(cgroup_subsys_state(cgrp, net_prio_subsys_id),
39 struct cgroup_netprio_state, css);
42 static int get_prioidx(
u32 *
prio)
49 if (prioidx ==
sizeof(
unsigned long) *
PRIOIDX_SZ) {
50 spin_unlock_irqrestore(&prioidx_map_lock, flags);
56 spin_unlock_irqrestore(&prioidx_map_lock, flags);
61 static void put_prioidx(
u32 idx)
67 spin_unlock_irqrestore(&prioidx_map_lock, flags);
72 size_t new_size =
sizeof(
struct netprio_map) +
74 struct netprio_map *new_priomap = kzalloc(new_size,
GFP_KERNEL);
75 struct netprio_map *old_priomap;
80 pr_warn(
"Unable to alloc new priomap!\n");
85 memcpy(new_priomap->priomap, old_priomap->priomap,
86 old_priomap->priomap_len *
87 sizeof(old_priomap->priomap[0]));
89 new_priomap->priomap_len = new_len;
97 static int write_update_netdev_table(
struct net_device *dev)
101 struct netprio_map *
map;
105 if (!map || map->priomap_len < max_len)
106 ret = extend_netdev_table(dev, max_len);
111 static struct cgroup_subsys_state *cgrp_create(
struct cgroup *cgrp)
113 struct cgroup_netprio_state *
cs;
120 if (cgrp->parent && cgrp_netprio_state(cgrp->parent)->prioidx)
123 ret = get_prioidx(&cs->prioidx);
125 pr_warn(
"No space in priority index array\n");
135 static void cgrp_destroy(
struct cgroup *cgrp)
137 struct cgroup_netprio_state *
cs;
139 struct netprio_map *
map;
141 cs = cgrp_netprio_state(cgrp);
145 if (map && cs->prioidx < map->priomap_len)
146 map->priomap[cs->prioidx] = 0;
149 put_prioidx(cs->prioidx);
153 static u64 read_prioidx(
struct cgroup *cgrp,
struct cftype *cft)
155 return (
u64)cgrp_netprio_state(cgrp)->prioidx;
158 static int read_priomap(
struct cgroup *
cont,
struct cftype *cft,
159 struct cgroup_map_cb *
cb)
162 u32 prioidx = cgrp_netprio_state(cont)->prioidx;
164 struct netprio_map *
map;
169 priority = (map && prioidx < map->priomap_len) ? map->priomap[prioidx] : 0;
170 cb->fill(cb, dev->
name, priority);
176 static int write_priomap(
struct cgroup *cgrp,
struct cftype *cft,
181 u32 prioidx = cgrp_netprio_state(cgrp)->prioidx;
185 struct netprio_map *
map;
194 goto out_free_devname;
196 priostr =
strstr(devname,
" ");
198 goto out_free_devname;
211 if (*priostr ==
'\0')
212 goto out_free_devname;
214 ret = kstrtoul(priostr, 10, &priority);
216 goto out_free_devname;
222 goto out_free_devname;
225 ret = write_update_netdev_table(dev);
242 static int update_netprio(
const void *
v,
struct file *
file,
unsigned n)
247 sock->
sk->sk_cgrp_prioidx = (
u32)(
unsigned long)
v;
256 cgroup_taskset_for_each(p, cgrp, tset) {
258 v = (
void *)(
unsigned long)task_netprioidx(p);
264 static struct cftype ss_files[] = {
267 .read_u64 = read_prioidx,
271 .read_map = read_priomap,
272 .write_string = write_priomap,
279 .create = cgrp_create,
280 .destroy = cgrp_destroy,
282 .subsys_id = net_prio_subsys_id,
283 .base_cftypes = ss_files,
294 .broken_hierarchy =
true,
301 struct netprio_map *old;
320 .notifier_call = netprio_device_event
323 static int __init init_cgroup_netprio(
void)
337 static void __exit exit_cgroup_netprio(
void)
339 struct netprio_map *old;