mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC 0/4] reduce pid_namespace footprint when not configured
@ 2015-09-30 20:49 Rasmus Villemoes
  2015-09-30 20:49 ` [RFC 1/4] pid_namespace: remove ->level and ->parent for !CONFIG_PID_NS Rasmus Villemoes
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Rasmus Villemoes @ 2015-09-30 20:49 UTC (permalink / raw)
  To: Eric W. Biederman, Oleg Nesterov; +Cc: Rasmus Villemoes, linux-kernel

A few suggestions for reducing the footprint of pid namespaces when
CONFIG_PID_NS=n. The savings are admittedly not huge:

$ scripts/bloat-o-meter /tmp/vmlinux.master vmlinux
add/remove: 0/7 grow/shrink: 30/25 up/down: 368/-1032 (-664)

Rasmus Villemoes (4):
  pid_namespace: remove ->level and ->parent for !CONFIG_PID_NS
  pid_namespace: remove .kref field for !CONFIG_PID_NS
  pid_namespace: make pid_nr_ns and pid_vnr static inlines for
    !CONFIG_PID_NS
  pid_namespace: disable_pid_allocation is unused for !CONFIG_PID_NS

 include/linux/pid.h           | 11 +++++++++++
 include/linux/pid_namespace.h | 20 ++++++++++++++++++++
 kernel/acct.c                 |  4 ++--
 kernel/pid.c                  | 24 +++++++++++++++---------
 4 files changed, 48 insertions(+), 11 deletions(-)

-- 
2.1.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC 1/4] pid_namespace: remove ->level and ->parent for !CONFIG_PID_NS
  2015-09-30 20:49 [RFC 0/4] reduce pid_namespace footprint when not configured Rasmus Villemoes
@ 2015-09-30 20:49 ` Rasmus Villemoes
  2015-09-30 20:49 ` [RFC 2/4] pid_namespace: remove .kref field " Rasmus Villemoes
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Rasmus Villemoes @ 2015-09-30 20:49 UTC (permalink / raw)
  To: Eric W. Biederman, Oleg Nesterov; +Cc: Rasmus Villemoes, linux-kernel

When !CONFIG_PID_NS, there is only ever one struct pid_namespace, and
for that we know that ->parent is NULL and ->level is 0. Telling the
compiler that allows it to generate slightly smaller code.

Removing the members from struct pid_namespace only saves a few bytes,
but it also helps ensure that everyone outside kernel/pid_namespace.c
use the new accessors pid_ns_{parent,level}.

Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
 include/linux/pid_namespace.h | 18 ++++++++++++++++++
 kernel/acct.c                 |  4 ++--
 kernel/pid.c                  | 18 +++++++++---------
 3 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index 918b117a7cd3..03a84a0cdc75 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -29,8 +29,10 @@ struct pid_namespace {
 	unsigned int nr_hashed;
 	struct task_struct *child_reaper;
 	struct kmem_cache *pid_cachep;
+#ifdef CONFIG_PID_NS
 	unsigned int level;
 	struct pid_namespace *parent;
+#endif
 #ifdef CONFIG_PROC_FS
 	struct vfsmount *proc_mnt;
 	struct dentry *proc_self;
@@ -58,6 +60,14 @@ static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
 		kref_get(&ns->kref);
 	return ns;
 }
+static inline struct pid_namespace *pid_ns_parent(struct pid_namespace *ns)
+{
+	return ns->parent;
+}
+static inline int pid_ns_level(struct pid_namespace *ns)
+{
+	return ns->level;
+}
 
 extern struct pid_namespace *copy_pid_ns(unsigned long flags,
 	struct user_namespace *user_ns, struct pid_namespace *ns);
@@ -72,6 +82,14 @@ static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
 {
 	return ns;
 }
+static inline struct pid_namespace *pid_ns_parent(struct pid_namespace *ns)
+{
+	return NULL;
+}
+static inline int pid_ns_level(struct pid_namespace *ns)
+{
+	return 0;
+}
 
 static inline struct pid_namespace *copy_pid_ns(unsigned long flags,
 	struct user_namespace *user_ns, struct pid_namespace *ns)
diff --git a/kernel/acct.c b/kernel/acct.c
index 74963d192c5d..43e570feea45 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -569,7 +569,7 @@ void acct_collect(long exitcode, int group_dead)
 
 static void slow_acct_process(struct pid_namespace *ns)
 {
-	for ( ; ns; ns = ns->parent) {
+	for ( ; ns; ns = pid_ns_parent(ns)) {
 		struct bsd_acct_struct *acct = acct_get(ns);
 		if (acct) {
 			do_acct_process(acct);
@@ -593,7 +593,7 @@ void acct_process(void)
 	 * alive and holds its namespace, which in turn holds
 	 * its parent.
 	 */
-	for (ns = task_active_pid_ns(current); ns != NULL; ns = ns->parent) {
+	for (ns = task_active_pid_ns(current); ns != NULL; ns = pid_ns_parent(ns)) {
 		if (ns->bacct)
 			break;
 	}
diff --git a/kernel/pid.c b/kernel/pid.c
index ca368793808e..909d3dcd8085 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -76,12 +76,12 @@ struct pid_namespace init_pid_ns = {
 	},
 	.last_pid = 0,
 	.nr_hashed = PIDNS_HASH_ADDING,
-	.level = 0,
 	.child_reaper = &init_task,
 	.user_ns = &init_user_ns,
 	.ns.inum = PROC_PID_INIT_INO,
 #ifdef CONFIG_PID_NS
 	.ns.ops = &pidns_operations,
+	.level = 0,
 #endif
 };
 EXPORT_SYMBOL_GPL(init_pid_ns);
@@ -308,8 +308,8 @@ struct pid *alloc_pid(struct pid_namespace *ns)
 		return ERR_PTR(retval);
 
 	tmp = ns;
-	pid->level = ns->level;
-	for (i = ns->level; i >= 0; i--) {
+	pid->level = pid_ns_level(ns);
+	for (i = pid_ns_level(ns); i >= 0; i--) {
 		nr = alloc_pidmap(tmp);
 		if (IS_ERR_VALUE(nr)) {
 			retval = nr;
@@ -318,7 +318,7 @@ struct pid *alloc_pid(struct pid_namespace *ns)
 
 		pid->numbers[i].nr = nr;
 		pid->numbers[i].ns = tmp;
-		tmp = tmp->parent;
+		tmp = pid_ns_parent(tmp);
 	}
 
 	if (unlikely(is_child_reaper(pid))) {
@@ -331,7 +331,7 @@ struct pid *alloc_pid(struct pid_namespace *ns)
 	for (type = 0; type < PIDTYPE_MAX; ++type)
 		INIT_HLIST_HEAD(&pid->tasks[type]);
 
-	upid = pid->numbers + ns->level;
+	upid = pid->numbers + pid_ns_level(ns);
 	spin_lock_irq(&pidmap_lock);
 	if (!(ns->nr_hashed & PIDNS_HASH_ADDING))
 		goto out_unlock;
@@ -349,7 +349,7 @@ out_unlock:
 	put_pid_ns(ns);
 
 out_free:
-	while (++i <= ns->level)
+	while (++i <= pid_ns_level(ns))
 		free_pidmap(pid->numbers + i);
 
 	kmem_cache_free(ns->pid_cachep, pid);
@@ -371,7 +371,7 @@ struct pid *find_pid_ns(int nr, struct pid_namespace *ns)
 			&pid_hash[pid_hashfn(nr, ns)], pid_chain)
 		if (pnr->nr == nr && pnr->ns == ns)
 			return container_of(pnr, struct pid,
-					numbers[ns->level]);
+					numbers[pid_ns_level(ns)]);
 
 	return NULL;
 }
@@ -502,8 +502,8 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
 	struct upid *upid;
 	pid_t nr = 0;
 
-	if (pid && ns->level <= pid->level) {
-		upid = &pid->numbers[ns->level];
+	if (pid && pid_ns_level(ns) <= pid->level) {
+		upid = &pid->numbers[pid_ns_level(ns)];
 		if (upid->ns == ns)
 			nr = upid->nr;
 	}
-- 
2.1.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC 2/4] pid_namespace: remove .kref field for !CONFIG_PID_NS
  2015-09-30 20:49 [RFC 0/4] reduce pid_namespace footprint when not configured Rasmus Villemoes
  2015-09-30 20:49 ` [RFC 1/4] pid_namespace: remove ->level and ->parent for !CONFIG_PID_NS Rasmus Villemoes
