Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 24588
b: refs/heads/master
c: 224b148
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Mar 29, 2006
1 parent f85a531 commit 969e84e
Show file tree
Hide file tree
Showing 17 changed files with 310 additions and 522 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c0e4077c946104e5d8a62f835dcdca5c79c8af7d
refs/heads/master: 224b148ef7c9a00642eb33dbdf62f2840bde974f
4 changes: 2 additions & 2 deletions trunk/arch/mips/kernel/irixsig.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ asmlinkage int irix_waitsys(int type, int pid,
/* move to end of parent's list to avoid starvation */
write_lock_irq(&tasklist_lock);
remove_parent(p);
add_parent(p, p->parent);
add_parent(p);
write_unlock_irq(&tasklist_lock);
retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
if (retval)
Expand Down Expand Up @@ -643,7 +643,7 @@ asmlinkage int irix_waitsys(int type, int pid,
write_lock_irq(&tasklist_lock);
remove_parent(p);
p->parent = p->real_parent;
add_parent(p, p->parent);
add_parent(p);
do_notify_parent(p, SIGCHLD);
write_unlock_irq(&tasklist_lock);
} else
Expand Down
1 change: 0 additions & 1 deletion trunk/arch/um/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ void smp_prepare_cpus(unsigned int maxcpus)
idle = idle_thread(cpu);

init_idle(idle, cpu);
unhash_process(idle);

waittime = 200000000;
while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
Expand Down
20 changes: 15 additions & 5 deletions trunk/drivers/char/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1094,8 +1094,8 @@ static void do_tty_hangup(void *data)
p->signal->tty = NULL;
if (!p->signal->leader)
continue;
send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p);
send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p);
group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
if (tty->pgrp > 0)
p->signal->tty_old_pgrp = tty->pgrp;
} while_each_task_pid(tty->session, PIDTYPE_SID, p);
Expand Down Expand Up @@ -2672,7 +2672,7 @@ static void __do_SAK(void *arg)
tty_hangup(tty);
#else
struct tty_struct *tty = arg;
struct task_struct *p;
struct task_struct *g, *p;
int session;
int i;
struct file *filp;
Expand All @@ -2693,8 +2693,18 @@ static void __do_SAK(void *arg)
tty->driver->flush_buffer(tty);

read_lock(&tasklist_lock);
/* Kill the entire session */
do_each_task_pid(session, PIDTYPE_SID, p) {
if (p->signal->tty == tty || session > 0) {
printk(KERN_NOTICE "SAK: killed process %d"
" (%s): p->signal->session==tty->session\n",
p->pid, p->comm);
send_sig(SIGKILL, p, 1);
} while_each_task_pid(session, PIDTYPE_SID, p);
/* Now kill any processes that happen to have the
* tty open.
*/
do_each_thread(g, p) {
if (p->signal->tty == tty) {
printk(KERN_NOTICE "SAK: killed process %d"
" (%s): p->signal->session==tty->session\n",
p->pid, p->comm);
Expand All @@ -2721,7 +2731,7 @@ static void __do_SAK(void *arg)
rcu_read_unlock();
}
task_unlock(p);
} while_each_task_pid(session, PIDTYPE_SID, p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
#endif
}
Expand Down
30 changes: 23 additions & 7 deletions trunk/fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,15 @@ static int de_thread(struct task_struct *tsk)
kmem_cache_free(sighand_cachep, newsighand);
return -EAGAIN;
}

/*
* child_reaper ignores SIGKILL, change it now.
* Reparenting needs write_lock on tasklist_lock,
* so it is safe to do it under read_lock.
*/
if (unlikely(current->group_leader == child_reaper))
child_reaper = current;

zap_other_threads(current);
read_unlock(&tasklist_lock);

Expand Down Expand Up @@ -699,22 +708,30 @@ static int de_thread(struct task_struct *tsk)
remove_parent(current);
remove_parent(leader);

