[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250509072054.148257-5-chenridong@huaweicloud.com>
Date: Fri, 9 May 2025 07:20:53 +0000
From: Chen Ridong <chenridong@...weicloud.com>
To: akpm@...ux-foundation.org,
paulmck@...nel.org,
bigeasy@...utronix.de,
legion@...nel.org,
roman.gushchin@...ux.dev,
brauner@...nel.org,
tglx@...utronix.de,
frederic@...nel.org,
peterz@...radead.org,
oleg@...hat.com,
joel.granados@...nel.org,
viro@...iv.linux.org.uk,
lorenzo.stoakes@...cle.com,
avagin@...gle.com,
mengensun@...cent.com,
linux@...ssschuh.net,
jlayton@...nel.org,
ruanjinjie@...wei.com,
kees@...nel.org
Cc: linux-kernel@...r.kernel.org,
lujialin4@...wei.com,
chenridong@...weicloud.com
Subject: [RFC next v2 4/5] uounts: factor out __inc_rlimit_get_ucounts/__dec_rlimit_put_ucounts
From: Chen Ridong <chenridong@...wei.com>
The __inc_rlimit_get_ucounts function has been factored out. This function
can increment the rlimit by a variable number and acquires an additional
ucount reference when the rlimit count was previously zero.
Correspondingly, the __dec_rlimit_put_ucounts function has also been
factored out. This function releases the ucount reference when the rlimit
reaches zero.
These functions not only make the code more concise but also serve as a
foundation for subsequent patches.
Signed-off-by: Chen Ridong <chenridong@...wei.com>
---
kernel/ucount.c | 56 +++++++++++++++++++++++++++++++------------------
1 file changed, 36 insertions(+), 20 deletions(-)
diff --git a/kernel/ucount.c b/kernel/ucount.c
index 8686e329b8f2..33605e416724 100644
--- a/kernel/ucount.c
+++ b/kernel/ucount.c
@@ -276,22 +276,46 @@ bool dec_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v)
return (new == 0);
}
+static void __dec_rlimit_put_ucounts(struct ucounts *ucounts,
+ enum rlimit_type type, long v)
+{
+ long dec = atomic_long_sub_return(v, &ucounts->rlimit[type]);
+
+ WARN_ON_ONCE(dec < 0);
+ if (dec == 0)
+ put_ucounts(ucounts);
+}
+
+static long __inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v)
+{
+ long new = atomic_long_add_return(v, &ucounts->rlimit[type]);
+
+ /*
+ * Grab an extra ucount reference for the caller when
+ * the rlimit count was previously 0.
+ */
+ if (new == v && !get_ucounts(ucounts)) {
+ long dec = atomic_long_sub_return(v, &ucounts->rlimit[type]);
+
+ WARN_ON_ONCE(dec < 0);
+ return 0;
+ }
+ return new;
+}
+
static void do_dec_rlimit_put_ucounts(struct ucounts *ucounts,
- struct ucounts *last, enum rlimit_type type)
+ struct ucounts *last, enum rlimit_type type, long v)
{
struct ucounts *iter, *next;
for (iter = ucounts; iter != last; iter = next) {
- long dec = atomic_long_sub_return(1, &iter->rlimit[type]);
- WARN_ON_ONCE(dec < 0);
next = iter->ns->ucounts;
- if (dec == 0)
- put_ucounts(iter);
+ __dec_rlimit_put_ucounts(ucounts, type, v);
}
}
void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum rlimit_type type)
{
- do_dec_rlimit_put_ucounts(ucounts, NULL, type);
+ do_dec_rlimit_put_ucounts(ucounts, NULL, type, 1);
}
long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type,
@@ -300,30 +324,22 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type,
/* Caller must hold a reference to ucounts */
struct ucounts *iter;
long max = LONG_MAX;
- long dec, ret = 0;
+ long ret = 0;
for (iter = ucounts; iter; iter = iter->ns->ucounts) {
- long new = atomic_long_add_return(1, &iter->rlimit[type]);
- if (new < 0 || new > max)
+ long new = __inc_rlimit_get_ucounts(iter, type, 1);
+
+ if (new <= 0 || new > max)
goto dec_unwind;
if (iter == ucounts)
ret = new;
if (!override_rlimit)
max = get_userns_rlimit_max(iter->ns, type);
- /*
- * Grab an extra ucount reference for the caller when
- * the rlimit count was previously 0.
- */
- if (new != 1)
- continue;
- if (!get_ucounts(iter))
- goto dec_unwind;
}
return ret;
+
dec_unwind:
- dec = atomic_long_sub_return(1, &iter->rlimit[type]);
- WARN_ON_ONCE(dec < 0);
- do_dec_rlimit_put_ucounts(ucounts, iter, type);
+ do_dec_rlimit_put_ucounts(ucounts, iter, type, 1);
return 0;
}
--
2.34.1
Powered by blists - more mailing lists