@ 2015-09-30 20:49 ` Rasmus Villemoes
  2015-09-30 20:49 ` [RFC 3/4] pid_namespace: make pid_nr_ns and pid_vnr static inlines " Rasmus Villemoes
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Rasmus Villemoes @ 2015-09-30 20:49 UTC (permalink / raw)
  To: Eric W. Biederman, Oleg Nesterov; +Cc: Rasmus Villemoes, linux-kernel

When there's only one global pid_namespace (init_pid_ns), the kref
field is unused (since both get_pid_ns and put_pid_ns are
no-ops). While we only save a few bytes by removing it, it could also
help catch users manipulating ->kref directly.

Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
 include/linux/pid_namespace.h | 2 ++
 kernel/pid.c                  | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index 03a84a0cdc75..1cac17eb0775 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -22,7 +22,9 @@ struct pidmap {
 struct fs_pin;
 
 struct pid_namespace {
+#ifdef CONFIG_PID_NS
 	struct kref kref;
+#endif
 	struct pidmap pidmap[PIDMAP_ENTRIES];
 	struct rcu_head rcu;
 	int last_pid;
diff --git a/kernel/pid.c b/kernel/pid.c
index 909d3dcd8085..25332679a4d3 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -68,9 +68,11 @@ static inline int mk_pid(struct pid_namespace *pid_ns,
  * the scheme scales to up to 4 million PIDs, runtime.
  */
 struct pid_namespace init_pid_ns = {
+#ifdef CONFIG_PID_NS
 	.kref = {
 		.refcount       = ATOMIC_INIT(2),
 	},
+#endif
 	.pidmap = {
 		[ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL }
 	},
-- 
2.1.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC 3/4] pid_namespace: make pid_nr_ns and pid_vnr static inlines for !CONFIG_PID_NS
  2015-09-30 20:49 [RFC 0/4] reduce pid_namespace footprint when not configured Rasmus Villemoes
  2015-09-30 20:49 ` [RFC 1/4] pid_namespace: remove ->level and ->parent for !CONFIG_PID_NS Rasmus Villemoes
  2015-09-30 20:49 ` [RFC 2/4] pid_namespace: remove .kref field " Rasmus Villemoes
@ 2015-09-30 20:49 ` Rasmus Villemoes
  2015-09-30 20:49 ` [RFC 4/4] pid_namespace: disable_pid_allocation is unused " Rasmus Villemoes
  2015-09-30 21:00 ` [RFC 0/4] reduce pid_namespace footprint when not configured Eric W. Biederman
  4 siblings, 0 replies; 7+ messages in thread
From: Rasmus Villemoes @ 2015-09-30 20:49 UTC (permalink / raw)
  To: Eric W. Biederman, Oleg Nesterov; +Cc: Rasmus Villemoes, linux-kernel

When there is only a single pid namespace, pid_nr_ns and pid_vnr
perform the same task as pid_nr, so we can save a little .text by
making them simple inlines.

Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
 include/linux/pid.h | 11 +++++++++++
 kernel/pid.c        |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/include/linux/pid.h b/include/linux/pid.h
index 23705a53abba..9aba74a90a64 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -169,8 +169,19 @@ static inline pid_t pid_nr(struct pid *pid)
 	return nr;
 }
 
+#ifdef CONFIG_PID_NS
 pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
 pid_t pid_vnr(struct pid *pid);
+#else
+static inline pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
+{
+	return pid_nr(pid);
+}
+static inline pid_t pid_vnr(struct pid *pid)
+{
+	return pid_nr(pid);
+}
+#endif
 
 #define do_each_pid_task(pid, type, task)				\
 	do {								\
diff --git a/kernel/pid.c b/kernel/pid.c
index 25332679a4d3..d422ddae0484 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -499,6 +499,7 @@ struct pid *find_get_pid(pid_t nr)
 }
 EXPORT_SYMBOL_GPL(find_get_pid);
 
+#ifdef CONFIG_PID_NS
 pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
 {
 	struct upid *upid;
@@ -518,6 +519,7 @@ pid_t pid_vnr(struct pid *pid)
 	return pid_nr_ns(pid, task_active_pid_ns(current));
 }
 EXPORT_SYMBOL_GPL(pid_vnr);
+#endif
 
 pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
 			struct pid_namespace *ns)
-- 
2.1.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC 4/4] pid_namespace: disable_pid_allocation is unused for !CONFIG_PID_NS
  2015-09-30 20:49 [RFC 0/4] reduce pid_namespace footprint when not configured Rasmus Villemoes
                   ` (2 preceding siblings ...)
  2015-09-30 20:49 ` [RFC 3/4] pid_namespace: make pid_nr_ns and pid_vnr static inlines " Rasmus Villemoes
@ 2015-09-30 20:49 ` Rasmus Villemoes
  2015-09-30 21:00 ` [RFC 0/4] reduce pid_namespace footprint when not configured Eric W. Biederman
  4 siblings, 0 replies; 7+ messages in thread
From: Rasmus Villemoes @ 2015-09-30 20:49 UTC (permalink / raw)
  To: Eric W. Biederman, Oleg Nesterov; +Cc: Rasmus Villemoes, linux-kernel

disable_pid_allocation only has a single caller, in
kernel/pid_namespace.c, so when CONFIG_PID_NS=n we don't need it. I
don't think we need to #ifdef the declaration away, since we'll just
fail at link time rather than compile time, should
disable_pid_allocation ever grow a caller outside pid_namespace.c.

Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
 kernel/pid.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/pid.c b/kernel/pid.c
index d422ddae0484..c9b595517c4f 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -358,12 +358,14 @@ out_free:
 	return ERR_PTR(retval);
 }
 
+#ifdef CONFIG_PID_NS
 void disable_pid_allocation(struct pid_namespace *ns)
 {
 	spin_lock_irq(&pidmap_lock);
 	ns->nr_hashed &= ~PIDNS_HASH_ADDING;
 	spin_unlock_irq(&pidmap_lock);
 }
+#endif
 
 struct pid *find_pid_ns(int nr, struct pid_namespace *ns)
 {
-- 
2.1.3


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC 0/4] reduce pid_namespace footprint when not configured
  2015-09-30 20:49 [RFC 0/4] reduce pid_namespace footprint when not configured Rasmus Villemoes
                   ` (3 preceding siblings ...)
  2015-09-30 20:49 ` [RFC 4/4] pid_namespace: disable_pid_allocation is unused " Rasmus Villemoes
@ 2015-09-30 21:00 ` Eric W. Biederman
  2015-09-30 21:34   ` Rasmus Villemoes
  4 siblings, 1 reply; 7+ messages in thread
From: Eric W. Biederman @ 2015-09-30 21:00 UTC (permalink / raw)
  To: Rasmus Villemoes; +Cc: Oleg Nesterov, linux-kernel, Linux Containers

Rasmus Villemoes <linux@rasmusvillemoes.dk> writes:

> A few suggestions for reducing the footprint of pid namespaces when
> CONFIG_PID_NS=n. The savings are admittedly not huge:
>
> $ scripts/bloat-o-meter /tmp/vmlinux.master vmlinux
> add/remove: 0/7 grow/shrink: 30/25 up/down: 368/-1032 (-664)

#ifdefs in C files.
More code to maintain.
Very minor savings.

I don't think it is worth the pain.  If anything I would prefer to
remove CONFIG_PID_NS.  The CONFIG_PID_NS ifdef really is about keeping
from exposing people to the feature tha don't use it more than it is
about size reduction.

Or do you have a case where this makes the difference between a usable
kernel and a kernel that is not?

Eric


> Rasmus Villemoes (4):
>   pid_namespace: remove ->level and ->parent for !CONFIG_PID_NS
>   pid_namespace: remove .kref field for !CONFIG_PID_NS
>   pid_namespace: make pid_nr_ns and pid_vnr static inlines for
>     !CONFIG_PID_NS
>   pid_namespace: disable_pid_allocation is unused for !CONFIG_PID_NS
>
>  include/linux/pid.h           | 11 +++++++++++
>  include/linux/pid_namespace.h | 20 ++++++++++++++++++++
>  kernel/acct.c                 |  4 ++--
>  kernel/pid.c                  | 24 +++++++++++++++---------
>  4 files changed, 48 insertions(+), 11 deletions(-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC 0/4] reduce pid_namespace footprint when not configured
  2015-09-30 21:00 ` [RFC 0/4] reduce pid_namespace footprint when not configured Eric W. Biederman
@ 2015-09-30 21:34   ` Rasmus Villemoes
  0 siblings, 0 replies; 7+ messages in thread
From: Rasmus Villemoes @ 2015-09-30 21:34 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: Oleg Nesterov, linux-kernel, Linux Containers

On Wed, Sep 30 2015, ebiederm@xmission.com (Eric W. Biederman) wrote:

> Rasmus Villemoes <linux@rasmusvillemoes.dk> writes:
>
>> A few suggestions for reducing the footprint of pid namespaces when
>> CONFIG_PID_NS=n. The savings are admittedly not huge:
>>
>> $ scripts/bloat-o-meter /tmp/vmlinux.master vmlinux
>> add/remove: 0/7 grow/shrink: 30/25 up/down: 368/-1032 (-664)
>
> #ifdefs in C files.
> More code to maintain.
> Very minor savings.
>
> I don't think it is worth the pain.  If anything I would prefer to
> remove CONFIG_PID_NS.  The CONFIG_PID_NS ifdef really is about keeping
> from exposing people to the feature tha don't use it more than it is
> about size reduction.
>
> Or do you have a case where this makes the difference between a usable
> kernel and a kernel that is not?

No, it was mostly a small tinification effort, and we'd presumably also
save a few cycles on thread creation, but not anything measurable.

Rasmus


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-09-30 21:34 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-30 20:49 [RFC 0/4] reduce pid_namespace footprint when not configured Rasmus Villemoes
2015-09-30 20:49 ` [RFC 1/4] pid_namespace: remove ->level and ->parent for !CONFIG_PID_NS Rasmus Villemoes
2015-09-30 20:49 ` [RFC 2/4] pid_namespace: remove .kref field " Rasmus Villemoes
2015-09-30 20:49 ` [RFC 3/4] pid_namespace: make pid_nr_ns and pid_vnr static inlines " Rasmus Villemoes
2015-09-30 20:49 ` [RFC 4/4] pid_namespace: disable_pid_allocation is unused " Rasmus Villemoes
2015-09-30 21:00 ` [RFC 0/4] reduce pid_namespace footprint when not configured Eric W. Biederman
2015-09-30 21:34   ` Rasmus Villemoes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome