Skip to contentSkip to conversation

Introduce a new field "guest" in cpustat

PATCH In review Laurent Vivier 4 participants 44 messages Aug 16, 2007 – Aug 20, 2007 4 messages not in the archive

Subsystems (6)
KVM MM core Scheduler virtio core +2 more subsystems
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH 1/4 Introduce a new field "guest" in cpustat

[PATCH 1/4] as modern CPUs introduce a third running state, after "user" and "system", we need a new field, "guest", in cpustat to store the time used by the CPU to run virtual CPU. Modify /proc/stat to display this new field.

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth
fs/proc/proc_misc.c +10 -5
Index: kvm/fs/proc/proc_misc.c
===================================================================
@@ -443,6 +443,7 @@
 	int i;
 	unsigned long jif;
 	cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
+	cputime64_t guest;
 	u64 sum = 0;
 	struct timespec boottime;
 	unsigned int *per_irq_sum;
@@ -452,7 +453,7 @@
 		return -ENOMEM;
 
 	user = nice = system = idle = iowait =
-		irq = softirq = steal = cputime64_zero;
+		irq = softirq = steal = guest = cputime64_zero;
 	getboottime(&boottime);
 	jif = boottime.tv_sec;
 
@@ -467,6 +468,7 @@
 		irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
 		softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
 		steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
+		guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
 		for (j = 0; j < NR_IRQS; j++) {
 			unsigned int temp = kstat_cpu(i).irqs[j];
 			sum += temp;
@@ -474,7 +476,7 @@
 		}
 	}
 
-	seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu\n",
+	seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
 		(unsigned long long)cputime64_to_clock_t(user),
 		(unsigned long long)cputime64_to_clock_t(nice),
 		(unsigned long long)cputime64_to_clock_t(system),
@@ -482,7 +484,8 @@
 		(unsigned long long)cputime64_to_clock_t(iowait),
 		(unsigned long long)cputime64_to_clock_t(irq),
 		(unsigned long long)cputime64_to_clock_t(softirq),
-		(unsigned long long)cputime64_to_clock_t(steal));
+		(unsigned long long)cputime64_to_clock_t(steal),
+		(unsigned long long)cputime64_to_clock_t(guest));
 	for_each_online_cpu(i) {
 
 		/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
@@ -494,7 +497,8 @@
 		irq = kstat_cpu(i).cpustat.irq;
 		softirq = kstat_cpu(i).cpustat.softirq;
 		steal = kstat_cpu(i).cpustat.steal;
-		seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu\n",
+		guest = kstat_cpu(i).cpustat.guest;
+		seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
 			i,
 			(unsigned long long)cputime64_to_clock_t(user),
 			(unsigned long long)cputime64_to_clock_t(nice),
@@ -503,7 +507,8 @@
 			(unsigned long long)cputime64_to_clock_t(iowait),
 			(unsigned long long)cputime64_to_clock_t(irq),
 			(unsigned long long)cputime64_to_clock_t(softirq),
-			(unsigned long long)cputime64_to_clock_t(steal));
+			(unsigned long long)cputime64_to_clock_t(steal),
+			(unsigned long long)cputime64_to_clock_t(guest));
 	}
 	seq_printf(p, "intr %llu", (unsigned long long)sum);
 
include/linux/kernel_stat.h +1 -0
Index: kvm/include/linux/kernel_stat.h
===================================================================
@@ -23,6 +23,7 @@
 	cputime64_t idle;
 	cputime64_t iowait;
 	cputime64_t steal;
+	cputime64_t guest;
 };
 
 struct kernel_stat {
#2 lore raw

PATCH 1/4 Introduce a new field "guest" in cpustat

In reply to a message not in the archive

[PATCH 1/4] as modern CPUs introduce a third running state, after "user" and "system", we need a new field, "guest", in cpustat to store the time used by the CPU to run virtual CPU. Modify /proc/stat to display this new field.

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth
fs/proc/proc_misc.c +10 -5
Index: kvm/fs/proc/proc_misc.c
===================================================================
@@ -443,6 +443,7 @@
 	int i;
 	unsigned long jif;
 	cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
+	cputime64_t guest;
 	u64 sum = 0;
 	struct timespec boottime;
 	unsigned int *per_irq_sum;
@@ -452,7 +453,7 @@
 		return -ENOMEM;
 
 	user = nice = system = idle = iowait =
-		irq = softirq = steal = cputime64_zero;
+		irq = softirq = steal = guest = cputime64_zero;
 	getboottime(&boottime);
 	jif = boottime.tv_sec;
 
@@ -467,6 +468,7 @@
 		irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
 		softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
 		steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
+		guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
 		for (j = 0; j < NR_IRQS; j++) {
 			unsigned int temp = kstat_cpu(i).irqs[j];
 			sum += temp;
@@ -474,7 +476,7 @@
 		}
 	}
 
-	seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu\n",
+	seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
 		(unsigned long long)cputime64_to_clock_t(user),
 		(unsigned long long)cputime64_to_clock_t(nice),
 		(unsigned long long)cputime64_to_clock_t(system),
@@ -482,7 +484,8 @@
 		(unsigned long long)cputime64_to_clock_t(iowait),
 		(unsigned long long)cputime64_to_clock_t(irq),
 		(unsigned long long)cputime64_to_clock_t(softirq),
-		(unsigned long long)cputime64_to_clock_t(steal));
+		(unsigned long long)cputime64_to_clock_t(steal),
+		(unsigned long long)cputime64_to_clock_t(guest));
 	for_each_online_cpu(i) {
 
 		/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
@@ -494,7 +497,8 @@
 		irq = kstat_cpu(i).cpustat.irq;
 		softirq = kstat_cpu(i).cpustat.softirq;
 		steal = kstat_cpu(i).cpustat.steal;
-		seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu\n",
+		guest = kstat_cpu(i).cpustat.guest;
+		seq_printf(p, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
 			i,
 			(unsigned long long)cputime64_to_clock_t(user),
 			(unsigned long long)cputime64_to_clock_t(nice),
@@ -503,7 +507,8 @@
 			(unsigned long long)cputime64_to_clock_t(iowait),
 			(unsigned long long)cputime64_to_clock_t(irq),
 			(unsigned long long)cputime64_to_clock_t(softirq),
-			(unsigned long long)cputime64_to_clock_t(steal));
+			(unsigned long long)cputime64_to_clock_t(steal),
+			(unsigned long long)cputime64_to_clock_t(guest));
 	}
 	seq_printf(p, "intr %llu", (unsigned long long)sum);
 
include/linux/kernel_stat.h +1 -0
Index: kvm/include/linux/kernel_stat.h
===================================================================
@@ -23,6 +23,7 @@
 	cputime64_t idle;
 	cputime64_t iowait;
 	cputime64_t steal;
+	cputime64_t guest;
 };
 
 struct kernel_stat {

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

A message that is not in the archive (sent off-list or not yet received): [email protected]

#4 lore raw

PATCH 2/4 Introduce a new field "guest" in task_struct

PATCH 2/4] like for cpustat, introduce the "guest" and "cguest" fields for the tasks. Modify
signal_struct and task_struct. Modify /proc/<pid>/stat to display these new field

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth
fs/proc/array.c +20 -6
Index: kvm/fs/proc/array.c
===================================================================
@@ -354,6 +354,13 @@
 	return stime;
 }
 
+static clock_t task_gtime(struct task_struct *p)
+{
+	clock_t gtime = cputime_to_clock_t(p->gtime);
+
+	return gtime;
+}
+
 static int do_task_stat(struct task_struct *task, char *buffer, int whole)
 {
 	unsigned long vsize, eip, esp, wchan = ~0UL;
@@ -368,8 +375,8 @@
 	unsigned long long start_time;
 	unsigned long cmin_flt = 0, cmaj_flt = 0;
 	unsigned long  min_flt = 0,  maj_flt = 0;
-	cputime_t cutime, cstime;
-	clock_t utime, stime;
+	cputime_t cutime, cstime, cgtime;
+	clock_t utime, stime, gtime;
 	unsigned long rsslim = 0;
 	char tcomm[sizeof(task->comm)];
 	unsigned long flags;
@@ -387,8 +394,8 @@
 
 	sigemptyset(&sigign);
 	sigemptyset(&sigcatch);
-	cutime = cstime = cputime_zero;
-	utime = stime = 0;
+	cutime = cstime = cgtime = cputime_zero;
+	utime = stime = gtime = 0;
 
 	rcu_read_lock();
 	if (lock_task_sighand(task, &flags)) {
@@ -406,6 +413,7 @@
 		cmaj_flt = sig->cmaj_flt;
 		cutime = sig->cutime;
 		cstime = sig->cstime;
+		cgtime = sig->cgtime;
 		rsslim = sig->rlim[RLIMIT_RSS].rlim_cur;
 
 		/* add up live thread stats at the group level */
@@ -416,6 +424,7 @@
 				maj_flt += t->maj_flt;
 				utime += task_utime(t);
 				stime += task_stime(t);
+				gtime += task_gtime(t);
 				t = next_thread(t);
 			} while (t != task);
 
@@ -423,6 +432,7 @@
 			maj_flt += sig->maj_flt;
 			utime += cputime_to_clock_t(sig->utime);
 			stime += cputime_to_clock_t(sig->stime);
+			gtime += cputime_to_clock_t(sig->gtime);
 		}
 
 		sid = signal_session(sig);
@@ -440,6 +450,7 @@
 		maj_flt = task->maj_flt;
 		utime = task_utime(task);
 		stime = task_stime(task);
+		gtime = task_gtime(task);
 	}
 
 	/* scale priority and nice values from timeslices to -20..20 */
@@ -457,7 +468,7 @@
 
 	res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \
 %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
-%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu\n",
+%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n",
 		task->pid,
 		tcomm,
 		state,
@@ -502,7 +513,10 @@
 		task_cpu(task),
 		task->rt_priority,
 		task->policy,
