[RHEL7,COMMIT] /proc/<pid>/vz_latency: Add scheduling stats

Submitted by Konstantin Khorenko on Aug. 31, 2018, 10:30 a.m.

Details

Message ID 201808311030.w7VAU1SV004742@finist_ce7.work
State New
Series "vz/latencies"
Headers show

Commit Message

Konstantin Khorenko Aug. 31, 2018, 10:30 a.m.
The commit is pushed to "branch-rh7-3.10.0-862.11.6.vz7.71.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.11.6.vz7.71.6
------>
commit 0ed8df6d0d18e079369cd004ff47caf119c86edb
Author: Andrey Ryabinin <aryabinin@virtuozzo.com>
Date:   Fri Aug 31 13:30:01 2018 +0300

    /proc/<pid>/vz_latency: Add scheduling stats
    
    Add schdeuling latncies to /proc/<pid>/vz_latency.
    They are the same as alloc latencies - total cumulative
    latency, number of schedule events, and latency maximum
    in the last 2 minutes.
    
    The sysctl kernel.sched_schedstats must be enabled to
    see these stats.
    
    https://jira.sw.ru/browse/PSBM-87797
    Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
    
    Cc: Pavel Borzenkov <Pavel.Borzenkov@acronis.com>
    Reviewed-by: Denis V. Lunev <den@openvz.org>
---
 fs/proc/base.c        | 18 ++++++++++++++++--
 include/linux/kstat.h |  5 +++++
 include/linux/sched.h |  4 ++--
 kernel/exit.c         |  6 ++----
 kernel/sched/fair.c   |  3 +++
 5 files changed, 28 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 222b4cfeed8e..f154232e4b81 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -588,13 +588,18 @@  static const char *alloc_descr[] = {
 	"allocatomic:",
 	"alloc:",
 	"allocmp:",
+	"scheduling:",
 };
 static const int alloc_types[] = {
 	KSTAT_ALLOCSTAT_ATOMIC,
 	KSTAT_ALLOCSTAT_LOW,
 	KSTAT_ALLOCSTAT_LOW_MP,
+	KSTAT_SCHED,
 };
 
+extern struct static_key sched_schedstats;
+# define schedstat_enabled()		static_key_false(&sched_schedstats)
+
 static int proc_tid_vz_lat(struct seq_file *m, struct pid_namespace *ns,
 			struct pid *pid, struct task_struct *task)
 {
@@ -603,9 +608,13 @@  static int proc_tid_vz_lat(struct seq_file *m, struct pid_namespace *ns,
 	seq_printf(m, "%-12s %20s %20s %20s\n",
 			"Type", "Total_lat", "Calls", "Max (2min)");
 
-	for (i = 0; i < ARRAY_SIZE(alloc_types); i++)
+	for (i = 0; i < ARRAY_SIZE(alloc_types); i++) {
+		if (alloc_types[i] == KSTAT_SCHED && !schedstat_enabled())
+			continue;
 		lastlat_seq_show(m, alloc_descr[i],
 				&task->alloc_lat[alloc_types[i]]);
+	}
+
 	return 0;
 }
 
@@ -645,15 +654,20 @@  static int proc_tgid_vz_lat(struct seq_file *m, struct pid_namespace *ns,
 				maxlats[i] = maxlat;
 
 		}
+
 		unlock_task_sighand(task, &flags);
 	}
 
 	seq_printf(m, "%-12s %20s %20s %20s\n",
 			"Type", "Total_lat", "Calls", "Max (2min)");
 
-	for (i = 0; i < ARRAY_SIZE(alloc_types); i++)
+	for (i = 0; i < ARRAY_SIZE(alloc_types); i++) {
+		if (alloc_types[i] == KSTAT_SCHED && !schedstat_enabled())
+			continue;
+
 		seq_printf(m, "%-12s %20Lu %20Lu %20Lu\n", alloc_descr[i],
 			lat[i], count[i], maxlats[i]);
+	}
 
 	return 0;
 }
diff --git a/include/linux/kstat.h b/include/linux/kstat.h
index 1e42c0317e6e..6f4ba09b74f4 100644
--- a/include/linux/kstat.h
+++ b/include/linux/kstat.h
@@ -9,6 +9,8 @@  enum {
 	KSTAT_ALLOCSTAT_HIGH_MP,
 	KSTAT_ALLOCSTAT_IRQ,
 	KSTAT_ALLOCSTAT_NR,
+	KSTAT_SCHED = KSTAT_ALLOCSTAT_NR,
+	KSTAT_NR,
 };
 
 struct kstat_perf_snap_struct {
@@ -47,4 +49,7 @@  struct kstat_lat_pcpu_struct {
 	u64 avg[3];
 };
 
+void update_maxlat(struct kstat_lat_snap_struct *alloc_lat,
+				u64 lat, unsigned long time);
+
 #endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 1e0469df2cfb..623572043ece 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -718,7 +718,7 @@  struct signal_struct {
 	struct taskstats *stats;
 #endif
 #ifdef CONFIG_VE
-	struct kstat_lat_snap_struct alloc_lat[KSTAT_ALLOCSTAT_NR];
+	struct kstat_lat_snap_struct alloc_lat[KSTAT_NR];
 #endif
 #ifdef CONFIG_AUDIT
 	unsigned audit_tty;
@@ -1857,7 +1857,7 @@  struct task_struct {
 	struct tlbflush_unmap_batch tlb_ubc;
 #endif
 #ifdef CONFIG_VE
-	struct kstat_lat_snap_struct alloc_lat[KSTAT_ALLOCSTAT_NR];
+	struct kstat_lat_snap_struct alloc_lat[KSTAT_NR];
 #endif
 #if defined(CONFIG_FUNCTION_GRAPH_TRACER) && defined(CONFIG_S390)
 	/* Index of current stored address in ret_stack */
diff --git a/kernel/exit.c b/kernel/exit.c
index c926cca30df3..cfa06c644f40 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -735,16 +735,13 @@  static void check_stack_usage(void)
 static inline void check_stack_usage(void) {}
 #endif
 
-void update_maxlat(struct kstat_lat_snap_struct *alloc_lat,
-				u64 lat, unsigned long time);
-
 void kstat_add_dying(struct task_struct *tsk)
 {
 #ifdef CONFIG_VE
 	int i;
 
 	spin_lock_irq(&tsk->sighand->siglock);
-	for (i = 0; i < KSTAT_ALLOCSTAT_NR; i++) {
+	for (i = 0; i < KSTAT_NR; i++) {
 		int j;
 
 		tsk->signal->alloc_lat[i].totlat += tsk->alloc_lat[i].totlat;
@@ -758,6 +755,7 @@  void kstat_add_dying(struct task_struct *tsk)
 			}
 		}
 	}
+
 	spin_unlock_irq(&tsk->sighand->siglock);
 #endif
 }
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 885e6b78a4e5..3c84c0891043 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -913,6 +913,9 @@  static inline void update_sched_lat(struct task_struct *t, u64 now)
 	if (ve_wstamp && now > ve_wstamp) {
 		KSTAT_LAT_PCPU_ADD(&kstat_glob.sched_lat, now - ve_wstamp);
 		KSTAT_LAT_PCPU_ADD(&t->task_ve->sched_lat_ve, now - ve_wstamp);
+		t->alloc_lat[KSTAT_SCHED].totlat += now - ve_wstamp;
+		t->alloc_lat[KSTAT_SCHED].count++;
+		update_maxlat(&t->alloc_lat[KSTAT_SCHED], now - ve_wstamp, now);
 	}
 #endif
 }