On Fri, May 21, 2021 at 9:09 PM Andrei Vagin [off-list ref] wrote:
On Thu, May 20, 2021 at 11:36:09AM -0700, Peter Oskolkov wrote:
quoted
@@ -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?