On 10/21, Peter Zijlstra wrote:minor nit, I think in theory this needs barrier(), or struct tty_struct *tty = ACCESS_ONCE(p->signal->tty); if (tty) *tg = tty->tg; No, I don't understand this ;) But I know nothig about task groups, most probably this is OK. It is not clear to me why do we need rcu_read_lock() and how it can help. The tty can go away right after dereferencing signal->tty. Even if the task doesn't exit, it (or its sub-thread) can do sys_setsid() at any moment and free this tty. If any thread was moved to tty->sg, doesn't this mean that, say, ->cfs_rq will point to the already freed tg->cfs_rq? From http://marc.info/?l=linux-kernel&m=128764874422614 +int sched_autogroup_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct task_struct *p, *t; + struct task_group *tg; + int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + + if (ret || !write) + return ret; + + for_each_process(p) { Hmm. This needs rcu lock at least? + tg = task_group(p); Why? + sched_move_task(p); + list_for_each_entry_rcu(t, &p->thread_group, thread_group) { + sched_move_task(t); + } + } Looks like, you can just do do_each_thread(p, t) { sched_move_task(t); } while_each_thread(p, t); With the same effect. Oleg. --
