#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/hash.h>
-#include <linux/vs_cvirt.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;
return -1;
}
-fastcall struct pid *find_pid(enum pid_type type, int nr)
+struct pid * fastcall 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)], pid_chain) {
if (pid->nr == nr)
return pid;
}
return NULL;
}
-void fastcall link_pid(task_t *task, struct pid_link *link, struct pid *pid)
-{
- atomic_inc(&pid->count);
- list_add_tail(&link->pid_chain, &pid->task_list);
- link->pidptr = pid;
-}
-
int fastcall attach_pid(task_t *task, enum pid_type type, int nr)
{
- struct pid *pid = find_pid(type, nr);
-
- if (pid)
- atomic_inc(&pid->count);
- else {
- pid = &task->pids[type].pid;
- pid->nr = nr;
- atomic_set(&pid->count, 1);
- INIT_LIST_HEAD(&pid->task_list);
- pid->task = task;
- get_task_struct(task);
- list_add(&pid->hash_chain, &pid_hash[type][pid_hashfn(nr)]);
+ struct pid *pid, *task_pid;
+
+ task_pid = &task->pids[type];
+ pid = find_pid(type, nr);
+ if (pid == NULL) {
+ hlist_add_head(&task_pid->pid_chain,
+ &pid_hash[type][pid_hashfn(nr)]);
+ INIT_LIST_HEAD(&task_pid->pid_list);
+ } else {
+ INIT_HLIST_NODE(&task_pid->pid_chain);
+ list_add_tail(&task_pid->pid_list, &pid->pid_list);
}
- list_add_tail(&task->pids[type].pid_chain, &pid->task_list);
- task->pids[type].pidptr = pid;
+ task_pid->nr = nr;
return 0;
}
static inline int __detach_pid(task_t *task, enum pid_type type)
{
- struct pid_link *link = task->pids + type;
- struct pid *pid = link->pidptr;
+ struct pid *pid, *pid_next;
int nr;
- list_del(&link->pid_chain);
- if (!atomic_dec_and_test(&pid->count))
- return 0;
-
+ pid = &task->pids[type];
+ if (!hlist_unhashed(&pid->pid_chain)) {
+ hlist_del(&pid->pid_chain);
+ if (!list_empty(&pid->pid_list)) {
+ pid_next = list_entry(pid->pid_list.next,
+ struct pid, pid_list);
+ /* insert next pid from pid_list to hash */
+ hlist_add_head(&pid_next->pid_chain,
+ &pid_hash[type][pid_hashfn(pid_next->nr)]);
+ }
+ }
+ list_del(&pid->pid_list);
nr = pid->nr;
- list_del(&pid->hash_chain);
- put_task_struct(pid->task);
+ pid->nr = 0;
return nr;
}
-static void _detach_pid(task_t *task, enum pid_type type)
-{
- __detach_pid(task, type);
-}
-
void fastcall detach_pid(task_t *task, enum pid_type type)
{
- int nr = __detach_pid(task, type);
+ int nr;
+ nr = __detach_pid(task, type);
if (!nr)
return;
free_pidmap(nr);
}
-task_t *find_task_by_pid(int nr)
+task_t *find_task_by_pid_type(int type, int nr)
{
- struct pid *pid = find_pid(PIDTYPE_PID,
- vx_rmap_tgid(current->vx_info, nr));
+ struct pid *pid;
+ pid = find_pid(type, nr);
if (!pid)
return NULL;
- return pid_task(pid->task_list.next, PIDTYPE_PID);
+
+ return pid_task(&pid->pid_list, type);
}
-EXPORT_SYMBOL(find_task_by_pid);
+EXPORT_SYMBOL(find_task_by_pid_type);
/*
* This function switches the PIDs if a non-leader thread calls
*/
void switch_exec_pids(task_t *leader, task_t *thread)
{
- _detach_pid(leader, PIDTYPE_PID);
- _detach_pid(leader, PIDTYPE_TGID);
- _detach_pid(leader, PIDTYPE_PGID);
- _detach_pid(leader, PIDTYPE_SID);
+ __detach_pid(leader, PIDTYPE_PID);
+ __detach_pid(leader, PIDTYPE_TGID);
+ __detach_pid(leader, PIDTYPE_PGID);
+ __detach_pid(leader, PIDTYPE_SID);
- _detach_pid(thread, PIDTYPE_PID);
- _detach_pid(thread, PIDTYPE_TGID);
+ __detach_pid(thread, PIDTYPE_PID);
+ __detach_pid(thread, PIDTYPE_TGID);
leader->pid = leader->tgid = thread->pid;
thread->pid = thread->tgid;
void __init pidhash_init(void)
{
int i, j, pidhash_size;
- unsigned long megabytes = max_pfn >> (20 - PAGE_SHIFT);
+ unsigned long megabytes = nr_kernel_pages >> (20 - PAGE_SHIFT);
pidhash_shift = max(4, fls(megabytes * 4));
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 *
- sizeof(struct list_head));
+ sizeof(*(pid_hash[i])));
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]);
}
}