From f3419807716be503c06f399b2bcbc68823be3a78 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 12 Sep 2012 16:12:01 +0200 Subject: cgroup: net_cls: Move sock_update_classid() declaration to cls_cgroup.h The only user of sock_update_classid() is net/socket.c which happens to include cls_cgroup.h directly. tj: Fix build breakage due to missing cls_cgroup.h inclusion in drivers/net/tun.c reported in linux-next by Stephen. Signed-off-by: Daniel Wagner Signed-off-by: Tejun Heo Acked-by: Li Zefan Acked-by: Neil Horman Reported-by: Stephen Rothwell Cc: Gao feng Cc: Jamal Hadi Salim Cc: John Fastabend Cc: netdev@vger.kernel.org Cc: cgroups@vger.kernel.org --- include/net/cls_cgroup.h | 6 ++++++ include/net/sock.h | 8 -------- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'include/net') diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h index a4dc5b027bd9..e88527a68454 100644 --- a/include/net/cls_cgroup.h +++ b/include/net/cls_cgroup.h @@ -24,6 +24,8 @@ struct cgroup_cls_state u32 classid; }; +extern void sock_update_classid(struct sock *sk); + #ifdef CONFIG_NET_CLS_CGROUP static inline u32 task_cls_classid(struct task_struct *p) { @@ -62,6 +64,10 @@ static inline u32 task_cls_classid(struct task_struct *p) } #endif #else +static inline void sock_update_classid(struct sock *sk) +{ +} + static inline u32 task_cls_classid(struct task_struct *p) { return 0; diff --git a/include/net/sock.h b/include/net/sock.h index 72132aef53fc..160a68093dbc 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1486,14 +1486,6 @@ extern void *sock_kmalloc(struct sock *sk, int size, extern void sock_kfree_s(struct sock *sk, void *mem, int size); extern void sk_send_sigurg(struct sock *sk); -#ifdef CONFIG_CGROUPS -extern void sock_update_classid(struct sock *sk); -#else -static inline void sock_update_classid(struct sock *sk) -{ -} -#endif - /* * Functions to fill in entries in struct proto_ops when a protocol * does not implement a particular function. -- cgit v1.2.3 From 8fb974c937570be38f944986456467b39a2dc252 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 12 Sep 2012 16:12:02 +0200 Subject: cgroup: net_cls: Do not define task_cls_classid() when not selected task_cls_classid() should not be defined in case the configuration is CONFIG_NET_CLS_CGROUP=n. The reason is that in a following patch the net_cls_subsys_id will only be defined if CONFIG_NET_CLS_CGROUP!=n. When net_cls is not built at all a callee should only get an empty task_cls_classid() without any references to net_cls_subsys_id. Signed-off-by: Daniel Wagner Signed-off-by: Tejun Heo Acked-by: Li Zefan Acked-by: Neil Horman Cc: Gao feng Cc: Jamal Hadi Salim Cc: John Fastabend Cc: netdev@vger.kernel.org Cc: cgroups@vger.kernel.org --- include/net/cls_cgroup.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'include/net') diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h index e88527a68454..9bd5db9e10ba 100644 --- a/include/net/cls_cgroup.h +++ b/include/net/cls_cgroup.h @@ -17,7 +17,7 @@ #include #include -#ifdef CONFIG_CGROUPS +#if IS_ENABLED(CONFIG_NET_CLS_CGROUP) struct cgroup_cls_state { struct cgroup_subsys_state css; @@ -26,7 +26,7 @@ struct cgroup_cls_state extern void sock_update_classid(struct sock *sk); -#ifdef CONFIG_NET_CLS_CGROUP +#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP) static inline u32 task_cls_classid(struct task_struct *p) { int classid; @@ -41,7 +41,8 @@ static inline u32 task_cls_classid(struct task_struct *p) return classid; } -#else +#elif IS_MODULE(CONFIG_NET_CLS_CGROUP) + extern int net_cls_subsys_id; static inline u32 task_cls_classid(struct task_struct *p) @@ -63,7 +64,7 @@ static inline u32 task_cls_classid(struct task_struct *p) return classid; } #endif -#else +#else /* !CGROUP_NET_CLS_CGROUP */ static inline void sock_update_classid(struct sock *sk) { } @@ -72,5 +73,5 @@ static inline u32 task_cls_classid(struct task_struct *p) { return 0; } -#endif +#endif /* CGROUP_NET_CLS_CGROUP */ #endif /* _NET_CLS_CGROUP_H */ -- cgit v1.2.3 From 51e4e7faba786d33e5e33f8776c5027a1c8d6fb7 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 12 Sep 2012 16:12:03 +0200 Subject: cgroup: net_prio: Do not define task_netpioidx() when not selected task_netprioidx() should not be defined in case the configuration is CONFIG_NETPRIO_CGROUP=n. The reason is that in a following patch the net_prio_subsys_id will only be defined if CONFIG_NETPRIO_CGROUP!=n. When net_prio is not built at all any callee should only get an empty task_netprioidx() without any references to net_prio_subsys_id. Signed-off-by: Daniel Wagner Signed-off-by: Tejun Heo Acked-by: Li Zefan Acked-by: Neil Horman Cc: Gao feng Cc: Jamal Hadi Salim Cc: John Fastabend Cc: netdev@vger.kernel.org Cc: cgroups@vger.kernel.org --- include/net/netprio_cgroup.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'include/net') diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h index 2719dec6b5a8..b202de882489 100644 --- a/include/net/netprio_cgroup.h +++ b/include/net/netprio_cgroup.h @@ -18,14 +18,13 @@ #include +#if IS_ENABLED(CONFIG_NETPRIO_CGROUP) struct netprio_map { struct rcu_head rcu; u32 priomap_len; u32 priomap[]; }; -#ifdef CONFIG_CGROUPS - struct cgroup_netprio_state { struct cgroup_subsys_state css; u32 prioidx; @@ -71,18 +70,17 @@ static inline u32 task_netprioidx(struct task_struct *p) rcu_read_unlock(); return idx; } +#endif -#else +#else /* !CONFIG_NETPRIO_CGROUP */ static inline u32 task_netprioidx(struct task_struct *p) { return 0; } -#endif /* CONFIG_NETPRIO_CGROUP */ - -#else #define sock_update_netprioidx(sk, task) -#endif + +#endif /* CONFIG_NETPRIO_CGROUP */ #endif /* _NET_CLS_CGROUP_H */ -- cgit v1.2.3 From 8a8e04df4747661daaee77e98e102d99c9e09b98 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 12 Sep 2012 16:12:07 +0200 Subject: cgroup: Assign subsystem IDs during compile time WARNING: With this change it is impossible to load external built controllers anymore. In case where CONFIG_NETPRIO_CGROUP=m and CONFIG_NET_CLS_CGROUP=m is set, corresponding subsys_id should also be a constant. Up to now, net_prio_subsys_id and net_cls_subsys_id would be of the type int and the value would be assigned during runtime. By switching the macro definition IS_SUBSYS_ENABLED from IS_BUILTIN to IS_ENABLED, all *_subsys_id will have constant value. That means we need to remove all the code which assumes a value can be assigned to net_prio_subsys_id and net_cls_subsys_id. A close look is necessary on the RCU part which was introduces by following patch: commit f845172531fb7410c7fb7780b1a6e51ee6df7d52 Author: Herbert Xu Mon May 24 09:12:34 2010 Committer: David S. Miller Mon May 24 09:12:34 2010 cls_cgroup: Store classid in struct sock Tis code was added to init_cgroup_cls() /* We can't use rcu_assign_pointer because this is an int. */ smp_wmb(); net_cls_subsys_id = net_cls_subsys.subsys_id; respectively to exit_cgroup_cls() net_cls_subsys_id = -1; synchronize_rcu(); and in module version of task_cls_classid() rcu_read_lock(); id = rcu_dereference(net_cls_subsys_id); if (id >= 0) classid = container_of(task_subsys_state(p, id), struct cgroup_cls_state, css)->classid; rcu_read_unlock(); Without an explicit explaination why the RCU part is needed. (The rcu_deference was fixed by exchanging it to rcu_derefence_index_check() in a later commit, but that is a minor detail.) So here is my pondering why it was introduced and why it safe to remove it now. Note that this code was copied over to net_prio the reasoning holds for that subsystem too. The idea behind the RCU use for net_cls_subsys_id is to make sure we get a valid pointer back from task_subsys_state(). task_subsys_state() is just blindly accessing the subsys array and returning the pointer. Obviously, passing in -1 as id into task_subsys_state() returns an invalid value (out of lower bound). So this code makes sure that only after module is loaded and the subsystem registered, the id is assigned. Before unregistering the module all old readers must have left the critical section. This is done by assigning -1 to the id and issuing a synchronized_rcu(). Any new readers wont call task_subsys_state() anymore and therefore it is safe to unregister the subsystem. The new code relies on the same trick, but it looks at the subsys pointer return by task_subsys_state() (remember the id is constant and therefore we allways have a valid index into the subsys array). No precautions need to be taken during module loading module. Eventually, all CPUs will get a valid pointer back from task_subsys_state() because rebind_subsystem() which is called after the module init() function will assigned subsys[net_cls_subsys_id] the newly loaded module subsystem pointer. When the subsystem is about to be removed, rebind_subsystem() will called before the module exit() function. In this case, rebind_subsys() will assign subsys[net_cls_subsys_id] a NULL pointer and then it calls synchronize_rcu(). All old readers have left by then the critical section. Any new reader wont access the subsystem anymore. At this point we are safe to unregister the subsystem. No synchronize_rcu() call is needed. Signed-off-by: Daniel Wagner Signed-off-by: Tejun Heo Acked-by: Li Zefan Acked-by: Neil Horman Cc: "David S. Miller" Cc: "Paul E. McKenney" Cc: Andrew Morton Cc: Eric Dumazet Cc: Gao feng Cc: Glauber Costa Cc: Herbert Xu Cc: Jamal Hadi Salim Cc: John Fastabend Cc: Kamezawa Hiroyuki Cc: netdev@vger.kernel.org Cc: cgroups@vger.kernel.org --- include/net/cls_cgroup.h | 12 ++++-------- include/net/netprio_cgroup.h | 18 +++++------------- 2 files changed, 9 insertions(+), 21 deletions(-) (limited to 'include/net') diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h index 9bd5db9e10ba..b6a6eeb3905f 100644 --- a/include/net/cls_cgroup.h +++ b/include/net/cls_cgroup.h @@ -42,22 +42,18 @@ static inline u32 task_cls_classid(struct task_struct *p) return classid; } #elif IS_MODULE(CONFIG_NET_CLS_CGROUP) - -extern int net_cls_subsys_id; - static inline u32 task_cls_classid(struct task_struct *p) { - int id; + struct cgroup_subsys_state *css; u32 classid = 0; if (in_interrupt()) return 0; rcu_read_lock(); - id = rcu_dereference_index_check(net_cls_subsys_id, - rcu_read_lock_held()); - if (id >= 0) - classid = container_of(task_subsys_state(p, id), + css = task_subsys_state(p, net_cls_subsys_id); + if (css) + classid = container_of(css, struct cgroup_cls_state, css)->classid; rcu_read_unlock(); diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h index b202de882489..2760f4f4ae9b 100644 --- a/include/net/netprio_cgroup.h +++ b/include/net/netprio_cgroup.h @@ -30,10 +30,6 @@ struct cgroup_netprio_state { u32 prioidx; }; -#ifndef CONFIG_NETPRIO_CGROUP -extern int net_prio_subsys_id; -#endif - extern void sock_update_netprioidx(struct sock *sk, struct task_struct *task); #if IS_BUILTIN(CONFIG_NETPRIO_CGROUP) @@ -55,18 +51,14 @@ static inline u32 task_netprioidx(struct task_struct *p) static inline u32 task_netprioidx(struct task_struct *p) { - struct cgroup_netprio_state *state; - int subsys_id; + struct cgroup_subsys_state *css; u32 idx = 0; rcu_read_lock(); - subsys_id = rcu_dereference_index_check(net_prio_subsys_id, - rcu_read_lock_held()); - if (subsys_id >= 0) { - state = container_of(task_subsys_state(p, subsys_id), - struct cgroup_netprio_state, css); - idx = state->prioidx; - } + css = task_subsys_state(p, net_prio_subsys_id); + if (css) + idx = container_of(css, + struct cgroup_netprio_state, css)->prioidx; rcu_read_unlock(); return idx; } -- cgit v1.2.3