-		(unsigned long long)delayacct_blkio_ticks(task));
+		(unsigned long long)delayacct_blkio_ticks(task),
+		gtime,
+		cputime_to_clock_t(cgtime)
+		);
 	if (mm)
 		mmput(mm);
 	return res;
include/linux/sched.h +2 -2
Index: kvm/include/linux/sched.h
===================================================================
@@ -514,7 +514,7 @@
 	 * Live threads maintain their own counters and add to these
 	 * in __exit_signal, except for the group leader.
 	 */
-	cputime_t utime, stime, cutime, cstime;
+	cputime_t utime, stime, gtime, cutime, cstime, cgtime;
 	unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
 	unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
 	unsigned long inblock, oublock, cinblock, coublock;
@@ -1018,7 +1018,7 @@
 	int __user *clear_child_tid;		/* CLONE_CHILD_CLEARTID */
 
 	unsigned int rt_priority;
-	cputime_t utime, stime;
+	cputime_t utime, stime, gtime;
 	unsigned long nvcsw, nivcsw; /* context switch counts */
 	struct timespec start_time; 		/* monotonic time */
 	struct timespec real_start_time;	/* boot based time */
kernel/exit.c +6 -0
Index: kvm/kernel/exit.c
===================================================================
@@ -120,6 +120,7 @@
 		 */
 		sig->utime = cputime_add(sig->utime, tsk->utime);
 		sig->stime = cputime_add(sig->stime, tsk->stime);
+		sig->gtime = cputime_add(sig->gtime, tsk->gtime);
 		sig->min_flt += tsk->min_flt;
 		sig->maj_flt += tsk->maj_flt;
 		sig->nvcsw += tsk->nvcsw;
@@ -1255,6 +1256,11 @@
 			cputime_add(p->stime,
 			cputime_add(sig->stime,
 				    sig->cstime)));
+		psig->cgtime =
+			cputime_add(psig->cgtime,
+			cputime_add(p->gtime,
+			cputime_add(sig->gtime,
+				    sig->cgtime)));
 		psig->cmin_flt +=
 			p->min_flt + sig->min_flt + sig->cmin_flt;
 		psig->cmaj_flt +=
kernel/fork.c +3 -1
Index: kvm/kernel/fork.c
===================================================================
@@ -876,7 +876,8 @@
 	sig->leader = 0;	/* session leadership doesn't inherit */
 	sig->tty_old_pgrp = NULL;
 
-	sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
+	sig->utime = sig->stime = sig->gtime = sig->cutime =
+				sig->cstime = sig->cgtime = cputime_zero;
 	sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
 	sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
 	sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
@@ -1045,6 +1046,7 @@
 
 	p->utime = cputime_zero;
 	p->stime = cputime_zero;
+	p->gtime = cputime_zero;
 
 #ifdef CONFIG_TASK_XACCT
 	p->rchar = 0;		/* I/O counter: bytes read */
#5 lore raw

PATCH 2/4 Introduce a new field "guest" in task_struct

In reply to a message not in the archive

PATCH 2/4] like for cpustat, introduce the "guest" and "cguest" fields for the tasks. Modify
signal_struct and task_struct. Modify /proc/<pid>/stat to display these new field

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth
fs/proc/array.c +20 -6
Index: kvm/fs/proc/array.c
===================================================================
@@ -354,6 +354,13 @@
 	return stime;
 }
 
+static clock_t task_gtime(struct task_struct *p)
+{
+	clock_t gtime = cputime_to_clock_t(p->gtime);
+
+	return gtime;
+}
+
 static int do_task_stat(struct task_struct *task, char *buffer, int whole)
 {
 	unsigned long vsize, eip, esp, wchan = ~0UL;
@@ -368,8 +375,8 @@
 	unsigned long long start_time;
 	unsigned long cmin_flt = 0, cmaj_flt = 0;
 	unsigned long  min_flt = 0,  maj_flt = 0;
-	cputime_t cutime, cstime;
-	clock_t utime, stime;
+	cputime_t cutime, cstime, cgtime;
+	clock_t utime, stime, gtime;
 	unsigned long rsslim = 0;
 	char tcomm[sizeof(task->comm)];
 	unsigned long flags;
@@ -387,8 +394,8 @@
 
 	sigemptyset(&sigign);
 	sigemptyset(&sigcatch);
-	cutime = cstime = cputime_zero;
-	utime = stime = 0;
+	cutime = cstime = cgtime = cputime_zero;
+	utime = stime = gtime = 0;
 
 	rcu_read_lock();
 	if (lock_task_sighand(task, &flags)) {
@@ -406,6 +413,7 @@
 		cmaj_flt = sig->cmaj_flt;
 		cutime = sig->cutime;
 		cstime = sig->cstime;
+		cgtime = sig->cgtime;
 		rsslim = sig->rlim[RLIMIT_RSS].rlim_cur;
 
 		/* add up live thread stats at the group level */
@@ -416,6 +424,7 @@
 				maj_flt += t->maj_flt;
 				utime += task_utime(t);
 				stime += task_stime(t);
+				gtime += task_gtime(t);
 				t = next_thread(t);
 			} while (t != task);
 
@@ -423,6 +432,7 @@
 			maj_flt += sig->maj_flt;
 			utime += cputime_to_clock_t(sig->utime);
 			stime += cputime_to_clock_t(sig->stime);
+			gtime += cputime_to_clock_t(sig->gtime);
 		}
 
 		sid = signal_session(sig);
@@ -440,6 +450,7 @@
 		maj_flt = task->maj_flt;
 		utime = task_utime(task);
 		stime = task_stime(task);
+		gtime = task_gtime(task);
 	}
 
 	/* scale priority and nice values from timeslices to -20..20 */
@@ -457,7 +468,7 @@
 
 	res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \
 %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
-%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu\n",
+%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n",
 		task->pid,
 		tcomm,
 		state,
@@ -502,7 +513,10 @@
 		task_cpu(task),
 		task->rt_priority,
 		task->policy,
-		(unsigned long long)delayacct_blkio_ticks(task));
+		(unsigned long long)delayacct_blkio_ticks(task),
+		gtime,
+		cputime_to_clock_t(cgtime)
+		);
 	if (mm)
 		mmput(mm);
 	return res;
include/linux/sched.h +2 -2
Index: kvm/include/linux/sched.h
===================================================================
@@ -514,7 +514,7 @@
 	 * Live threads maintain their own counters and add to these
 	 * in __exit_signal, except for the group leader.
 	 */
-	cputime_t utime, stime, cutime, cstime;
+	cputime_t utime, stime, gtime, cutime, cstime, cgtime;
 	unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
 	unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
 	unsigned long inblock, oublock, cinblock, coublock;
@@ -1018,7 +1018,7 @@
 	int __user *clear_child_tid;		/* CLONE_CHILD_CLEARTID */
 
 	unsigned int rt_priority;
-	cputime_t utime, stime;
+	cputime_t utime, stime, gtime;
 	unsigned long nvcsw, nivcsw; /* context switch counts */
 	struct timespec start_time; 		/* monotonic time */
 	struct timespec real_start_time;	/* boot based time */
kernel/exit.c +6 -0
Index: kvm/kernel/exit.c
===================================================================
@@ -120,6 +120,7 @@
 		 */
 		sig->utime = cputime_add(sig->utime, tsk->utime);
 		sig->stime = cputime_add(sig->stime, tsk->stime);
+		sig->gtime = cputime_add(sig->gtime, tsk->gtime);
 		sig->min_flt += tsk->min_flt;
 		sig->maj_flt += tsk->maj_flt;
 		sig->nvcsw += tsk->nvcsw;
@@ -1255,6 +1256,11 @@
 			cputime_add(p->stime,
 			cputime_add(sig->stime,
 				    sig->cstime)));
+		psig->cgtime =
+			cputime_add(psig->cgtime,
+			cputime_add(p->gtime,
+			cputime_add(sig->gtime,
+				    sig->cgtime)));
 		psig->cmin_flt +=
 			p->min_flt + sig->min_flt + sig->cmin_flt;
 		psig->cmaj_flt +=
kernel/fork.c +3 -1
Index: kvm/kernel/fork.c
===================================================================
@@ -876,7 +876,8 @@
 	sig->leader = 0;	/* session leadership doesn't inherit */
 	sig->tty_old_pgrp = NULL;
 
-	sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
+	sig->utime = sig->stime = sig->gtime = sig->cutime =
+				sig->cstime = sig->cgtime = cputime_zero;
 	sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
 	sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
 	sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
@@ -1045,6 +1046,7 @@
 
 	p->utime = cputime_zero;
 	p->stime = cputime_zero;
+	p->gtime = cputime_zero;
 
 #ifdef CONFIG_TASK_XACCT
 	p->rchar = 0;		/* I/O counter: bytes read */

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

A message that is not in the archive (sent off-list or not yet received): [email protected]

#7 lore raw

PATCH 3/4 Introduce "account modifiers" mechanism

[PATCH 3/3] introduce "account modifiers" mechanism in the kernel allowing a module to modify the collected accounting for a given task. This implementation is based on the "preempt_notifier". "account_system_time()" and "account_user_time()" can call functions registered by a module to modify the cputime value.

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth
include/linux/sched.h +29 -0
Index: kvm/include/linux/sched.h
===================================================================
@@ -955,6 +955,10 @@
 	/* list of struct preempt_notifier: */
 	struct hlist_head preempt_notifiers;
 #endif
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	/* list of struct account_modifiers: */
+	struct hlist_head account_modifiers;
+#endif
 
 	unsigned short ioprio;
 #ifdef CONFIG_BLK_DEV_IO_TRACE
