[Devel] [PATCH hci-8.1 v2 4/6] ve/printk: Fix time virtualization
Vladimir Riabchun
vladimir.riabchun at virtuozzo.com
Wed Oct 7 00:53:55 MSK 2026
The usage of get_exec_env() in ve_timens_add_boottime_ns can lead
to time travels - a printk from IRQ might use container time for
printing to host dmesg and vice versa.
Do time adjustments on message submission in vprintk_store_log,
there we know the final destination and VE, so we can get actual
time namespace and offsets there.
https://virtuozzo.atlassian.net/browse/VSTOR-146839
Feature: ve printk
Signed-off-by: Vladimir Riabchun <vladimir.riabchun at virtuozzo.com>
---
kernel/printk/internal.h | 4 ++++
kernel/printk/printk.c | 12 +++++-------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h
index d00ac40d8401..d678718482ed 100644
--- a/kernel/printk/internal.h
+++ b/kernel/printk/internal.h
@@ -354,11 +354,15 @@ struct log_state {
*/
struct latched_seq clear_seq;
struct printk_ringbuffer *prb;
+ struct ve_struct *owner_ve;
};
+#define GET_VE_LOG(ve) ((struct log_state *) ve->log_state)
+
extern struct log_state init_log_state;
struct log_state *ve_log_state(void);
+struct log_state *__ve_log_state(struct ve_struct *ve);
bool printk_get_next_message(struct log_state *log,
struct printk_message *pmsg, u64 seq,
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index d5680fda32ca..cf4baacd22d8 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -534,6 +534,7 @@ struct log_state init_log_state = {
.val[1] = 0,
},
.prb = &printk_rb_static,
+ .owner_ve = &ve0,
};
/* kdump relies on some log_* symbols, let's make it happy */
@@ -698,12 +699,12 @@ static void append_char(char **pp, char *e, char c)
*(*pp)++ = c;
}
-static inline u64 ve_timens_add_boottime_ns(u64 nsec)
+static inline u64 ve_timens_add_boottime_ns(u64 nsec, struct ve_struct *ve)
{
struct time_namespace *ve_time_ns;
struct timens_offsets *ns_offsets;
- ve_time_ns = ve_get_time_ns(get_exec_env());
+ ve_time_ns = ve_get_time_ns(ve);
if (unlikely(!ve_time_ns)) {
/* container not yet started */
return nsec;
@@ -731,8 +732,6 @@ static ssize_t info_print_ext_header(char *buf, size_t size,
caller[0] = '\0';
#endif
- /* shift the timestamp on the Container uptime value */
- ts_usec = ve_timens_add_boottime_ns(ts_usec);
do_div(ts_usec, 1000);
return scnprintf(buf, size, "%u,%llu,%llu,%c%s;",
@@ -1431,9 +1430,6 @@ static size_t print_time(u64 ts, char *buf)
{
unsigned long rem_nsec;
- /* shift the timestamp on the Container uptime value */
- ts = ve_timens_add_boottime_ns(ts);
-
rem_nsec = do_div(ts, 1000000000);
return sprintf(buf, "[%5lu.%06lu]",
@@ -2329,6 +2325,7 @@ static int vprintk_store_log(struct log_state *log, int facility, int level,
* timestamp with respect to the caller.
*/
ts_nsec = local_clock();
+ ts_nsec = ve_timens_add_boottime_ns(ts_nsec, log->owner_ve);
caller_id = printk_caller_id();
@@ -5294,6 +5291,7 @@ int ve_log_init(struct ve_struct *ve)
seqcount_latch_init(&log->clear_seq.latch);
ve->log_state = log;
+ log->owner_ve = ve;
return 0;
}
--
2.52.0
More information about the Devel
mailing list