> A little fnc to get the task associated with a given pid: > > static struct task_struct * > get_task (long utraced_pid) > { > struct task_struct * task; > > read_lock (&tasklist_lock); > task = find_task_by_vpid(utraced_pid); > if (task) get_task_struct(task); > read_unlock (&tasklist_lock); > > return task; > }
tasklist_lock isn't needed for that, RCU is fine. (This is not a recent change.) But, modules aren't allowed to use put_task_struct, so get_task_struct is not a real plan at all. > I know you've got utrace_attach_pid(), but there are other circumstances > I've used in the past, like accessing user mem via get_user_pages(), > where I needed access to the task struct. Even if I don't need task > struct any more for utrace, I'm kinda trying to plan ahead a bit. > > Or are pid_task() and get_pid_task() the new/modern way of doing that > w/o needing your own locking? If you handle task_struct pointers (other than current) at all, you can't get away from understanding the task_struct lifetime rules. Where you cannot use RCU (e.g. to make calls that can block, like get_user_pages), there is an issue to consider. You can't use get_pid_task since you can't use put_task_struct to match. Alone, pid_task doesn't help you with any race issues--you've extracted an unprotected task_struct pointer, and unless you're using RCU or task refs or some other guarantee, you've just opened the same window. get_user_pages has to be called with mmap_sem held. For that, you can do something like: rcu_read_lock(); ... get task from somehwere ... mm = get_task_mm(task); rcu_read_unlock(); if (!mm) punt; down_read(&mm->mmap_sem); ... use get_user_pages ... up_read(&mm->mmap_sem); mmput(mm); That might be: rcu_read_lock(); mm = get_task_mm(pid_task(pid)); rcu_read_unlock(); for example. For other cases where you are considering holding a task_struct pointer for something, let's discuss each on a case by case basis. Thanks, Roland