linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] cpustat: print watchdog time and statistics of soft and hard interrupts in soft lockup scenes
@ 2019-08-19  7:12 c00423981
  2019-08-20 11:04 ` Peter Zijlstra
  0 siblings, 1 reply; 7+ messages in thread
From: c00423981 @ 2019-08-19  7:12 UTC (permalink / raw)
  To: tglx, mingo, hpa, x86; +Cc: linux-kernel

Currently we cannot determine quickly if a soft lockup occurrs, and
do not know what the cpu is doing in soft lockup scenes neither.

The new feature adds a new interface(/proc/cpuirqstat) to view
the statistics of interrupts in real time on a certain cpu, as well as
the time occupancy of user space, system space and so on. Also, we can
view the time after the last-time watchdog which is named cpu time.
If cpu time is longer than twice of watchdot_thresh, a soft lockup occurrs.

The feature enhances the ability of solving problems in soft lockup scenes.

For example, if we want to view the statistics of interrupts on cpu 1, we can
enter the following command to set the cpu index:
		echo 1 > /proc/cpuirqstat
And we can enter the following command to view the statistics:
		cat /proc/cpuirqstat
Then, the result is as follows:

cpu index: 1
cpu time: 2283720189 ns(HZ: 1000)
occupied: 1000000 us, 3000000 sy, 0 ni, 2269677000 id, 2709000 wa, 0 hi, 0 si, 2000000 st
softirq:
         TIMER: 73
        NET_TX: 10
        NET_RX: 26
         BLOCK: 1
         SCHED: 22
           RCU: 37
hardirq:
     irq(  72): delta     88, total:         0, timer4
     irq(  73): delta      2, total:         0, resched4

Also, we creat a watchdog thread for each cpu, and the watchdog
thread is used to check if soft lockup occurs. If so, the statistics
of interrupts will be printed automatically.


Signed-off-by: Meng Cao <caomeng5@huawei.com>
Signed-off-by: Chunmei Xu <xuchunmei@huawei.com>
Suggested-by: Feilong Lin <linfeilong@kernel.org>
Reviewed-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
Reviewed-by: Jingxian He <hejingxian@huawei.com>

---
 kernel/cpustat.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/cpustat.h |   7 ++
 2 files changed, 221 insertions(+)
 create mode 100644 kernel/cpustat.c
 create mode 100644 kernel/cpustat.h

diff --git a/kernel/cpustat.c b/kernel/cpustat.c
new file mode 100644
index 0000000..bb16160
--- /dev/null
+++ b/kernel/cpustat.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2016 Huawei Ltd
+ */
+#include <linux/kernel_stat.h>
+#include <linux/time.h>
+#include <linux/tick.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+struct cpustat_info {
+	struct kernel_stat kstat;
+	struct kernel_cpustat cpustat;
+	unsigned long timestamp;
+};
+
+static struct cpustat_info __percpu *cpustat_data;
+
+#define cpustat_last_softirqs(cpu, i)  \
+	(per_cpu_ptr(cpustat_data, (cpu))->kstat.softirqs[i])
+#define cpustat_last_cputime(cpu, i)   \
+	(per_cpu_ptr(cpustat_data, (cpu))->cpustat.cpustat[i])
+#define cpustat_timestamp(cpu)         \
+	(per_cpu_ptr(cpustat_data, (cpu))->timestamp)
+
+static unsigned int cpustat_cpu_num;
+#define cpustat_print(m, args...)	\
+do {					\
+	if (m)				\
+		seq_printf(m, args);	\
+	else				\
+		pr_warn(args);		\
+} while (0)
+
+static u64 cpustat_curr_cputime(int cpu, int index)
+{
+	u64 time;
+
+	if (index == CPUTIME_IDLE)
+		time = get_idle_time(cpu);
+	else if (index == CPUTIME_IOWAIT)
+		time = get_iowait_time(cpu);
+	else
+		time = kcpustat_cpu(cpu).cpustat[index];
+
+	return time;
+}
+
+static void cpustat_update_cputime(int cpu)
+{
+	int i;
+
+	for (i = 0; i < NR_STATS; i++)
+		cpustat_last_cputime(cpu, i) = cpustat_curr_cputime(cpu, i);
+
+	cpustat_timestamp(cpu) = ktime_to_ns(ktime_get());
+}
+
+static void cpustat_update_softirq(int cpu)
+{
+	int i;
+
+	for (i = 0; i < NR_SOFTIRQS; i++)
+		cpustat_last_softirqs(cpu, i) = kstat_softirqs_cpu(i, cpu);
+}
+
+static void cpustat_print_softirq(int cpu, struct seq_file *m)
+{
+	int i;
+	unsigned long count;
+
+	cpustat_print(m, "softirq:\n");
+	for (i = 0; i < NR_SOFTIRQS; i++) {
+		count = kstat_softirqs_cpu(i, cpu) -
+			cpustat_last_softirqs(cpu, i);
+		if (count)
+			cpustat_print(m, "%14s: %lu\n", softirq_to_name[i], count);
+	}
+}
+
+static void cpustat_print_hardirq(int cpu, struct seq_file *m)
+{
+	int irq;
+	unsigned long flag = 0;
+	unsigned int stat, diff;
+	struct irq_desc *desc;
+
+	cpustat_print(m, "hardirq:\n");
+	for_each_irq_desc(irq, desc) {
+		if (!desc)
+			continue;
+
+		stat = kstat_irqs_cpu(irq, cpu);
+		diff = kstat_irqs_diff_cpu(irq, cpu);
+		if (diff) {
+			cpustat_print(m, "     irq(%4d): delta %6u, total: %9u, %s\n",
+				irq, diff, stat,
+				desc->action ? desc->action->name : "none");
+			flag++;
+		}
+	}
+	if (flag == 0)
+		cpustat_print(m, "		no hard irqs found.\n");
+}
+
+void cpustat_update_cpu(void)
+{
+	int cpu;
+
+	if (!cpustat_data)
+		return;
+	cpu = smp_processor_id();
+	cpustat_update_cputime(cpu);
+	cpustat_update_softirq(cpu);
+	kstat_irq_update();
+}
+
+static void cpustat_print_cputime(int cpu, struct seq_file *m)
+{
+	int i;
+	unsigned long time;
+	u64 cputime[NR_STATS];
+
+	for (i = 0; i < NR_STATS; i++) {
+		cputime[i] = cpustat_curr_cputime(cpu, i);
+		cputime[i] -= cpustat_last_cputime(cpu, i);
+	}
+
+	time = ktime_to_ns(ktime_get()) - cpustat_timestamp(cpu);
+	cpustat_print(m, "cpu time: %lu ns(HZ: %d)\n", time, HZ);
+	cpustat_print(m, "occupied: %llu us, %llu sy, %llu ni,"
+		" %llu id, %llu wa, %llu hi, %llu si, %llu st\n",
+		cputime[CPUTIME_USER],
+		cputime[CPUTIME_SYSTEM],
+		cputime[CPUTIME_NICE],
+		cputime[CPUTIME_IDLE],
+		cputime[CPUTIME_IOWAIT],
+		cputime[CPUTIME_IRQ],
+		cputime[CPUTIME_SOFTIRQ],
+		cputime[CPUTIME_STEAL]);
+}
+
+void cpustat_print_cpu(void)
+{
+	int cpu;
+
+	if (!cpustat_data)
+		return;
+	cpu = smp_processor_id();
+	cpustat_print_cputime(cpu, NULL);
+	cpustat_print_softirq(cpu, NULL);
+	cpustat_print_hardirq(cpu, NULL);
+}
+
+static ssize_t proc_cpustat_write(struct file *file, const char __user *ubuf,
+		size_t cnt, loff_t *ppos)
+{
+	unsigned int val;
+	int ret;
+
+	ret = kstrtouint_from_user(ubuf, cnt, 0, &val);
+	if (ret) {
+		pr_err("[cpustat]: parse input parameter failed.\n");
+		return ret;
+	}
+
+	if (val >= num_online_cpus())
+		return -EINVAL;
+
+	cpustat_cpu_num = val;
+
+	return cnt;
+}
+
+static int cpustat_proc_show(struct seq_file *m, void *s)
+{
+	unsigned int cpu_num = cpustat_cpu_num;
+
+	if (cpu_num >= num_online_cpus())
+		return -EINVAL;
+
+	cpustat_print(m, "cpu index: %u\n", cpu_num);
+
+	cpustat_print_cputime(cpu_num, m);
+	cpustat_print_softirq(cpu_num, m);
+	cpustat_print_hardirq(cpu_num, m);
+	return 0;
+}
+
+static int proc_cpustat_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, cpustat_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_cpustat_file_operations = {
+	.owner		= THIS_MODULE,
+	.open		= proc_cpustat_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= proc_cpustat_write,
+};
+
+void cpustat_init(void)
+{
+	cpustat_data = __alloc_percpu(sizeof(struct cpustat_info), 8);
+	if (!cpustat_data) {
+		pr_err("alloc percpu cpustat_info fail.\n");
+		return;
+	}
+
+	if (!proc_create("cpuirqstat", S_IRUSR|S_IWUSR, NULL, &proc_cpustat_file_operations)) {
+		pr_err("[cpuirqstat]: create /proc/cpuirqstat failed.\n");
+	}
+}
diff --git a/kernel/cpustat.h b/kernel/cpustat.h
new file mode 100644
index 0000000..7a79ee8
--- /dev/null
+++ b/kernel/cpustat.h
@@ -0,0 +1,7 @@
+#ifndef LINUX_CPUSTAT_H
+#define LINUX_CPUSTAT_H
+
+extern void cpustat_init(void);
+extern void cpustat_print_cpu(void);
+extern void cpustat_update_cpu(void);
+#endif
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] cpustat: print watchdog time and statistics of soft and hard interrupts in soft lockup scenes
  2019-08-19  7:12 [PATCH] cpustat: print watchdog time and statistics of soft and hard interrupts in soft lockup scenes c00423981
@ 2019-08-20 11:04 ` Peter Zijlstra
  2019-08-21  8:26   ` c00423981
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Zijlstra @ 2019-08-20 11:04 UTC (permalink / raw)
  To: c00423981; +Cc: tglx, mingo, hpa, x86, linux-kernel

On Mon, Aug 19, 2019 at 03:12:24PM +0800, c00423981 wrote:
> +static u64 cpustat_curr_cputime(int cpu, int index)
> +{
> +	u64 time;
> +
> +	if (index == CPUTIME_IDLE)
> +		time = get_idle_time(cpu);
> +	else if (index == CPUTIME_IOWAIT)
> +		time = get_iowait_time(cpu);

NAK; don't add new users of this terminally broken interface.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] cpustat: print watchdog time and statistics of soft and hard interrupts in soft lockup scenes
  2019-08-20 11:04 ` Peter Zijlstra