@@ -1873,6 +1877,31 @@
 }
 #endif
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+struct account_modifier;
+struct account_ops {
+	cputime_t (*user_time)(struct account_modifier *,
+				struct task_struct *, cputime_t );
+	cputime_t (*system_time)(struct account_modifier *,
+				struct task_struct *, int, cputime_t);
+};
+
+struct account_modifier {
+	struct hlist_node link;
+	struct account_ops *ops;
+};
+
+void account_modifier_register(struct account_modifier *modifier);
+void account_modifier_unregister(struct account_modifier *modifier);
+
+static inline void account_modifier_init(struct account_modifier *modifier,
+					struct account_ops *ops)
+{
+	INIT_HLIST_NODE(&modifier->link);
+	modifier->ops = ops;
+}
+#endif
+
 #endif /* __KERNEL__ */
 
 #endif
kernel/sched.c +66 -0

96 lines not on this page · raw message

#8 lore raw

Re: [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

Quoted 7 lines · Laurent Vivier

[PATCH 3/3] introduce "account modifiers" mechanism in the kernel allowing a module to modify the collected accounting for a given task. This implementation is based on the "preempt_notifier". "account_system_time()" and "account_user_time()" can call functions registered by a module to modify the cputime value.

Hi Laurent,

This seems a little like overkill. Why not just add an
"account_guest_time" which subtracts the given amount of time from system time (if available) and adds it to guest time? Then kvm (and lguest) should just need to call this at the right times.

Am I missing something?
Rusty.

#9 lore raw

Re: [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

Quoted 11 lines · Rusty Russell
Quoted 7 lines · Laurent Vivier

[PATCH 3/3] introduce "account modifiers" mechanism in the kernel allowing a module to modify the collected accounting for a given task. This implementation is based on the "preempt_notifier". "account_system_time()" and "account_user_time()" can call functions registered by a module to modify the cputime value.

Hi Laurent,

Hi Rusty,
how are your puppies ?
And thank you for your comment.

Quoted 4 lines

This seems a little like overkill. Why not just add an
"account_guest_time" which subtracts the given amount of time from system time (if available) and adds it to guest time? Then kvm (and lguest) should just need to call this at the right times.

We can. I did something like this before.
By doing like that, I think there is a major issue: system time can be decreasing (as we substract a value from it), and thus we can have negative value in a tool like top. It's why I play with the cputime to add to system time and not directly with the system time.

BUT I'm very open, my only goal is be able to compute guest time, "how" is not very important...

what we can do:

- keep PATCHES 1 and 2, because we need to store guest time for cpu and tasks. It is very generic.

- remove PATCH 3, and add in task_struct a "ktime vtime" where we accumulate guest time (by calling something like guest_enter() and guest_exit() from the virtualization engine), and when in account_system_time() we have cputime > vtime we substrate vtime from cputime and add vtime to user time and guest time. But doing like this we freeze in kernel/sched.c the link between system time, user time and guest time (i.e. system time = system time - vtime, user time = user time + vtime and guest time = guest time + vtime).

- modify PATCH 4 to use new PATCH 3.

Do you agree ? Anybody doesn't agree ?

Laurent

Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected]  --------------
          "Software is hard" - Donald Knuth

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#10 lore raw

Re: [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

Quoted 5 lines · Laurent Vivier
Quoted 1 line · Rusty Russell

Hi Laurent,

Hi Rusty,
how are your puppies ?

They're getting a little fat, actually. Too many features ...

Quoted 7 lines

- remove PATCH 3, and add in task_struct a "ktime vtime" where we accumulate guest time (by calling something like guest_enter() and guest_exit() from the virtualization engine), and when in account_system_time() we have cputime > vtime we substrate vtime from cputime and add vtime to user time and guest time. But doing like this we freeze in kernel/sched.c the link between system time, user time and guest time (i.e. system time = system time - vtime, user time = user time + vtime and guest time = guest time + vtime).

Actually, I think we can set a per-cpu "in_guest" flag for the scheduler code, which then knows to add the tick to the guest time. That seems the simplest possible solution.

lguest or kvm would set the flag before running the guest (which is done with preempt disabled or using preemption hooks), and reset it afterwards.

Thoughts?
Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#11 lore raw

Re: [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

Quoted 20 lines · Rusty Russell
Quoted 4 lines · Laurent Vivier
Quoted 1 line · Rusty Russell

Hi Laurent,

Hi Rusty,
how are your puppies ?

They're getting a little fat, actually. Too many features ...

Quoted 7 lines

- remove PATCH 3, and add in task_struct a "ktime vtime" where we accumulate guest time (by calling something like guest_enter() and guest_exit() from the virtualization engine), and when in account_system_time() we have cputime > vtime we substrate vtime from cputime and add vtime to user time and guest time. But doing like this we freeze in kernel/sched.c the link between system time, user time and guest time (i.e. system time = system time - vtime, user time = user time + vtime and guest time = guest time + vtime).

Actually, I think we can set a per-cpu "in_guest" flag for the scheduler code, which then knows to add the tick to the guest time. That seems the simplest possible solution.

Quoted 5 lines

lguest or kvm would set the flag before running the guest (which is done with preempt disabled or using preemption hooks), and reset it afterwards.

Thoughts?

It was my first attempt (except I didn't have a per-cpu flag, but a per-task flag), it's not visible but I love simplicity... ;-)

A KVM VCPU is stopped by preemption, so when we enter in scheduler we have exited from VCPU and thus this flags is off (so we account 0 to the guest). What I did then is "set the flag on when we enter in the VCPU, and "account_system_time()" sets the flag off when it adds this timeslice to cpustat (and compute correctly guest, user, system time). But I didn't like this idea because all code executed after we entered in the VCPU is accounted to the guest until we have an account_system_time() and I suppose we can have real system time in this part. And I guess a VCPU can be less than 1 ms (unit of cputime) in a timeslice.

So ? What's best ?
Laurent

Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected]  --------------
          "Software is hard" - Donald Knuth

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#12 lore raw

PATCH 3/4 Introduce "account_guest_time"

This is another way to compute guest time... I remove the "account modifiers" mechanism and call directly account_guest_time() from account_system_time(). account_system_time() computes user, system and guest times according value accumulated in vtime (a ktime_t) in task_struct by the virtual machine.

Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected]  --------------
          "Software is hard" - Donald Knuth
include/linux/sched.h +3 -0
Index: kvm/include/linux/sched.h
===================================================================
@@ -1192,6 +1192,9 @@
 #ifdef CONFIG_FAULT_INJECTION
 	int make_it_fail;
 #endif
+#ifdef CONFIG_GUEST_ACCOUNTING
+	ktime_t vtime;
+#endif
 };
 
 /*
kernel/sched.c +35 -0
Index: kvm/kernel/sched.c
===================================================================
@@ -3233,6 +3233,37 @@
 		cpustat->user = cputime64_add(cpustat->user, tmp);
 }
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+/*
+ * Account guest time to a process
+ * @p: the process that the cpu time gets accounted to
+ * @cputime: the cpu time spent in kernel space since the last update
+ */
+
+static cputime_t account_guest_time(struct task_struct *p, cputime_t cputime)
+{
+	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
+	ktime_t kmsec = ktime_set(0, NSEC_PER_MSEC);
+	cputime_t cmsec = msecs_to_cputime(1);
+
+	while ((ktime_to_ns(p->vtime) >= NSEC_PER_MSEC) &&
+		(cputime_to_msecs(cputime) >= 1)) {
+		p->vtime = ktime_sub(p->vtime, kmsec);
+		p->utime = cputime_add(p->utime, cmsec);
+		p->gtime = cputime_add(p->gtime, cmsec);
+
+		cpustat->guest = cputime64_add(cpustat->guest,
+				cputime_to_cputime64(cmsec));
+		cpustat->user = cputime64_add(cpustat->user,
+		cputime_to_cputime64(cmsec));
+
+		cputime = cputime_sub(cputime, cmsec);
+	}
+
+	return cputime;
+}
+#endif
+
 /*
  * Account system cpu time to a process.
  * @p: the process that the cpu time gets accounted to
@@ -3246,6 +3277,10 @@
 	struct rq *rq = this_rq();
 	cputime64_t tmp;
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+	cputime = account_guest_time(p, cputime);
+#endif
+
 	p->stime = cputime_add(p->stime, cputime);
 
 	/* Add system time to cpustat. */

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#13 lore raw

Re: [PATCH/RFC 4/4, second shot]KVM uses "account_guest_time()"

KVM updates vtime in task_struct to allow account_guest_time() to modify user, system and guest time in cpustat accordingly.

drivers/kvm/Kconfig +6 -0
Index: kvm/drivers/kvm/Kconfig
===================================================================
@@ -41,4 +41,10 @@
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
+config GUEST_ACCOUNTING
+	bool "Virtual Machine accounting support"
+	depends on KVM
+	---help---
+	  Allows to account CPU time used by the Virtual Machines.
+
 endif # VIRTUALIZATION
drivers/kvm/kvm.h +13 -0
Index: kvm/drivers/kvm/kvm.h
===================================================================
@@ -589,6 +589,19 @@
 
 int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+static inline ktime_t kvm_guest_enter(void)
