Replace PID bitmap allocation with IDR API
Subsystems (8)
v2 cover Replace PID bitmap allocation with IDR API
This patch series replaces kernel bitmap implementation of PID allocation
with IDR API. These patches are written to simplify the kernel by replacing custom code with calls to generic code.
The following are the stats for pid and pid_namespace object files before and after the replacement. There is a noteworthy change between the IDR and bitmap implementation.
Before
text data bss dec hex filename
8447 3894 64 12405 3075 kernel/pid.o
After
text data bss dec hex filename
3301 304 0 3605 e15 kernel/pid.o
Before
text data bss dec hex filename
5692 1842 192 7726 1e2e kernel/pid_namespace.o
After
text data bss dec hex filename
2870 216 16 3102 c1e kernel/pid_namespace.o
There wasn't a considerable difference between the time required for allocation of PIDs to the processes.
---
Changes in v2:
- Removed redundant IDR function that was introduced in the previous patchset.
- Renamed PIDNS_HASH_ADDING
- Used idr_for_each_entry_continue()
- Used idr_find() to lookup pids
Gargi Sharma (2):
pid: Replace pid bitmap implementation with IDR API
pid: Remove pidhash
arch/powerpc/platforms/cell/spufs/sched.c | 2 +- fs/proc/loadavg.c | 2 +- include/linux/init_task.h | 1 - include/linux/pid.h | 2 - include/linux/pid_namespace.h | 18 +-- init/main.c | 3 +- kernel/fork.c | 2 +- kernel/pid.c | 239 +++++------------------------- kernel/pid_namespace.c | 54 +++---- 9 files changed, 68 insertions(+), 255 deletions(-)
Signature · 1 line
2.7.4
PATCH v2 1/2 pid: Replace pid bitmap implementation with IDR API
This patch replaces the current bitmap implemetation for Process ID allocation. Functions that are no longer required, for example, free_pidmap(), alloc_pidmap(), etc. are removed. The rest of the functions are modified to use the IDR API. The change was made to make the PID allocation less complex by replacing custom code with calls to generic API.
--- arch/powerpc/platforms/cell/spufs/sched.c | 2 +- fs/proc/loadavg.c | 2 +- include/linux/pid_namespace.h | 14 +-- init/main.c | 2 +- kernel/pid.c | 193 +++++------------------------- kernel/pid_namespace.c | 47 +++----- 6 files changed, 55 insertions(+), 205 deletions(-)
arch/powerpc/platforms/cell/spufs/sched.c +1 -1
@@ -1093,7 +1093,7 @@ static int show_spu_loadavg(struct seq_file *s, void *private)LOAD_INT (c),LOAD_FRAC (c),count_active_contexts (),atomic_read (&nr_spu_contexts), - task_active_pid_ns(current)->last_pid); + task_active_pid_ns(current)->idr.idr_next-1);return 0 ; }
fs/proc/loadavg.c +1 -1
@@ -23,7 +23,7 @@ static int loadavg_proc_show(struct seq_file *m, void *v)LOAD_INT (avnrun[1 ]),LOAD_FRAC (avnrun[1 ]),LOAD_INT (avnrun[2 ]),LOAD_FRAC (avnrun[2 ]),nr_running (), nr_threads, - task_active_pid_ns(current)->last_pid); + task_active_pid_ns(current)->idr.idr_next-1);return 0 ; }
include/linux/pid_namespace.h +3 -11
@@ -9,15 +9,8 @@#include <linux/nsproxy.h> #include <linux/kref.h> #include <linux/ns_common.h> +#include <linux/idr.h> -struct pidmap { -atomic_t nr_free; -void *page; -}; - -#define BITS_PER_PAGE (PAGE_SIZE * 8) -#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) -#define PIDMAP_ENTRIES ((PID_MAX_LIMIT+BITS_PER_PAGE-1)/BITS_PER_PAGE)struct fs_pin ;
@@ -29,9 +22,8 @@ enum { /* definitions for pid_namespace's hide_pid field */struct pid_namespace {struct kref kref; -struct pidmap pidmap[PIDMAP_ENTRIES ]; +struct idr idr;struct rcu_head rcu; -int last_pid;unsigned int nr_hashed;struct task_struct *child_reaper;struct kmem_cache *pid_cachep;
@@ -105,6 +97,6 @@ static inline int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd)extern struct pid_namespace *task_active_pid_ns (struct task_struct *tsk);void pidhash_init (void ); -void pidmap_init (void ); +void pid_idr_init (void );#endif /* _LINUX_PID_NS_H */
init/main.c +1 -1
@@ -667,7 +667,7 @@ asmlinkage __visible void __init start_kernel(void)if (late_time_init)late_time_init ();calibrate_delay (); -pidmap_init (); +pid_idr_init ();anon_vma_init ();acpi_early_init ();#ifdef CONFIG_X86
kernel/pid.c +30 -163
266 lines not on this page · raw message
kernel/pid_namespace.c +19 -28
111 lines not on this page · raw message
Signature · 1 line
2.7.4
Re: [PATCH v2 1/2] pid: Replace pid bitmap implementation with IDR API
Quoted 6 lines · Gargi Sharma
This patch replaces the current bitmap implemetation for Process ID allocation. Functions that are no longer required, for example,
free_pidmap(),alloc_pidmap(), etc. are removed. The rest of the functions are modified to use the IDR API. The change was made to make the PID allocation less complex by replacing custom code with calls to generic API.
I like where this is going. Just a few last comments from me :)
arch/powerpc/platforms/cell/spufs/sched.c static int show_spu_loadavg(struct seq_file *s, · line 1099
Quoted 11 lines
arch/powerpc/platforms/cell/spufs/sched.c +1
-1@@ -1093,7 +1093,7 @@ static int show_spu_loadavg(struct seq_file *s, void *private) LOAD_INT(c), LOAD_FRAC(c), count_active_contexts(), atomic_read(&nr_spu_contexts), - task_active_pid_ns(current)->last_pid); + task_active_pid_ns(current)->idr.idr_next-1); return 0; }
Everywhere you use idr.idr_next or idr->idr_next directly, you could use idr_get_cursor(idr) instead, exposing less of the IDR internals to the rest of the code.
Quoted 26 lines
arch/powerpc/platforms/cell/spufs/sched.c +2
-3@@ -240,17 +230,18 @@ void zap_pid_ns_processes(struct pid_namespace*pid_ns) * */ read_lock(&tasklist_lock); - nr =next_pidmap (pid_ns,1 ); -while (nr >0 ) { -rcu_read_lock (); + pid =idr_get_next (&pid_ns->idr, &nr); +while (pid) {arch/powerpc/platforms/cell/spufs/sched.c +0
-3- task =pid_task (find_vpid (nr),PIDTYPE_PID ); -if (task && !__fatal_signal_pending (task)) - send_sig_info(SIGKILL, SEND_SIG_FORCED,task);
arch/powerpc/platforms/cell/spufs/sched.c +1
-0+rcu_read_lock ();arch/powerpc/platforms/cell/spufs/sched.c +4
-0+idr_for_each_entry_continue (&pid_ns->idr, pid, nr) { + task =pid_task (pid,PIDTYPE_PID ); +if (task && !__fatal_signal_pending (task)) + send_sig_info(SIGKILL,
SEND_SIG_FORCED, task);arch/powerpc/platforms/cell/spufs/sched.c +1
-0+ }
rcu_read_unlock();arch/powerpc/platforms/cell/spufs/sched.c +0
-1- nr =next_pidmap (pid_ns, nr);
Quoted 3 lines
}
read_unlock(&tasklist_lock);
I believe we should be fine with just the idr_for_each_entry_continue() surrounding the loop, and not need the while (pid) around that.
That should still iterate over all the pids in the namespace, and simplify the code even more.
You have done a great job understanding some complicated code, and simplifying it during your Outreachy internship.
Signature · 1 line
All Rights Reversed.
Re: [PATCH v2 1/2] pid: Replace pid bitmap implementation with IDR API
Quoted 25 lines · Rik van Riel
Quoted 25 lines
kernel/pid_namespace.c +2
-3@@ -240,17 +230,18 @@ void zap_pid_ns_processes(struct pid_namespace*pid_ns) * */ read_lock(&tasklist_lock); - nr =next_pidmap (pid_ns,1 ); -while (nr >0 ) { -rcu_read_lock (); + pid =idr_get_next (&pid_ns->idr, &nr); +while (pid) {kernel/pid_namespace.c +0
-3- task =pid_task (find_vpid (nr),PIDTYPE_PID ); -if (task && !__fatal_signal_pending (task)) - send_sig_info(SIGKILL, SEND_SIG_FORCED,task);
kernel/pid_namespace.c +1
-0+rcu_read_lock ();kernel/pid_namespace.c +4
-0+idr_for_each_entry_continue (&pid_ns->idr, pid, nr) { + task =pid_task (pid,PIDTYPE_PID ); +if (task && !__fatal_signal_pending (task)) + send_sig_info(SIGKILL,
SEND_SIG_FORCED, task);kernel/pid_namespace.c +1
-0+ }
rcu_read_unlock();
Quoted 8 lines
Quoted 5 lines
kernel/pid_namespace.c +0
-1- nr =next_pidmap (pid_ns, nr);}
read_unlock(&tasklist_lock);I believe we should be fine with just the
idr_for_each_entry_continue()surrounding the loop,
Yes, and please move "nr = 2" close to idr_for_each_entry_continue() to make it clear why do we use _continue (to skip nr == 1).
Quoted 4 lines
and not need the while (pid) around that.
That should still iterate over all the pids in the namespace, and simplify the code even more.
And make this patch correct ;)
because currently it is wrong, zap_pid_ns_processes() won't kill the pid returned by the first idr_get_next().
Oleg.
Re: [PATCH v2 1/2] pid: Replace pid bitmap implementation with IDR API
Quoted 40 lines · Oleg Nesterov
Quoted 26 lines · Rik van Riel
Quoted 26 lines
kernel/pid_namespace.c +8
-6@@ -240,17 +230,18 @@ void zap_pid_ns_processes(struct pid_namespace*pid_ns) * */ read_lock (&tasklist_lock); - nr =next_pidmap (pid_ns,1 ); -while (nr >0 ) { -rcu_read_lock (); + pid =idr_get_next (&pid_ns->idr, &nr); +while (pid) { - task =pid_task (find_vpid (nr),PIDTYPE_PID ); -if (task && !__fatal_signal_pending (task)) -send_sig_info (SIGKILL ,SEND_SIG_FORCED , task); +rcu_read_lock (); +idr_for_each_entry_continue (&pid_ns->idr, pid, nr) { + task =pid_task (pid,PIDTYPE_PID ); +if (task && !__fatal_signal_pending (task)) +send_sig_info (SIGKILL ,SEND_SIG_FORCED , task); + }rcu_read_unlock ();Quoted 7 lines
Quoted 4 lines
kernel/pid_namespace.c +0
-1- nr =next_pidmap (pid_ns, nr);} read_unlock(&tasklist_lock);I believe we should be fine with just the
idr_for_each_entry_continue()surrounding the loop,Yes, and please move "nr = 2" close to
idr_for_each_entry_continue()to make it clear why do we use_continue(to skip nr == 1).Quoted 2 lines
and not need the while (pid) around that.
Quoted 7 lines
Quoted 2 lines
That should still iterate over all the pids in the namespace, and simplify the code even more.
And make this patch correct ;)
because currently it is wrong,
zap_pid_ns_processes()won't kill the pid returned by the firstidr_get_next().
Yes, I missed this. I can simply remove the idr_get_next() before the idr_for_each_continue and that will take care of it.
Thanks!
Gargi
Quoted 3 lines
Oleg.
Re: [PATCH v2 1/2] pid: Replace pid bitmap implementation with IDR API
Quoted 8 lines · Gargi Sharma
Quoted 6 lines
And make this patch correct ;)
because currently it is wrong,
zap_pid_ns_processes()won't kill the pid returned by the firstidr_get_next().Yes, I missed this. I can simply remove the
idr_get_next()before theidr_for_each_continueand that will take care of it.
Yes, and also remove the while(pid) loop as Rik suggests, just do
read_lock(&tasklist_lock);
nr = 2;
idr_for_each_entry_continue(..., nr) {
kill pid_task()
}
read_unlock(&tasklist_lock);Oleg.
Re: [PATCH v2 1/2] pid: Replace pid bitmap implementation with IDR API
In reply to Rik van RielQuoted 10 lines · Rik van Riel
Quoted 6 lines · Gargi Sharma
This patch replaces the current bitmap implemetation for Process ID allocation. Functions that are no longer required, for example,
free_pidmap(),alloc_pidmap(), etc. are removed. The rest of the functions are modified to use the IDR API. The change was made to make the PID allocation less complex by replacing custom code with calls to generic API.I like where this is going. Just a few last comments from me :)
Quoted 15 lines
arch/powerpc/platforms/cell/spufs/sched.c static int show_spu_loadavg(struct seq_file *s, · line 1099
Quoted 11 lines
arch/powerpc/platforms/cell/spufs/sched.c +1
-1@@ -1093,7 +1093,7 @@ static int show_spu_loadavg(struct seq_file *s, void *private) LOAD_INT(c), LOAD_FRAC(c), count_active_contexts(), atomic_read(&nr_spu_contexts), - task_active_pid_ns(current)->last_pid); + task_active_pid_ns(current)->idr.idr_next-1);return 0 ; }Everywhere you use idr.idr_next or
idr->idr_nextdirectly, you could useidr_get_cursor(idr)instead, exposing less of the IDR internals to the rest of the code.
Yes, will change this in the next version.
Quoted 34 lines
Quoted 27 lines
arch/powerpc/platforms/cell/spufs/sched.c +8
-7@@ -240,17 +230,18 @@ void zap_pid_ns_processes(struct pid_namespace*pid_ns) * */ read_lock (&tasklist_lock); - nr =next_pidmap (pid_ns,1 ); -while (nr >0 ) { -rcu_read_lock (); + pid =idr_get_next (&pid_ns->idr, &nr); +while (pid) { - task =pid_task (find_vpid (nr),PIDTYPE_PID ); -if (task && !__fatal_signal_pending (task)) -send_sig_info (SIGKILL ,SEND_SIG_FORCED , task); +rcu_read_lock (); +idr_for_each_entry_continue (&pid_ns->idr, pid, nr) { + task =pid_task (pid,PIDTYPE_PID ); +if (task && !__fatal_signal_pending (task)) +send_sig_info (SIGKILL ,SEND_SIG_FORCED , task); + }rcu_read_unlock (); - nr =next_pidmap (pid_ns, nr);Quoted 3 lines
} read_unlock(&tasklist_lock);I believe we should be fine with just the
idr_for_each_entry_continue()surrounding the loop, and not need the while (pid) around that.
Quoted 2 lines
That should still iterate over all the pids in the namespace, and simplify the code even more.
Yes, one loop suffices. I will fix this in the next version.
Quoted 3 lines
You have done a great job understanding some complicated code, and simplifying it during your Outreachy internship.
Thanks!
Gargi
Quoted 3 lines
--
All Rights Reversed.
Re: [PATCH v2 1/2] pid: Replace pid bitmap implementation with IDR API
In reply to Gargi SharmaQuoted 26 lines · Gargi Sharma
kernel/pid.c +16
-1@@ -309,7 +168,22 @@ struct pid *alloc_pid(struct pid_namespace *ns) tmp = ns; pid->level = ns->level;for (i = ns->level; i >=0 ; i--) { - nr =alloc_pidmap (tmp); +int pid_min =1 ; +idr_preload (GFP_KERNEL ); +spin_lock_irq (&pidmap_lock); + +/* +* init really needs pid 1, but after reaching the maximum +* wrap back to RESERVED_PIDS +*/ +if (tmp->idr.idr_next >RESERVED_PIDS ) + pid_min =RESERVED_PIDS ; + + nr =idr_alloc_cyclic (&tmp->idr, pid, pid_min, + pid_max,GFP_ATOMIC ); +spin_unlock_irq (&pidmap_lock); +idr_preload_end (); +if (nr <0 ) { retval = nr; goto out_free;
kernel/pid.c struct pid *alloc_pid(struct pid_namespace *ns) · line 224
Quoted 6 lines
kernel/pid.c +1
-1@@ -346,12 +220,14 @@ struct pid *alloc_pid(struct pid_namespace *ns)return pid; out_unlock: -spin_unlock_irq (&pidmap_lock);put_pid_ns (ns); +spin_unlock_irq (&pidmap_lock);
Why? No need to move put_pid_ns() under pidmap_lock, please remove this change...
kernel/pid.c struct pid *find_ge_pid(int nr, struct pid_namespace *ns) · line 449
Quoted 10 lines
kernel/pid.c +3
-0void __init pidhash_init (void ) { +unsigned int pidhash_size; + pid_hash =alloc_large_system_hash ("PID" ,sizeof (*pid_hash),0 ,18 ,HASH_EARLY |HASH_SMALL |HASH_ZERO , &pidhash_shift,NULL ,0 ,4096 ); + pidhash_size =1U << pidhash_shift; }
Hmm, this change makes no sense. And the next patch kills pidhash_init() altogether.
Oleg.
Re: [PATCH v2 1/2] pid: Replace pid bitmap implementation with IDR API
In reply to Gargi SharmaReview
Quoted 2 lines
(quoted diff) +1
-1- task_active_pid_ns(current)->last_pid); + task_active_pid_ns(current)->idr.idr_next-1);
I think we want a well documented helper for this pattern instead of poking into the internals.
Also is last - 1 always the correct answer? Even with idr_alloc_cyclic we could wrap around, couldn't we?
Re: [PATCH v2 1/2] pid: Replace pid bitmap implementation with IDR API
Quoted 5 lines · Christoph Hellwig
Review
Quoted 2 lines
(quoted diff) +1
-1- task_active_pid_ns(current)->last_pid); + task_active_pid_ns(current)->idr.idr_next-1);I think we want a well documented helper for this pattern instead of poking into the internals.
idr_get_cursor() get can be used instead of idr.idr_next, so that we do not expose the internals.
Quoted 3 lines
Also is last - 1 always the correct answer? Even with
idr_alloc_cyclicwe could wrap around, couldn't we?
-1 will be incorrect when the pids wrap around. Should we go back to setting up last_pid as it was done before? Or should we use idr_get_cursor and determine if pid was rolled over and then perform necessary action?
Thanks!
Gargi
Re: [PATCH v2 1/2] pid: Replace pid bitmap implementation with IDR API
Quoted 16 lines · Gargi Sharma
Quoted 5 lines · Christoph Hellwig
Quoted 2 lines
- task_active_pid_ns(current)->last_pid); + task_active_pid_ns(current)->idr.idr_next-1);
I think we want a well documented helper for this pattern instead of poking into the internals.
idr_get_cursor()get can be used instead of idr.idr_next, so that we do not
expose the internals.Quoted 4 lines
Also is last - 1 always the correct answer? Even with
idr_alloc_cyclic
we could wrap around, couldn't we?
Quoted 5 lines
-1 will be incorrect when the pids wrap around. Should we go back to setting up
last_pidas it was done before? Or should we useidr_get_cursor
and determine if pid was rolled over and then perform necessary action?
Looking at it some more, it appears the value is only ever used in /proc/loadavg.
Would anyone object to the code simply calling idr_get_cursor() as is, and leaving out the -1?
Somehow I suspect nobody will care that the pid value in /proc/loadavg reflects the next PID allocated, rather than the previous one.
Any objections?
Signature · 1 line
All Rights Reversed.
Re: [PATCH v2 1/2] pid: Replace pid bitmap implementation with IDR API
In reply to Christoph HellwigQuoted 9 lines · Christoph Hellwig
Review
Quoted 2 lines
(quoted diff) +1
-1- task_active_pid_ns(current)->last_pid); + task_active_pid_ns(current)->idr.idr_next-1);I think we want a well documented helper for this pattern instead of poking into the internals.
Also is last - 1 always the correct answer? Even with
idr_alloc_cyclic
we could wrap around, couldn't we?
Good point. I wonder if it makes sense to change the IDR code, so idr_get_cursor returns the last allocated ID?
I see only two users of idr_get_cursor in the kernel, and it looks like both would work fine if idr_get_cursor returned the previously allocated value.
That would require a small change to idr_alloc_cyclic, to have it start searching at a position one larger than the cursor, and maybe renaming idr->idr_next to idr->cursor, since it would now represent the last value allocated, not the next.
Would that make sense?
Signature · 1 line
All Rights Reversed.
PATCH v2 2/2 pid: Remove pidhash
In reply to Gargi Sharmapidhash is no longer required as all the information can be looked up from idr tree. nr_hashed represented the number of pids that had been hashed. Since, nr_hashed and PIDNS_HASH_ADDING are no longer relevant, it has been renamed to pid_allocated and PIDNS_ADDING respectively.
--- include/linux/init_task.h | 1 - include/linux/pid.h | 2 -- include/linux/pid_namespace.h | 4 ++-- init/main.c | 1 - kernel/fork.c | 2 +- kernel/pid.c | 52 ++++++++----------------------------------- kernel/pid_namespace.c | 7 +++--- 7 files changed, 16 insertions(+), 53 deletions(-)
include/linux/init_task.h +0 -1
@@ -104,7 +104,6 @@ extern struct group_info init_groups; .numbers = { { \ .nr = 0, \ .ns = &init_pid_ns, \ - .pid_chain = { .next = NULL, .pprev = NULL }, \ }, } \ }
include/linux/pid.h +0 -2
@@ -50,10 +50,8 @@ enum pid_type*/ struct upid { -/* Try to keep pid_chain in the same cacheline as nr for find_vpid */ int nr;struct pid_namespace *ns; -struct hlist_node pid_chain; };struct pid
include/linux/pid_namespace.h +2 -2
@@ -24,7 +24,7 @@ struct pid_namespace {struct kref kref;struct idr idr;struct rcu_head rcu; -unsigned int nr_hashed; +unsigned int pid_allocated;struct task_struct *child_reaper;struct kmem_cache *pid_cachep;unsigned int level;
@@ -48,7 +48,7 @@ struct pid_namespace {extern struct pid_namespace init_pid_ns; -#define PIDNS_HASH_ADDING (1U << 31) +#define PIDNS_ADDING (1U << 31)#ifdef CONFIG_PID_NS static inline struct pid_namespace *get_pid_ns (struct pid_namespace *ns)
init/main.c +0 -1
@@ -562,7 +562,6 @@ asmlinkage __visible void __init start_kernel(void)* kmem_cache_init() */ setup_log_buf (0 ); -pidhash_init ();vfs_caches_init_early ();sort_main_extable ();trap_init ();
kernel/fork.c +1 -1
@@ -1853,7 +1853,7 @@ static __latent_entropy struct task_struct *copy_process( retval = -ERESTARTNOINTR ; goto bad_fork_cancel_cgroup; } -if (unlikely (!(ns_of_pid (pid)->nr_hashed &PIDNS_HASH_ADDING ))) { +if (unlikely (!(ns_of_pid (pid)->pid_allocated &PIDNS_ADDING ))) { retval = -ENOMEM ; goto bad_fork_cancel_cgroup; }
kernel/pid.c +9 -43
112 lines not on this page · raw message
kernel/pid_namespace.c +4 -3
@@ -133,7 +133,8 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns ns->parent =get_pid_ns (parent_pid_ns); ns->user_ns =get_user_ns (user_ns); ns->ucounts = ucounts; - ns->nr_hashed =PIDNS_HASH_ADDING ; + ns->pid_allocated =PIDNS_ADDING ; +INIT_WORK (&ns->proc_work, proc_cleanup_work);return ns;
@@ -259,7 +260,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)* sys_wait4() above can't reap the EXIT_DEAD children but we do not * really care, we could reparent them to the global init. We could * exit and reap ->child_reaper even if it is not the last thread in -* this pid_ns, free_pid(nr_hashed == 0) calls proc_cleanup_work(), +* this pid_ns, free_pid(pid_allocated == 0) calls proc_cleanup_work(), * pid_ns can not go away until proc_kill_sb() drops the reference. * * But this ns can also have other tasks injected by setns()+fork().
@@ -273,7 +274,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)*/ for (;;) {set_current_state (TASK_INTERRUPTIBLE ); -if (pid_ns->nr_hashed == init_pids) +if (pid_ns->pid_allocated == init_pids)break ;schedule (); }
Signature · 1 line
2.7.4
Re: [PATCH v2 2/2] pid: Remove pidhash
kernel/pid.c int pid_max = PID_MAX_DEFAULT; · line 59
Quoted 4 lines · Gargi Sharma
kernel/pid.c +0
-3-#define find_next_offset (map, off) \ - find_next_zero_bit((map)->page, BITS_PER_PAGE, off) -
this should go into the previous patch, but this is minor...
kernel/pid.c struct pid *alloc_pid(struct pid_namespace *ns) · line 206
Quoted 12 lines
kernel/pid.c +2
-4@@ -208,12 +200,10 @@ struct pid *alloc_pid(struct pid_namespace *ns) upid = pid->numbers + ns->level;spin_lock_irq (&pidmap_lock); -if (!(ns->nr_hashed &PIDNS_HASH_ADDING )) +if (!(ns->pid_allocated &PIDNS_ADDING )) goto out_unlock;for ( ; upid >= pid->numbers; --upid) { -hlist_add_head_rcu (&upid->pid_chain, - &pid_hash[pid_hashfn (upid->nr, upid->ns)]); - upid->ns->nr_hashed++; + upid->ns->pid_allocated++;
No, this is wrong.
It is too late to check PIDNS_HASH_ADDING/PIDNS_ADDING and increment pid_allocated, once we call idr_alloc_cyclic() this pid is already "hashed" in that it can be found by find_pid_ns() with this patch applied.
And of course, it is too late to do atomic_set(&pid->count, 1) and initialize pid->tasks[type] lists by the same reason.
Oleg.
Re: [PATCH v2 2/2] pid: Remove pidhash
If I was not clear...
in short, after this patch the very first idr_alloc_cyclic() is already wrong. Because, once again, the new not-fully-initialized pid can be found by find_pid_ns().
perhaps you should chane the previous patch to do idr_alloc_cyclic(ptr = NULL) and use idr_replace() in this patch after the PIDNS_HASH_ADDING check.
And I just noticed you didn't cc Eric Biederman <[email protected]>, please do next time.
Quoted 32 lines · Oleg Nesterov
kernel/pid.c int pid_max = PID_MAX_DEFAULT; · line 59
Quoted 4 lines · Gargi Sharma
kernel/pid.c +0
-3-#define find_next_offset (map, off) \ - find_next_zero_bit((map)->page, BITS_PER_PAGE, off) -this should go into the previous patch, but this is minor...
kernel/pid.c struct pid *alloc_pid(struct pid_namespace *ns) · line 206
Quoted 12 lines
kernel/pid.c +2
-4@@ -208,12 +200,10 @@ struct pid *alloc_pid(struct pid_namespace *ns) upid = pid->numbers + ns->level;spin_lock_irq (&pidmap_lock); -if (!(ns->nr_hashed &PIDNS_HASH_ADDING )) +if (!(ns->pid_allocated &PIDNS_ADDING )) goto out_unlock;for ( ; upid >= pid->numbers; --upid) { -hlist_add_head_rcu (&upid->pid_chain, - &pid_hash[pid_hashfn (upid->nr, upid->ns)]); - upid->ns->nr_hashed++; + upid->ns->pid_allocated++;No, this is wrong.
It is too late to check PIDNS_HASH_ADDING/PIDNS_ADDING and increment
pid_allocated, once we callidr_alloc_cyclic()this pid is already "hashed" in that it can be found byfind_pid_ns()with this patch applied.And of course, it is too late to do
atomic_set(&pid->count, 1)and initialize pid->tasks[type] lists by the same reason.Oleg.
Re: [PATCH v2 2/2] pid: Remove pidhash
Quoted 5 lines · Oleg Nesterov
If I was not clear...
in short, after this patch the very first
idr_alloc_cyclic()is already wrong. Because, once again, the new not-fully-initialized pid can be found byfind_pid_ns().
If the PIDNS_ADDING check fails, I jump to the flag that performs this
while (++i <= ns->level)
idr_remove(&ns->idr, (pid->numbers + i)->nr);
So when find_pid_ns() is called, it will not find this pid.
Quoted 4 lines
perhaps you should chane the previous patch to do
idr_alloc_cyclic(ptr = NULL)and useidr_replace()in this patch after thePIDNS_HASH_ADDINGcheck.
I'm not sure if I understand this. Do we want to do this to make sure the pid namespace is
initialized before the first process enters into
the namespace? If yes, how does idr_alloc_cyclic(ptr = NULL) help?
Quoted 3 lines
And I just noticed you didn't cc Eric Biederman <[email protected]>, please do next time.
Sorry for missing out on this. Will do with the next version.
Thanks!
Gargi
Quoted 36 lines · Oleg Nesterov
Quoted 32 lines · Gargi Sharma
kernel/pid.c int pid_max = PID_MAX_DEFAULT; · line 59
Quoted 4 lines
kernel/pid.c +0
-3-#define find_next_offset (map, off) \ - find_next_zero_bit((map)->page, BITS_PER_PAGE, off) -this should go into the previous patch, but this is minor...
kernel/pid.c struct pid *alloc_pid(struct pid_namespace *ns) · line 206
Quoted 12 lines
kernel/pid.c +2
-4@@ -208,12 +200,10 @@ struct pid *alloc_pid(struct pid_namespace *ns) upid = pid->numbers + ns->level;spin_lock_irq (&pidmap_lock); -if (!(ns->nr_hashed &PIDNS_HASH_ADDING )) +if (!(ns->pid_allocated &PIDNS_ADDING )) goto out_unlock;for ( ; upid >= pid->numbers; --upid) { -hlist_add_head_rcu (&upid->pid_chain, - &pid_hash[pid_hashfn (upid->nr, upid->ns)]); - upid->ns->nr_hashed++; + upid->ns->pid_allocated++;No, this is wrong.
It is too late to check PIDNS_HASH_ADDING/PIDNS_ADDING and increment
pid_allocated, once we callidr_alloc_cyclic()this pid is already "hashed" in that it can be found byfind_pid_ns()with this patch applied.And of course, it is too late to do
atomic_set(&pid->count, 1)and initialize pid->tasks[type] lists by the same reason.Oleg.
Re: [PATCH v2 2/2] pid: Remove pidhash
Quoted 8 lines · Gargi Sharma
Quoted 5 lines · Oleg Nesterov
If I was not clear...
in short, after this patch the very first
idr_alloc_cyclic()is already wrong. Because, once again, the new not-fully-initialized pid can be found byfind_pid_ns().
Quoted 5 lines
If the
PIDNS_ADDINGcheck fails, I jump to the flag that performs this
while (++i <=ns->level)idr_remove(&ns->idr, (pid->numbers + i)->nr);So when
find_pid_ns()is called, it will not find this pid.
You misunderstood.
OK, to simplify lets forget about namespaces, locking, everything. So after this patch alloc_pid() roughly does:
pid = kmem_cache_alloc(); nr = idr_alloc_cyclic(idr, pid); // lets suppose it returns 1234 /* WINDOW */ for (type = 0; type < PIDTYPE_MAX; ++type) INIT_HLIST_HEAD(&pid->tasks[type]);
now suppose that in that WINDOW above another CPU does, just for example, sys_tkill(1234, SIG) which implies find_task_by_vpid(1234) which does pid_task(find_pid_ns(1234)).
find_pid_ns() returns the non-initialized pid above, because with this patch it is idr_find() and this pid was already added by idr_alloc_cyclic().
Then pid_task(pid) returns garbage because pid->tasks[] was not initialised yet.
And of course we have the same problems with pid->count/numbers/etc.
See?
Quoted 8 lines
Quoted 3 lines
perhaps you should chane the previous patch to do
idr_alloc_cyclic(ptr = NULL)and useidr_replace()in this patch after thePIDNS_HASH_ADDINGcheck.I'm not sure if I understand this. Do we want to do this to make sure the pid namespace is
initialized before the first process enters into
the namespace? If yes,
No,
Quoted 1 line
how does
idr_alloc_cyclic(ptr = NULL)help?
In this case find_pid_ns/idr_find will return NULL until we do idr_replace(idr, pid) when this pid is fully initialized.
Oleg.
Re: [PATCH v2 2/2] pid: Remove pidhash
In reply to Oleg NesterovQuoted 33 lines · Oleg Nesterov
Quoted 6 lines · Gargi Sharma
-#define
find_next_offset(map, off)
\(quoted diff) +0
-1- find_next_zero_bit((map)->page, BITS_PER_PAGE,off)
-this should go into the previous patch, but this is minor...
Quoted 12 lines
(quoted diff) +0
-0@@ -208,12 +200,10 @@ struct pid *alloc_pid(struct pid_namespace *ns)
upid =pid->numbers+ns->level;
spin_lock_irq(&pidmap_lock);kernel/pid.c +1
-1-if (!(ns->nr_hashed &PIDNS_HASH_ADDING )) +if (!(ns->pid_allocated &PIDNS_ADDING ))goto
out_unlock;
for ( ; upid >=pid->numbers; --upid) {(quoted diff) +0
-2- hlist_add_head_rcu(&upid->pid_chain, - &pid_hash[pid_hashfn(upid->nr,
upid->ns)]);kernel/pid.c struct pid *alloc_pid(struct pid_namespace *ns) · line 206
Quoted 2 lines
kernel/pid.c +1
-1- upid->ns->nr_hashed++; + upid->ns->pid_allocated++;No, this is wrong.
It is too late to check PIDNS_HASH_ADDING/PIDNS_ADDING and increment
pid_allocated,
once we callidr_alloc_cyclic()this pid is already "hashed" in that it can be found
byfind_pid_ns()with this patch applied.
Quoted 3 lines
And of course, it is too late to do
atomic_set(&pid->count, 1)and initialize
pid->tasks[type] lists by the same reason.
Hi Oleg,
Gargi and I are looking at that code, and trying to figure out exactly what needs to be done to make all of this correct.
We are thinking something along these lines:
1) First, check if this is a new namespace (PIDNS_ADDING), and do the call to pid_ns_prepare_proc, before we even call idr_alloc. Maybe something like:
if (unlikely(ns->nr_allocated == PIDNS_ADDING)) {
if (pid_ns_prepare_proc(ns)) {
disable_pid_allocations(ns);
goto out_free_ns;
}2) With pid_ns_prepare_proc out of the way, we can put all the code from below where the call to pid_ns_prepare_proc is now (except error handing) into the main loop of pid allocation, so we can do all that stuff under the pidmap_lock:
for (i = ns->level; i >= 0; i--) {
...
idr_alloc_cyclic(...)
get_pid_ns(ns);
atomic_set(&pid->count, 1);
for (...)
INIT_HLIST_HEAD(...)
ns->nr_allocated++;
...
}Would that resolve your objection, or are we barking up the wrong tree?
Signature · 1 line
All Rights Reversed.
Re: [PATCH v2 2/2] pid: Remove pidhash
Quoted 41 lines · Rik van Riel
Quoted 36 lines · Oleg Nesterov
Quoted 7 lines · Gargi Sharma
-#define
find_next_offset(map, off)\
(quoted diff) +0
-1- find_next_zero_bit((map)->page, BITS_PER_PAGE,off)
-this should go into the previous patch, but this is minor...
Quoted 12 lines
(quoted diff) +0
-0@@ -208,12 +200,10 @@ struct pid *alloc_pid(struct pid_namespace *ns)
upid =pid->numbers+ns->level;
spin_lock_irq(&pidmap_lock);kernel/pid.c +1
-1-if (!(ns->nr_hashed &PIDNS_HASH_ADDING )) +if (!(ns->pid_allocated &PIDNS_ADDING ))goto
out_unlock;
for ( ; upid >=pid->numbers; --upid) {(quoted diff) +0
-2- hlist_add_head_rcu(&upid->pid_chain, - &pid_hash[pid_hashfn(upid->nr,
upid->ns)]);kernel/pid.c struct pid *alloc_pid(struct pid_namespace *ns) · line 206
Quoted 2 lines
kernel/pid.c +1
-1- upid->ns->nr_hashed++; + upid->ns->pid_allocated++;No, this is wrong.
It is too late to check PIDNS_HASH_ADDING/PIDNS_ADDING and increment
pid_allocated,
once we callidr_alloc_cyclic()this pid is already "hashed" in that
it can be found
byfind_pid_ns()with this patch applied.Quoted 3 lines
And of course, it is too late to do
atomic_set(&pid->count, 1)and initialize
pid->tasks[type] lists by the same reason.
Quoted 6 lines
Hi Oleg,
Gargi and I are looking at that code, and trying to figure out exactly what needs to be done to make all of this correct.
We are thinking something along these lines:
.... and we looked at the code some more. Some of the way the code is laid out currently looks like an artifact of history.
Lets try this again:
1) pid = kmem_cache_alloc(...)
2) get_pid_ns(ns);
atomic_set(&pid->count, 1);
for (type = 0; ...)
INIT_HLIST(...)
Quoted 19 lines
3) First, check if this is a new namespace (
PIDNS_ADDING), and do the call topid_ns_prepare_proc, before we even callidr_alloc. Maybe something like:if (
unlikely(ns->nr_allocated == PIDNS_ADDING)) { if (pid_ns_prepare_proc(ns)) {disable_pid_allocations(ns);
gotoout_free_ns;
}4) With
pid_ns_prepare_procout of the way, we can put all the code from below where the call topid_ns_prepare_procis now (except error handing) into the main loop of pid allocation, so we can do all that stuff under thepidmap_lock:for (i =
ns->level; i >= 0; i--) {
...
idr_alloc_cyclic(...)
Quoted 6 lines
ns->nr_allocated++;
...
}Would that resolve your objection, or are we barking up the wrong tree?
Now the per-pid struct stuff is done once, before the loop, and the loop deals only with allocated numbers inside each parent namespace.
The error path would unwind stuff done earlier.
Signature · 1 line
All Rights Reversed.
Re: [PATCH v2 2/2] pid: Remove pidhash
In reply to Rik van RielHi Rik,
Quoted 3 lines · Rik van Riel
Gargi and I are looking at that code, and trying to figure out exactly what needs to be done to make all of this correct.
see another email I sent to Gargi a minute ago,
Quoted 5 lines
2) With
pid_ns_prepare_procout of the way, we can put all the code from below where the call topid_ns_prepare_procis now (except error handing) into the main loop of pid allocation, so we can do all that stuff under thepidmap_lock:
Quoted 10 lines
for (i = ns->level; i >= 0; i--) {
...
idr_alloc_cyclic(...)
get_pid_ns(ns);
atomic_set(&pid->count, 1);
for (...)
INIT_HLIST_HEAD(...)
ns->nr_allocated++;
...
}I do not see how this can fix the problem with not-fully-initialized pid returned by find_pid_ns().
As for PIDNS_ADDING/PIDNS_HASH_ADDING, _perhaps_ we can cleanup this logic a bit and do the check earlier, but imo this needs another/separate change.
I'd suggest to keep the current logic and the order of initialization and just do
for (i = ns->level; i >= 0; i--) {
...
// do not expose the new pid to find_pid_ns() until it
// is fully initialized
nr = idr_alloc_cyclic(&tmp->idr, /*pid*/ NULL, ...);
...
}
...
spin_lock_irq(&pidmap_lock);
if (!(ns->nr_hashed & PIDNS_HASH_ADDING))
goto out_unlock;
for ( ; upid >= pid->numbers; --upid) {
- hlist_add_head_rcu(&upid->pid_chain,
- &pid_hash[pid_hashfn(upid->nr, upid->ns)]);
+ // finally make it visible to find_pid_ns()
+ idr_replace(upid->ns-idr, pid, upid->nr);
upid->ns->nr_hashed++;
}
spin_unlock_irq(&pidmap_lock);Or I missed something?
Oleg.
Re: [PATCH v2 2/2] pid: Remove pidhash
Quoted 61 lines · Oleg Nesterov
Hi Rik,
Quoted 3 lines · Rik van Riel
Gargi and I are looking at that code, and trying to figure out exactly what needs to be done to make all of this correct.
see another email I sent to Gargi a minute ago,
Quoted 5 lines
2) With
pid_ns_prepare_procout of the way, we can put all the code from below where the call topid_ns_prepare_procis now (except error handing) into the main loop of pid allocation, so we can do all that stuff under thepidmap_lock:Quoted 10 lines
for (i =
ns->level; i >= 0; i--) {
...
idr_alloc_cyclic(...)
get_pid_ns(ns);
atomic_set(&pid->count, 1);
for (...)
INIT_HLIST_HEAD(...)
ns->nr_allocated++;
...
}I do not see how this can fix the problem with not-fully-initialized pid returned by
find_pid_ns().As for PIDNS_ADDING/PIDNS_HASH_ADDING, _perhaps_ we can cleanup this logic
a bit and do the check earlier, but imo this needs another/separate change.I'd suggest to keep the current logic and the order of initialization and
just dofor (i = ns->level; i >= 0; i--) { ... // do not expose the new pid to find_pid_ns() until it // is fully initialized nr = idr_alloc_cyclic(&tmp->idr, /*pid*/ NULL, ...); ... } ... spin_lock_irq(&pidmap_lock); if (!(ns->nr_hashed & PIDNS_HASH_ADDING)) goto out_unlock; for ( ; upid >= pid->numbers; --upid) {(quoted diff) +0
-2- hlist_add_head_rcu(&upid->pid_chain, - &pid_hash[pid_hashfn(upid->nr, upid-Quoted 1 line
ns)]);
(quoted diff) +2
-0+ // finally make it visible to find_pid_ns() + idr_replace(upid->ns-idr, pid, upid->nr);upid->ns->nr_hashed++; } spin_unlock_irq(&pidmap_lock);
Quoted 1 line
Or I missed something?
You are right, that would both fix the problem, and keep the error paths relatively simple.
Gargi, what do you think?
Signature · 1 line
All Rights Reversed.
Re: [PATCH v2 2/2] pid: Remove pidhash
Quoted 55 lines · Rik van Riel
Quoted 54 lines · Oleg Nesterov
Hi Rik,
Quoted 3 lines · Rik van Riel
Gargi and I are looking at that code, and trying to figure out exactly what needs to be done to make all of this correct.
see another email I sent to Gargi a minute ago,
Quoted 5 lines
2) With
pid_ns_prepare_procout of the way, we can put all the code from below where the call topid_ns_prepare_procis now (except error handing) into the main loop of pid allocation, so we can do all that stuff under thepidmap_lock:Quoted 10 lines
for (i = ns->level; i >= 0; i--) { ... idr_alloc_cyclic(...) get_pid_ns(ns); atomic_set(&pid->count, 1); for (...) INIT_HLIST_HEAD(...) ns->nr_allocated++; ... }I do not see how this can fix the problem with not-fully-initialized pid returned by
find_pid_ns().As for PIDNS_ADDING/PIDNS_HASH_ADDING, _perhaps_ we can cleanup this logic
a bit and do the check earlier, but imo this needs another/separate change.I'd suggest to keep the current logic and the order of initialization and
just dofor (i = ns->level; i >= 0; i--) { ... // do not expose the new pid to find_pid_ns() until it // is fully initialized nr = idr_alloc_cyclic(&tmp->idr, /*pid*/ NULL, ...); ... } ... spin_lock_irq(&pidmap_lock); if (!(ns->nr_hashed & PIDNS_HASH_ADDING)) goto out_unlock; for ( ; upid >= pid->numbers; --upid) {(quoted diff) +0
-2- hlist_add_head_rcu(&upid->pid_chain, - &pid_hash[pid_hashfn(upid->nr, upid-
Quoted 8 lines
Quoted 8 lines
Quoted 1 line
ns)]);
(quoted diff) +2
-0+ // finally make it visible to find_pid_ns() + idr_replace(upid->ns-idr, pid, upid->nr); upid->ns->nr_hashed++; } spin_unlock_irq(&pidmap_lock);Or I missed something?
Thanks for detailed explanation Oleg!
Quoted 5 lines
You are right, that would both fix the problem, and keep the error paths relatively simple.
Gargi, what do you think?
I understand better now. Thanks!
Best,
Gargi
Quoted 3 lines
--
All Rights Reversed.
Quoted 21 lines · Gargi Sharma
This patch series replaces kernel bitmap implementation of PID allocation
with IDR API. These patches are written to simplify the kernel by replacing custom code with calls to generic code.The following are the stats for pid and
pid_namespaceobject files before and after the replacement. There is a noteworthy change between the IDR and bitmap implementation.Before
text data bss dec hex filename
8447 3894 64 12405 3075kernel/pid.o
After
text data bss dec hex filename
3301 304 0 3605 e15kernel/pid.oBefore
text data bss dec hex filename
5692 1842 192 7726 1e2ekernel/pid_namespace.o
After
text data bss dec hex filename
2870 216 16 3102 c1ekernel/pid_namespace.o
Quoted 2 lines
There wasn't a considerable difference between the time required for allocation of PIDs to the processes.
How about the time to call readdir on /proc?
How many processes were you testing with?
Why just the bitmap? Why not update the hash table as well. An rbtree or an rhashtable might be better.
Hmm. Oh look there is patch 2/2 and you do replace the hashtable with the idr as well. Now I am very interested in a comparison of data structures.
How does the runtime memory footprint of your new pid hash implementation compare to the old memory footprint?
There are a lot of options in this space and it does not sound like you have looked at the options very thoroughly.
I am a little worried that in the quest to reuse code you may have made the total amount of code executed larger and more susceptible to more cache line misses.
Quoted 1 line
From what Oleg has pointed out and from your the holes in your
description I am generally leery of this patchset as the attention to detail was appears lower than necessary for this to be more than a proof of concept.
Eric
Quoted 22 lines
---
Changes in v2:
- Removed redundant IDR function that was introduced in the previous patchset.
- RenamedPIDNS_HASH_ADDING
- Usedidr_for_each_entry_continue()
- Usedidr_find()to lookup pidsGargi Sharma (2):
pid: Replace pid bitmap implementation with IDR API
pid: Remove pidhasharch/powerpc/platforms/cell/spufs/sched.c | 2 +- fs/proc/loadavg.c | 2 +- include/linux/init_task.h | 1 - include/linux/pid.h | 2 - include/linux/pid_namespace.h | 18 +-- init/main.c | 3 +- kernel/fork.c | 2 +- kernel/pid.c | 239 +++++------------------------- kernel/pid_namespace.c | 54 +++---- 9 files changed, 68 insertions(+), 255 deletions(-)
A message that is not in the archive (sent off-list or not yet received): CAOCi2DESqWV2YPcRTe6NYjx6m6N19ewXbAyfLfeBa23kJiEO9Q@mail.gmail.com
Quoted 13 lines · Gargi Sharma
1000 processes that just sleep and sit around without doing anything(100 second sleep and then exit).
pstree with 10,000 processes
real 0m0.859s
user 0m0.536s
sys 0m0.172sps with 10,000 processes
real 0m0.918s
user 0m0.100s
sys 0m0.172s
Quoted 4 lines
Stats for calling readdir on /proc with 10,000 processes real 0m0.092s
user 0m0.000s
sys 0m0.020s
Is that with or without your patches?
How does it compare to a kernel with(out) your patches?
Signature · 1 line
All Rights Reversed.
Quoted 15 lines · Rik van Riel
Quoted 13 lines · Gargi Sharma
1000 processes that just sleep and sit around without doing anything(100 second sleep and then exit).
pstree with 10,000 processes
real 0m0.859s
user 0m0.536s
sys 0m0.172sps with 10,000 processes
real 0m0.918s
user 0m0.100s
sys 0m0.172s
Quoted 8 lines
Quoted 4 lines
Stats for calling readdir on /proc with 10,000 processes
real 0m0.092s
user 0m0.000s
sys 0m0.020sIs that with or without your patches?
How does it compare to a kernel with(out) your patches?
Ah thanks for pointing this out. Those were without the patches. Here are the stats for easier comparison.
With Patches Without patches
pstree
real 0m0.542s real 0m0.859s
user 0m0.335s user 0m0.536s
sys 0m0.150s sys 0m0.172s
ps
real 0m0.722s real 0m0.918s
user 0m0.064s user 0m0.100s
sys 0m0.162s sys 0m0.172s
readdir
real 0m0.080s real 0m0.092s
user 0m0.000s user 0m0.000s
sys 0m0.021s sys 0m0.020s
Thanks!
Gargi
Quoted 3 lines
--
All Rights Reversed.
Quoted 26 lines · Rik van Riel
Quoted 13 lines · Gargi Sharma
1000 processes that just sleep and sit around without doing anything(100 second sleep and then exit).
pstree with 10,000 processes
real 0m0.859s
user 0m0.536s
sys 0m0.172sps with 10,000 processes
real 0m0.918s
user 0m0.100s
sys 0m0.172sQuoted 4 lines
Stats for calling readdir on /proc with 10,000 processes
real 0m0.092s
user 0m0.000s
sys 0m0.020sIs that with or without your patches?
How does it compare to a kernel with(out) your patches?
--
All Rights Reversed.
Quoted 25 lines · Gargi Sharma
Quoted 8 lines · Rik van Riel
Quoted 2 lines · Gargi Sharma
1000 processes that just sleep and sit around without doing anything(100 second sleep and then exit).
Is that with or without your patches?
How does it compare to a kernel with(out) your patches?
Ah thanks for pointing this out. Those were without the patches. Here are the stats for easier comparison.
With Patches Without patches
pstree
real 0m0.542s real 0m0.859s
user 0m0.335s user 0m0.536s
sys 0m0.150s sys 0m0.172sps
real 0m0.722s real 0m0.918s
user 0m0.064s user 0m0.100s
sys 0m0.162s sys 0m0.172s
Quoted 4 lines
readdir
real 0m0.080s real 0m0.092s
user 0m0.000s user 0m0.000s
sys 0m0.021s sys 0m0.020s
So your patches speed up the use of /proc?
I suspect pstree and ps benefit from the simplification and speedup of find_pid_ns, which is called from find_task_by_pid_ns.
That is great news.
Signature · 1 line
All Rights Reversed.