@ 2019-08-21  8:26   ` c00423981
  2019-08-21 10:46     ` Peter Zijlstra
  0 siblings, 1 reply; 7+ messages in thread
From: c00423981 @ 2019-08-21  8:26 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: tglx, mingo, hpa, x86, linux-kernel

Sorry, I cannot understand this problem accurately. I try to understand it and I guess what you want
to express is that the return value type should be cputime64_t but not u64, just like as follows:

+static cputime64_t cpustat_curr_cputime(int cpu, int index)
+{
+	cputime64_t time;
+
+	if (index == CPUTIME_IDLE)
+		time = get_idle_time(cpu);
+	else if (index == CPUTIME_IOWAIT)
+		time = get_iowait_time(cpu);

I don't know if I understand it correctly. Looking forward to your answer.




On 2019/8/20 19:04, Peter Zijlstra wrote:
> On Mon, Aug 19, 2019 at 03:12:24PM +0800, c00423981 wrote:
>> +static u64 cpustat_curr_cputime(int cpu, int index)
>> +{
>> +	u64 time;
>> +
>> +	if (index == CPUTIME_IDLE)
>> +		time = get_idle_time(cpu);
>> +	else if (index == CPUTIME_IOWAIT)
>> +		time = get_iowait_time(cpu);
> 
> NAK; don't add new users of this terminally broken interface.
> 
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] cpustat: print watchdog time and statistics of soft and hard interrupts in soft lockup scenes
  2019-08-21  8:26   ` c00423981
@ 2019-08-21 10:46     ` Peter Zijlstra
  2019-08-22 11:58       ` [PATCH V2] " c00423981
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Zijlstra @ 2019-08-21 10:46 UTC (permalink / raw)
  To: c00423981; +Cc: tglx, mingo, hpa, x86, linux-kernel


A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?

On Wed, Aug 21, 2019 at 04:26:17PM +0800, c00423981 wrote:
> Sorry, I cannot understand this problem accurately. I try to understand it and I guess what you want
> to express is that the return value type should be cputime64_t but not u64, just like as follows:
> 
> +static cputime64_t cpustat_curr_cputime(int cpu, int index)
> +{
> +	cputime64_t time;
> +
> +	if (index == CPUTIME_IDLE)
> +		time = get_idle_time(cpu);
> +	else if (index == CPUTIME_IOWAIT)
> +		time = get_iowait_time(cpu);
> 
> I don't know if I understand it correctly. Looking forward to your answer.

get_iowait_time(cpu) is terminally broken, see commit:

  e33a9bba85a8 ("sched/core: move IO scheduling accounting from io_schedule_timeout() into scheduler")

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH V2] cpustat: print watchdog time and statistics of soft and hard interrupts in soft lockup scenes
  2019-08-21 10:46     ` Peter Zijlstra
@ 2019-08-22 11:58       ` c00423981
  2019-08-22 16:14         ` Peter Zijlstra
  0 siblings, 1 reply; 7+ messages in thread
From: c00423981 @ 2019-08-22 11:58 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: tglx, mingo, hpa, x86, linux-kernel

Currently we cannot determine quickly if a soft lockup occurrs, and
do not know what the cpu is doing in soft lockup scenes neither.

The new feature adds a new interface(/proc/cpuirqstat) to view
the statistics of interrupts in real time on a certain cpu, as well as
the time occupancy of user space, system space and so on. Also, we can
view the time after the last-time watchdog which is named cpu time.
If cpu time is longer than twice of watchdot_thresh, a soft lockup occurrs.

The feature enhances the ability of solving problems in soft lockup scenes.

For example, if we want to view the statistics of interrupts on cpu 1, we can
enter the following command to set the cpu index:
		echo 1 > /proc/cpuirqstat
And we can enter the following command to view the statistics:
		cat /proc/cpuirqstat
Then, the result is as follows:

cpu index: 1
cpu time: 2283720189 ns(HZ: 1000)
occupied: 1000000 us, 3000000 sy, 0 ni, 2269677000 id, 2709000 wa, 0 hi, 0 si, 2000000 st
softirq:
         TIMER: 73
        NET_TX: 10
        NET_RX: 26
         BLOCK: 1
         SCHED: 22
           RCU: 37
hardirq:
     irq(  72): delta     88, total:         0, timer4
     irq(  73): delta      2, total:         0, resched4

Also, we creat a watchdog thread for each cpu, and the watchdog
thread is used to check if soft lockup occurs. If so, the statistics
of interrupts will be printed automatically.


Signed-off-by: Meng Cao <caomeng5@huawei.com>
Signed-off-by: Chunmei Xu <xuchunmei@huawei.com>
Suggested-by: Feilong Lin <linfeilong@kernel.org>
Reviewed-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
Reviewed-by: Jingxian He <hejingxian@huawei.com>

---
V1->V2
- fix the broken interfaces: get_idle_time and get_iowait_time

 kernel/cpustat.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/cpustat.h |   7 ++
 2 files changed, 221 insertions(+)
 create mode 100644 kernel/cpustat.c
 create mode 100644 kernel/cpustat.h

diff --git a/kernel/cpustat.c b/kernel/cpustat.c
new file mode 100644
index 0000000..bb16160
--- /dev/null
+++ b/kernel/cpustat.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2016 Huawei Ltd
+ */
+#include <linux/kernel_stat.h>
+#include <linux/time.h>
+#include <linux/tick.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+struct cpustat_info {
+	struct kernel_stat kstat;
+	struct kernel_cpustat cpustat;
+	unsigned long timestamp;
+};
+
+static struct cpustat_info __percpu *cpustat_data;
+
+#define cpustat_last_softirqs(cpu, i)  \
+	(per_cpu_ptr(cpustat_data, (cpu))->kstat.softirqs[i])
+#define cpustat_last_cputime(cpu, i)   \
+	(per_cpu_ptr(cpustat_data, (cpu))->cpustat.cpustat[i])
+#define cpustat_timestamp(cpu)         \
+	(per_cpu_ptr(cpustat_data, (cpu))->timestamp)
+
+static unsigned int cpustat_cpu_num;
+#define cpustat_print(m, args...)	\
+do {					\
+	if (m)				\
+		seq_printf(m, args);	\
+	else				\
+		pr_warn(args);		\
+} while (0)
+
+static u64 cpustat_curr_cputime(int cpu, int index)
+{
+	u64 time;
+	struct kernel_cpustat *kcs = &kcpustat_cpu(cpu);
+
+	if (index == CPUTIME_IDLE)
+		time = get_idle_time(kcs, cpu);
+	else if (index == CPUTIME_IOWAIT)
+		time = get_iowait_time(kcs, cpu);
+	else
+		time = kcpustat_cpu(cpu).cpustat[index];
+
+	return time;
+}
+
+static void cpustat_update_cputime(int cpu)
+{
+	int i;
+
+	for (i = 0; i < NR_STATS; i++)
+		cpustat_last_cputime(cpu, i) = cpustat_curr_cputime(cpu, i);
+
+	cpustat_timestamp(cpu) = ktime_to_ns(ktime_get());
+}
+
+static void cpustat_update_softirq(int cpu)
+{
+	int i;
+
+	for (i = 0; i < NR_SOFTIRQS; i++)
+		cpustat_last_softirqs(cpu, i) = kstat_softirqs_cpu(i, cpu);
+}
+
+static void cpustat_print_softirq(int cpu, struct seq_file *m)
+{
+	int i;
+	unsigned long count;
+
+	cpustat_print(m, "softirq:\n");
+	for (i = 0; i < NR_SOFTIRQS; i++) {
+		count = kstat_softirqs_cpu(i, cpu) -
+			cpustat_last_softirqs(cpu, i);
+		if (count)
+			cpustat_print(m, "%14s: %lu\n", softirq_to_name[i], count);
+	}
+}
+
+static void cpustat_print_hardirq(int cpu, struct seq_file *m)
+{
+	int irq;
+	unsigned long flag = 0;
+	unsigned int stat, diff;
+	struct irq_desc *desc;
+
+	cpustat_print(m, "hardirq:\n");
+	for_each_irq_desc(irq, desc) {
+		if (!desc)
+			continue;
+
+		stat = kstat_irqs_cpu(irq, cpu);
+		diff = kstat_irqs_diff_cpu(irq, cpu);
+		if (diff) {
+			cpustat_print(m, "     irq(%4d): delta %6u, total: %9u, %s\n",
+				irq, diff, stat,
+				desc->action ? desc->action->name : "none");
+			flag++;
+		}
+	}
+	if (flag == 0)
+		cpustat_print(m, "		no hard irqs found.\n");
+}
+
+void cpustat_update_cpu(void)
+{
+	int cpu;
+
+	if (!cpustat_data)
+		return;
+	cpu = smp_processor_id();
+	cpustat_update_cputime(cpu);
+	cpustat_update_softirq(cpu);
+	kstat_irq_update();
+}
+
+static void cpustat_print_cputime(int cpu, struct seq_file *m)
+{
+	int i;
+	unsigned long time;
+	u64 cputime[NR_STATS];
+
+	for (i = 0; i < NR_STATS; i++) {
+		cputime[i] = cpustat_curr_cputime(cpu, i);
+		cputime[i] -= cpustat_last_cputime(cpu, i);
+	}
+
+	time = ktime_to_ns(ktime_get()) - cpustat_timestamp(cpu);
+	cpustat_print(m, "cpu time: %lu ns(HZ: %d)\n", time, HZ);
+	cpustat_print(m, "occupied: %llu us, %llu sy, %llu ni,"
+		" %llu id, %llu wa, %llu hi, %llu si, %llu st\n",
+		cputime[CPUTIME_USER],
+		cputime[CPUTIME_SYSTEM],
+		cputime[CPUTIME_NICE],
+		cputime[CPUTIME_IDLE],
+		cputime[CPUTIME_IOWAIT],
+		cputime[CPUTIME_IRQ],
+		cputime[CPUTIME_SOFTIRQ],
+		cputime[CPUTIME_STEAL]);
+}
+
+void cpustat_print_cpu(void)
+{
+	int cpu;
+
+	if (!cpustat_data)
+		return;
+	cpu = smp_processor_id();
+	cpustat_print_cputime(cpu, NULL);
+	cpustat_print_softirq(cpu, NULL);
+	cpustat_print_hardirq(cpu, NULL);
+}
+
+static ssize_t proc_cpustat_write(struct file *file, const char __user *ubuf,
+		size_t cnt, loff_t *ppos)
+{
+	unsigned int val;
+	int ret;
+
+	ret = kstrtouint_from_user(ubuf, cnt, 0, &val);
+	if (ret) {
+		pr_err("[cpustat]: parse input parameter failed.\n");
+		return ret;
+	}
+
+	if (val >= num_online_cpus())
+		return -EINVAL;
+
+	cpustat_cpu_num = val;
+
+	return cnt;
+}
+
+static int cpustat_proc_show(struct seq_file *m, void *s)
+{
+	unsigned int cpu_num = cpustat_cpu_num;
+
+	if (cpu_num >= num_online_cpus())
+		return -EINVAL;
+
+	cpustat_print(m, "cpu index: %u\n", cpu_num);
+
+	cpustat_print_cputime(cpu_num, m);
+	cpustat_print_softirq(cpu_num, m);
+	cpustat_print_hardirq(cpu_num, m);
+	return 0;
+}
+
+static int proc_cpustat_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, cpustat_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations proc_cpustat_file_operations = {
+	.owner		= THIS_MODULE,
+	.open		= proc_cpustat_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= proc_cpustat_write,
+};
+
+void cpustat_init(void)
+{
+	cpustat_data = __alloc_percpu(sizeof(struct cpustat_info), 8);
+	if (!cpustat_data) {
+		pr_err("alloc percpu cpustat_info fail.\n");
+		return;
+	}
+
+	if (!proc_create("cpuirqstat", S_IRUSR|S_IWUSR, NULL, &proc_cpustat_file_operations)) {
+		pr_err("[cpuirqstat]: create /proc/cpuirqstat failed.\n");
+	}
+}
diff --git a/kernel/cpustat.h b/kernel/cpustat.h
new file mode 100644
index 0000000..7a79ee8
--- /dev/null
+++ b/kernel/cpustat.h
@@ -0,0 +1,7 @@
+#ifndef LINUX_CPUSTAT_H
+#define LINUX_CPUSTAT_H
+
+extern void cpustat_init(void);
+extern void cpustat_print_cpu(void);
+extern void cpustat_update_cpu(void);
+#endif
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH V2] cpustat: print watchdog time and statistics of soft and hard interrupts in soft lockup scenes
  2019-08-22 11:58       ` [PATCH V2] " c00423981
@ 2019-08-22 16:14         ` Peter Zijlstra
  2019-08-23  7:26           ` c00423981
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Zijlstra @ 2019-08-22 16:14 UTC (permalink / raw)
  To: c00423981; +Cc: tglx, mingo, hpa, x86, linux-kernel

On Thu, Aug 22, 2019 at 07:58:37PM +0800, c00423981 wrote:

> V1->V2
> - fix the broken interfaces: get_idle_time and get_iowait_time

> +	else if (index == CPUTIME_IOWAIT)
> +		time = get_iowait_time(kcs, cpu);

I'm confused; isn't that still reporting per-cpu iowait, which is still
complete garbage?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH V2] cpustat: print watchdog time and statistics of soft and hard interrupts in soft lockup scenes
  2019-08-22 16:14         ` Peter Zijlstra