switch_exec_pids(leader, current);

/* Become a process group leader with the old leader's pid.
* Note: The old leader also uses thispid until release_task
* is called. Odd but simple and correct.
*/
detach_pid(current, PIDTYPE_PID);
current->pid = leader->pid;
attach_pid(current, PIDTYPE_PID, current->pid);
attach_pid(current, PIDTYPE_PGID, current->signal->pgrp);
attach_pid(current, PIDTYPE_SID, current->signal->session);
list_add_tail(&current->tasks, &init_task.tasks);

current->parent = current->real_parent = leader->real_parent;
leader->parent = leader->real_parent = child_reaper;
current->group_leader = current;
leader->group_leader = leader;

add_parent(current, current->parent);
add_parent(leader, leader->parent);
add_parent(current);
add_parent(leader);
if (ptrace) {
current->ptrace = ptrace;
__ptrace_link(current, parent);
}

list_del(&current->tasks);
list_add_tail(&current->tasks, &init_task.tasks);
current->exit_signal = SIGCHLD;

BUG_ON(leader->exit_state != EXIT_ZOMBIE);
Expand Down Expand Up @@ -751,7 +768,6 @@ static int de_thread(struct task_struct *tsk)
/*
* Move our state over to newsighand and switch it in.
*/
spin_lock_init(&newsighand->siglock);
atomic_set(&newsighand->count, 1);
memcpy(newsighand->action, oldsighand->action,
sizeof(newsighand->action));
Expand All @@ -768,7 +784,7 @@ static int de_thread(struct task_struct *tsk)
write_unlock_irq(&tasklist_lock);

if (atomic_dec_and_test(&oldsighand->count))
sighand_free(oldsighand);
kmem_cache_free(sighand_cachep, oldsighand);
}

BUG_ON(!thread_group_leader(current));
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/init_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
.posix_timers = LIST_HEAD_INIT(sig.posix_timers), \
.cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \
.rlim = INIT_RLIMITS, \
.pgrp = 1, \
.session = 1, \
}

#define INIT_SIGHAND(sighand) { \
Expand Down
2 changes: 0 additions & 2 deletions trunk/include/linux/pid.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
enum pid_type
{
PIDTYPE_PID,
PIDTYPE_TGID,
PIDTYPE_PGID,
PIDTYPE_SID,
PIDTYPE_MAX
Expand Down Expand Up @@ -38,7 +37,6 @@ extern struct pid *FASTCALL(find_pid(enum pid_type, int));

extern int alloc_pidmap(void);
extern void FASTCALL(free_pidmap(int));
extern void switch_exec_pids(struct task_struct *leader, struct task_struct *thread);

#define do_each_task_pid(who, type, task) \
if ((task = find_task_by_pid_type(type, who))) { \
Expand Down
51 changes: 20 additions & 31 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,16 +355,8 @@ struct sighand_struct {
atomic_t count;
struct k_sigaction action[_NSIG];
spinlock_t siglock;
struct rcu_head rcu;
};

extern void sighand_free_cb(struct rcu_head *rhp);

static inline void sighand_free(struct sighand_struct *sp)
{
call_rcu(&sp->rcu, sighand_free_cb);
}

/*
* NOTE! "signal_struct" does not have it's own
* locking, because a shared signal_struct always
Expand Down Expand Up @@ -760,6 +752,7 @@ struct task_struct {

/* PID/PID hash table linkage. */
struct pid pids[PIDTYPE_MAX];
struct list_head thread_group;

struct completion *vfork_done; /* for vfork() */
int __user *set_child_tid; /* CLONE_CHILD_SETTID */
Expand Down Expand Up @@ -1101,7 +1094,6 @@ extern void force_sig_specific(int, struct task_struct *);
extern int send_sig(int, struct task_struct *, int);
extern void zap_other_threads(struct task_struct *p);
extern int kill_pg(pid_t, int, int);
extern int kill_sl(pid_t, int, int);
extern int kill_proc(pid_t, int, int);
extern struct sigqueue *sigqueue_alloc(void);
extern void sigqueue_free(struct sigqueue *);
Expand Down Expand Up @@ -1158,10 +1150,8 @@ extern void flush_thread(void);
extern void exit_thread(void);

extern void exit_files(struct task_struct *);
extern void exit_signal(struct task_struct *);
extern void __exit_signal(struct task_struct *);
extern void exit_sighand(struct task_struct *);
extern void __exit_sighand(struct task_struct *);
extern void __cleanup_signal(struct signal_struct *);
extern void __cleanup_sighand(struct sighand_struct *);
extern void exit_itimers(struct signal_struct *);

extern NORET_TYPE void do_group_exit(int);
Expand All @@ -1185,19 +1175,7 @@ extern void wait_task_inactive(task_t * p);
#endif

#define remove_parent(p) list_del_init(&(p)->sibling)
#define add_parent(p, parent) list_add_tail(&(p)->sibling,&(parent)->children)

#define REMOVE_LINKS(p) do { \
if (thread_group_leader(p)) \
list_del_init(&(p)->tasks); \
remove_parent(p); \
} while (0)

#define SET_LINKS(p) do { \
if (thread_group_leader(p)) \
list_add_tail(&(p)->tasks,&init_task.tasks); \
add_parent(p, (p)->parent); \
} while (0)
#define add_parent(p) list_add_tail(&(p)->sibling,&(p)->parent->children)

