✓ StartupAllowedCPUs=
✓ AllowedMemoryNodes=
✓ StartupAllowedMemoryNodes=
+✓ CPUSetPartition=
✓ DisableControllers=
✓ Delegate=
✓ MemoryMin=
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly ay StartupAllowedMemoryNodes = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly s CPUSetPartition = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly b IOAccounting = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t IOWeight = ...;
<!--property StartupAllowedMemoryNodes is not documented!-->
+ <!--property CPUSetPartition is not documented!-->
+
<!--property IOAccounting is not documented!-->
<!--property IOWeight is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="StartupAllowedMemoryNodes"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="CPUSetPartition"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="IOAccounting"/>
<variablelist class="dbus-property" generated="True" extra-ref="IOWeight"/>
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly ay StartupAllowedMemoryNodes = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly s CPUSetPartition = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly b IOAccounting = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t IOWeight = ...;
<!--property StartupAllowedMemoryNodes is not documented!-->
+ <!--property CPUSetPartition is not documented!-->
+
<!--property IOAccounting is not documented!-->
<!--property IOWeight is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="StartupAllowedMemoryNodes"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="CPUSetPartition"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="IOAccounting"/>
<variablelist class="dbus-property" generated="True" extra-ref="IOWeight"/>
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly ay StartupAllowedMemoryNodes = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly s CPUSetPartition = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly b IOAccounting = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t IOWeight = ...;
<!--property StartupAllowedMemoryNodes is not documented!-->
+ <!--property CPUSetPartition is not documented!-->
+
<!--property IOAccounting is not documented!-->
<!--property IOWeight is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="StartupAllowedMemoryNodes"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="CPUSetPartition"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="IOAccounting"/>
<variablelist class="dbus-property" generated="True" extra-ref="IOWeight"/>
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly ay StartupAllowedMemoryNodes = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly s CPUSetPartition = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly b IOAccounting = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t IOWeight = ...;
<!--property StartupAllowedMemoryNodes is not documented!-->
+ <!--property CPUSetPartition is not documented!-->
+
<!--property IOAccounting is not documented!-->
<!--property IOWeight is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="StartupAllowedMemoryNodes"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="CPUSetPartition"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="IOAccounting"/>
<variablelist class="dbus-property" generated="True" extra-ref="IOWeight"/>
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly ay StartupAllowedMemoryNodes = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly s CPUSetPartition = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly b IOAccounting = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t IOWeight = ...;
<!--property StartupAllowedMemoryNodes is not documented!-->
+ <!--property CPUSetPartition is not documented!-->
+
<!--property IOAccounting is not documented!-->
<!--property IOWeight is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="StartupAllowedMemoryNodes"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="CPUSetPartition"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="IOAccounting"/>
<variablelist class="dbus-property" generated="True" extra-ref="IOWeight"/>
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly ay StartupAllowedMemoryNodes = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+ readonly s CPUSetPartition = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly b IOAccounting = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t IOWeight = ...;
<!--property StartupAllowedMemoryNodes is not documented!-->
+ <!--property CPUSetPartition is not documented!-->
+
<!--property IOAccounting is not documented!-->
<!--property IOWeight is not documented!-->
<variablelist class="dbus-property" generated="True" extra-ref="StartupAllowedMemoryNodes"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="CPUSetPartition"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="IOAccounting"/>
<variablelist class="dbus-property" generated="True" extra-ref="IOWeight"/>
<varname>RefreshOnReload</varname>, and <varname>RootMStack</varname> were added in version 260.</para>
<para><varname>CPUPressureThresholdUSec</varname>,
<varname>CPUPressureWatch</varname>,
- <varname>IOPressureThresholdUSec</varname>, and
- <varname>IOPressureWatch</varname> were added in version 261.</para>
+ <varname>IOPressureThresholdUSec</varname>,
+ <varname>IOPressureWatch</varname>, and
+ <varname>CPUSetPartition</varname> were added in version 261.</para>
</refsect2>
<refsect2>
<title>Socket Unit Objects</title>
<varname>RootMStack</varname> were added in version 260.</para>
<para><varname>CPUPressureThresholdUSec</varname>,
<varname>CPUPressureWatch</varname>,
- <varname>IOPressureThresholdUSec</varname>, and
- <varname>IOPressureWatch</varname> were added in version 261.</para>
+ <varname>IOPressureThresholdUSec</varname>,
+ <varname>IOPressureWatch</varname>, and
+ <varname>CPUSetPartition</varname> were added in version 261.</para>
</refsect2>
<refsect2>
<title>Mount Unit Objects</title>
<varname>RootMStack</varname> were added in version 260.</para>
<para><varname>CPUPressureThresholdUSec</varname>,
<varname>CPUPressureWatch</varname>,
- <varname>IOPressureThresholdUSec</varname>, and
- <varname>IOPressureWatch</varname> were added in version 261.</para>
+ <varname>IOPressureThresholdUSec</varname>,
+ <varname>IOPressureWatch</varname>, and
+ <varname>CPUSetPartition</varname> were added in version 261.</para>
</refsect2>
<refsect2>
<title>Swap Unit Objects</title>
<varname>RootMStack</varname> were added in version 260.</para>
<para><varname>CPUPressureThresholdUSec</varname>,
<varname>CPUPressureWatch</varname>,
- <varname>IOPressureThresholdUSec</varname>, and
- <varname>IOPressureWatch</varname> were added in version 261.</para>
+ <varname>IOPressureThresholdUSec</varname>,
+ <varname>IOPressureWatch</varname>, and
+ <varname>CPUSetPartition</varname> were added in version 261.</para>
</refsect2>
<refsect2>
<title>Slice Unit Objects</title>
<para><varname>BindNetworkInterface</varname> was added in version 260.</para>
<para><varname>CPUPressureThresholdUSec</varname>,
<varname>CPUPressureWatch</varname>,
- <varname>IOPressureThresholdUSec</varname>, and
- <varname>IOPressureWatch</varname> were added in version 261.</para>
+ <varname>IOPressureThresholdUSec</varname>,
+ <varname>IOPressureWatch</varname>, and
+ <varname>CPUSetPartition</varname> were added in version 261.</para>
</refsect2>
<refsect2>
<title>Scope Unit Objects</title>
<para><varname>BindNetworkInterface</varname> was added in version 260.</para>
<para><varname>CPUPressureThresholdUSec</varname>,
<varname>CPUPressureWatch</varname>,
- <varname>IOPressureThresholdUSec</varname>, and
- <varname>IOPressureWatch</varname> were added in version 261.</para>
+ <varname>IOPressureThresholdUSec</varname>,
+ <varname>IOPressureWatch</varname>, and
+ <varname>CPUSetPartition</varname> were added in version 261.</para>
</refsect2>
<refsect2>
<title>Job Objects</title>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>CPUSetPartition=</varname></term>
+
+ <listitem>
+ <para>Sets the <option>cpuset</option> partition type for the executed processes. Takes one
+ of <literal>member</literal>, <literal>root</literal>, or <literal>isolated</literal>. This setting
+ controls the <literal>cpuset.cpus.partition</literal> cgroup attribute.</para>
+
+ <para>When set to <literal>member</literal>, the cpuset operates in normal mode.
+ <literal>root</literal> creates a partition root, which can further divide CPUs among child cgroups.
+ <literal>isolated</literal> provides full CPU isolation, useful for real-time workloads that
+ require dedicated CPU resources without interference from other processes.
+ Defaults to the kernel default, which is <literal>member</literal>. For more details about this
+ control group attribute, see <ulink url="https://docs.kernel.org/admin-guide/cgroup-v2.html">
+ Control Groups v2</ulink>.</para>
+
+ <para>This setting requires <varname>AllowedCPUs=</varname> to also be set.</para>
+
+ <xi:include href="version-info.xml" xpointer="v261"/>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect2><refsect2><title>Process Accounting and Control</title>
.tasks_max = CGROUP_TASKS_MAX_UNSET,
+ .cpuset_partition = _CPUSET_PARTITION_INVALID,
+
.moom_swap = MANAGED_OOM_AUTO,
.moom_mem_pressure = MANAGED_OOM_AUTO,
.moom_preference = MANAGED_OOM_PREFERENCE_NONE,
"%sStartupAllowedCPUs: %s\n"
"%sAllowedMemoryNodes: %s\n"
"%sStartupAllowedMemoryNodes: %s\n"
+ "%sCPUSetPartition: %s\n"
"%sIOWeight: %" PRIu64 "\n"
"%sStartupIOWeight: %" PRIu64 "\n"
"%sMemoryMin: %" PRIu64 "%s\n"
prefix, strempty(startup_cpuset_cpus),
prefix, strempty(cpuset_mems),
prefix, strempty(startup_cpuset_mems),
+ prefix, strna(cpuset_partition_to_string(c->cpuset_partition)),
prefix, c->io_weight,
prefix, c->startup_io_weight,
prefix, c->memory_min, format_cgroup_memory_limit_comparison(u, "MemoryMin", cda, sizeof(cda)),
(void) set_attribute_and_warn(u, name, buf);
}
+static int cgroup_cpuset_partition_invalid(const char *partition) {
+ _cleanup_free_ char *part_str = NULL, *invalid = NULL;
+ int r;
+
+ assert(partition);
+
+ /* An invalid line looks like <partition> invalid (<reason>) */
+ r = extract_many_words(&partition, /* separators= */ NULL, /* flags= */ 0, &part_str, &invalid);
+ if (r < 0)
+ return r;
+ if (r < 2)
+ return false;
+
+ return streq_ptr(invalid, "invalid");
+}
+
+static void cgroup_apply_cpuset_partition(Unit *u, const char *name, const char *partition) {
+ _cleanup_free_ char *buf = NULL;
+ CGroupRuntime *crt;
+ int r;
+
+ assert(u);
+ assert(name);
+ assert(partition);
+
+ if (set_attribute_and_warn(u, name, partition) < 0)
+ return;
+
+ /* We are writing and then reading back, crt is already checked while writing */
+ crt = ASSERT_PTR(unit_get_cgroup_runtime(u));
+
+ r = cg_get_attribute(crt->cgroup_path, name, &buf);
+ if (r < 0) {
+ log_unit_full_errno(u, LOG_LEVEL_CGROUP_WRITE(r), r, "Failed to read back '%s' attribute on '%s' as '%.*s': %m",
+ name, empty_to_root(crt->cgroup_path), (int) strcspn(partition, NEWLINE), partition);
+ return;
+ }
+
+ r = cgroup_cpuset_partition_invalid(buf);
+ if (r < 0)
+ log_unit_full_errno(u, LOG_LEVEL_CGROUP_WRITE(r), r, "Failed to read back '%s' attribute on '%s' as '%.*s': %m",
+ name, empty_to_root(crt->cgroup_path), (int) strcspn(partition, NEWLINE), partition);
+ else if (r)
+ log_unit_warning(u, "Failed to set '%s' attribute on '%s' to '%.*s': %s",
+ name, empty_to_root(crt->cgroup_path), (int) strcspn(partition, NEWLINE), partition, buf);
+}
+
static bool cgroup_context_has_io_config(CGroupContext *c) {
assert(c);
if ((apply_mask & CGROUP_MASK_CPUSET) && !is_local_root) {
cgroup_apply_cpuset(u, cgroup_context_allowed_cpus(c, state), "cpuset.cpus");
cgroup_apply_cpuset(u, cgroup_context_allowed_mems(c, state), "cpuset.mems");
+
+ if (c->cpuset_partition >= 0)
+ cgroup_apply_cpuset_partition(u, "cpuset.cpus.partition", cpuset_partition_to_string(c->cpuset_partition));
}
/* The 'io' controller attributes are not exported on the host's root cgroup (being a pure cgroup v2
DEFINE_STRING_TABLE_LOOKUP(cgroup_device_policy, CGroupDevicePolicy);
+static const char* const cpuset_partition_table[_CPUSET_PARTITION_MAX] = {
+ [CPUSET_PARTITION_MEMBER] = "member",
+ [CPUSET_PARTITION_ROOT] = "root",
+ [CPUSET_PARTITION_ISOLATED] = "isolated",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(cpuset_partition, CPUSetPartition);
+
static const char* const cgroup_pressure_watch_table[_CGROUP_PRESSURE_WATCH_MAX] = {
[CGROUP_PRESSURE_WATCH_NO] = "no",
[CGROUP_PRESSURE_WATCH_YES] = "yes",
_FREEZER_ACTION_INVALID = -EINVAL,
} FreezerAction;
+typedef enum CPUSetPartition {
+ CPUSET_PARTITION_MEMBER,
+ CPUSET_PARTITION_ROOT,
+ CPUSET_PARTITION_ISOLATED,
+ _CPUSET_PARTITION_MAX,
+ _CPUSET_PARTITION_INVALID = -EINVAL,
+} CPUSetPartition;
+
typedef enum CGroupDevicePermissions {
/* We reuse the same bit meanings the kernel's BPF_DEVCG_ACC_xyz definitions use */
CGROUP_DEVICE_MKNOD = 1 << 0,
CPUSet startup_cpuset_cpus;
CPUSet cpuset_mems;
CPUSet startup_cpuset_mems;
+ CPUSetPartition cpuset_partition;
uint64_t io_weight;
uint64_t startup_io_weight;
int unit_cgroup_freezer_action(Unit *u, FreezerAction action);
DECLARE_STRING_TABLE_LOOKUP(freezer_action, FreezerAction);
+DECLARE_STRING_TABLE_LOOKUP(cpuset_partition, CPUSetPartition);
CGroupRuntime* cgroup_runtime_new(void);
CGroupRuntime* cgroup_runtime_free(CGroupRuntime *crt);
BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_cgroup_pressure_watch, cgroup_pressure_watch, CGroupPressureWatch);
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cpuset_partition, cpuset_partition, CPUSetPartition);
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_managed_oom_mode, managed_oom_mode, ManagedOOMMode);
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_managed_oom_preference, managed_oom_preference, ManagedOOMPreference);
SD_BUS_PROPERTY("StartupAllowedCPUs", "ay", property_get_cpuset, offsetof(CGroupContext, startup_cpuset_cpus), 0),
SD_BUS_PROPERTY("AllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_mems), 0),
SD_BUS_PROPERTY("StartupAllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, startup_cpuset_mems), 0),
+ SD_BUS_PROPERTY("CPUSetPartition", "s", property_get_cpuset_partition, offsetof(CGroupContext, cpuset_partition), 0),
SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, io_accounting), 0),
SD_BUS_PROPERTY("IOWeight", "t", NULL, offsetof(CGroupContext, io_weight), 0),
SD_BUS_PROPERTY("StartupIOWeight", "t", NULL, offsetof(CGroupContext, startup_io_weight), 0),
return 1;
+ } else if (streq(name, "CPUSetPartition")) {
+ const char *partition_str;
+ CPUSetPartition p;
+
+ r = sd_bus_message_read(message, "s", &partition_str);
+ if (r < 0)
+ return r;
+
+ if (isempty(partition_str))
+ p = _CPUSET_PARTITION_INVALID;
+ else {
+ p = cpuset_partition_from_string(partition_str);
+ if (p < 0)
+ return sd_bus_error_setf(reterr_error, SD_BUS_ERROR_INVALID_ARGS,
+ "Invalid CPUSetPartition value: %s", partition_str);
+ }
+
+ if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+ c->cpuset_partition = p;
+ unit_invalidate_cgroup(u, CGROUP_MASK_CPUSET);
+
+ if (p == _CPUSET_PARTITION_INVALID)
+ unit_write_settingf(u, flags, name, "%s=", name);
+ else
+ unit_write_settingf(u, flags, name, "%s=%s", name, partition_str);
+ }
+
+ return 1;
+
} else if (streq(name, "DeviceAllow")) {
const char *path, *rwm;
unsigned n = 0;
if (r < 0)
return r;
+ if (c->cpuset_partition >= 0) {
+ r = serialize_item(f, "exec-cgroup-context-cpuset-partition", cpuset_partition_to_string(c->cpuset_partition));
+ if (r < 0)
+ return r;
+ }
+
if (c->io_weight != CGROUP_WEIGHT_INVALID) {
r = serialize_item_format(f, "exec-cgroup-context-io-weight", "%" PRIu64, c->io_weight);
if (r < 0)
r = parse_cpu_set(val, &c->startup_cpuset_mems);
if (r < 0)
return r;
+ } else if ((val = startswith(l, "exec-cgroup-context-cpuset-partition="))) {
+ c->cpuset_partition = cpuset_partition_from_string(val);
+ if (c->cpuset_partition < 0)
+ return -EINVAL;
} else if ((val = startswith(l, "exec-cgroup-context-io-weight="))) {
r = safe_atou64(val, &c->io_weight);
if (r < 0)
{{type}}.StartupAllowedCPUs, config_parse_unit_cpu_set, 0, offsetof({{type}}, cgroup_context.startup_cpuset_cpus)
{{type}}.AllowedMemoryNodes, config_parse_unit_cpu_set, 0, offsetof({{type}}, cgroup_context.cpuset_mems)
{{type}}.StartupAllowedMemoryNodes, config_parse_unit_cpu_set, 0, offsetof({{type}}, cgroup_context.startup_cpuset_mems)
+{{type}}.CPUSetPartition, config_parse_cpuset_partition, 0, offsetof({{type}}, cgroup_context.cpuset_partition)
{{type}}.CPUAccounting, config_parse_warn_compat, DISABLED_LEGACY, 0
{{type}}.CPUWeight, config_parse_cg_cpu_weight, 0, offsetof({{type}}, cgroup_context.cpu_weight)
{{type}}.StartupCPUWeight, config_parse_cg_cpu_weight, 0, offsetof({{type}}, cgroup_context.startup_cpu_weight)
DEFINE_CONFIG_PARSE(config_parse_exec_secure_bits, secure_bits_from_string);
DEFINE_CONFIG_PARSE_ENUM(config_parse_collect_mode, collect_mode, CollectMode);
DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy);
+DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_cpuset_partition, cpuset_partition, CPUSetPartition, _CPUSET_PARTITION_INVALID);
DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode);
DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_proc, protect_proc, ProtectProc);
DEFINE_CONFIG_PARSE_ENUM(config_parse_proc_subset, proc_subset, ProcSubset);
CONFIG_PARSER_PROTOTYPE(config_parse_concurrency_max);
CONFIG_PARSER_PROTOTYPE(config_parse_bind_network_interface);
CONFIG_PARSER_PROTOTYPE(config_parse_exec_memory_thp);
+CONFIG_PARSER_PROTOTYPE(config_parse_cpuset_partition);
/* gperf prototypes */
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
JSON_BUILD_PAIR_FINITE_USEC("CPUQuotaPeriodUSec", c->cpu_quota_period_usec),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("AllowedCPUs", cpuset_build_json, &c->cpuset_cpus),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("StartupAllowedCPUs", cpuset_build_json, &c->startup_cpuset_cpus),
+ JSON_BUILD_PAIR_ENUM("CPUSetPartition", cpuset_partition_to_string(c->cpuset_partition)),
/* Memory Accounting and Control */
SD_JSON_BUILD_PAIR_BOOLEAN("MemoryAccounting", c->memory_accounting),
{ "StartupAllowedCPUs", bus_append_parse_cpu_set },
{ "AllowedMemoryNodes", bus_append_parse_cpu_set },
{ "StartupAllowedMemoryNodes", bus_append_parse_cpu_set },
+ { "CPUSetPartition", bus_append_string },
{ "DisableControllers", bus_append_strv },
{ "Delegate", bus_append_parse_delegate },
{ "MemoryMin", bus_append_parse_resource_limit },
SD_VARLINK_FIELD_COMMENT("The device permissions"),
SD_VARLINK_DEFINE_FIELD(permissions, SD_VARLINK_STRING, 0));
+static SD_VARLINK_DEFINE_ENUM_TYPE(
+ CPUSetPartition,
+ SD_VARLINK_DEFINE_ENUM_VALUE(member),
+ SD_VARLINK_DEFINE_ENUM_VALUE(root),
+ SD_VARLINK_DEFINE_ENUM_VALUE(isolated));
+
static SD_VARLINK_DEFINE_STRUCT_TYPE(
CGroupContext,
SD_VARLINK_DEFINE_FIELD(AllowedCPUs, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#AllowedCPUs="),
SD_VARLINK_DEFINE_FIELD(StartupAllowedCPUs, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
+ SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#CPUSetPartition="),
+ SD_VARLINK_DEFINE_FIELD_BY_TYPE(CPUSetPartition, CPUSetPartition, SD_VARLINK_NULLABLE),
/* Memory Accounting and Control
* https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html#Memory%20Accounting%20and%20Control */
&vl_type_CGroupBPFProgram,
&vl_type_CGroupController,
&vl_type_CGroupDeviceAllow,
+ &vl_type_CPUSetPartition,
SD_VARLINK_SYMBOL_COMMENT("CGroup context of a unit"),
&vl_type_CGroupContext,
SD_VARLINK_SYMBOL_COMMENT("CGroup runtime of a unit"),
"StartupAllowedMemoryNodes=0",
"StartupAllowedMemoryNodes=1-3",
+ "CPUSetPartition=member",
+ "CPUSetPartition=root",
+ "CPUSetPartition=isolated",
+ "CPUSetPartition=",
+
"DisableControllers=cpu",
"DisableControllers= "
" cpu cpuacct cpuset io blkio memory devices pids bpf-firewall bpf-devices "