@ 2019-08-23  7:26           ` c00423981
  0 siblings, 0 replies; 7+ messages in thread
From: c00423981 @ 2019-08-23  7:26 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: tglx, mingo, hpa, x86, linux-kernel



On 2019/8/23 0:14, Peter Zijlstra wrote:
> On Thu, Aug 22, 2019 at 07:58:37PM +0800, c00423981 wrote:
> 
>> V1->V2
>> - fix the broken interfaces: get_idle_time and get_iowait_time
> 
>> +	else if (index == CPUTIME_IOWAIT)
>> +		time = get_iowait_time(kcs, cpu);
> 
> I'm confused; isn't that still reporting per-cpu iowait, which is still
> complete garbage?
> 
> 

Yes, I understand that these two interfaces(nr_iowait_cpu and nr_iowait) will
use nonsensical data. Thanks for your answer very much.

By the way, are there an alternative about these two interfaces?
Looking forward to your reply.


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-08-23  7:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-19  7:12 [PATCH] cpustat: print watchdog time and statistics of soft and hard interrupts in soft lockup scenes c00423981
2019-08-20 11:04 ` Peter Zijlstra
2019-08-21  8:26   ` c00423981
2019-08-21 10:46     ` Peter Zijlstra
2019-08-22 11:58       ` [PATCH V2] " c00423981
2019-08-22 16:14         ` Peter Zijlstra
2019-08-23  7:26           ` c00423981

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).