From: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
To: Konstantin Khorenko <khorenko@virtuozzo.com>,
vasileios.almpanis@virtuozzo.com
Cc: devel@openvz.org
Subject: [Devel] [PATCH hci-8.1 3/6] ve/printk: Specify ve in printks
Date: Fri, 02 Oct 2026 23:26:12 +0200 [thread overview]
Message-ID: <20261002-ve-printk-irq-v1-3-cb55896d455c@virtuozzo.com> (raw)
In-Reply-To: <20261002-ve-printk-irq-v1-0-cb55896d455c@virtuozzo.com>
Introduce ve_printk helpers that accept VE structure,
so we can provide correct VE where get_exec_env is unreliable.
This is true for ve_printk_deferred functions, and their users.
Now VE ratelimiting requires specified VE, and this requirement
is further forwarded to ve_net_ratelimited kind.
https://virtuozzo.atlassian.net/browse/VSTOR-146839
Feature: ve printk
Signed-off-by: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
---
include/linux/net.h | 16 ++++----
include/linux/printk.h | 23 ++++++++++--
include/linux/ratelimit_types.h | 6 ++-
kernel/printk/printk.c | 74 +++++++++++++++++++++++++++++++------
lib/ratelimit.c | 7 ++--
net/core/utils.c | 4 +-
net/netfilter/nf_conntrack_core.c | 2 +-
net/netfilter/nf_conntrack_expect.c | 2 +-
net/netfilter/xt_TCPMSS.c | 4 +-
9 files changed, 104 insertions(+), 34 deletions(-)
diff --git a/include/linux/net.h b/include/linux/net.h
index 3f3bbe9f149d..4c34b9a0386f 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -265,7 +265,7 @@ struct socket *sockfd_lookup(int fd, int *err);
struct socket *sock_from_file(struct file *file);
#define sockfd_put(sock) fput(sock->file)
int net_ratelimit(void);
-int ve_net_ratelimit(int dst);
+int ve_net_ratelimit(int dst, struct ve_struct *ve);
#define net_ratelimited_function(function, ...) \
do { \
@@ -273,10 +273,10 @@ do { \
function(__VA_ARGS__); \
} while (0)
-#define ve_net_ratelimited_function(function, dst, ...) \
+#define ve_net_ratelimited_function(function, dst, ve, ...) \
do { \
- if (ve_net_ratelimit(dst)) \
- function(dst, __VA_ARGS__); \
+ if (ve_net_ratelimit(dst, ve)) \
+ function(dst, ve, __VA_ARGS__); \
} while (0)
#define net_emerg_ratelimited(fmt, ...) \
@@ -311,10 +311,10 @@ do { \
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#endif
-#define net_velog_ratelimited(fmt, ...) \
- ve_net_ratelimited_function(ve_printk, VE_LOG, fmt, ##__VA_ARGS__)
-#define net_veboth_ratelimited(fmt, ...) \
- ve_net_ratelimited_function(ve_printk, VE_LOG_BOTH, fmt, ##__VA_ARGS__)
+#define net_velog_ratelimited(ve, fmt, ...) \
+ ve_net_ratelimited_function(__ve_printk, VE_LOG, ve, fmt, ##__VA_ARGS__)
+#define net_veboth_ratelimited(ve, fmt, ...) \
+ ve_net_ratelimited_function(__ve_printk, VE_LOG_BOTH, ve, fmt, ##__VA_ARGS__)
#define net_get_random_once(buf, nbytes) \
get_random_once((buf), (nbytes))
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 3b0af0deb6c3..1478e47dc582 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -76,6 +76,7 @@ extern int console_printk[];
#define VE0_LOG 1
#define VE_LOG 2
#define VE_LOG_BOTH (VE0_LOG | VE_LOG)
+struct ve_struct;
extern void console_verbose(void);
@@ -160,6 +161,11 @@ int ve_vprintk_emit(int facility, int level,
const struct dev_printk_info *dev_info,
const char *fmt, va_list args);
+asmlinkage __printf(5, 0)
+int __ve_vprintk_emit(struct ve_struct *ve, int facility, int level,
+ const struct dev_printk_info *dev_info,
+ const char *fmt, va_list args);
+
asmlinkage __printf(1, 0)
int vprintk(const char *fmt, va_list args);
__printf(1, 0)
@@ -171,8 +177,11 @@ int _printk(const char *fmt, ...);
asmlinkage __printf(2, 3) __cold
int ve_printk(int dst, const char *fmt, ...);
-asmlinkage __printf(2, 3) __cold
-int ve_printk_deferred(int dst, const char *fmt, ...);
+asmlinkage __printf(3, 4) __cold
+int __ve_printk(int dst, struct ve_struct *ve, const char *fmt, ...);
+
+asmlinkage __printf(3, 4) __cold
+int ve_printk_deferred(int dst, struct ve_struct *ve, const char *fmt, ...);
struct ve_struct;
int ve_log_init(struct ve_struct *ve);
@@ -248,8 +257,13 @@ int ve_printk(int dst, const char *s, ...)
{
return 0;
}
+static inline __printf(3, 4) __cold
+int __ve_printk(int dst, struct ve_struct *ve, const char *s, ...)
+{
+ return 0;
+}
static inline __printf(2, 3) __cold
-int ve_printk_deferred(int dst, const char *s, ...)
+int ve_printk_deferred(int dst, struct ve_struct *ve, const char *s, ...)
{
return 0;
}
@@ -747,7 +761,8 @@ struct pi_entry {
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
\
- if (ve_ratelimit(dst, &_rs)) \
+ WARN_ON_ONCE((dst & VE_LOG) && !in_task()); \
+ if (ve_ratelimit(dst, get_exec_env(), &_rs)) \
ve_printk(dst, fmt, ##__VA_ARGS__); \
})
#else
diff --git a/include/linux/ratelimit_types.h b/include/linux/ratelimit_types.h
index 3902066f0fee..aa9eee2a2455 100644
--- a/include/linux/ratelimit_types.h
+++ b/include/linux/ratelimit_types.h
@@ -44,7 +44,9 @@ struct ratelimit_state {
extern int ___ratelimit(struct ratelimit_state *rs, const char *func);
#define __ratelimit(state) ___ratelimit(state, __func__)
-extern int __ve_ratelimit(int dst, struct ratelimit_state *rs, const char *func);
-#define ve_ratelimit(dst, state) __ve_ratelimit(dst, state, __func__)
+struct ve_struct;
+extern int __ve_ratelimit(int dst, struct ve_struct *ve,
+ struct ratelimit_state *rs, const char *func);
+#define ve_ratelimit(dst, ve, state) __ve_ratelimit(dst, ve, state, __func__)
#endif /* _LINUX_RATELIMIT_TYPES_H */
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index b06fc835d7c7..df7cf83fb4af 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -567,6 +567,16 @@ struct log_state *ve_log_state(void)
return log;
}
+struct log_state *__ve_log_state(struct ve_struct *ve)
+{
+ struct log_state *log = &init_log_state;
+#ifdef CONFIG_VE
+ if (ve->log_state)
+ log = ve->log_state;
+#endif
+ return log;
+}
+
void log_poll_wait(struct file *filp, poll_table *p)
{
poll_wait(filp, &ve_log_state()->wait, p);
@@ -2525,26 +2535,45 @@ asmlinkage int ve_vprintk_emit(int facility, int level,
}
EXPORT_SYMBOL(ve_vprintk_emit);
+asmlinkage int __ve_vprintk_emit(struct ve_struct *ve, int facility, int level,
+ const struct dev_printk_info *dev_info,
+ const char *fmt, va_list args)
+{
+ return vprintk_emit_log(__ve_log_state(ve),
+ facility, level, dev_info,
+ fmt, args);
+}
+EXPORT_SYMBOL(__ve_vprintk_emit);
+
int vprintk_default(const char *fmt, va_list args)
{
return vprintk_emit(0, LOGLEVEL_DEFAULT, NULL, fmt, args);
}
EXPORT_SYMBOL_GPL(vprintk_default);
-static asmlinkage int ve_vprintk(int dst, const char *fmt, va_list args)
+static asmlinkage int ve_vprintk(int dst, struct ve_struct *ve,
+ const char *fmt, va_list args)
{
va_list args2;
- int r = 0;
+ int r = 0, ve_provided = (ve != NULL);
WARN_ON_ONCE(!dst || (dst & ~VE_LOG_BOTH));
+ if (!ve)
+ ve = get_exec_env();
+
va_copy(args2, args);
if (ve_is_super(get_exec_env()) || (dst & VE0_LOG))
r = vprintk(fmt, args);
/* Report IRQ usage here - printing to VE requires explicit ve reference */
- if ((dst & VE_LOG) && !WARN_ON_ONCE(!in_task()) && !ve_is_super(get_exec_env()))
- r = ve_vprintk_emit(0, LOGLEVEL_DEFAULT, NULL, fmt, args2);
+ if ((dst & VE_LOG)) {
+ if (!ve_provided && WARN_ON_ONCE(!in_task()))
+ goto done;
+ if (!ve_is_super(ve))
+ r = __ve_vprintk_emit(ve, 0, LOGLEVEL_DEFAULT, NULL, fmt, args2);
+ }
+done:
va_end(args2);
return r;
@@ -2560,39 +2589,62 @@ asmlinkage int ve_printk(int dst, const char *fmt, ...)
int r;
va_start(args, fmt);
- r = ve_vprintk(dst, fmt, args);
+ r = ve_vprintk(dst, NULL, fmt, args);
va_end(args);
return r;
}
EXPORT_SYMBOL(ve_printk);
-static asmlinkage int ve_vprintk_deferred(int dst, const char *fmt, va_list args)
+asmlinkage int __ve_printk(int dst, struct ve_struct *ve, const char *fmt, ...)
+{
+ va_list args;
+ int r;
+
+ va_start(args, fmt);
+ r = ve_vprintk(dst, ve, fmt, args);
+ va_end(args);
+
+ return r;
+}
+EXPORT_SYMBOL(__ve_printk);
+
+static asmlinkage int ve_vprintk_deferred(int dst, struct ve_struct *ve,
+ const char *fmt, va_list args)
{
va_list args2;
- int r = 0;
+ int r = 0, ve_provided = (ve != NULL);
WARN_ON_ONCE(!dst || (dst & ~VE_LOG_BOTH));
+ if (!ve)
+ ve = get_exec_env();
+
va_copy(args2, args);
if (ve_is_super(get_exec_env()) || (dst & VE0_LOG))
r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args);
/* Report IRQ usage here - printing to VE requires explicit ve reference */
- if ((dst & VE_LOG) && !WARN_ON_ONCE(!in_task()) && !ve_is_super(get_exec_env()))
- r = ve_vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args2);
+ if ((dst & VE_LOG)) {
+ if (!ve_provided && WARN_ON_ONCE(!in_task()))
+ goto done;
+ if (!ve_is_super(ve))
+ r = __ve_vprintk_emit(ve, 0, LOGLEVEL_SCHED, NULL, fmt, args2);
+ }
+done:
va_end(args2);
return r;
}
-asmlinkage int ve_printk_deferred(int dst, const char *fmt, ...)
+asmlinkage int ve_printk_deferred(int dst, struct ve_struct *ve,
+ const char *fmt, ...)
{
va_list args;
int r;
va_start(args, fmt);
- r = ve_vprintk_deferred(dst, fmt, args);
+ r = ve_vprintk_deferred(dst, ve, fmt, args);
va_end(args);
return r;
diff --git a/lib/ratelimit.c b/lib/ratelimit.c
index 98409e870eea..98c45bb19e50 100644
--- a/lib/ratelimit.c
+++ b/lib/ratelimit.c
@@ -11,6 +11,7 @@
#include <linux/ratelimit.h>
#include <linux/jiffies.h>
#include <linux/export.h>
+#include <linux/ve_proto.h>
/*
* __ratelimit - rate limiting
@@ -24,7 +25,7 @@
* 0 means callbacks will be suppressed.
* 1 means go ahead and do it.
*/
-int __ve_ratelimit(int dst, struct ratelimit_state *rs, const char *func)
+int __ve_ratelimit(int dst, struct ve_struct *ve, struct ratelimit_state *rs, const char *func)
{
/* Paired with WRITE_ONCE() in .proc_handler().
* Changing two values seperately could be inconsistent
@@ -55,7 +56,7 @@ int __ve_ratelimit(int dst, struct ratelimit_state *rs, const char *func)
if (m) {
if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) {
- ve_printk_deferred(dst, KERN_WARNING
+ ve_printk_deferred(dst, ve, KERN_WARNING
"%s: %d callbacks suppressed\n", func, m);
}
}
@@ -77,6 +78,6 @@ EXPORT_SYMBOL(__ve_ratelimit);
int ___ratelimit(struct ratelimit_state *rs, const char *func)
{
- return __ve_ratelimit(VE0_LOG, rs, func);
+ return __ve_ratelimit(VE0_LOG, get_ve0(), rs, func);
}
EXPORT_SYMBOL(___ratelimit);
diff --git a/net/core/utils.c b/net/core/utils.c
index cffc3bc44baa..bf4e53205a8e 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -41,9 +41,9 @@ int net_ratelimit(void)
}
EXPORT_SYMBOL(net_ratelimit);
-int ve_net_ratelimit(int dst)
+int ve_net_ratelimit(int dst, struct ve_struct *ve)
{
- return ve_ratelimit(dst, &net_ratelimit_state);
+ return ve_ratelimit(dst, ve, &net_ratelimit_state);
}
EXPORT_SYMBOL(ve_net_ratelimit);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index f078136edddd..8900a41b48b6 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1701,7 +1701,7 @@ __nf_conntrack_alloc(struct net *net,
if (!conntrack_gc_work.early_drop)
conntrack_gc_work.early_drop = true;
atomic_dec(&cnet->count);
- net_veboth_ratelimited(KERN_WARNING "VE%s: "
+ net_veboth_ratelimited(net->owner_ve, KERN_WARNING "VE%s: "
"nf_conntrack table full in netns %u, dropping packet\n",
ve_name(net->owner_ve), net->ns.inum);
return ERR_PTR(-ENOMEM);
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 4b077b2cb432..23e78957bb79 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -508,7 +508,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect,
cnet = nf_ct_pernet(net);
if (cnet->expect_count >= cnet->expect_max) {
- net_veboth_ratelimited(KERN_WARNING "VE%s: "
+ net_veboth_ratelimited(net->owner_ve, KERN_WARNING "VE%s: "
"nf_conntrack: expectation table full in netns %u\n",
ve_name(net->owner_ve), net->ns.inum);
ret = -EMFILE;
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index 822b3f71570e..0b9ccc8987e2 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -105,8 +105,8 @@ tcpmss_mangle_packet(struct sk_buff *skb,
unsigned int min_mtu = min(dst_mtu(skb_dst(skb)), in_mtu);
if (min_mtu <= minlen) {
- net_velog_ratelimited("unknown or invalid path-MTU (%u)\n",
- min_mtu);
+ net_velog_ratelimited(net->owner_ve, "unknown or invalid path-MTU (%u)\n",
+ min_mtu);
return -1;
}
newmss = min_mtu - minlen;
--
2.52.0
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
next prev parent reply other threads:[~2026-10-02 21:28 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-02 21:26 [Devel] [PATCH hci-8.1 0/6] ve/printk: Fix logs leakage via ve_printk called from IRQ context Vladimir Riabchun
2026-10-02 21:26 ` [Devel] [PATCH hci-8.1 1/6] ve/printk: Add sanity checks in ve_printk functions Vladimir Riabchun
2026-10-02 21:31 ` no-reply
2026-10-03 12:26 ` Vladimir Riabchun
2026-10-02 21:26 ` [Devel] [PATCH hci-8.1 2/6] ve/printk: Report potentially leaking usage of " Vladimir Riabchun
2026-10-02 21:32 ` no-reply
2026-10-03 12:26 ` Vladimir Riabchun
2026-10-02 21:26 ` Vladimir Riabchun [this message]
2026-10-02 21:36 ` [Devel] [PATCH hci-8.1 3/6] ve/printk: Specify ve in printks no-reply
2026-10-03 13:49 ` Vladimir Riabchun
2026-10-02 21:26 ` [Devel] [PATCH hci-8.1 4/6] ve/printk: Fix time virtualization Vladimir Riabchun
2026-10-02 21:37 ` no-reply
2026-10-05 8:45 ` Vladimir Riabchun
2026-10-02 21:26 ` [Devel] [PATCH hci-8.1 5/6] ve/failcount: Use ve_printk with specified ve Vladimir Riabchun
2026-10-02 21:38 ` no-reply
2026-10-05 9:56 ` Vladimir Riabchun
2026-10-02 21:26 ` [Devel] [PATCH hci-8.1 6/6] ve: add neigh_tbl failcounter Vladimir Riabchun
2026-10-02 21:40 ` no-reply
2026-10-05 10:02 ` Vladimir Riabchun
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261002-ve-printk-irq-v1-3-cb55896d455c@virtuozzo.com \
--to=vladimir.riabchun@virtuozzo.com \
--cc=devel@openvz.org \
--cc=khorenko@virtuozzo.com \
--cc=vasileios.almpanis@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.