[rh8] ve: Add interface for ve::clock_[monotonic|bootbased] adjustment

Submitted by Konstantin Khorenko on Oct. 12, 2020, 12:19 p.m.

Details

Message ID 20201012121935.1428303-1-khorenko@virtuozzo.com
State New
Series "ve: Add interface for ve::clock_[monotonic|bootbased] adjustment"
Headers show

Commit Message

Konstantin Khorenko Oct. 12, 2020, 12:19 p.m.
From: Cyrill Gorcunov <gorcunov@virtuozzo.com>

This two members represent monotonic and bootbased clocks for
container's uptime. When container is in suspended state (or
moving to another node) we trest monotonic and bootbased
clocks as being stopped so we need to account delta time
on restore and adjust the members in subject.

Moreover this timestamps are involved into posix-timers
setup so once application tries to setup monotonic clocks
after the restore (with absolute time specification) we
adjust the values as well.

The application which migrate a container must fetch
the current settings from /sys/fs/cgroup/ve/$VE/ve.real_start_timespec
and /sys/fs/cgroup/ve/$VE/ve.start_timespec, then write them
back on the restore.

https://jira.sw.ru/browse/PSBM-41311
https://jira.sw.ru/browse/PSBM-41406

v2:
 - use clock_[monotonic|bootbased] for cgroup entry names instead

Original-by: Andrew Vagin <avagin@openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@virtuozzo.com>
Reviewed-by: Vladimir Davydov <vdavydov@virtuozzo.com>

(cherry picked from vz7 commit 43f4b0c752abd84aa1b346373d152941123d2446
("ve: Add interface for @start_timespec and @real_start_timespec
adjustmen"))

Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 kernel/ve/ve.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

Patch hide | download patch | download mbox

diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index ac2252445841..cc26d3b2fa9b 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -925,6 +925,66 @@  static ssize_t ve_os_release_write(struct kernfs_open_file *of, char *buf,
 	return ret ? ret : nbytes;
 }
 
+enum {
+	VE_CF_CLOCK_MONOTONIC,
+	VE_CF_CLOCK_BOOTBASED,
+};
+
+static int ve_ts_read(struct seq_file *sf, void *v)
+{
+	struct ve_struct *ve = css_to_ve(seq_css(sf));
+	struct timespec ts;
+	u64 now, delta;
+
+	switch (seq_cft(sf)->private) {
+		case VE_CF_CLOCK_MONOTONIC:
+			now = ktime_get_ns();
+			delta = ve->start_time;
+			break;
+		case VE_CF_CLOCK_BOOTBASED:
+			now = ktime_get_boot_ns();
+			delta = ve->real_start_time;
+			break;
+		default:
+			now = delta = 0;
+			WARN_ON_ONCE(1);
+			break;
+	}
+
+	ts = ns_to_timespec(now - delta);
+	seq_printf(sf, "%ld %ld", ts.tv_sec, ts.tv_nsec);
+	return 0;
+}
+
+static ssize_t ve_ts_write(struct kernfs_open_file *of, char *buf,
+			   size_t nbytes, loff_t off)
+{
+	struct ve_struct *ve = css_to_ve(of_css(of));
+	struct timespec delta;
+	u64 delta_ns, now, *target;
+
+	if (sscanf(buf, "%ld %ld", &delta.tv_sec, &delta.tv_nsec) != 2)
+		return -EINVAL;
+	delta_ns = timespec_to_ns(&delta);
+
+	switch (of_cft(of)->private) {
+		case VE_CF_CLOCK_MONOTONIC:
+			now = ktime_get_ns();
+			target = &ve->start_time;
+			break;
+		case VE_CF_CLOCK_BOOTBASED:
+			now = ktime_get_boot_ns();
+			target = &ve->real_start_time;
+			break;
+		default:
+			WARN_ON_ONCE(1);
+			return -EINVAL;
+	}
+
+	*target = now - delta_ns;
+	return nbytes;
+}
+
 static u64 ve_netns_max_nr_read(struct cgroup_subsys_state *css, struct cftype *cft)
 {
 	return css_to_ve(css)->netns_max_nr;
@@ -994,6 +1054,20 @@  static struct cftype ve_cftypes[] = {
 		.read_u64		= ve_iptables_mask_read,
 		.write_u64		= ve_iptables_mask_write,
 	},
+	{
+		.name			= "clock_monotonic",
+		.flags			= CFTYPE_NOT_ON_ROOT,
+		.seq_show		= ve_ts_read,
+		.write			= ve_ts_write,
+		.private		= VE_CF_CLOCK_MONOTONIC,
+	},
+	{
+		.name			= "clock_bootbased",
+		.flags			= CFTYPE_NOT_ON_ROOT,
+		.seq_show		= ve_ts_read,
+		.write			= ve_ts_write,
+		.private		= VE_CF_CLOCK_BOOTBASED,
+	},
 #endif
 	{
 		.name			= "netns_max_nr",