This adds support for creating a process in a different cgroup than its parent. Callers can limit and account processes and threads right from the moment they are spawned: - A service manager can directly spawn new services into dedicated cgroups. - A process can be directly created in a frozen cgroup and will be frozen as well. - The initial accounting jitter experienced by process supervisors and daemons is eliminated with this. - Threaded applications or even thread implementations can choose to create a specific cgroup layout where each thread is spawned directly into a dedicated cgroup. This feature is limited to the unified hierarchy. Callers need to pass a directory file descriptor for the target cgroup. The caller can choose to pass an O_PATH file descriptor. All usual migration restrictions apply, i.e. there can be no processes in inner nodes. In general, creating a process directly in a target cgroup adheres to all migration restrictions. One of the biggest advantages of this feature is that CLONE_INTO_GROUP does not need to grab the write side of the cgroup cgroup_threadgroup_rwsem. This global lock makes moving tasks/threads around super expensive. With clone3() this lock is avoided.
Showing the changes to include/uapi/linux (1 of 7 files). Show all
Unified · Split
| @@ -35,6 +35,7 @@ · 34 unmodified lines | |||
| 35 | 35 | ||
| 36 | /* Flags for the clone3() syscall. */ | 36 | /* Flags for the clone3() syscall. */ |
| 37 | #define CLONE_CLEAR_SIGHAND 0x100000000ULL /* Clear any signal handler and reset to SIG_DFL. */ | 37 | #define CLONE_CLEAR_SIGHAND 0x100000000ULL /* Clear any signal handler and reset to SIG_DFL. */ |
| 38 | #define CLONE_INTO_CGROUP 0x200000000ULL /* Clone into a specific cgroup given the right permissions. */ | ||
| 38 | 39 | ||
| 39 | /* | 40 | /* |
| 40 | * cloning flags intersect with CSIGNAL so can be used with unshare and clone3 | 41 | * cloning flags intersect with CSIGNAL so can be used with unshare and clone3 |
| @@ -81,6 +82,8 @@ · 40 unmodified lines | |||
| 81 | * @set_tid_size: This defines the size of the array referenced | 82 | * @set_tid_size: This defines the size of the array referenced |
| 82 | * in @set_tid. This cannot be larger than the | 83 | * in @set_tid. This cannot be larger than the |
| 83 | * kernel's limit of nested PID namespaces. | 84 | * kernel's limit of nested PID namespaces. |
| 85 | * @cgroup: If CLONE_INTO_CGROUP is specified set this to | ||
| 86 | * a file descriptor for the cgroup. | ||
| 84 | * | 87 | * |
| 85 | * The structure is versioned by size and thus extensible. | 88 | * The structure is versioned by size and thus extensible. |
| 86 | * New struct members must go at the end of the struct and | 89 | * New struct members must go at the end of the struct and |
| @@ -97,11 +100,13 @@ struct clone_args { · 10 unmodified lines | |||
| 97 | __aligned_u64 tls; | 100 | __aligned_u64 tls; |
| 98 | __aligned_u64 set_tid; | 101 | __aligned_u64 set_tid; |
| 99 | __aligned_u64 set_tid_size; | 102 | __aligned_u64 set_tid_size; |
| 103 | __aligned_u64 cgroup; | ||
| 100 | }; | 104 | }; |
| 101 | #endif | 105 | #endif |
| 102 | 106 | ||
| 103 | #define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */ | 107 | #define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */ |
| 104 | #define CLONE_ARGS_SIZE_VER1 80 /* sizeof second published struct */ | 108 | #define CLONE_ARGS_SIZE_VER1 80 /* sizeof second published struct */ |
| 109 | #define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */ | ||
| 105 | 110 | ||
| 106 | /* | 111 | /* |
| 107 | * Scheduling policies | 112 | * Scheduling policies |