#define next_task(p) list_entry((p)->tasks.next, struct task_struct, tasks)
#define prev_task(p) list_entry((p)->tasks.prev, struct task_struct, tasks)
Expand All @@ -1215,20 +1193,22 @@ extern void wait_task_inactive(task_t * p);
#define while_each_thread(g, t) \
while ((t = next_thread(t)) != g)

extern task_t * FASTCALL(next_thread(const task_t *p));

#define thread_group_leader(p) (p->pid == p->tgid)

static inline task_t *next_thread(task_t *p)
{
return list_entry(rcu_dereference(p->thread_group.next),
task_t, thread_group);
}

static inline int thread_group_empty(task_t *p)
{
return list_empty(&p->pids[PIDTYPE_TGID].pid_list);
return list_empty(&p->thread_group);
}

#define delay_group_leader(p) \
(thread_group_leader(p) && !thread_group_empty(p))

extern void unhash_process(struct task_struct *p);

/*
* Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring
* subscriptions and synchronises with wait4(). Also used in procfs. Also
Expand All @@ -1248,6 +1228,15 @@ static inline void task_unlock(struct task_struct *p)
spin_unlock(&p->alloc_lock);
}

extern struct sighand_struct *lock_task_sighand(struct task_struct *tsk,
unsigned long *flags);

static inline void unlock_task_sighand(struct task_struct *tsk,
unsigned long *flags)
{
spin_unlock_irqrestore(&tsk->sighand->siglock, *flags);
}

#ifndef __HAVE_THREAD_FUNCTIONS

#define task_thread_info(task) (task)->thread_info
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ static inline void init_sigpending(struct sigpending *sig)
INIT_LIST_HEAD(&sig->list);
}

extern void flush_sigqueue(struct sigpending *queue);

/* Test if 'sig' is valid signal. Use this instead of testing _NSIG directly */
static inline int valid_signal(unsigned long sig)
{
Expand Down
1 change: 0 additions & 1 deletion trunk/include/linux/slab.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ extern kmem_cache_t *names_cachep;
extern kmem_cache_t *files_cachep;
extern kmem_cache_t *filp_cachep;
extern kmem_cache_t *fs_cachep;
extern kmem_cache_t *signal_cachep;
extern kmem_cache_t *sighand_cachep;
extern kmem_cache_t *bio_cachep;

Expand Down
Loading

0 comments on commit 969e84e

Please sign in to comment.