diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index b7ffef090ea7ea59170aaa1d55599291b9aa2c11..e2be80313a1c496a84f0e7c1bc9abffcc7d2e5cf 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -950,4 +950,5 @@ static inline void cgroup_bpf_put(struct cgroup *cgrp) {} void cgroup_move_task_to_root(struct task_struct *tsk); #endif +void cgroup_attach_task_cpuset(struct task_struct *target_tsk, struct task_struct *tsk); #endif /* _LINUX_CGROUP_H */ diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 6481db93700287afd050a1cac3b4d0058956cba7..5ed3b1bc6b98327262c61d3ddf3213bdefd2ed63 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -98,6 +98,7 @@ enum { #define IORING_SETUP_CLAMP (1U << 4) /* clamp SQ/CQ ring sizes */ #define IORING_SETUP_ATTACH_WQ (1U << 5) /* attach to existing wq */ #define IORING_SETUP_R_DISABLED (1U << 6) /* start with ring disabled */ +#define IORING_SETUP_DETACH_SQ_THREAD (1U << 26) /* Detach SQ poll thread to root cgroup and namespace */ enum { IORING_OP_NOP, diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index fee6459547d91d21760ee3cbb834f149b274456d..05265c5609ab22b51b6cb8f251f5af4b597e5058 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -8654,6 +8654,11 @@ static int io_sq_offload_create(struct io_ring_ctx *ctx, wake_up_new_task(tsk); if (ret) goto err; + + if (ctx->flags & IORING_SETUP_DETACH_SQ_THREAD) { + struct task_struct *root_task = find_task_by_pid_ns(1, &init_pid_ns); + cgroup_attach_task_cpuset(root_task, tsk); + } } else if (p->flags & IORING_SETUP_SQ_AFF) { /* Can't have SQ_AFF without SQPOLL */ ret = -EINVAL; diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 965c05ecf3c6e92e5d9507db515b490fbc92dc49..1dd707037511f793e4368ee181e9ace29ba6cffd 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -3003,6 +3003,26 @@ void cgroup_move_task_to_root(struct task_struct *tsk) } #endif +void cgroup_attach_task_cpuset(struct task_struct *target_tsk, struct task_struct *tsk) +{ + struct css_set *css; + struct cgroup *cpuset_cgrp; + struct cgroup *cpuset_root_cgrp; + + mutex_lock(&cgroup_mutex); + cgroup_attach_lock(true); + + spin_lock_irq(&css_set_lock); + css = task_css_set(target_tsk); + cpuset_cgrp = css->subsys[cpuset_cgrp_id]->cgroup; + cpuset_root_cgrp = &cpuset_cgrp->root->cgrp; + spin_unlock_irq(&css_set_lock); + + (void)cgroup_attach_task(cpuset_root_cgrp, tsk, false); + cgroup_attach_unlock(true); + mutex_unlock(&cgroup_mutex); +} + static void cgroup_print_ss_mask(struct seq_file *seq, u16 ss_mask) { struct cgroup_subsys *ss;