+{
+	 return ktime_get();
+}
+
+static inline void kvm_guest_exit(ktime_t enter)
+{
+	 ktime_t delta = ktime_sub(ktime_get(), enter);
+	 current->vtime = ktime_add(current->vtime, delta);
+}
+#endif
+
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 {
drivers/kvm/svm.c +9 -0
Index: kvm/drivers/kvm/svm.c
===================================================================
@@ -1392,6 +1392,9 @@
 	u16 gs_selector;
 	u16 ldt_selector;
 	int r;
+#ifdef CONFIG_GUEST_ACCOUNTING
+	ktime_t now;
+#endif
 
 again:
 	r = kvm_mmu_reload(vcpu);
@@ -1404,6 +1407,9 @@
 	clgi();
 
 	vcpu->guest_mode = 1;
+#ifdef CONFIG_GUEST_ACCOUNTING
+	now = kvm_guest_enter();
+#endif
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    svm_flush_tlb(vcpu);
@@ -1536,6 +1542,9 @@
 #endif
 		: "cc", "memory" );
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+	kvm_guest_exit(now);
+#endif
 	vcpu->guest_mode = 0;
 
 	if (vcpu->fpu_active) {
drivers/kvm/vmx.c +9 -0
Index: kvm/drivers/kvm/vmx.c
===================================================================
@@ -2052,6 +2052,9 @@
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	u8 fail;
 	int r;
+#ifdef CONFIG_GUEST_ACCOUNTING
+	ktime_t now;
+#endif
 
 preempted:
 	if (vcpu->guest_debug.enabled)
@@ -2078,6 +2081,9 @@
 	local_irq_disable();
 
 	vcpu->guest_mode = 1;
+#ifdef CONFIG_GUEST_ACCOUNTING
+	now = kvm_guest_enter();
+#endif
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    vmx_flush_tlb(vcpu);
@@ -2198,6 +2204,9 @@
 		[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
 	      : "cc", "memory" );
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+	kvm_guest_exit(now);
+#endif
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
#14 lore raw

Re: [kvm-devel] [PATCH/RFC 4/4, second shot]KVM uses "account_guest_time()"

Quoted 7 lines · Laurent Vivier

KVM updates vtime in task_struct to allow account_guest_time() to modify user, system and guest time in cpustat accordingly.

drivers/kvm/Kconfig line 49

Quoted 9 lines
drivers/kvm/Kconfig +6 -0
@@ -41,4 +41,10 @@
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
+config GUEST_ACCOUNTING
+	bool "Virtual Machine accounting support"
+	depends on KVM
+	---help---
+	  Allows to account CPU time used by the Virtual Machines.
+

Other way round. In the patch that adds account_guest_time(), have a CONFIG_GUEST_ACCOUNTING (defaulting to n, with no description, help, or dependencies. Then, CONFIG_KVM can select GUEST_ACCOUNTING.

The advantages of this are:
- the puppyvisor can also select this if it so wishes
- we don't have core code reference some obscure module

CONFIG_PREEMPT_NOTIFIERS does the same thing.

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
#15 lore raw

Re: [kvm-devel] [PATCH/RFC 4/4, second shot]KVM uses "account_guest_time()"

Quoted 11 lines · Avi Kivity
Quoted 10 lines · Laurent Vivier

KVM updates vtime in task_struct to allow account_guest_time() to modify user, system and guest time in cpustat accordingly.

drivers/kvm/Kconfig +0 -0
@@ -41,4 +41,10 @@
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
Quoted 11 lines

drivers/kvm/Kconfig line 49

Quoted 6 lines
drivers/kvm/Kconfig +6 -0
+config GUEST_ACCOUNTING
+	bool "Virtual Machine accounting support"
+	depends on KVM
+	---help---
+	  Allows to account CPU time used by the Virtual Machines.
+

Other way round. In the patch that adds account_guest_time(), have a CONFIG_GUEST_ACCOUNTING (defaulting to n, with no description, help, or dependencies. Then, CONFIG_KVM can select GUEST_ACCOUNTING.

I was wondering in which Kconfig I can put it...

Quoted 3 lines

The advantages of this are:
- the puppyvisor can also select this if it so wishes
- we don't have core code reference some obscure module

I agree.

Quoted 1 line

CONFIG_PREEMPT_NOTIFIERS does the same thing.

I saw

Laurent

Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected]  --------------
          "Software is hard" - Donald Knuth

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#16 lore raw

Re: [kvm-devel] [PATCH/RFC 4/4, second shot]KVM uses "account_guest_time()"

Quoted 8 lines · Laurent Vivier
Quoted 4 lines

Other way round. In the patch that adds account_guest_time(), have a CONFIG_GUEST_ACCOUNTING (defaulting to n, with no description, help, or dependencies. Then, CONFIG_KVM can select GUEST_ACCOUNTING.

I was wondering in which Kconfig I can put it...

Looks like init/Kconfig has similar stuff.

Signature · 1 line
error compiling committee.c: too many arguments to function
#17 lore raw

Re: [kvm-devel] [PATCH/RFC 4/4, second shot]KVM uses "account_guest_time()"

In reply to Laurent Vivier
Quoted 8 lines · Laurent Vivier
Quoted 4 lines

Other way round. In the patch that adds account_guest_time(), have a CONFIG_GUEST_ACCOUNTING (defaulting to n, with no description, help, or dependencies. Then, CONFIG_KVM can select GUEST_ACCOUNTING.

I was wondering in which Kconfig I can put it...

Looks like init/Kconfig has similar stuff.

Signature · 1 line
error compiling committee.c: too many arguments to function
#18 lore raw

Re: [kvm-devel] [PATCH/RFC 4/4, second shot]KVM uses "account_guest_time()"

In reply to Avi Kivity
Quoted 11 lines · Avi Kivity
Quoted 10 lines · Laurent Vivier

KVM updates vtime in task_struct to allow account_guest_time() to modify user, system and guest time in cpustat accordingly.

drivers/kvm/Kconfig +0 -0
@@ -41,4 +41,10 @@
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
Quoted 11 lines

drivers/kvm/Kconfig line 49

Quoted 6 lines
drivers/kvm/Kconfig +6 -0
+config GUEST_ACCOUNTING
+	bool "Virtual Machine accounting support"
+	depends on KVM
+	---help---
+	  Allows to account CPU time used by the Virtual Machines.
+

Other way round. In the patch that adds account_guest_time(), have a CONFIG_GUEST_ACCOUNTING (defaulting to n, with no description, help, or dependencies. Then, CONFIG_KVM can select GUEST_ACCOUNTING.

I was wondering in which Kconfig I can put it...

Quoted 3 lines

The advantages of this are:
- the puppyvisor can also select this if it so wishes
- we don't have core code reference some obscure module

I agree.

Quoted 1 line

CONFIG_PREEMPT_NOTIFIERS does the same thing.

I saw

Laurent

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#19 lore raw

Re: [kvm-devel] [PATCH/RFC 4/4, second shot]KVM uses "account_guest_time()"

In reply to Laurent Vivier
Quoted 7 lines · Laurent Vivier

KVM updates vtime in task_struct to allow account_guest_time() to modify user, system and guest time in cpustat accordingly.

drivers/kvm/Kconfig line 49

Quoted 9 lines
drivers/kvm/Kconfig +6 -0
@@ -41,4 +41,10 @@
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
+config GUEST_ACCOUNTING
+	bool "Virtual Machine accounting support"
+	depends on KVM
+	---help---
+	  Allows to account CPU time used by the Virtual Machines.
+

Other way round. In the patch that adds account_guest_time(), have a CONFIG_GUEST_ACCOUNTING (defaulting to n, with no description, help, or dependencies. Then, CONFIG_KVM can select GUEST_ACCOUNTING.

The advantages of this are:
- the puppyvisor can also select this if it so wishes
- we don't have core code reference some obscure module

CONFIG_PREEMPT_NOTIFIERS does the same thing.

Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
#20 lore raw

Re: [PATCH/RFC 4/4, second shot]KVM uses "account_guest_time()"

In reply to Laurent Vivier

KVM updates vtime in task_struct to allow account_guest_time() to modify user, system and guest time in cpustat accordingly.

drivers/kvm/Kconfig +6 -0
Index: kvm/drivers/kvm/Kconfig
===================================================================
@@ -41,4 +41,10 @@
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
+config GUEST_ACCOUNTING
+	bool "Virtual Machine accounting support"
+	depends on KVM
+	---help---
+	  Allows to account CPU time used by the Virtual Machines.
+
 endif # VIRTUALIZATION
drivers/kvm/kvm.h +13 -0
Index: kvm/drivers/kvm/kvm.h
===================================================================
@@ -589,6 +589,19 @@
 
 int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+static inline ktime_t kvm_guest_enter(void)
+{
+	 return ktime_get();
+}
+
+static inline void kvm_guest_exit(ktime_t enter)
+{
+	 ktime_t delta = ktime_sub(ktime_get(), enter);
+	 current->vtime = ktime_add(current->vtime, delta);
+}
+#endif
+
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 {
drivers/kvm/svm.c +9 -0
Index: kvm/drivers/kvm/svm.c
===================================================================
@@ -1392,6 +1392,9 @@
 	u16 gs_selector;
 	u16 ldt_selector;
 	int r;
+#ifdef CONFIG_GUEST_ACCOUNTING
+	ktime_t now;
+#endif
 
 again:
 	r = kvm_mmu_reload(vcpu);
@@ -1404,6 +1407,9 @@
 	clgi();
 
 	vcpu->guest_mode = 1;
+#ifdef CONFIG_GUEST_ACCOUNTING
+	now = kvm_guest_enter();
+#endif
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    svm_flush_tlb(vcpu);
@@ -1536,6 +1542,9 @@
 #endif
 		: "cc", "memory" );
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+	kvm_guest_exit(now);
+#endif
 	vcpu->guest_mode = 0;
 
 	if (vcpu->fpu_active) {
drivers/kvm/vmx.c +9 -0
Index: kvm/drivers/kvm/vmx.c
===================================================================
@@ -2052,6 +2052,9 @@
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	u8 fail;
 	int r;
+#ifdef CONFIG_GUEST_ACCOUNTING
+	ktime_t now;
+#endif
 
 preempted:
 	if (vcpu->guest_debug.enabled)
@@ -2078,6 +2081,9 @@
 	local_irq_disable();
 
 	vcpu->guest_mode = 1;
+#ifdef CONFIG_GUEST_ACCOUNTING
+	now = kvm_guest_enter();
+#endif
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    vmx_flush_tlb(vcpu);
@@ -2198,6 +2204,9 @@
 		[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
 	      : "cc", "memory" );
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+	kvm_guest_exit(now);
+#endif
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#21 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4, second shot]Introduce "account_guest_time"

In reply to Laurent Vivier
Quoted 8 lines · Laurent Vivier

This is another way to compute guest time... I remove the "account modifiers" mechanism and call directly account_guest_time() from account_system_time(). account_system_time() computes user, system and guest times according value accumulated in vtime (a ktime_t) in task_struct by the virtual machine.

kernel/sched.c line 3286

Quoted 10 lines
kernel/sched.c +4 -0
@@ -3246,6 +3277,10 @@
 	struct rq *rq = this_rq();
 	cputime64_t tmp;
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+	cputime = account_guest_time(p, cputime);
+#endif
+
 	p->stime = cputime_add(p->stime, cputime);
 
 	/* Add system time to cpustat. */

In order to reduce the impact on whatever function this is in (use diff -p please), you can always have a definition of account_guest_time:

#else

static cputime_t account_guest_time(struct task_struct *p, cputime_t cputime)

{
        return cputime;
}

#endif

This way the #ifdef/#endif is not necessary when calling it.

Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
#22 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4, second shot]Introduce "account_guest_time"

In reply to Laurent Vivier
Quoted 8 lines · Laurent Vivier

This is another way to compute guest time... I remove the "account modifiers" mechanism and call directly account_guest_time() from account_system_time(). account_system_time() computes user, system and guest times according value accumulated in vtime (a ktime_t) in task_struct by the virtual machine.

kernel/sched.c line 3286

Quoted 10 lines
kernel/sched.c +4 -0
@@ -3246,6 +3277,10 @@
 	struct rq *rq = this_rq();
 	cputime64_t tmp;
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+	cputime = account_guest_time(p, cputime);
+#endif
+
 	p->stime = cputime_add(p->stime, cputime);
 
 	/* Add system time to cpustat. */

In order to reduce the impact on whatever function this is in (use diff -p please), you can always have a definition of account_guest_time:

#else

static cputime_t account_guest_time(struct task_struct *p, cputime_t cputime)

{
        return cputime;
}

#endif

This way the #ifdef/#endif is not necessary when calling it.

Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
#23 lore raw

PATCH 3/4 Introduce "account_guest_time"

In reply to Laurent Vivier

This is another way to compute guest time... I remove the "account modifiers" mechanism and call directly account_guest_time() from account_system_time(). account_system_time() computes user, system and guest times according value accumulated in vtime (a ktime_t) in task_struct by the virtual machine.

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth
include/linux/sched.h +3 -0
Index: kvm/include/linux/sched.h
===================================================================
@@ -1192,6 +1192,9 @@
 #ifdef CONFIG_FAULT_INJECTION
 	int make_it_fail;
 #endif
+#ifdef CONFIG_GUEST_ACCOUNTING
+	ktime_t vtime;
+#endif
 };
 
 /*
kernel/sched.c +35 -0
Index: kvm/kernel/sched.c
===================================================================
@@ -3233,6 +3233,37 @@
 		cpustat->user = cputime64_add(cpustat->user, tmp);
 }
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+/*
+ * Account guest time to a process
+ * @p: the process that the cpu time gets accounted to
+ * @cputime: the cpu time spent in kernel space since the last update
+ */
+
+static cputime_t account_guest_time(struct task_struct *p, cputime_t cputime)
+{
+	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
+	ktime_t kmsec = ktime_set(0, NSEC_PER_MSEC);
+	cputime_t cmsec = msecs_to_cputime(1);
+
+	while ((ktime_to_ns(p->vtime) >= NSEC_PER_MSEC) &&
+		(cputime_to_msecs(cputime) >= 1)) {
+		p->vtime = ktime_sub(p->vtime, kmsec);
+		p->utime = cputime_add(p->utime, cmsec);
+		p->gtime = cputime_add(p->gtime, cmsec);
+
+		cpustat->guest = cputime64_add(cpustat->guest,
+				cputime_to_cputime64(cmsec));
+		cpustat->user = cputime64_add(cpustat->user,
+		cputime_to_cputime64(cmsec));
+
+		cputime = cputime_sub(cputime, cmsec);
+	}
+
+	return cputime;
+}
+#endif
+
 /*
  * Account system cpu time to a process.
  * @p: the process that the cpu time gets accounted to
@@ -3246,6 +3277,10 @@
 	struct rq *rq = this_rq();
 	cputime64_t tmp;
 
+#ifdef CONFIG_GUEST_ACCOUNTING
+	cputime = account_guest_time(p, cputime);
+#endif
+
 	p->stime = cputime_add(p->stime, cputime);
 
 	/* Add system time to cpustat. */

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#24 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Laurent Vivier
Quoted 33 lines · Laurent Vivier
Quoted 13 lines
Quoted 9 lines

- remove PATCH 3, and add in task_struct a "ktime vtime" where we accumulate guest time (by calling something like guest_enter() and guest_exit() from the virtualization engine), and when in account_system_time() we have cputime > vtime we substrate vtime from cputime and add vtime to user time and guest time. But doing like this we freeze in kernel/sched.c the link between system time, user time and guest time (i.e. system time = system time - vtime, user time = user time + vtime and guest time = guest time + vtime).

Actually, I think we can set a per-cpu "in_guest" flag for the scheduler code, which then knows to add the tick to the guest time. That seems the simplest possible solution.

Quoted 6 lines

lguest or kvm would set the flag before running the guest (which is done with preempt disabled or using preemption hooks), and reset it afterwards.

Thoughts?

It was my first attempt (except I didn't have a per-cpu flag, but a per-task flag), it's not visible but I love simplicity... ;-)

A KVM VCPU is stopped by preemption, so when we enter in scheduler we have exited from VCPU and thus this flags is off (so we account 0 to the guest). What I did then is "set the flag on when we enter in the VCPU, and "account_system_time()" sets the flag off when it adds this timeslice to cpustat (and compute correctly guest, user, system time). But I didn't like this idea because all code executed after we entered in the VCPU is accounted to the guest until we have an account_system_time() and I suppose we can have real system time in this part. And I guess a VCPU can be less than 1 ms (unit of cputime) in a timeslice.

Quoted 2 lines

So ? What's best ?

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

So I think it is okay to have the same limitation for guest time.

Signature · 8 lines
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
#25 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

Quoted 33 lines · Avi Kivity
Quoted 32 lines · Laurent Vivier
Quoted 13 lines
Quoted 9 lines

- remove PATCH 3, and add in task_struct a "ktime vtime" where we accumulate guest time (by calling something like guest_enter() and guest_exit() from the virtualization engine), and when in account_system_time() we have cputime > vtime we substrate vtime from cputime and add vtime to user time and guest time. But doing like this we freeze in kernel/sched.c the link between system time, user time and guest time (i.e. system time = system time - vtime, user time = user time + vtime and guest time = guest time + vtime).

Actually, I think we can set a per-cpu "in_guest" flag for the scheduler code, which then knows to add the tick to the guest time. That seems the simplest possible solution.

Quoted 6 lines

lguest or kvm would set the flag before running the guest (which is done with preempt disabled or using preemption hooks), and reset it afterwards.

Thoughts?

It was my first attempt (except I didn't have a per-cpu flag, but a per-task flag), it's not visible but I love simplicity... ;-)

A KVM VCPU is stopped by preemption, so when we enter in scheduler we have exited from VCPU and thus this flags is off (so we account 0 to the guest). What I did then is "set the flag on when we enter in the VCPU, and "account_system_time()" sets the flag off when it adds this timeslice to cpustat (and compute correctly guest, user, system time). But I didn't like this idea because all code executed after we entered in the VCPU is accounted to the guest until we have an account_system_time() and I suppose we can have real system time in this part. And I guess a VCPU can be less than 1 ms (unit of cputime) in a timeslice.

Quoted 5 lines
Quoted 2 lines

So ? What's best ?

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

Yes... but perhaps I should rewrite this too ;-)

Quoted 1 line

So I think it is okay to have the same limitation for guest time.

OK, so we can go back to my first patch. Who can decide to introduce this into the kernel ?

Laurent

Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected]  --------------
          "Software is hard" - Donald Knuth

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#26 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

Am Freitag, 17. August 2007 schrieb Laurent Vivier:

Quoted 4 lines
Quoted 2 lines

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

Yes... but perhaps I should rewrite this too ;-)

If you look further, you will see, that this was actually rewritten in 2.6.12 and thats why we have cputime_t. The infrastructure is currently only used by s390 and ppc64. On s390 we use our cpu timer to get the current time on each syscall/irq/context switch etc to get precise accounting data for system/user/irq/softirq/nice. We also get steal time (this is interesting for the guest: how much of my cpu was actually not available because the hypervisor scheduled me away). I dont know enough about other architectures to say which one could exploit this infrastructure as well.

The current git tree is somewhat broken for CONFIG_VIRT_CPU_ACCOUTING due to the accouting changes introduced by CFS - we work on this.

If you are interested in the cputime stuff, you can have a look at arch/s390/kernel/vtime.c (account_system_vtime, account_vtime) as well as:

http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;a=commit;h=6be7071fdd321c206b1ee7a3e534782f25572830
for the first introduction and
http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;a=commit;h=db59f519d37f80683f3611927f6b5c3bdfc0f9e6
for the s390 exploitation.

Christian

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#27 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Laurent Vivier

Am Freitag, 17. August 2007 schrieb Laurent Vivier:

Quoted 4 lines
Quoted 2 lines

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

Yes... but perhaps I should rewrite this too ;-)

If you look further, you will see, that this was actually rewritten in 2.6.12 and thats why we have cputime_t. The infrastructure is currently only used by s390 and ppc64. On s390 we use our cpu timer to get the current time on each syscall/irq/context switch etc to get precise accounting data for system/user/irq/softirq/nice. We also get steal time (this is interesting for the guest: how much of my cpu was actually not available because the hypervisor scheduled me away). I dont know enough about other architectures to say which one could exploit this infrastructure as well.

The current git tree is somewhat broken for CONFIG_VIRT_CPU_ACCOUTING due to the accouting changes introduced by CFS - we work on this.

If you are interested in the cputime stuff, you can have a look at arch/s390/kernel/vtime.c (account_system_vtime, account_vtime) as well as:

http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;a=commit;h=6be7071fdd321c206b1ee7a3e534782f25572830
for the first introduction and
http://git.kernel.org/?p=linux/kernel/git/torvalds/old-2.6-bkcvs.git;a=commit;h=db59f519d37f80683f3611927f6b5c3bdfc0f9e6
for the s390 exploitation.

Christian

#28 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Laurent Vivier
Quoted 6 lines · Laurent Vivier
Quoted 2 lines

So I think it is okay to have the same limitation for guest time.

OK, so we can go back to my first patch. Who can decide to introduce this into the kernel ?

The sched.c parts are best merged by Ingo, and I can carry the kvm parts. Alternatively, I can carry the entire patchset if Ingo acks it.

Signature · 1 line
error compiling committee.c: too many arguments to function
#29 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Laurent Vivier
Quoted 6 lines · Laurent Vivier
Quoted 2 lines

So I think it is okay to have the same limitation for guest time.

OK, so we can go back to my first patch. Who can decide to introduce this into the kernel ?

The sched.c parts are best merged by Ingo, and I can carry the kvm parts. Alternatively, I can carry the entire patchset if Ingo acks it.

Signature · 1 line
error compiling committee.c: too many arguments to function
#30 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Avi Kivity
Quoted 33 lines · Avi Kivity
Quoted 32 lines · Laurent Vivier
Quoted 13 lines
Quoted 9 lines

- remove PATCH 3, and add in task_struct a "ktime vtime" where we accumulate guest time (by calling something like guest_enter() and guest_exit() from the virtualization engine), and when in account_system_time() we have cputime > vtime we substrate vtime from cputime and add vtime to user time and guest time. But doing like this we freeze in kernel/sched.c the link between system time, user time and guest time (i.e. system time = system time - vtime, user time = user time + vtime and guest time = guest time + vtime).

Actually, I think we can set a per-cpu "in_guest" flag for the scheduler code, which then knows to add the tick to the guest time. That seems the simplest possible solution.

Quoted 6 lines

lguest or kvm would set the flag before running the guest (which is done with preempt disabled or using preemption hooks), and reset it afterwards.

Thoughts?

It was my first attempt (except I didn't have a per-cpu flag, but a per-task flag), it's not visible but I love simplicity... ;-)

A KVM VCPU is stopped by preemption, so when we enter in scheduler we have exited from VCPU and thus this flags is off (so we account 0 to the guest). What I did then is "set the flag on when we enter in the VCPU, and "account_system_time()" sets the flag off when it adds this timeslice to cpustat (and compute correctly guest, user, system time). But I didn't like this idea because all code executed after we entered in the VCPU is accounted to the guest until we have an account_system_time() and I suppose we can have real system time in this part. And I guess a VCPU can be less than 1 ms (unit of cputime) in a timeslice.

Quoted 5 lines
Quoted 2 lines

So ? What's best ?

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

Yes... but perhaps I should rewrite this too ;-)

Quoted 1 line

So I think it is okay to have the same limitation for guest time.

OK, so we can go back to my first patch. Who can decide to introduce this into the kernel ?

Laurent

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#31 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Avi Kivity

Avi Kivity wrote:
[...]

Quoted 6 lines

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

So I think it is okay to have the same limitation for guest time.

So this is how it looks like.
PATCH 1 and 2 are always a prerequisite.

Laurent

include/linux/sched.h +1 -0
Index: kvm/include/linux/sched.h
===================================================================
@@ -1310,6 +1310,7 @@
 #define PF_STARTING	0x00000002	/* being created */
 #define PF_EXITING	0x00000004	/* getting shut down */
 #define PF_EXITPIDONE	0x00000008	/* pi exit done on shut down */
+#define PF_VCPU		0x00000010	/* I'm a virtual CPU */
 #define PF_FORKNOEXEC	0x00000040	/* forked but didn't exec */
 #define PF_SUPERPRIV	0x00000100	/* used super-user privileges */
 #define PF_DUMPCORE	0x00000200	/* dumped core */
kernel/sched.c +13 -1
Index: kvm/kernel/sched.c
===================================================================
@@ -3246,10 +3246,22 @@
 	struct rq *rq = this_rq();
 	cputime64_t tmp;
 
+	tmp = cputime_to_cputime64(cputime);
+	if (p->flags & PF_VCPU) {
+		p->utime = cputime_add(p->utime, cputime);
+		p->gtime = cputime_add(p->gtime, cputime);
+
+		cpustat->guest = cputime64_add(cpustat->guest, tmp);
+		cpustat->user = cputime64_add(cpustat->user, tmp);
+
+		p->flags &= ~PF_VCPU;
+
+		return;
+	}
+
 	p->stime = cputime_add(p->stime, cputime);
 
 	/* Add system time to cpustat. */
-	tmp = cputime_to_cputime64(cputime);
 	if (hardirq_count() - hardirq_offset)
 		cpustat->irq = cputime64_add(cpustat->irq, tmp);
 	else if (softirq_count())
drivers/kvm/kvm.h +13 -0
Index: kvm/drivers/kvm/kvm.h
===================================================================
@@ -589,6 +589,19 @@
 
 int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
+#ifndef PF_VCPU
+#define PF_VCPU	0	/* no kernel support */
+#endif
+
+static inline void kvm_guest_enter(void)
+{
+	current->flags |= PF_VCPU;
+}
+
+static inline void kvm_guest_exit(void)
+{
+}
+
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 {
drivers/kvm/svm.c +2 -0
Index: kvm/drivers/kvm/svm.c
===================================================================
@@ -1404,6 +1404,7 @@
 	clgi();
 
 	vcpu->guest_mode = 1;
+	kvm_guest_enter();
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    svm_flush_tlb(vcpu);
@@ -1536,6 +1537,7 @@
 #endif
 		: "cc", "memory" );
 
+	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 
 	if (vcpu->fpu_active) {
drivers/kvm/vmx.c +2 -0
Index: kvm/drivers/kvm/vmx.c
===================================================================
@@ -2078,6 +2078,7 @@
 	local_irq_disable();
 
 	vcpu->guest_mode = 1;
+	kvm_guest_enter();
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    vmx_flush_tlb(vcpu);
@@ -2198,6 +2199,7 @@
 		[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
 	      : "cc", "memory" );
 
+	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#32 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

Quoted 18 lines · Laurent Vivier

Avi Kivity wrote:
[...]

Quoted 6 lines

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

So I think it is okay to have the same limitation for guest time.

So this is how it looks like.
PATCH 1 and 2 are always a prerequisite.

kernel/sched.c +3 -0
+	tmp = cputime_to_cputime64(cputime);
+	if (p->flags & PF_VCPU) {
+		p->utime = cputime_add(p->utime, cputime);

kernel/sched.c line 3261

Quoted 10 lines
kernel/sched.c +10 -0
+		p->gtime = cputime_add(p->gtime, cputime);
+
+		cpustat->guest = cputime64_add(cpustat->guest, tmp);
+		cpustat->user = cputime64_add(cpustat->user, tmp);
+
+		p->flags &= ~PF_VCPU;
+
+		return;
+	}
+

Where did CONFIG_GUEST_ACCOUNTING go?

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
#33 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

Quoted 16 lines · Avi Kivity
Quoted 14 lines · Laurent Vivier

Avi Kivity wrote:
[...]

Quoted 6 lines

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

So I think it is okay to have the same limitation for guest time.

So this is how it looks like.
PATCH 1 and 2 are always a prerequisite.

Quoted 16 lines

kernel/sched.c line 3261

Quoted 13 lines
kernel/sched.c +13 -0
+    tmp = cputime_to_cputime64(cputime);
+    if (p->flags & PF_VCPU) {
+        p->utime = cputime_add(p->utime, cputime);
+        p->gtime = cputime_add(p->gtime, cputime);
+
+        cpustat->guest = cputime64_add(cpustat->guest, tmp);
+        cpustat->user = cputime64_add(cpustat->user, tmp);
+
+        p->flags &= ~PF_VCPU;
+
+        return;
+    }
+

Where did CONFIG_GUEST_ACCOUNTING go?

Lost in the sea ...

Actually, I thought this modification is not enough expensive (in time and space) to justify a CONFIG_*. But if you think so I can add this in init/Kconfig.

Laurent

Signature · 2 lines
------------- Laurent.Vivier-6ktuUTfB/[email protected]  --------------
          "Software is hard" - Donald Knuth

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#34 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

Quoted 11 lines · Laurent Vivier
Quoted 4 lines

Where did CONFIG_GUEST_ACCOUNTING go?

Lost in the sea ...

Actually, I thought this modification is not enough expensive (in time and space) to justify a CONFIG_*. But if you think so I can add this in init/Kconfig.

The difference between "convince everyone that it isn't expensive, including the embedded guys" and preemptively adding a config option can be quite large...

Signature · 1 line
error compiling committee.c: too many arguments to function
#35 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Laurent Vivier
Quoted 11 lines · Laurent Vivier
Quoted 4 lines

Where did CONFIG_GUEST_ACCOUNTING go?

Lost in the sea ...

Actually, I thought this modification is not enough expensive (in time and space) to justify a CONFIG_*. But if you think so I can add this in init/Kconfig.

The difference between "convince everyone that it isn't expensive, including the embedded guys" and preemptively adding a config option can be quite large...

Signature · 1 line
error compiling committee.c: too many arguments to function
#36 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Avi Kivity
Quoted 16 lines · Avi Kivity
Quoted 14 lines · Laurent Vivier

Avi Kivity wrote:
[...]

Quoted 6 lines

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

So I think it is okay to have the same limitation for guest time.

So this is how it looks like.
PATCH 1 and 2 are always a prerequisite.

Quoted 16 lines

kernel/sched.c line 3261

Quoted 13 lines
kernel/sched.c +13 -0
+    tmp = cputime_to_cputime64(cputime);
+    if (p->flags & PF_VCPU) {
+        p->utime = cputime_add(p->utime, cputime);
+        p->gtime = cputime_add(p->gtime, cputime);
+
+        cpustat->guest = cputime64_add(cpustat->guest, tmp);
+        cpustat->user = cputime64_add(cpustat->user, tmp);
+
+        p->flags &= ~PF_VCPU;
+
+        return;
+    }
+

Where did CONFIG_GUEST_ACCOUNTING go?

Lost in the sea ...

Actually, I thought this modification is not enough expensive (in time and space) to justify a CONFIG_*. But if you think so I can add this in init/Kconfig.

Laurent

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#37 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Laurent Vivier
Quoted 18 lines · Laurent Vivier

Avi Kivity wrote:
[...]

Quoted 6 lines

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

So I think it is okay to have the same limitation for guest time.

So this is how it looks like.
PATCH 1 and 2 are always a prerequisite.

kernel/sched.c +3 -0
+	tmp = cputime_to_cputime64(cputime);
+	if (p->flags & PF_VCPU) {
+		p->utime = cputime_add(p->utime, cputime);

kernel/sched.c line 3261

Quoted 10 lines
kernel/sched.c +10 -0
+		p->gtime = cputime_add(p->gtime, cputime);
+
+		cpustat->guest = cputime64_add(cpustat->guest, tmp);
+		cpustat->user = cputime64_add(cpustat->user, tmp);
+
+		p->flags &= ~PF_VCPU;
+
+		return;
+	}
+

Where did CONFIG_GUEST_ACCOUNTING go?

Signature · 1 line
error compiling committee.c: too many arguments to function
#38 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Avi Kivity

Avi Kivity wrote:
[...]

Quoted 6 lines

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

So I think it is okay to have the same limitation for guest time.

So this is how it looks like.
PATCH 1 and 2 are always a prerequisite.

Laurent

include/linux/sched.h +1 -0
Index: kvm/include/linux/sched.h
===================================================================
@@ -1310,6 +1310,7 @@
 #define PF_STARTING	0x00000002	/* being created */
 #define PF_EXITING	0x00000004	/* getting shut down */
 #define PF_EXITPIDONE	0x00000008	/* pi exit done on shut down */
+#define PF_VCPU		0x00000010	/* I'm a virtual CPU */
 #define PF_FORKNOEXEC	0x00000040	/* forked but didn't exec */
 #define PF_SUPERPRIV	0x00000100	/* used super-user privileges */
 #define PF_DUMPCORE	0x00000200	/* dumped core */
kernel/sched.c +13 -1
Index: kvm/kernel/sched.c
===================================================================
@@ -3246,10 +3246,22 @@
 	struct rq *rq = this_rq();
 	cputime64_t tmp;
 
+	tmp = cputime_to_cputime64(cputime);
+	if (p->flags & PF_VCPU) {
+		p->utime = cputime_add(p->utime, cputime);
+		p->gtime = cputime_add(p->gtime, cputime);
+
+		cpustat->guest = cputime64_add(cpustat->guest, tmp);
+		cpustat->user = cputime64_add(cpustat->user, tmp);
+
+		p->flags &= ~PF_VCPU;
+
+		return;
+	}
+
 	p->stime = cputime_add(p->stime, cputime);
 
 	/* Add system time to cpustat. */
-	tmp = cputime_to_cputime64(cputime);
 	if (hardirq_count() - hardirq_offset)
 		cpustat->irq = cputime64_add(cpustat->irq, tmp);
 	else if (softirq_count())
drivers/kvm/kvm.h +13 -0
Index: kvm/drivers/kvm/kvm.h
===================================================================
@@ -589,6 +589,19 @@
 
 int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
+#ifndef PF_VCPU
+#define PF_VCPU	0	/* no kernel support */
+#endif
+
+static inline void kvm_guest_enter(void)
+{
+	current->flags |= PF_VCPU;
+}
+
+static inline void kvm_guest_exit(void)
+{
+}
+
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 {
drivers/kvm/svm.c +2 -0
Index: kvm/drivers/kvm/svm.c
===================================================================
@@ -1404,6 +1404,7 @@
 	clgi();
 
 	vcpu->guest_mode = 1;
+	kvm_guest_enter();
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    svm_flush_tlb(vcpu);
@@ -1536,6 +1537,7 @@
 #endif
 		: "cc", "memory" );
 
+	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 
 	if (vcpu->fpu_active) {
drivers/kvm/vmx.c +2 -0
Index: kvm/drivers/kvm/vmx.c
===================================================================
@@ -2078,6 +2078,7 @@
 	local_irq_disable();
 
 	vcpu->guest_mode = 1;
+	kvm_guest_enter();
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    vmx_flush_tlb(vcpu);
@@ -2198,6 +2199,7 @@
 		[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
 	      : "cc", "memory" );
 
+	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#39 lore raw

Re: [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Laurent Vivier
Quoted 33 lines · Laurent Vivier
Quoted 13 lines
Quoted 9 lines

- remove PATCH 3, and add in task_struct a "ktime vtime" where we accumulate guest time (by calling something like guest_enter() and guest_exit() from the virtualization engine), and when in account_system_time() we have cputime > vtime we substrate vtime from cputime and add vtime to user time and guest time. But doing like this we freeze in kernel/sched.c the link between system time, user time and guest time (i.e. system time = system time - vtime, user time = user time + vtime and guest time = guest time + vtime).

Actually, I think we can set a per-cpu "in_guest" flag for the scheduler code, which then knows to add the tick to the guest time. That seems the simplest possible solution.

Quoted 6 lines

lguest or kvm would set the flag before running the guest (which is done with preempt disabled or using preemption hooks), and reset it afterwards.

Thoughts?

It was my first attempt (except I didn't have a per-cpu flag, but a per-task flag), it's not visible but I love simplicity... ;-)

A KVM VCPU is stopped by preemption, so when we enter in scheduler we have exited from VCPU and thus this flags is off (so we account 0 to the guest). What I did then is "set the flag on when we enter in the VCPU, and "account_system_time()" sets the flag off when it adds this timeslice to cpustat (and compute correctly guest, user, system time). But I didn't like this idea because all code executed after we entered in the VCPU is accounted to the guest until we have an account_system_time() and I suppose we can have real system time in this part. And I guess a VCPU can be less than 1 ms (unit of cputime) in a timeslice.

Quoted 2 lines

So ? What's best ?

The normal user/system accounting has the same issue, no? Whereever we happen to land (kernel or user) gets the whole tick.

So I think it is okay to have the same limitation for guest time.

Signature · 1 line
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
#40 lore raw

Re: [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Rusty Russell
Quoted 20 lines · Rusty Russell
Quoted 4 lines · Laurent Vivier
Quoted 1 line · Rusty Russell

Hi Laurent,

Hi Rusty,
how are your puppies ?

They're getting a little fat, actually. Too many features ...

Quoted 7 lines

- remove PATCH 3, and add in task_struct a "ktime vtime" where we accumulate guest time (by calling something like guest_enter() and guest_exit() from the virtualization engine), and when in account_system_time() we have cputime > vtime we substrate vtime from cputime and add vtime to user time and guest time. But doing like this we freeze in kernel/sched.c the link between system time, user time and guest time (i.e. system time = system time - vtime, user time = user time + vtime and guest time = guest time + vtime).

Actually, I think we can set a per-cpu "in_guest" flag for the scheduler code, which then knows to add the tick to the guest time. That seems the simplest possible solution.

Quoted 5 lines

lguest or kvm would set the flag before running the guest (which is done with preempt disabled or using preemption hooks), and reset it afterwards.

Thoughts?

It was my first attempt (except I didn't have a per-cpu flag, but a per-task flag), it's not visible but I love simplicity... ;-)

A KVM VCPU is stopped by preemption, so when we enter in scheduler we have exited from VCPU and thus this flags is off (so we account 0 to the guest). What I did then is "set the flag on when we enter in the VCPU, and "account_system_time()" sets the flag off when it adds this timeslice to cpustat (and compute correctly guest, user, system time). But I didn't like this idea because all code executed after we entered in the VCPU is accounted to the guest until we have an account_system_time() and I suppose we can have real system time in this part. And I guess a VCPU can be less than 1 ms (unit of cputime) in a timeslice.

So ? What's best ?
Laurent

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#41 lore raw

Re: [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Laurent Vivier
Quoted 5 lines · Laurent Vivier
Quoted 1 line · Rusty Russell

Hi Laurent,

Hi Rusty,
how are your puppies ?

They're getting a little fat, actually. Too many features ...

Quoted 7 lines

- remove PATCH 3, and add in task_struct a "ktime vtime" where we accumulate guest time (by calling something like guest_enter() and guest_exit() from the virtualization engine), and when in account_system_time() we have cputime > vtime we substrate vtime from cputime and add vtime to user time and guest time. But doing like this we freeze in kernel/sched.c the link between system time, user time and guest time (i.e. system time = system time - vtime, user time = user time + vtime and guest time = guest time + vtime).

Actually, I think we can set a per-cpu "in_guest" flag for the scheduler code, which then knows to add the tick to the guest time. That seems the simplest possible solution.

lguest or kvm would set the flag before running the guest (which is done with preempt disabled or using preemption hooks), and reset it afterwards.

Thoughts?
Rusty.

#42 lore raw

Re: [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Rusty Russell
Quoted 11 lines · Rusty Russell
Quoted 7 lines · Laurent Vivier

[PATCH 3/3] introduce "account modifiers" mechanism in the kernel allowing a module to modify the collected accounting for a given task. This implementation is based on the "preempt_notifier". "account_system_time()" and "account_user_time()" can call functions registered by a module to modify the cputime value.

Hi Laurent,

Hi Rusty,
how are your puppies ?
And thank you for your comment.

Quoted 4 lines

This seems a little like overkill. Why not just add an
"account_guest_time" which subtracts the given amount of time from system time (if available) and adds it to guest time? Then kvm (and lguest) should just need to call this at the right times.

We can. I did something like this before.
By doing like that, I think there is a major issue: system time can be decreasing (as we substract a value from it), and thus we can have negative value in a tool like top. It's why I play with the cputime to add to system time and not directly with the system time.

BUT I'm very open, my only goal is be able to compute guest time, "how" is not very important...

what we can do:

- keep PATCHES 1 and 2, because we need to store guest time for cpu and tasks. It is very generic.

- remove PATCH 3, and add in task_struct a "ktime vtime" where we accumulate guest time (by calling something like guest_enter() and guest_exit() from the virtualization engine), and when in account_system_time() we have cputime > vtime we substrate vtime from cputime and add vtime to user time and guest time. But doing like this we freeze in kernel/sched.c the link between system time, user time and guest time (i.e. system time = system time - vtime, user time = user time + vtime and guest time = guest time + vtime).

- modify PATCH 4 to use new PATCH 3.

Do you agree ? Anybody doesn't agree ?

Laurent

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

#43 lore raw

Re: [PATCH/RFC 3/4]Introduce "account modifiers" mechanism

In reply to Laurent Vivier
Quoted 7 lines · Laurent Vivier

[PATCH 3/3] introduce "account modifiers" mechanism in the kernel allowing a module to modify the collected accounting for a given task. This implementation is based on the "preempt_notifier". "account_system_time()" and "account_user_time()" can call functions registered by a module to modify the cputime value.

Hi Laurent,

This seems a little like overkill. Why not just add an
"account_guest_time" which subtracts the given amount of time from system time (if available) and adds it to guest time? Then kvm (and lguest) should just need to call this at the right times.

Am I missing something?
Rusty.

#44 lore raw

PATCH 3/4 Introduce "account modifiers" mechanism

In reply to a message not in the archive

[PATCH 3/3] introduce "account modifiers" mechanism in the kernel allowing a module to modify the collected accounting for a given task. This implementation is based on the "preempt_notifier". "account_system_time()" and "account_user_time()" can call functions registered by a module to modify the cputime value.

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth
include/linux/sched.h +29 -0
Index: kvm/include/linux/sched.h
===================================================================
@@ -955,6 +955,10 @@
 	/* list of struct preempt_notifier: */
 	struct hlist_head preempt_notifiers;
 #endif
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	/* list of struct account_modifiers: */
+	struct hlist_head account_modifiers;
+#endif
 
 	unsigned short ioprio;
 #ifdef CONFIG_BLK_DEV_IO_TRACE
@@ -1873,6 +1877,31 @@
 }
 #endif
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+struct account_modifier;
+struct account_ops {
+	cputime_t (*user_time)(struct account_modifier *,
+				struct task_struct *, cputime_t );
+	cputime_t (*system_time)(struct account_modifier *,
+				struct task_struct *, int, cputime_t);
+};
+
+struct account_modifier {
+	struct hlist_node link;
+	struct account_ops *ops;
+};
+
+void account_modifier_register(struct account_modifier *modifier);
+void account_modifier_unregister(struct account_modifier *modifier);
+
+static inline void account_modifier_init(struct account_modifier *modifier,
+					struct account_ops *ops)
+{
+	INIT_HLIST_NODE(&modifier->link);
+	modifier->ops = ops;
+}
+#endif
+
 #endif /* __KERNEL__ */
 
 #endif
kernel/sched.c +66 -0

96 lines not on this page · raw message

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization

A message that is not in the archive (sent off-list or not yet received): [email protected]

#46 lore raw

PATCH 4/4 Modify KVM to use the "account modifiers"

[PATCH 4/4] Modify KVM to use the "account modifiers". KVM can now measure time consumed by a Virtual Machine on a per-cpu basis and modify kernel statistics to report this value.

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth
drivers/kvm/kvm.h +18 -0
Index: kvm/drivers/kvm/kvm.h
===================================================================
@@ -408,6 +408,10 @@
 	struct file *filp;
 	struct kvm_io_bus mmio_bus;
 	struct kvm_io_bus pio_bus;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	struct account_modifier account_modifier;
+	ktime_t vtime[NR_CPUS];
+#endif
 };
 
 struct descriptor_table {
@@ -589,6 +593,20 @@
 
 int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+static inline ktime_t kvm_guest_enter(void)
+{
+	return ktime_get();
+}
+
+static inline void kvm_guest_exit(struct kvm *kvm, ktime_t enter)
+{
+	ktime_t delta = ktime_sub(ktime_get(), enter);
+	kvm->vtime[smp_processor_id()] =
+		ktime_add(kvm->vtime[smp_processor_id()], delta);
+}
+#endif
+
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 {
drivers/kvm/kvm_main.c +52 -0

82 lines not on this page · raw message

drivers/kvm/svm.c +9 -0
Index: kvm/drivers/kvm/svm.c
===================================================================
@@ -1392,6 +1392,9 @@
 	u16 gs_selector;
 	u16 ldt_selector;
 	int r;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	ktime_t now;
+#endif
 
 again:
 	r = kvm_mmu_reload(vcpu);
@@ -1404,6 +1407,9 @@
 	clgi();
 
 	vcpu->guest_mode = 1;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	now = kvm_guest_enter();
+#endif
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    svm_flush_tlb(vcpu);
@@ -1536,6 +1542,9 @@
 #endif
 		: "cc", "memory" );
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	kvm_guest_exit(vcpu->kvm, now);
+#endif
 	vcpu->guest_mode = 0;
 
 	if (vcpu->fpu_active) {
drivers/kvm/vmx.c +9 -0
Index: kvm/drivers/kvm/vmx.c
===================================================================
@@ -2052,6 +2052,9 @@
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	u8 fail;
 	int r;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	ktime_t now;
+#endif
 
 preempted:
 	if (vcpu->guest_debug.enabled)
@@ -2078,6 +2081,9 @@
 	local_irq_disable();
 
 	vcpu->guest_mode = 1;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	now = kvm_guest_enter();
+#endif
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    vmx_flush_tlb(vcpu);
@@ -2198,6 +2204,9 @@
 		[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
 	      : "cc", "memory" );
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	kvm_guest_exit(vcpu->kvm, now);
+#endif
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
drivers/kvm/Kconfig +6 -0
Index: kvm/drivers/kvm/Kconfig
===================================================================
@@ -41,4 +41,10 @@
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
+config ACCOUNT_MODIFIERS
+        bool "Virtual Machine accounting support"
+	depends on KVM
+	---help---
+	  Allows to account CPU time used by the Virtual Machines.
+
 endif # VIRTUALIZATION
#47 lore raw

PATCH 4/4 Modify KVM to use the "account modifiers"

In reply to a message not in the archive

[PATCH 4/4] Modify KVM to use the "account modifiers". KVM can now measure time consumed by a Virtual Machine on a per-cpu basis and modify kernel statistics to report this value.

Signature · 2 lines
------------- [email protected]  --------------
          "Software is hard" - Donald Knuth
drivers/kvm/kvm.h +18 -0
Index: kvm/drivers/kvm/kvm.h
===================================================================
@@ -408,6 +408,10 @@
 	struct file *filp;
 	struct kvm_io_bus mmio_bus;
 	struct kvm_io_bus pio_bus;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	struct account_modifier account_modifier;
+	ktime_t vtime[NR_CPUS];
+#endif
 };
 
 struct descriptor_table {
@@ -589,6 +593,20 @@
 
 int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+static inline ktime_t kvm_guest_enter(void)
+{
+	return ktime_get();
+}
+
+static inline void kvm_guest_exit(struct kvm *kvm, ktime_t enter)
+{
+	ktime_t delta = ktime_sub(ktime_get(), enter);
+	kvm->vtime[smp_processor_id()] =
+		ktime_add(kvm->vtime[smp_processor_id()], delta);
+}
+#endif
+
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 {
drivers/kvm/kvm_main.c +52 -0

82 lines not on this page · raw message

drivers/kvm/svm.c +9 -0
Index: kvm/drivers/kvm/svm.c
===================================================================
@@ -1392,6 +1392,9 @@
 	u16 gs_selector;
 	u16 ldt_selector;
 	int r;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	ktime_t now;
+#endif
 
 again:
 	r = kvm_mmu_reload(vcpu);
@@ -1404,6 +1407,9 @@
 	clgi();
 
 	vcpu->guest_mode = 1;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	now = kvm_guest_enter();
+#endif
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    svm_flush_tlb(vcpu);
@@ -1536,6 +1542,9 @@
 #endif
 		: "cc", "memory" );
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	kvm_guest_exit(vcpu->kvm, now);
+#endif
 	vcpu->guest_mode = 0;
 
 	if (vcpu->fpu_active) {
drivers/kvm/vmx.c +9 -0
Index: kvm/drivers/kvm/vmx.c
===================================================================
@@ -2052,6 +2052,9 @@
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	u8 fail;
 	int r;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	ktime_t now;
+#endif
 
 preempted:
 	if (vcpu->guest_debug.enabled)
@@ -2078,6 +2081,9 @@
 	local_irq_disable();
 
 	vcpu->guest_mode = 1;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	now = kvm_guest_enter();
+#endif
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    vmx_flush_tlb(vcpu);
@@ -2198,6 +2204,9 @@
 		[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
 	      : "cc", "memory" );
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	kvm_guest_exit(vcpu->kvm, now);
+#endif
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
drivers/kvm/Kconfig +6 -0
Index: kvm/drivers/kvm/Kconfig
===================================================================
@@ -41,4 +41,10 @@
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
+config ACCOUNT_MODIFIERS
+        bool "Virtual Machine accounting support"
+	depends on KVM
+	---help---
+	  Allows to account CPU time used by the Virtual Machines.
+
 endif # VIRTUALIZATION

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/virtualization