]> git.hungrycats.org Git - linux/commitdiff
[PATCH] hide-threads-2.5.34-C1
authorIngo Molnar <mingo@elte.hu>
Sat, 14 Sep 2002 02:35:26 +0000 (19:35 -0700)
committerIngo Molnar <mingo@elte.hu>
Sat, 14 Sep 2002 02:35:26 +0000 (19:35 -0700)
I fixed up the 'remove thread group inferiors from the tasklist' patch. I
think i managed to find a reasonably good construct to iterate over all
threads:

do_each_thread(g, p) {
...
} while_each_thread(g, p);

the only caveat with this is that the construct suggests a single-loop -
while it's two loops internally - and 'break' will not work. I added a
comment to sched.h that warns about this, but perhaps it would help more
to have naming that suggests two loops:

for_each_process_do_each_thread(g, p) {
...
} while_each_thread(g, p);

but this looks a bit too long. I dont know. We might as well use it all
unrolled and no helper macros - although with the above construct it's
pretty straightforward to iterate over all threads in the system.

18 files changed:
arch/i386/kernel/vm86.c
drivers/char/sysrq.c
drivers/char/tty_io.c
fs/fcntl.c
fs/namespace.c
fs/proc/base.c
fs/proc/inode.c
include/linux/sched.h
kernel/capability.c
kernel/exit.c
kernel/fork.c
kernel/sched.c
kernel/signal.c
kernel/suspend.c
kernel/sys.c
mm/oom_kill.c
net/ipv4/netfilter/ipt_owner.c
net/ipv6/netfilter/ip6t_owner.c

index 90b273f1cb5b6a5d0ea1ad6482278a43cdbce2ed..a0fcf591080a101f9f0af59a048cf184db1f8452 100644 (file)
@@ -608,16 +608,17 @@ static inline void free_vm86_irq(int irqnumber)
 
 static inline int task_valid(struct task_struct *tsk)
 {
-       struct task_struct *p;
+       struct task_struct *g, *p;
        int ret = 0;
 
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       do_each_thread(g, p)
                if ((p == tsk) && (p->sig)) {
                        ret = 1;
-                       break;
+                       goto out;
                }
-       }
+       while_each_thread(g, p);
+out:
        read_unlock(&tasklist_lock);
        return ret;
 }
index dc64c9071787d351b1d9478b374bec370390ed35..bb98bc23500462423c70eb4c05cf8b1bab4ad231 100644 (file)
@@ -299,7 +299,7 @@ static void send_sig_all(int sig)
 {
        struct task_struct *p;
 
-       for_each_task(p) {
+       for_each_process(p) {
                if (p->mm && p->pid != 1)
                        /* Not swapper, init nor kernel thread */
                        force_sig(sig, p);
index f9fd6deb583c09736d4617b57c8fb52f79135ec3..9746fb9c1117f987dc7cbcff634bbe6c5a1536c6 100644 (file)
@@ -496,7 +496,7 @@ void do_tty_hangup(void *data)
        }
        
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       for_each_process(p) {
                if ((tty->session > 0) && (p->session == tty->session) &&
                    p->leader) {
                        send_sig(SIGHUP,p,1);
@@ -598,7 +598,7 @@ void disassociate_ctty(int on_exit)
        tty->pgrp = -1;
 
        read_lock(&tasklist_lock);
-       for_each_task(p)
+       for_each_process(p)
                if (p->session == current->session)
                        p->tty = NULL;
        read_unlock(&tasklist_lock);
@@ -1223,7 +1223,7 @@ static void release_dev(struct file * filp)
                struct task_struct *p;
 
                read_lock(&tasklist_lock);
-               for_each_task(p) {
+               for_each_process(p) {
                        if (p->tty == tty || (o_tty && p->tty == o_tty))
                                p->tty = NULL;
                }
@@ -1561,7 +1561,7 @@ static int tiocsctty(struct tty_struct *tty, int arg)
                        struct task_struct *p;
 
                        read_lock(&tasklist_lock);
-                       for_each_task(p)
+                       for_each_process(p)
                                if (p->tty == tty)
                                        p->tty = NULL;
                        read_unlock(&tasklist_lock);
@@ -1834,7 +1834,7 @@ static void __do_SAK(void *arg)
        if (tty->driver.flush_buffer)
                tty->driver.flush_buffer(tty);
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       for_each_process(p) {
                if ((p->tty == tty) ||
                    ((session > 0) && (p->session == session))) {
                        printk(KERN_NOTICE "SAK: killed process %d"
index c68baf1f81da442e3d0990f70d24a2deb39899e8..4a87786a0a43f1c332c665299e0af3b3471fa0aa 100644 (file)
@@ -493,7 +493,7 @@ void send_sigio(struct fown_struct *fown, int fd, int band)
                send_sigio_to_task(p, fown, fd, band);
                goto out_unlock_task;
        }
-       for_each_task(p) {
+       for_each_process(p) {
                int match = p->pid;
                if (pid < 0)
                        match = -p->pgrp;
@@ -531,7 +531,7 @@ int send_sigurg(struct fown_struct *fown)
                send_sigurg_to_task(p, fown);
                goto out_unlock_task;
        }
-       for_each_task(p) {
+       for_each_process(p) {
                int match = p->pid;
                if (pid < 0)
                        match = -p->pgrp;
index 79a4c5a459e8de21473d54e07c83b6dfaaab8800..3f2f41aa15cdff6d314f4f77efdf913ed2a4331e 100644 (file)
@@ -883,11 +883,11 @@ out1:
 
 static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
 {
-       struct task_struct *p;
+       struct task_struct *g, *p;
        struct fs_struct *fs;
 
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       do_each_thread(g, p) {
                task_lock(p);
                fs = p->fs;
                if (fs) {
@@ -900,7 +900,7 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
                        put_fs_struct(fs);
                } else
                        task_unlock(p);
-       }
+       } while_each_thread(g, p);
        read_unlock(&tasklist_lock);
 }
 
@@ -1012,7 +1012,7 @@ static void __init init_mount_tree(void)
 {
        struct vfsmount *mnt;
        struct namespace *namespace;
-       struct task_struct *p;
+       struct task_struct *g, *p;
 
        mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
        if (IS_ERR(mnt))
@@ -1028,10 +1028,10 @@ static void __init init_mount_tree(void)
 
        init_task.namespace = namespace;
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       do_each_thread(g, p) {
                get_namespace(namespace);
                p->namespace = namespace;
-       }
+       } while_each_thread(g, p);
        read_unlock(&tasklist_lock);
 
        set_fs_pwd(current->fs, namespace->root, namespace->root->mnt_root);
index 7dd33906d6d5329d8a1e96285738ff126cb71668..f82541d8e29a6588da9a04633d8bc6516d2862eb 100644 (file)
@@ -1136,7 +1136,7 @@ static int get_pid_list(int index, unsigned int *pids)
 
        index--;
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       for_each_process(p) {
                int pid = p->pid;
                if (!pid)
                        continue;
index 2a7bb8eec4d896caa1f09387f92fd277143833de..86785974eeb283a58100f12bab10fab2c8a72b15 100644 (file)
@@ -235,7 +235,9 @@ int proc_fill_super(struct super_block *s, void *data, int silent)
         * Fixup the root inode's nlink value
         */
        read_lock(&tasklist_lock);
-       for_each_task(p) if (p->pid) root_inode->i_nlink++;
+       for_each_process(p)
+               if (p->pid)
+                       root_inode->i_nlink++;
        read_unlock(&tasklist_lock);
        s->s_root = d_alloc_root(root_inode);
        if (!s->s_root)
index 337b2f3965892b16c5470815e3de63f06d5fe409..5a7e7c21009f3e7023575bb76fd7acc13392e130 100644 (file)
@@ -760,14 +760,16 @@ static inline void remove_wait_queue_locked(wait_queue_head_t *q,
 #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 {                           \
-       list_del_init(&(p)->tasks);                     \
-       remove_parent(p);                               \
+#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 {                              \
-       list_add_tail(&(p)->tasks,&init_task.tasks);    \
-       add_parent(p, (p)->parent);                     \
+#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)
 
 static inline struct task_struct *eldest_child(struct task_struct *p)
@@ -797,11 +799,18 @@ static inline struct task_struct *younger_sibling(struct task_struct *p)
 #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)
 
-#define for_each_task(p) \
+#define for_each_process(p) \
        for (p = &init_task ; (p = next_task(p)) != &init_task ; )
 
-#define for_each_thread(task) \
-       for (task = next_thread(current) ; task != current ; task = next_thread(task))
+/*
+ * Careful: do_each_thread/while_each_thread is a double loop so
+ *          'break' will not work as expected - use goto instead.
+ */
+#define do_each_thread(g, t) \
+       for (g = t = &init_task ; (g = t = next_task(g)) != &init_task ; ) do
+
+#define while_each_thread(g, t) \
+       while ((t = next_thread(t)) != g)
 
 static inline task_t *next_thread(task_t *p)
 {
index 223d22dece42028a54821f6893e958d61952d075..774cf612d8c5d0ec276dedb070306e9f1f99aef0 100644 (file)
@@ -83,13 +83,13 @@ static inline void cap_set_pg(int pgrp, kernel_cap_t *effective,
                              kernel_cap_t *inheritable,
                              kernel_cap_t *permitted)
 {
-     task_t *target;
+     task_t *g, *target;
 
-     for_each_task(target) {
+     do_each_thread(g, target) {
              if (target->pgrp != pgrp)
                      continue;
             security_ops->capset_set(target, effective, inheritable, permitted);
-     }
+     } while_each_thread(g, target);
 }
 
 /*
@@ -100,13 +100,13 @@ static inline void cap_set_all(kernel_cap_t *effective,
                               kernel_cap_t *inheritable,
                               kernel_cap_t *permitted)
 {
-     task_t *target;
+     task_t *g, *target;
 
-     for_each_task(target) {
+     do_each_thread(g, target) {
              if (target == current || target->pid == 1)
                      continue;
             security_ops->capset_set(target, effective, inheritable, permitted);
-     }
+     } while_each_thread(g, target);
 }
 
 /*
index 49f279e1a004b3b480111fecc07f90a60fa8e038..115a7cd7b8073f3ca45fcd129e292bdf446e086b 100644 (file)
@@ -115,7 +115,7 @@ int session_of_pgrp(int pgrp)
 
        fallback = -1;
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       for_each_process(p) {
                if (p->session <= 0)
                        continue;
                if (p->pgrp == pgrp) {
@@ -141,7 +141,7 @@ static int __will_become_orphaned_pgrp(int pgrp, struct task_struct * ignored_ta
 {
        struct task_struct *p;
 
-       for_each_task(p) {
+       for_each_process(p) {
                if ((p == ignored_task) || (p->pgrp != pgrp) ||
                    (p->state == TASK_ZOMBIE) ||
                    (p->parent->pid == 1))
@@ -175,7 +175,7 @@ static inline int __has_stopped_jobs(int pgrp)
        int retval = 0;
        struct task_struct * p;
 
-       for_each_task(p) {
+       for_each_process(p) {
                if (p->pgrp != pgrp)
                        continue;
                if (p->state != TASK_STOPPED)
index b210f1ee459bb12bec3a9e5d8457f69bdfa2fa21..dec0136c59f1fe0bd6fcb561d16cae9387771fb2 100644 (file)
@@ -161,7 +161,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
 
 static int get_pid(unsigned long flags)
 {
-       struct task_struct *p;
+       struct task_struct *g, *p;
        int pid;
 
        if (flags & CLONE_IDLETASK)
@@ -178,7 +178,7 @@ inside:
                next_safe = pid_max;
                read_lock(&tasklist_lock);
        repeat:
-               for_each_task(p) {
+               do_each_thread(g, p) {
                        if (p->pid == last_pid  ||
                           p->pgrp == last_pid  ||
                           p->session == last_pid) {
@@ -195,7 +195,8 @@ inside:
                                next_safe = p->pgrp;
                        if (p->session > last_pid && next_safe > p->session)
                                next_safe = p->session;
-               }
+               } while_each_thread(g, p);
+
                read_unlock(&tasklist_lock);
        }
        pid = last_pid;
index b094fa97b9b6984a77afcac83194a944e4b40eca..806b30b9da73de5399d3308e8c743040b7380b77 100644 (file)
@@ -1838,7 +1838,7 @@ char * render_sigset_t(sigset_t *set, char *buffer)
 
 void show_state(void)
 {
-       task_t *p;
+       task_t *g, *p;
 
 #if (BITS_PER_LONG == 32)
        printk("\n"
@@ -1850,14 +1850,15 @@ void show_state(void)
        printk("  task                 PC        stack   pid father child younger older\n");
 #endif
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       do_each_thread(g, p) {
                /*
                 * reset the NMI-timeout, listing all files on a slow
                 * console might take alot of time:
                 */
                touch_nmi_watchdog();
                show_task(p);
-       }
+       } while_each_thread(g, p);
+
        read_unlock(&tasklist_lock);
 }
 
index 3052e34af8cc54dbd6a696dc02dfc356fb74d440..a897b044b07dd422a82d3e6e2555566c6f4763e6 100644 (file)
@@ -938,8 +938,8 @@ int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
                struct task_struct *p;
 
                retval = -ESRCH;
-               for_each_task(p) {
-                       if (p->pgrp == pgrp && thread_group_leader(p)) {
+               for_each_process(p) {
+                       if (p->pgrp == pgrp) {
                                int err = send_sig_info(sig, info, p);
                                if (retval)
                                        retval = err;
@@ -976,7 +976,7 @@ kill_sl_info(int sig, struct siginfo *info, pid_t sess)
 
                retval = -ESRCH;
                read_lock(&tasklist_lock);
-               for_each_task(p) {
+               for_each_process(p) {
                        if (p->leader && p->session == sess) {
                                int err = send_sig_info(sig, info, p);
                                if (retval)
@@ -1020,8 +1020,8 @@ static int kill_something_info(int sig, struct siginfo *info, int pid)
                struct task_struct * p;
 
                read_lock(&tasklist_lock);
-               for_each_task(p) {
-                       if (p->pid > 1 && p != current && thread_group_leader(p)) {
+               for_each_process(p) {
+                       if (p->pid > 1 && p != current) {
                                int err = send_sig_info(sig, info, p);
                                ++count;
                                if (err != -EPERM)
index ae49384a38c8a30b0aca1941170895e94ecead37..2d7eeaabe1271b2e7b7c90453bbcb16184c023f0 100644 (file)
@@ -204,14 +204,14 @@ void refrigerator(unsigned long flag)
 int freeze_processes(void)
 {
        int todo, start_time;
-       struct task_struct *p;
+       struct task_struct *g, *p;
        
        printk( "Stopping tasks: " );
        start_time = jiffies;
        do {
                todo = 0;
                read_lock(&tasklist_lock);
-               for_each_task(p) {
+               do_each_thread(g, p) {
                        unsigned long flags;
                        INTERESTING(p);
                        if (p->flags & PF_FROZEN)
@@ -224,7 +224,7 @@ int freeze_processes(void)
                        signal_wake_up(p);
                        spin_unlock_irqrestore(&p->sigmask_lock, flags);
                        todo++;
-               }
+               } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
                yield();
                if (time_after(jiffies, start_time + TIMEOUT)) {
@@ -240,18 +240,19 @@ int freeze_processes(void)
 
 void thaw_processes(void)
 {
-       struct task_struct *p;
+       struct task_struct *g, *p;
 
        printk( "Restarting tasks..." );
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       do_each_thread(g, p) {
                INTERESTING(p);
                
                if (p->flags & PF_FROZEN) p->flags &= ~PF_FROZEN;
                else
                        printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
                wake_up_process(p);
-       }
+       } while_each_thread(g, p);
+
        read_unlock(&tasklist_lock);
        printk( " done\n" );
        MDELAY(500);
index 94976695e15c4f31760fd0813826fe4a76474225..7e0f8bea1201daf35dd22d3520cb5c89d811bb72 100644 (file)
@@ -227,7 +227,7 @@ static int proc_sel(struct task_struct *p, int which, int who)
 
 asmlinkage long sys_setpriority(int which, int who, int niceval)
 {
-       struct task_struct *p;
+       struct task_struct *g, *p;
        int error;
 
        if (which > 2 || which < 0)
@@ -241,7 +241,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
                niceval = 19;
 
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       do_each_thread(g, p) {
                int no_nice;
                if (!proc_sel(p, which, who))
                        continue;
@@ -262,8 +262,8 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
                        continue;
                }
                set_user_nice(p, niceval);
+       } while_each_thread(g, p);
 
-       }
        read_unlock(&tasklist_lock);
 
        return error;
@@ -277,21 +277,21 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
  */
 asmlinkage long sys_getpriority(int which, int who)
 {
-       struct task_struct *p;
+       struct task_struct *g, *p;
        long retval = -ESRCH;
 
        if (which > 2 || which < 0)
                return -EINVAL;
 
        read_lock(&tasklist_lock);
-       for_each_task (p) {
+       do_each_thread(g, p) {
                long niceval;
                if (!proc_sel(p, which, who))
                        continue;
                niceval = 20 - task_nice(p);
                if (niceval > retval)
                        retval = niceval;
-       }
+       } while_each_thread(g, p);
        read_unlock(&tasklist_lock);
 
        return retval;
@@ -882,12 +882,12 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
        if (p->leader)
                goto out;
        if (pgid != pid) {
-               struct task_struct * tmp;
-               for_each_task (tmp) {
+               struct task_struct *g, *tmp;
+               do_each_thread(g, tmp) {
                        if (tmp->pgrp == pgid &&
                            tmp->session == current->session)
                                goto ok_pgid;
-               }
+               } while_each_thread(g, tmp);
                goto out;
        }
 
@@ -956,14 +956,14 @@ asmlinkage long sys_getsid(pid_t pid)
 
 asmlinkage long sys_setsid(void)
 {
-       struct task_struct * p;
+       struct task_struct *g, *p;
        int err = -EPERM;
 
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       do_each_thread(g, p)
                if (p->pgrp == current->pid)
                        goto out;
-       }
+       while_each_thread(g, p);
 
        current->leader = 1;
        current->session = current->pgrp = current->pid;
index edbe913530676e32a4640fa8109a221a661c7590..afc2a7f26abd6b496cd1611d6c028a7c71547e9c 100644 (file)
@@ -116,10 +116,10 @@ static int badness(struct task_struct *p)
 static struct task_struct * select_bad_process(void)
 {
        int maxpoints = 0;
-       struct task_struct *p = NULL;
+       struct task_struct *g, *p;
        struct task_struct *chosen = NULL;
 
-       for_each_task(p) {
+       do_each_thread(g, p)
                if (p->pid) {
                        int points = badness(p);
                        if (points > maxpoints) {
@@ -127,7 +127,7 @@ static struct task_struct * select_bad_process(void)
                                maxpoints = points;
                        }
                }
-       }
+       while_each_thread(g, p);
        return chosen;
 }
 
@@ -166,7 +166,7 @@ void oom_kill_task(struct task_struct *p)
  */
 static void oom_kill(void)
 {
-       struct task_struct *p, *q;
+       struct task_struct *g, *p, *q;
        
        read_lock(&tasklist_lock);
        p = select_bad_process();
@@ -176,9 +176,11 @@ static void oom_kill(void)
                panic("Out of memory and no killable processes...\n");
 
        /* kill all processes that share the ->mm (i.e. all threads) */
-       for_each_task(q) {
-               if(q->mm == p->mm) oom_kill_task(q);
-       }
+       do_each_thread(g, q)
+               if (q->mm == p->mm)
+                       oom_kill_task(q);
+       while_each_thread(g, q);
+
        read_unlock(&tasklist_lock);
 
        /*
index 7455f7efff900af4625706c989f919e54e83092f..acb9997276b47803962af579320e2fdee0ef9e9c 100644 (file)
 static int
 match_comm(const struct sk_buff *skb, const char *comm)
 {
-       struct task_struct *p;
+       struct task_struct *g, *p;
        struct files_struct *files;
        int i;
 
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       do_each_thread(g, p) {
                if(strncmp(p->comm, comm, sizeof(p->comm)))
                        continue;
 
@@ -38,7 +38,7 @@ match_comm(const struct sk_buff *skb, const char *comm)
                        read_unlock(&files->file_lock);
                }
                task_unlock(p);
-       }
+       } while_each_thread(g, p);
        read_unlock(&tasklist_lock);
        return 0;
 }
@@ -77,12 +77,12 @@ out:
 static int
 match_sid(const struct sk_buff *skb, pid_t sid)
 {
-       struct task_struct *p;
+       struct task_struct *g, *p;
        struct file *file = skb->sk->socket->file;
        int i, found=0;
 
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       do_each_thread(g, p) {
                struct files_struct *files;
                if (p->session != sid)
                        continue;
@@ -100,9 +100,10 @@ match_sid(const struct sk_buff *skb, pid_t sid)
                        read_unlock(&files->file_lock);
                }
                task_unlock(p);
-               if(found)
-                       break;
-       }
+               if (found)
+                       goto out;
+       } while_each_thread(g, p);
+out:
        read_unlock(&tasklist_lock);
 
        return found;
index 1f31ef262f796919c9ab595955521efb89af33a0..544543dc0a939b4bae0228be3f98a3d679169313 100644 (file)
@@ -49,12 +49,12 @@ out:
 static int
 match_sid(const struct sk_buff *skb, pid_t sid)
 {
-       struct task_struct *p;
+       struct task_struct *g, *p;
        struct file *file = skb->sk->socket->file;
        int i, found=0;
 
        read_lock(&tasklist_lock);
-       for_each_task(p) {
+       do_each_thread(g, p) {
                struct files_struct *files;
                if (p->session != sid)
                        continue;
@@ -72,9 +72,10 @@ match_sid(const struct sk_buff *skb, pid_t sid)
                        read_unlock(&files->file_lock);
                }
                task_unlock(p);
-               if(found)
-                       break;
-       }
+               if (found)
+                       goto out;
+       } while_each_thread(g, p);
+out:
        read_unlock(&tasklist_lock);
 
        return found;