834f04
From a9b1927c15fce3c9945ac249d8e8ddc42028a057 Mon Sep 17 00:00:00 2001
834f04
From: Anita Zhang <the.anitazha@gmail.com>
834f04
Date: Tue, 2 Feb 2021 01:47:08 -0800
834f04
Subject: [PATCH 1/2] parse-util: add permyriad parsing
834f04
834f04
---
834f04
 src/basic/parse-util.c     | 137 ++++++++++++++++++++++++++-----------
834f04
 src/basic/parse-util.h     |   3 +
834f04
 src/test/test-parse-util.c |  68 ++++++++++++++++++
834f04
 3 files changed, 169 insertions(+), 39 deletions(-)
834f04
834f04
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
834f04
index 5d4dafe3a5..a0fb2c9d17 100644
834f04
--- a/src/basic/parse-util.c
834f04
+++ b/src/basic/parse-util.c
834f04
@@ -671,11 +671,11 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
834f04
         return 0;
834f04
 }
834f04
 
834f04
-int parse_percent_unbounded(const char *p) {
834f04
+static int parse_parts_value_whole(const char *p, const char *symbol) {
834f04
         const char *pc, *n;
834f04
         int r, v;
834f04
 
834f04
-        pc = endswith(p, "%");
834f04
+        pc = endswith(p, symbol);
834f04
         if (!pc)
834f04
                 return -EINVAL;
834f04
 
834f04
@@ -689,6 +689,74 @@ int parse_percent_unbounded(const char *p) {
834f04
         return v;
834f04
 }
834f04
 
834f04
+static int parse_parts_value_with_tenths_place(const char *p, const char *symbol) {
834f04
+        const char *pc, *dot, *n;
834f04
+        int r, q, v;
834f04
+
834f04
+        pc = endswith(p, symbol);
834f04
+        if (!pc)
834f04
+                return -EINVAL;
834f04
+
834f04
+        dot = memchr(p, '.', pc - p);
834f04
+        if (dot) {
834f04
+                if (dot + 2 != pc)
834f04
+                        return -EINVAL;
834f04
+                if (dot[1] < '0' || dot[1] > '9')
834f04
+                        return -EINVAL;
834f04
+                q = dot[1] - '0';
834f04
+                n = strndupa(p, dot - p);
834f04
+        } else {
834f04
+                q = 0;
834f04
+                n = strndupa(p, pc - p);
834f04
+        }
834f04
+        r = safe_atoi(n, &v);
834f04
+        if (r < 0)
834f04
+                return r;
834f04
+        if (v < 0)
834f04
+                return -ERANGE;
834f04
+        if (v > (INT_MAX - q) / 10)
834f04
+                return -ERANGE;
834f04
+
834f04
+        v = v * 10 + q;
834f04
+        return v;
834f04
+}
834f04
+
834f04
+static int parse_parts_value_with_hundredths_place(const char *p, const char *symbol) {
834f04
+        const char *pc, *dot, *n;
834f04
+        int r, q, v;
834f04
+
834f04
+        pc = endswith(p, symbol);
834f04
+        if (!pc)
834f04
+                return -EINVAL;
834f04
+
834f04
+        dot = memchr(p, '.', pc - p);
834f04
+        if (dot) {
834f04
+                if (dot + 3 != pc)
834f04
+                        return -EINVAL;
834f04
+                if (dot[1] < '0' || dot[1] > '9' || dot[2] < '0' || dot[2] > '9')
834f04
+                        return -EINVAL;
834f04
+                q = (dot[1] - '0') * 10 + (dot[2] - '0');
834f04
+                n = strndupa(p, dot - p);
834f04
+        } else {
834f04
+                q = 0;
834f04
+                n = strndupa(p, pc - p);
834f04
+        }
834f04
+        r = safe_atoi(n, &v);
834f04
+        if (r < 0)
834f04
+                return r;
834f04
+        if (v < 0)
834f04
+                return -ERANGE;
834f04
+        if (v > (INT_MAX - q) / 100)
834f04
+                return -ERANGE;
834f04
+
834f04
+        v = v * 100 + q;
834f04
+        return v;
834f04
+}
834f04
+
834f04
+int parse_percent_unbounded(const char *p) {
834f04
+        return parse_parts_value_whole(p, "%");
834f04
+}
834f04
+
834f04
 int parse_percent(const char *p) {
834f04
         int v;
834f04
 
834f04
@@ -700,46 +768,13 @@ int parse_percent(const char *p) {
834f04
 }
834f04
 
834f04
 int parse_permille_unbounded(const char *p) {
834f04
-        const char *pc, *pm, *dot, *n;
834f04
-        int r, q, v;
834f04
+        const char *pm;
834f04
 
834f04
         pm = endswith(p, "‰");
834f04
-        if (pm) {
834f04
-                n = strndupa(p, pm - p);
834f04
-                r = safe_atoi(n, &v);
834f04
-                if (r < 0)
834f04
-                        return r;
834f04
-                if (v < 0)
834f04
-                        return -ERANGE;
834f04
-        } else {
834f04
-                pc = endswith(p, "%");
834f04
-                if (!pc)
834f04
-                        return -EINVAL;
834f04
-
834f04
-                dot = memchr(p, '.', pc - p);
834f04
-                if (dot) {
834f04
-                        if (dot + 2 != pc)
834f04
-                                return -EINVAL;
834f04
-                        if (dot[1] < '0' || dot[1] > '9')
834f04
-                                return -EINVAL;
834f04
-                        q = dot[1] - '0';
834f04
-                        n = strndupa(p, dot - p);
834f04
-                } else {
834f04
-                        q = 0;
834f04
-                        n = strndupa(p, pc - p);
834f04
-                }
834f04
-                r = safe_atoi(n, &v);
834f04
-                if (r < 0)
834f04
-                        return r;
834f04
-                if (v < 0)
834f04
-                        return -ERANGE;
834f04
-                if (v > (INT_MAX - q) / 10)
834f04
-                        return -ERANGE;
834f04
+        if (pm)
834f04
+                return parse_parts_value_whole(p, "‰");
834f04
 
834f04
-                v = v * 10 + q;
834f04
-        }
834f04
-
834f04
-        return v;
834f04
+        return parse_parts_value_with_tenths_place(p, "%");
834f04
 }
834f04
 
834f04
 int parse_permille(const char *p) {
834f04
@@ -752,6 +787,30 @@ int parse_permille(const char *p) {
834f04
         return v;
834f04
 }
834f04
 
834f04
+int parse_permyriad_unbounded(const char *p) {
834f04
+        const char *pm;
834f04
+
834f04
+        pm = endswith(p, "‱");
834f04
+        if (pm)
834f04
+                return parse_parts_value_whole(p, "‱");
834f04
+
834f04
+        pm = endswith(p, "‰");
834f04
+        if (pm)
834f04
+                return parse_parts_value_with_tenths_place(p, "‰");
834f04
+
834f04
+        return parse_parts_value_with_hundredths_place(p, "%");
834f04
+}
834f04
+
834f04
+int parse_permyriad(const char *p) {
834f04
+        int v;
834f04
+
834f04
+        v = parse_permyriad_unbounded(p);
834f04
+        if (v > 10000)
834f04
+                return -ERANGE;
834f04
+
834f04
+        return v;
834f04
+}
834f04
+
834f04
 int parse_nice(const char *p, int *ret) {
834f04
         int n, r;
834f04
 
834f04
diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h
834f04
index 81478ed059..3e29291f26 100644
834f04
--- a/src/basic/parse-util.h
834f04
+++ b/src/basic/parse-util.h
834f04
@@ -136,6 +136,9 @@ int parse_percent(const char *p);
834f04
 int parse_permille_unbounded(const char *p);
834f04
 int parse_permille(const char *p);
834f04
 
834f04
+int parse_permyriad_unbounded(const char *p);
834f04
+int parse_permyriad(const char *p);
834f04
+
834f04
 int parse_nice(const char *p, int *ret);
834f04
 
834f04
 int parse_ip_port(const char *s, uint16_t *ret);
834f04
diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c
834f04
index 1c969091ef..6e23efe134 100644
834f04
--- a/src/test/test-parse-util.c
834f04
+++ b/src/test/test-parse-util.c
834f04
@@ -790,6 +790,72 @@ static void test_parse_permille_unbounded(void) {
834f04
         assert_se(parse_permille_unbounded("429496729.6%") == -ERANGE);
834f04
 }
834f04
 
834f04
+static void test_parse_permyriad(void) {
834f04
+        assert_se(parse_permyriad("") == -EINVAL);
834f04
+        assert_se(parse_permyriad("foo") == -EINVAL);
834f04
+        assert_se(parse_permyriad("0") == -EINVAL);
834f04
+        assert_se(parse_permyriad("50") == -EINVAL);
834f04
+        assert_se(parse_permyriad("100") == -EINVAL);
834f04
+        assert_se(parse_permyriad("-1") == -EINVAL);
834f04
+
834f04
+        assert_se(parse_permyriad("0‱") == 0);
834f04
+        assert_se(parse_permyriad("555‱") == 555);
834f04
+        assert_se(parse_permyriad("1000‱") == 1000);
834f04
+        assert_se(parse_permyriad("-7‱") == -ERANGE);
834f04
+        assert_se(parse_permyriad("10007‱") == -ERANGE);
834f04
+        assert_se(parse_permyriad("‱") == -EINVAL);
834f04
+        assert_se(parse_permyriad("‱‱") == -EINVAL);
834f04
+        assert_se(parse_permyriad("‱1") == -EINVAL);
834f04
+        assert_se(parse_permyriad("1‱‱") == -EINVAL);
834f04
+        assert_se(parse_permyriad("3.2‱") == -EINVAL);
834f04
+
834f04
+        assert_se(parse_permyriad("0‰") == 0);
834f04
+        assert_se(parse_permyriad("555.5‰") == 5555);
834f04
+        assert_se(parse_permyriad("1000.0‰") == 10000);
834f04
+        assert_se(parse_permyriad("-7‰") == -ERANGE);
834f04
+        assert_se(parse_permyriad("1007‰") == -ERANGE);
834f04
+        assert_se(parse_permyriad("‰") == -EINVAL);
834f04
+        assert_se(parse_permyriad("‰‰") == -EINVAL);
834f04
+        assert_se(parse_permyriad("‰1") == -EINVAL);
834f04
+        assert_se(parse_permyriad("1‰‰") == -EINVAL);
834f04
+        assert_se(parse_permyriad("3.22‰") == -EINVAL);
834f04
+
834f04
+        assert_se(parse_permyriad("0%") == 0);
834f04
+        assert_se(parse_permyriad("55%") == 5500);
834f04
+        assert_se(parse_permyriad("55.53%") == 5553);
834f04
+        assert_se(parse_permyriad("100%") == 10000);
834f04
+        assert_se(parse_permyriad("-7%") == -ERANGE);
834f04
+        assert_se(parse_permyriad("107%") == -ERANGE);
834f04
+        assert_se(parse_permyriad("%") == -EINVAL);
834f04
+        assert_se(parse_permyriad("%%") == -EINVAL);
834f04
+        assert_se(parse_permyriad("%1") == -EINVAL);
834f04
+        assert_se(parse_permyriad("1%%") == -EINVAL);
834f04
+        assert_se(parse_permyriad("3.212%") == -EINVAL);
834f04
+}
834f04
+
834f04
+static void test_parse_permyriad_unbounded(void) {
834f04
+        assert_se(parse_permyriad_unbounded("1001‱") == 1001);
834f04
+        assert_se(parse_permyriad_unbounded("4000‱") == 4000);
834f04
+        assert_se(parse_permyriad_unbounded("2147483647‱") == 2147483647);
834f04
+        assert_se(parse_permyriad_unbounded("2147483648‱") == -ERANGE);
834f04
+        assert_se(parse_permyriad_unbounded("4294967295‱") == -ERANGE);
834f04
+        assert_se(parse_permyriad_unbounded("4294967296‱") == -ERANGE);
834f04
+
834f04
+        assert_se(parse_permyriad_unbounded("101‰") == 1010);
834f04
+        assert_se(parse_permyriad_unbounded("400‰") == 4000);
834f04
+        assert_se(parse_permyriad_unbounded("214748364.7‰") == 2147483647);
834f04
+        assert_se(parse_permyriad_unbounded("214748364.8‰") == -ERANGE);
834f04
+        assert_se(parse_permyriad_unbounded("429496729.5‰") == -ERANGE);
834f04
+        assert_se(parse_permyriad_unbounded("429496729.6‰") == -ERANGE);
834f04
+
834f04
+        assert_se(parse_permyriad_unbounded("99%") == 9900);
834f04
+        assert_se(parse_permyriad_unbounded("40%") == 4000);
834f04
+        assert_se(parse_permyriad_unbounded("21474836.47%") == 2147483647);
834f04
+        assert_se(parse_permyriad_unbounded("21474836.48%") == -ERANGE);
834f04
+        assert_se(parse_permyriad_unbounded("42949672.95%") == -ERANGE);
834f04
+        assert_se(parse_permyriad_unbounded("42949672.96%") == -ERANGE);
834f04
+}
834f04
+
834f04
 static void test_parse_nice(void) {
834f04
         int n;
834f04
 
834f04
@@ -987,6 +1053,8 @@ int main(int argc, char *argv[]) {
834f04
         test_parse_percent_unbounded();
834f04
         test_parse_permille();
834f04
         test_parse_permille_unbounded();
834f04
+        test_parse_permyriad();
834f04
+        test_parse_permyriad_unbounded();
834f04
         test_parse_nice();
834f04
         test_parse_dev();
834f04
         test_parse_errno();
834f04
-- 
834f04
2.29.2
834f04
834f04
834f04
From 5fdc5d3384f81888704a0a19db3cb33bce2d8bdb Mon Sep 17 00:00:00 2001
834f04
From: Anita Zhang <the.anitazha@gmail.com>
834f04
Date: Tue, 2 Feb 2021 14:16:03 -0800
834f04
Subject: [PATCH 2/2] oom: rework *MemoryPressureLimit= properties to have
834f04
 1/10000 precision
834f04
834f04
Requested in
834f04
https://github.com/systemd/systemd/pull/15206#discussion_r505506657,
834f04
preserve the full granularity for memory pressure limits (permyriad)
834f04
instead of capping out at percent.
834f04
---
834f04
 docs/TRANSIENT-SETTINGS.md             |  2 +-
834f04
 man/oomd.conf.xml                      |  6 ++---
834f04
 man/org.freedesktop.systemd1.xml       | 36 +++++++++++++-------------
834f04
 man/systemd.resource-control.xml       |  2 +-
834f04
 src/core/cgroup.c                      |  4 +--
834f04
 src/core/cgroup.h                      |  2 +-
834f04
 src/core/core-varlink.c                |  2 +-
834f04
 src/core/dbus-cgroup.c                 | 16 +++++++++---
834f04
 src/core/dbus-util.c                   | 29 ---------------------
834f04
 src/core/dbus-util.h                   |  1 -
834f04
 src/core/load-fragment-gperf.gperf.m4  |  2 +-
834f04
 src/core/load-fragment.c               |  6 ++---
834f04
 src/oom/oomd-manager.c                 | 24 +++++++++++------
834f04
 src/oom/oomd-manager.h                 |  4 +--
834f04
 src/oom/oomd-util.c                    |  4 +--
834f04
 src/oom/oomd.c                         | 10 +++----
834f04
 src/oom/oomd.conf                      |  2 +-
834f04
 src/shared/bus-get-properties.c        | 17 ------------
834f04
 src/shared/bus-get-properties.h        |  1 -
834f04
 src/shared/bus-unit-util.c             | 19 ++++++++++++--
834f04
 src/shared/conf-parser.c               |  1 +
834f04
 src/shared/conf-parser.h               |  1 +
834f04
 test/units/testsuite-56-workload.slice |  2 +-
834f04
 test/units/testsuite-56.sh             |  2 +-
834f04
 24 files changed, 91 insertions(+), 104 deletions(-)
834f04
834f04
diff --git a/docs/TRANSIENT-SETTINGS.md b/docs/TRANSIENT-SETTINGS.md
834f04
index 50b9a42fa1..5037060254 100644
834f04
--- a/docs/TRANSIENT-SETTINGS.md
834f04
+++ b/docs/TRANSIENT-SETTINGS.md
834f04
@@ -272,7 +272,7 @@ All cgroup/resource control settings are available for transient units
834f04
 ✓ IPAddressDeny=
834f04
 ✓ ManagedOOMSwap=
834f04
 ✓ ManagedOOMMemoryPressure=
834f04
-✓ ManagedOOMMemoryPressureLimitPercent=
834f04
+✓ ManagedOOMMemoryPressureLimit=
834f04
 ```
834f04
 
834f04
 ## Process Killing Settings
834f04
diff --git a/man/oomd.conf.xml b/man/oomd.conf.xml
834f04
index bb5da87c54..2a12be8cad 100644
834f04
--- a/man/oomd.conf.xml
834f04
+++ b/man/oomd.conf.xml
834f04
@@ -59,10 +59,10 @@
834f04
       </varlistentry>
834f04
 
834f04
       <varlistentry>
834f04
-        <term><varname>DefaultMemoryPressureLimitPercent=</varname></term>
834f04
+        <term><varname>DefaultMemoryPressureLimit=</varname></term>
834f04
 
834f04
         <listitem><para>Sets the limit for memory pressure on the unit's cgroup before <command>systemd-oomd</command>
834f04
-        will take action. A unit can override this value with <varname>ManagedOOMMemoryPressureLimitPercent=</varname>.
834f04
+        will take action. A unit can override this value with <varname>ManagedOOMMemoryPressureLimit=</varname>.
834f04
         The memory pressure for this property represents the fraction of time in a 10 second window in which all tasks
834f04
         in the cgroup were delayed. For each monitored cgroup, if the memory pressure on that cgroup exceeds the
834f04
         limit set for longer than the duration set by <varname>DefaultMemoryPressureDurationSec=</varname>,
834f04
@@ -78,7 +78,7 @@
834f04
 
834f04
         <listitem><para>Sets the amount of time a unit's cgroup needs to have exceeded memory pressure limits before
834f04
         <command>systemd-oomd</command> will take action. Memory pressure limits are defined by
834f04
-        <varname>DefaultMemoryPressureLimitPercent=</varname> and <varname>ManagedOOMMemoryPressureLimitPercent=</varname>.
834f04
+        <varname>DefaultMemoryPressureLimit=</varname> and <varname>ManagedOOMMemoryPressureLimit=</varname>.
834f04
         Defaults to 30 seconds when this property is unset or set to 0.</para></listitem>
834f04
       </varlistentry>
834f04
 
834f04
diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
834f04
index 78fd0b3378..7809b65062 100644
834f04
--- a/man/org.freedesktop.systemd1.xml
834f04
+++ b/man/org.freedesktop.systemd1.xml
834f04
@@ -2419,7 +2419,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
       readonly s ManagedOOMMemoryPressure = '...';
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
834f04
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
834f04
       readonly as Environment = ['...', ...];
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
834f04
@@ -2938,7 +2938,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
834f04
 
834f04
     
834f04
 
834f04
-    
834f04
+    
834f04
 
834f04
     
834f04
 
834f04
@@ -3494,7 +3494,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
834f04
 
834f04
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
834f04
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
834f04
 
834f04
@@ -4146,7 +4146,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
       readonly s ManagedOOMMemoryPressure = '...';
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
834f04
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
834f04
       readonly as Environment = ['...', ...];
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
834f04
@@ -4693,7 +4693,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
834f04
 
834f04
     
834f04
 
834f04
-    
834f04
+    
834f04
 
834f04
     
834f04
 
834f04
@@ -5251,7 +5251,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
834f04
 
834f04
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
834f04
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
834f04
 
834f04
@@ -5827,7 +5827,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
       readonly s ManagedOOMMemoryPressure = '...';
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
834f04
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
834f04
       readonly as Environment = ['...', ...];
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
834f04
@@ -6302,7 +6302,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
834f04
 
834f04
     
834f04
 
834f04
-    
834f04
+    
834f04
 
834f04
     
834f04
 
834f04
@@ -6778,7 +6778,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
834f04
 
834f04
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
834f04
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
834f04
 
834f04
@@ -7475,7 +7475,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
       readonly s ManagedOOMMemoryPressure = '...';
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
834f04
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
834f04
       readonly as Environment = ['...', ...];
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
834f04
@@ -7936,7 +7936,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
834f04
 
834f04
     
834f04
 
834f04
-    
834f04
+    
834f04
 
834f04
     
834f04
 
834f04
@@ -8398,7 +8398,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
834f04
 
834f04
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
834f04
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
834f04
 
834f04
@@ -8948,7 +8948,7 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
       readonly s ManagedOOMMemoryPressure = '...';
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
834f04
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
834f04
   };
834f04
   interface org.freedesktop.DBus.Peer { ... };
834f04
   interface org.freedesktop.DBus.Introspectable { ... };
834f04
@@ -9083,7 +9083,7 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
834f04
 
834f04
     
834f04
 
834f04
-    
834f04
+    
834f04
 
834f04
     
834f04
 
834f04
@@ -9223,7 +9223,7 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
834f04
 
834f04
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
834f04
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
834f04
 
834f04
     
834f04
 
834f04
@@ -9383,7 +9383,7 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
       readonly s ManagedOOMMemoryPressure = '...';
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
834f04
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
834f04
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
834f04
       readonly s KillMode = '...';
834f04
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
834f04
@@ -9534,7 +9534,7 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
834f04
 
834f04
     
834f04
 
834f04
-    
834f04
+    
834f04
 
834f04
     
834f04
 
834f04
@@ -9700,7 +9700,7 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
834f04
 
834f04
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
834f04
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
834f04
 
834f04
     <variablelist class="dbus-property" generated="True" extra-ref="KillMode"/>
834f04
 
834f04
diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml
834f04
index 26dedda3fd..4381c4e1b7 100644
834f04
--- a/man/systemd.resource-control.xml
834f04
+++ b/man/systemd.resource-control.xml
834f04
@@ -901,7 +901,7 @@ DeviceAllow=/dev/loop-control
834f04
       </varlistentry>
834f04
 
834f04
       <varlistentry>
834f04
-        <term><varname>ManagedOOMMemoryPressureLimitPercent=</varname></term>
834f04
+        <term><varname>ManagedOOMMemoryPressureLimit=</varname></term>
834f04
 
834f04
         <listitem>
834f04
           <para>Overrides the default memory pressure limit set by
834f04
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
834f04
index 7dc6c20bb7..e2ed0e546e 100644
834f04
--- a/src/core/cgroup.c
834f04
+++ b/src/core/cgroup.c
834f04
@@ -417,7 +417,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
834f04
                 "%sDelegate: %s\n"
834f04
                 "%sManagedOOMSwap: %s\n"
834f04
                 "%sManagedOOMMemoryPressure: %s\n"
834f04
-                "%sManagedOOMMemoryPressureLimitPercent: %d%%\n",
834f04
+                "%sManagedOOMMemoryPressureLimit: %" PRIu32 ".%02" PRIu32 "%%\n",
834f04
                 prefix, yes_no(c->cpu_accounting),
834f04
                 prefix, yes_no(c->io_accounting),
834f04
                 prefix, yes_no(c->blockio_accounting),
834f04
@@ -450,7 +450,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
834f04
                 prefix, yes_no(c->delegate),
834f04
                 prefix, managed_oom_mode_to_string(c->moom_swap),
834f04
                 prefix, managed_oom_mode_to_string(c->moom_mem_pressure),
834f04
-                prefix, c->moom_mem_pressure_limit);
834f04
+                prefix, c->moom_mem_pressure_limit_permyriad / 100, c->moom_mem_pressure_limit_permyriad % 100);
834f04
 
834f04
         if (c->delegate) {
834f04
                 _cleanup_free_ char *t = NULL;
834f04
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
834f04
index 66f3a63b82..9fbfabbb7e 100644
834f04
--- a/src/core/cgroup.h
834f04
+++ b/src/core/cgroup.h
834f04
@@ -163,7 +163,7 @@ struct CGroupContext {
834f04
         /* Settings for systemd-oomd */
834f04
         ManagedOOMMode moom_swap;
834f04
         ManagedOOMMode moom_mem_pressure;
834f04
-        int moom_mem_pressure_limit;
834f04
+        uint32_t moom_mem_pressure_limit_permyriad;
834f04
 };
834f04
 
834f04
 /* Used when querying IP accounting data */
834f04
diff --git a/src/core/core-varlink.c b/src/core/core-varlink.c
834f04
index dd6c11ab4d..17fb9bc83f 100644
834f04
--- a/src/core/core-varlink.c
834f04
+++ b/src/core/core-varlink.c
834f04
@@ -83,7 +83,7 @@ static int build_managed_oom_json_array_element(Unit *u, const char *property, J
834f04
                                  JSON_BUILD_PAIR("mode", JSON_BUILD_STRING(mode)),
834f04
                                  JSON_BUILD_PAIR("path", JSON_BUILD_STRING(u->cgroup_path)),
834f04
                                  JSON_BUILD_PAIR("property", JSON_BUILD_STRING(property)),
834f04
-                                 JSON_BUILD_PAIR_CONDITION(use_limit, "limit", JSON_BUILD_UNSIGNED(c->moom_mem_pressure_limit))));
834f04
+                                 JSON_BUILD_PAIR_CONDITION(use_limit, "limit", JSON_BUILD_UNSIGNED(c->moom_mem_pressure_limit_permyriad))));
834f04
 }
834f04
 
834f04
 int manager_varlink_send_managed_oom_update(Unit *u) {
834f04
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
834f04
index 37c581fb22..df35ec114d 100644
834f04
--- a/src/core/dbus-cgroup.c
834f04
+++ b/src/core/dbus-cgroup.c
834f04
@@ -395,7 +395,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
834f04
         SD_BUS_PROPERTY("DisableControllers", "as", property_get_cgroup_mask, offsetof(CGroupContext, disable_controllers), 0),
834f04
         SD_BUS_PROPERTY("ManagedOOMSwap", "s", property_get_managed_oom_mode, offsetof(CGroupContext, moom_swap), 0),
834f04
         SD_BUS_PROPERTY("ManagedOOMMemoryPressure", "s", property_get_managed_oom_mode, offsetof(CGroupContext, moom_mem_pressure), 0),
834f04
-        SD_BUS_PROPERTY("ManagedOOMMemoryPressureLimitPercent", "s", bus_property_get_percent, offsetof(CGroupContext, moom_mem_pressure_limit), 0),
834f04
+        SD_BUS_PROPERTY("ManagedOOMMemoryPressureLimitPermyriad", "u", NULL, offsetof(CGroupContext, moom_mem_pressure_limit_permyriad), 0),
834f04
         SD_BUS_VTABLE_END
834f04
 };
834f04
 
834f04
@@ -1697,14 +1697,24 @@ int bus_cgroup_set_property(
834f04
                 return 1;
834f04
         }
834f04
 
834f04
-        if (streq(name, "ManagedOOMMemoryPressureLimitPercent")) {
834f04
+        if (streq(name, "ManagedOOMMemoryPressureLimitPermyriad")) {
834f04
+                uint32_t v;
834f04
+
834f04
                 if (!UNIT_VTABLE(u)->can_set_managed_oom)
834f04
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot set %s for this unit type", name);
834f04
 
834f04
-                r = bus_set_transient_percent(u, name, &c->moom_mem_pressure_limit, message, flags, error);
834f04
+                r = sd_bus_message_read(message, "u", &v);
834f04
                 if (r < 0)
834f04
                         return r;
834f04
 
834f04
+                if (v > 10000)
834f04
+                        return -ERANGE;
834f04
+
834f04
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
834f04
+                        c->moom_mem_pressure_limit_permyriad = v;
834f04
+                        unit_write_settingf(u, flags, name, "ManagedOOMMemoryPressureLimit=%" PRIu32 ".%02" PRIu32 "%%", v / 100, v % 100);
834f04
+                }
834f04
+
834f04
                 if (c->moom_mem_pressure == MANAGED_OOM_KILL)
834f04
                         (void) manager_varlink_send_managed_oom_update(u);
834f04
 
834f04
diff --git a/src/core/dbus-util.c b/src/core/dbus-util.c
834f04
index d6223db305..eb03d30cf7 100644
834f04
--- a/src/core/dbus-util.c
834f04
+++ b/src/core/dbus-util.c
834f04
@@ -91,35 +91,6 @@ int bus_set_transient_bool(
834f04
         return 1;
834f04
 }
834f04
 
834f04
-int bus_set_transient_percent(
834f04
-                Unit *u,
834f04
-                const char *name,
834f04
-                int *p,
834f04
-                sd_bus_message *message,
834f04
-                UnitWriteFlags flags,
834f04
-                sd_bus_error *error) {
834f04
-
834f04
-        const char *v;
834f04
-        int r;
834f04
-
834f04
-        assert(p);
834f04
-
834f04
-        r = sd_bus_message_read(message, "s", &v);
834f04
-        if (r < 0)
834f04
-                return r;
834f04
-
834f04
-        r = parse_percent(v);
834f04
-        if (r < 0)
834f04
-                return r;
834f04
-
834f04
-        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
834f04
-                *p = r;
834f04
-                unit_write_settingf(u, flags, name, "%s=%d%%", name, r);
834f04
-        }
834f04
-
834f04
-        return 1;
834f04
-}
834f04
-
834f04
 int bus_set_transient_usec_internal(
834f04
                 Unit *u,
834f04
                 const char *name,
834f04
diff --git a/src/core/dbus-util.h b/src/core/dbus-util.h
834f04
index 4e7c68e843..b68ec38ada 100644
834f04
--- a/src/core/dbus-util.h
834f04
+++ b/src/core/dbus-util.h
834f04
@@ -240,7 +240,6 @@ int bus_set_transient_user_relaxed(Unit *u, const char *name, char **p, sd_bus_m
834f04
 int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
834f04
 int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
834f04
 int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
834f04
-int bus_set_transient_percent(Unit *u, const char *name, int *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
834f04
 int bus_set_transient_usec_internal(Unit *u, const char *name, usec_t *p, bool fix_0, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
834f04
 static inline int bus_set_transient_usec(Unit *u, const char *name, usec_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) {
834f04
         return bus_set_transient_usec_internal(u, name, p, false, message, flags, error);
834f04
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
834f04
index 946862c398..db2a4e28a8 100644
834f04
--- a/src/core/load-fragment-gperf.gperf.m4
834f04
+++ b/src/core/load-fragment-gperf.gperf.m4
834f04
@@ -226,7 +226,7 @@ $1.IPIngressFilterPath,                  config_parse_ip_filter_bpf_progs,
834f04
 $1.IPEgressFilterPath,                   config_parse_ip_filter_bpf_progs,            0,                                  offsetof($1, cgroup_context.ip_filters_egress)
834f04
 $1.ManagedOOMSwap,                       config_parse_managed_oom_mode,               0,                                  offsetof($1, cgroup_context.moom_swap)
834f04
 $1.ManagedOOMMemoryPressure,             config_parse_managed_oom_mode,               0,                                  offsetof($1, cgroup_context.moom_mem_pressure)
834f04
-$1.ManagedOOMMemoryPressureLimitPercent, config_parse_managed_oom_mem_pressure_limit, 0,                                  offsetof($1, cgroup_context.moom_mem_pressure_limit)
834f04
+$1.ManagedOOMMemoryPressureLimit,        config_parse_managed_oom_mem_pressure_limit, 0,                                  offsetof($1, cgroup_context.moom_mem_pressure_limit_permyriad)
834f04
 $1.NetClass,                             config_parse_warn_compat,                    DISABLED_LEGACY,                    0'
834f04
 )m4_dnl
834f04
 Unit.Description,                        config_parse_unit_string_printf,             0,                                  offsetof(Unit, description)
834f04
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
834f04
index 4964249bf2..e0e9920e06 100644
834f04
--- a/src/core/load-fragment.c
834f04
+++ b/src/core/load-fragment.c
834f04
@@ -3859,7 +3859,7 @@ int config_parse_managed_oom_mem_pressure_limit(
834f04
                 const char *rvalue,
834f04
                 void *data,
834f04
                 void *userdata) {
834f04
-        int *limit = data;
834f04
+        uint32_t *limit = data;
834f04
         UnitType t;
834f04
         int r;
834f04
 
834f04
@@ -3874,9 +3874,9 @@ int config_parse_managed_oom_mem_pressure_limit(
834f04
                 return 0;
834f04
         }
834f04
 
834f04
-        r = parse_percent(rvalue);
834f04
+        r = parse_permyriad(rvalue);
834f04
         if (r < 0) {
834f04
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse limit percent value, ignoring: %s", rvalue);
834f04
+                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse memory pressure limit value, ignoring: %s", rvalue);
834f04
                 return 0;
834f04
         }
834f04
 
834f04
diff --git a/src/oom/oomd-manager.c b/src/oom/oomd-manager.c
834f04
index 3efa629002..338935b3ec 100644
834f04
--- a/src/oom/oomd-manager.c
834f04
+++ b/src/oom/oomd-manager.c
834f04
@@ -100,10 +100,10 @@ static int process_managed_oom_reply(
834f04
                 limit = m->default_mem_pressure_limit;
834f04
 
834f04
                 if (streq(reply.property, "ManagedOOMMemoryPressure")) {
834f04
-                        if (reply.limit > 100)
834f04
+                        if (reply.limit > 10000)
834f04
                                 continue;
834f04
                         else if (reply.limit != 0) {
834f04
-                                ret = store_loadavg_fixed_point((unsigned long) reply.limit, 0, &limit);
834f04
+                                ret = store_loadavg_fixed_point((unsigned long) reply.limit / 100, (unsigned long) reply.limit % 100, &limit);
834f04
                                 if (ret < 0)
834f04
                                         continue;
834f04
                         }
834f04
@@ -478,8 +478,8 @@ static int manager_connect_bus(Manager *m) {
834f04
         return 0;
834f04
 }
834f04
 
834f04
-int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit, usec_t mem_pressure_usec) {
834f04
-        unsigned long l;
834f04
+int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit_permyriad, usec_t mem_pressure_usec) {
834f04
+        unsigned long l, f;
834f04
         int r;
834f04
 
834f04
         assert(m);
834f04
@@ -489,8 +489,16 @@ int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressur
834f04
         m->swap_used_limit = swap_used_limit != -1 ? swap_used_limit : DEFAULT_SWAP_USED_LIMIT;
834f04
         assert(m->swap_used_limit <= 100);
834f04
 
834f04
-        l = mem_pressure_limit != -1 ? mem_pressure_limit : DEFAULT_MEM_PRESSURE_LIMIT;
834f04
-        r = store_loadavg_fixed_point(l, 0, &m->default_mem_pressure_limit);
834f04
+        if (mem_pressure_limit_permyriad != -1) {
834f04
+                assert(mem_pressure_limit_permyriad <= 10000);
834f04
+
834f04
+                l = mem_pressure_limit_permyriad / 100;
834f04
+                f = mem_pressure_limit_permyriad % 100;
834f04
+        } else {
834f04
+                l = DEFAULT_MEM_PRESSURE_LIMIT_PERCENT;
834f04
+                f = 0;
834f04
+        }
834f04
+        r = store_loadavg_fixed_point(l, f, &m->default_mem_pressure_limit);
834f04
         if (r < 0)
834f04
                 return r;
834f04
 
834f04
@@ -530,12 +538,12 @@ int manager_get_dump_string(Manager *m, char **ret) {
834f04
         fprintf(f,
834f04
                 "Dry Run: %s\n"
834f04
                 "Swap Used Limit: %u%%\n"
834f04
-                "Default Memory Pressure Limit: %lu%%\n"
834f04
+                "Default Memory Pressure Limit: %lu.%02lu%%\n"
834f04
                 "Default Memory Pressure Duration: %s\n"
834f04
                 "System Context:\n",
834f04
                 yes_no(m->dry_run),
834f04
                 m->swap_used_limit,
834f04
-                LOAD_INT(m->default_mem_pressure_limit),
834f04
+                LOAD_INT(m->default_mem_pressure_limit), LOAD_FRAC(m->default_mem_pressure_limit),
834f04
                 format_timespan(buf, sizeof(buf), m->default_mem_pressure_duration_usec, USEC_PER_SEC));
834f04
         oomd_dump_system_context(&m->system_context, f, "\t");
834f04
 
834f04
diff --git a/src/oom/oomd-manager.h b/src/oom/oomd-manager.h
834f04
index ee17abced2..521665e0a8 100644
834f04
--- a/src/oom/oomd-manager.h
834f04
+++ b/src/oom/oomd-manager.h
834f04
@@ -17,7 +17,7 @@
834f04
  * Generally 60 or higher might be acceptable for something like system.slice with no memory.high set; processes in
834f04
  * system.slice are assumed to be less latency sensitive. */
834f04
 #define DEFAULT_MEM_PRESSURE_DURATION_USEC (30 * USEC_PER_SEC)
834f04
-#define DEFAULT_MEM_PRESSURE_LIMIT 60
834f04
+#define DEFAULT_MEM_PRESSURE_LIMIT_PERCENT 60
834f04
 #define DEFAULT_SWAP_USED_LIMIT 90
834f04
 
834f04
 #define RECLAIM_DURATION_USEC (30 * USEC_PER_SEC)
834f04
@@ -56,7 +56,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
834f04
 
834f04
 int manager_new(Manager **ret);
834f04
 
834f04
-int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit, usec_t mem_pressure_usec);
834f04
+int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit_permyriad, usec_t mem_pressure_usec);
834f04
 
834f04
 int manager_get_dump_string(Manager *m, char **ret);
834f04
 
834f04
diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c
834f04
index cec656f6fa..fcccddb92e 100644
834f04
--- a/src/oom/oomd-util.c
834f04
+++ b/src/oom/oomd-util.c
834f04
@@ -415,11 +415,11 @@ void oomd_dump_memory_pressure_cgroup_context(const OomdCGroupContext *ctx, FILE
834f04
 
834f04
         fprintf(f,
834f04
                 "%sPath: %s\n"
834f04
-                "%s\tMemory Pressure Limit: %lu%%\n"
834f04
+                "%s\tMemory Pressure Limit: %lu.%02lu%%\n"
834f04
                 "%s\tPressure: Avg10: %lu.%02lu Avg60: %lu.%02lu Avg300: %lu.%02lu Total: %s\n"
834f04
                 "%s\tCurrent Memory Usage: %s\n",
834f04
                 strempty(prefix), ctx->path,
834f04
-                strempty(prefix), LOAD_INT(ctx->mem_pressure_limit),
834f04
+                strempty(prefix), LOAD_INT(ctx->mem_pressure_limit), LOAD_FRAC(ctx->mem_pressure_limit),
834f04
                 strempty(prefix),
834f04
                 LOAD_INT(ctx->memory_pressure.avg10), LOAD_FRAC(ctx->memory_pressure.avg10),
834f04
                 LOAD_INT(ctx->memory_pressure.avg60), LOAD_FRAC(ctx->memory_pressure.avg60),
834f04
diff --git a/src/oom/oomd.c b/src/oom/oomd.c
834f04
index 1fbcf41492..811d211b58 100644
834f04
--- a/src/oom/oomd.c
834f04
+++ b/src/oom/oomd.c
834f04
@@ -18,14 +18,14 @@
834f04
 
834f04
 static bool arg_dry_run = false;
834f04
 static int arg_swap_used_limit = -1;
834f04
-static int arg_mem_pressure_limit = -1;
834f04
+static int arg_mem_pressure_limit_permyriad = -1;
834f04
 static usec_t arg_mem_pressure_usec = 0;
834f04
 
834f04
 static int parse_config(void) {
834f04
         static const ConfigTableItem items[] = {
834f04
-                { "OOM", "SwapUsedLimitPercent",              config_parse_percent, 0, &arg_swap_used_limit    },
834f04
-                { "OOM", "DefaultMemoryPressureLimitPercent", config_parse_percent, 0, &arg_mem_pressure_limit },
834f04
-                { "OOM", "DefaultMemoryPressureDurationSec",  config_parse_sec,     0, &arg_mem_pressure_usec  },
834f04
+                { "OOM", "SwapUsedLimitPercent",             config_parse_percent,   0, &arg_swap_used_limit              },
834f04
+                { "OOM", "DefaultMemoryPressureLimit",       config_parse_permyriad, 0, &arg_mem_pressure_limit_permyriad },
834f04
+                { "OOM", "DefaultMemoryPressureDurationSec", config_parse_sec,       0, &arg_mem_pressure_usec            },
834f04
                 {}
834f04
         };
834f04
 
834f04
@@ -160,7 +160,7 @@ static int run(int argc, char *argv[]) {
834f04
         if (r < 0)
834f04
                 return log_error_errno(r, "Failed to create manager: %m");
834f04
 
834f04
-        r = manager_start(m, arg_dry_run, arg_swap_used_limit, arg_mem_pressure_limit, arg_mem_pressure_usec);
834f04
+        r = manager_start(m, arg_dry_run, arg_swap_used_limit, arg_mem_pressure_limit_permyriad, arg_mem_pressure_usec);
834f04
         if (r < 0)
834f04
                 return log_error_errno(r, "Failed to start up daemon: %m");
834f04
 
834f04
diff --git a/src/oom/oomd.conf b/src/oom/oomd.conf
834f04
index 766cb1717f..bd6a9391c6 100644
834f04
--- a/src/oom/oomd.conf
834f04
+++ b/src/oom/oomd.conf
834f04
@@ -13,5 +13,5 @@
834f04
 
834f04
 [OOM]
834f04
 #SwapUsedLimitPercent=90%
834f04
-#DefaultMemoryPressureLimitPercent=60%
834f04
+#DefaultMemoryPressureLimit=60%
834f04
 #DefaultMemoryPressureDurationSec=30s
834f04
diff --git a/src/shared/bus-get-properties.c b/src/shared/bus-get-properties.c
834f04
index 32f68d5e6a..a5ce7ef17f 100644
834f04
--- a/src/shared/bus-get-properties.c
834f04
+++ b/src/shared/bus-get-properties.c
834f04
@@ -55,23 +55,6 @@ int bus_property_get_id128(
834f04
                 return sd_bus_message_append_array(reply, 'y', id->bytes, 16);
834f04
 }
834f04
 
834f04
-int bus_property_get_percent(
834f04
-                sd_bus *bus,
834f04
-                const char *path,
834f04
-                const char *interface,
834f04
-                const char *property,
834f04
-                sd_bus_message *reply,
834f04
-                void *userdata,
834f04
-                sd_bus_error *error) {
834f04
-
834f04
-        char pstr[DECIMAL_STR_MAX(int) + 2];
834f04
-        int p = *(int*) userdata;
834f04
-
834f04
-        xsprintf(pstr, "%d%%", p);
834f04
-
834f04
-        return sd_bus_message_append_basic(reply, 's', pstr);
834f04
-}
834f04
-
834f04
 #if __SIZEOF_SIZE_T__ != 8
834f04
 int bus_property_get_size(
834f04
                 sd_bus *bus,
834f04
diff --git a/src/shared/bus-get-properties.h b/src/shared/bus-get-properties.h
834f04
index 9832c0d067..26f3e8588c 100644
834f04
--- a/src/shared/bus-get-properties.h
834f04
+++ b/src/shared/bus-get-properties.h
834f04
@@ -8,7 +8,6 @@
834f04
 int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
834f04
 int bus_property_set_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error);
834f04
 int bus_property_get_id128(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
834f04
-int bus_property_get_percent(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
834f04
 
834f04
 #define bus_property_get_usec ((sd_bus_property_get_t) NULL)
834f04
 #define bus_property_set_usec ((sd_bus_property_set_t) NULL)
834f04
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
834f04
index 2bab2299fb..f96059c699 100644
834f04
--- a/src/shared/bus-unit-util.c
834f04
+++ b/src/shared/bus-unit-util.c
834f04
@@ -435,10 +435,25 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
834f04
         if (STR_IN_SET(field, "DevicePolicy",
834f04
                               "Slice",
834f04
                               "ManagedOOMSwap",
834f04
-                              "ManagedOOMMemoryPressure",
834f04
-                              "ManagedOOMMemoryPressureLimitPercent"))
834f04
+                              "ManagedOOMMemoryPressure"))
834f04
                 return bus_append_string(m, field, eq);
834f04
 
834f04
+        if (STR_IN_SET(field, "ManagedOOMMemoryPressureLimit")) {
834f04
+                char *n;
834f04
+
834f04
+                r = parse_permyriad(eq);
834f04
+                if (r < 0)
834f04
+                        return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
834f04
+
834f04
+                n = strjoina(field, "Permyriad");
834f04
+
834f04
+                r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) r);
834f04
+                if (r < 0)
834f04
+                        return bus_log_create_error(r);
834f04
+
834f04
+                return 1;
834f04
+        }
834f04
+
834f04
         if (STR_IN_SET(field, "CPUAccounting",
834f04
                               "MemoryAccounting",
834f04
                               "IOAccounting",
834f04
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
834f04
index 35d301d9db..c8c253d603 100644
834f04
--- a/src/shared/conf-parser.c
834f04
+++ b/src/shared/conf-parser.c
834f04
@@ -1245,3 +1245,4 @@ int config_parse_vlanprotocol(const char* unit,
834f04
 }
834f04
 
834f04
 DEFINE_CONFIG_PARSE(config_parse_percent, parse_percent, "Failed to parse percent value");
834f04
+DEFINE_CONFIG_PARSE(config_parse_permyriad, parse_permyriad, "Failed to parse permyriad value");
834f04
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
834f04
index f115cb23af..988d81e43a 100644
834f04
--- a/src/shared/conf-parser.h
834f04
+++ b/src/shared/conf-parser.h
834f04
@@ -148,6 +148,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_mtu);
834f04
 CONFIG_PARSER_PROTOTYPE(config_parse_rlimit);
834f04
 CONFIG_PARSER_PROTOTYPE(config_parse_vlanprotocol);
834f04
 CONFIG_PARSER_PROTOTYPE(config_parse_percent);
834f04
+CONFIG_PARSER_PROTOTYPE(config_parse_permyriad);
834f04
 
834f04
 typedef enum Disabled {
834f04
         DISABLED_CONFIGURATION,
834f04
diff --git a/test/units/testsuite-56-workload.slice b/test/units/testsuite-56-workload.slice
834f04
index 45b04914c6..8c32b28094 100644
834f04
--- a/test/units/testsuite-56-workload.slice
834f04
+++ b/test/units/testsuite-56-workload.slice
834f04
@@ -7,4 +7,4 @@ MemoryAccounting=true
834f04
 IOAccounting=true
834f04
 TasksAccounting=true
834f04
 ManagedOOMMemoryPressure=kill
834f04
-ManagedOOMMemoryPressureLimitPercent=1%
834f04
+ManagedOOMMemoryPressureLimit=1%
834f04
diff --git a/test/units/testsuite-56.sh b/test/units/testsuite-56.sh
834f04
index 4dc9d8c7a8..8b01fe37ed 100755
834f04
--- a/test/units/testsuite-56.sh
834f04
+++ b/test/units/testsuite-56.sh
834f04
@@ -20,7 +20,7 @@ systemctl start testsuite-56-testbloat.service
834f04
 
834f04
 # Verify systemd-oomd is monitoring the expected units
834f04
 oomctl | grep "/testsuite-56-workload.slice"
834f04
-oomctl | grep "1%"
834f04
+oomctl | grep "1.00%"
834f04
 oomctl | grep "Default Memory Pressure Duration: 5s"
834f04
 
834f04
 # systemd-oomd watches for elevated pressure for 30 seconds before acting.
834f04
-- 
834f04
2.29.2
834f04