On Fri, May 21, 2021 at 2:32 PM Jann Horn <jannh@xxxxxxxxxx> wrote: > > On Fri, May 21, 2021 at 9:09 PM Andrei Vagin <avagin@xxxxxxxxx> wrote: > > On Thu, May 20, 2021 at 11:36:09AM -0700, Peter Oskolkov wrote: > > > @@ -67,7 +137,75 @@ SYSCALL_DEFINE4(umcg_register_task, u32, api_version, u32, flags, u32, group_id, > > > */ > > > SYSCALL_DEFINE1(umcg_unregister_task, u32, flags) > > > { > > > - return -ENOSYS; > > > + struct umcg_task_data *utd; > > > + int ret = -EINVAL; > > > + > > > + rcu_read_lock(); > > > + utd = rcu_dereference(current->umcg_task_data); > > > + > > > + if (!utd || flags) > > > + goto out; > > > + > > > + task_lock(current); > > > + rcu_assign_pointer(current->umcg_task_data, NULL); > > > + task_unlock(current); > > > + > > > + ret = 0; > > > + > > > +out: > > > + rcu_read_unlock(); > > > + if (!ret && utd) { > > > + synchronize_rcu(); > > > > synchronize_rcu is expensive. Do we really need to call it here? Can we > > use kfree_rcu? > > > > Where is task->umcg_task_data freed when a task is destroyed? > > or executed - the umcg stuff includes a userspace pointer, so it > probably shouldn't normally be kept around across execve? Ack - thanks for these and other comments. Please keep them coming. I'll address them in v0.2. Thanks, Peter