Commit e5b36baf authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Create a per-cpu proces counter for /proc reporting

proc_fill_super() simply wants a count of processes, not threads.
This creates a per-cpu counter for it to use to determine that.
parent 82184668
...@@ -221,7 +221,6 @@ printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&d ...@@ -221,7 +221,6 @@ printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&d
int proc_fill_super(struct super_block *s, void *data, int silent) int proc_fill_super(struct super_block *s, void *data, int silent)
{ {
struct inode * root_inode; struct inode * root_inode;
struct task_struct *p;
s->s_blocksize = 1024; s->s_blocksize = 1024;
s->s_blocksize_bits = 10; s->s_blocksize_bits = 10;
...@@ -234,11 +233,7 @@ int proc_fill_super(struct super_block *s, void *data, int silent) ...@@ -234,11 +233,7 @@ int proc_fill_super(struct super_block *s, void *data, int silent)
/* /*
* Fixup the root inode's nlink value * Fixup the root inode's nlink value
*/ */
read_lock(&tasklist_lock); root_inode->i_nlink += nr_processes();
for_each_process(p)
if (p->pid)
root_inode->i_nlink++;
read_unlock(&tasklist_lock);
s->s_root = d_alloc_root(root_inode); s->s_root = d_alloc_root(root_inode);
if (!s->s_root) if (!s->s_root)
goto out_no_root; goto out_no_root;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/pid.h> #include <linux/pid.h>
#include <linux/percpu.h>
struct exec_domain; struct exec_domain;
...@@ -87,6 +88,8 @@ extern unsigned long avenrun[]; /* Load averages */ ...@@ -87,6 +88,8 @@ extern unsigned long avenrun[]; /* Load averages */
extern int nr_threads; extern int nr_threads;
extern int last_pid; extern int last_pid;
DECLARE_PER_CPU(unsigned long, process_counts);
extern int nr_processes(void);
extern unsigned long nr_running(void); extern unsigned long nr_running(void);
extern unsigned long nr_uninterruptible(void); extern unsigned long nr_uninterruptible(void);
extern unsigned long nr_iowait(void); extern unsigned long nr_iowait(void);
......
...@@ -41,6 +41,8 @@ static struct dentry * __unhash_process(struct task_struct *p) ...@@ -41,6 +41,8 @@ static struct dentry * __unhash_process(struct task_struct *p)
if (thread_group_leader(p)) { if (thread_group_leader(p)) {
detach_pid(p, PIDTYPE_PGID); detach_pid(p, PIDTYPE_PGID);
detach_pid(p, PIDTYPE_SID); detach_pid(p, PIDTYPE_SID);
if (p->pid)
per_cpu(process_counts, smp_processor_id())--;
} }
REMOVE_LINKS(p); REMOVE_LINKS(p);
......
...@@ -48,6 +48,8 @@ int nr_threads; ...@@ -48,6 +48,8 @@ int nr_threads;
int max_threads; int max_threads;
unsigned long total_forks; /* Handle normal Linux uptimes. */ unsigned long total_forks; /* Handle normal Linux uptimes. */
DEFINE_PER_CPU(unsigned long, process_counts) = 0;
rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */ rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */
/* /*
...@@ -57,6 +59,18 @@ rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */ ...@@ -57,6 +59,18 @@ rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED; /* outer */
*/ */
static task_t *task_cache[NR_CPUS] __cacheline_aligned; static task_t *task_cache[NR_CPUS] __cacheline_aligned;
int nr_processes(void)
{
int cpu;
int total = 0;
for (cpu = 0; cpu < NR_CPUS; cpu++) {
if (cpu_online(cpu))
total += per_cpu(process_counts, cpu);
}
return total;
}
void __put_task_struct(struct task_struct *tsk) void __put_task_struct(struct task_struct *tsk)
{ {
if (tsk != current) { if (tsk != current) {
...@@ -931,6 +945,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, ...@@ -931,6 +945,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
attach_pid(p, PIDTYPE_TGID, p->tgid); attach_pid(p, PIDTYPE_TGID, p->tgid);
attach_pid(p, PIDTYPE_PGID, p->pgrp); attach_pid(p, PIDTYPE_PGID, p->pgrp);
attach_pid(p, PIDTYPE_SID, p->session); attach_pid(p, PIDTYPE_SID, p->session);
if (p->pid)
per_cpu(process_counts, smp_processor_id())++;
} else } else
link_pid(p, p->pids + PIDTYPE_TGID, &p->group_leader->pids[PIDTYPE_TGID].pid); link_pid(p, p->pids + PIDTYPE_TGID, &p->group_leader->pids[PIDTYPE_TGID].pid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment