summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorNick Piggin <nickpiggin@yahoo.com.au>2004-08-30 20:36:01 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-30 20:36:01 -0700
commitf59ad67e9647b385fd8738b3757ce9be2369bcbc (patch)
treebdf25e24e42dd4c5c1d4b219d486d5a8ed47070b /kernel
parent2c05d9eb31eac02a105f2b05c144272f8b382864 (diff)
[PATCH] use hlist for pid hash
Use hlists for the PID hashes. This halves the memory footprint of these hashes. No benchmarks, but I think this is a worthy improvement because the hashes are something that would be likely to have significant portions loaded into the cache of every CPU on some workloads. This comes at the "expense" of 1. reintroducing the memory prefetch into the hash traversal loop; 2. adding new pids to the head of the list instead of the tail. I suspect that if this was a big problem then the hash isn't sized well or could benefit from moving hot entries to the head. Also, account for all the pid hashes when reporting hash memory usage. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/pid.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/kernel/pid.c b/kernel/pid.c
index 11d834532302..8c9b7510174a 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -27,7 +27,7 @@
#include <linux/hash.h>
#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
-static struct list_head *pid_hash[PIDTYPE_MAX];
+static struct hlist_head *pid_hash[PIDTYPE_MAX];
static int pidhash_shift;
int pid_max = PID_MAX_DEFAULT;
@@ -148,11 +148,11 @@ failure:
fastcall struct pid *find_pid(enum pid_type type, int nr)
{
- struct list_head *elem, *bucket = &pid_hash[type][pid_hashfn(nr)];
+ struct hlist_node *elem;
struct pid *pid;
- __list_for_each(elem, bucket) {
- pid = list_entry(elem, struct pid, hash_chain);
+ hlist_for_each_entry(pid, elem,
+ &pid_hash[type][pid_hashfn(nr)], hash_chain) {
if (pid->nr == nr)
return pid;
}
@@ -179,7 +179,8 @@ int fastcall attach_pid(task_t *task, enum pid_type type, int nr)
INIT_LIST_HEAD(&pid->task_list);
pid->task = task;
get_task_struct(task);
- list_add(&pid->hash_chain, &pid_hash[type][pid_hashfn(nr)]);
+ hlist_add_head(&pid->hash_chain,
+ &pid_hash[type][pid_hashfn(nr)]);
}
list_add_tail(&task->pids[type].pid_chain, &pid->task_list);
task->pids[type].pidptr = pid;
@@ -198,7 +199,7 @@ static inline int __detach_pid(task_t *task, enum pid_type type)
return 0;
nr = pid->nr;
- list_del(&pid->hash_chain);
+ hlist_del(&pid->hash_chain);
put_task_struct(pid->task);
return nr;
@@ -277,9 +278,9 @@ void __init pidhash_init(void)
pidhash_shift = min(12, pidhash_shift);
pidhash_size = 1 << pidhash_shift;
- printk("PID hash table entries: %d (order %d: %Zd bytes)\n",
+ printk("PID hash table entries: %d (order: %d, %Zd bytes)\n",
pidhash_size, pidhash_shift,
- pidhash_size * sizeof(struct list_head));
+ PIDTYPE_MAX * pidhash_size * sizeof(struct hlist_head));
for (i = 0; i < PIDTYPE_MAX; i++) {
pid_hash[i] = alloc_bootmem(pidhash_size *
@@ -287,7 +288,7 @@ void __init pidhash_init(void)
if (!pid_hash[i])
panic("Could not alloc pidhash!\n");
for (j = 0; j < pidhash_size; j++)
- INIT_LIST_HEAD(&pid_hash[i][j]);
+ INIT_HLIST_HEAD(&pid_hash[i][j]);
}
}