From: Pingfan Liu <hidden> Date: 2021-09-23 14:10:22
hard lockup detector is helpful to diagnose unpaired irq enable/disable.
Sumit has tried with a series, and the last one is V5 [1].
Since it lasts a long time without any update, I takes a retry, which
addresses the delay intialization of watchdog_hld.
( To: Sumit, I think the main body of [4/4] is contributed from you,so I
keep you as the author, please let me know if you dislike it and my
modification.)
There is an obstacle to integrate arm64 hw perf event into watchdog_hld.
When lockup_detector_init()->watchdog_nmi_probe(), on arm64, PMU is not
ready until device_initcall(armv8_pmu_driver_init). And it is deeply
integrated with the driver model and cpuhp. Hence it is hard to push
the initialization of armv8_pmu_driver_init() before smp_init().
But it is easy to take an opposite approach by enabling watchdog_hld to
get the capability of PMU async.
The async model is achieved by expanding watchdog_nmi_probe() with
-EBUSY, and a re-initializing work_struct which waits on a
wait_queue_head.
In this series, [1-2/4] are trivial cleanup. [3-4/4] is for this async
model.
v1 > v2:
uplift the async model from hard lockup layer to watchdog layter.
The benefit is simpler code, the drawback is re-initialize means wasted
alloc/free.
[1]: http://lore.kernel.org/linux-arm-kernel/1610712101-14929-1-git-send-email-sumit.garg@linaro.org
Cc: Sumit Garg <redacted>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <redacted>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Kees Cook <redacted>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
To: linux-arm-kernel@lists.infradead.org
To: linux-kernel@vger.kernel.org
*** BLURB HERE ***
Pingfan Liu (3):
kernel/watchdog: trival cleanups
kernel/watchdog_hld: clarify the condition in
hardlockup_detector_event_create()
kernel/watchdog: adapt the watchdog_hld interface for async model
Sumit Garg (1):
arm64: Enable perf events based hard lockup detector
arch/arm64/Kconfig | 2 ++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/perf_event.c | 11 +++++++--
arch/arm64/kernel/watchdog_hld.c | 36 +++++++++++++++++++++++++++
drivers/perf/arm_pmu.c | 5 ++++
include/linux/nmi.h | 5 +++-
include/linux/perf/arm_pmu.h | 2 ++
kernel/watchdog.c | 42 +++++++++++++++++++++++++++-----
kernel/watchdog_hld.c | 5 +++-
9 files changed, 99 insertions(+), 10 deletions(-)
create mode 100644 arch/arm64/kernel/watchdog_hld.c
--
2.31.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pingfan Liu <hidden> Date: 2021-09-23 14:10:28
No reference to WATCHDOG_DEFAULT, remove it.
And nobody cares about the return value of watchdog_nmi_enable(),
changing its prototype to void.
Signed-off-by: Pingfan Liu <redacted>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-arm-kernel@lists.infradead.org
To: linux-kernel@vger.kernel.org
---
include/linux/nmi.h | 2 +-
kernel/watchdog.c | 5 +----
2 files changed, 2 insertions(+), 5 deletions(-)
From: Pingfan Liu <hidden> Date: 2021-09-23 14:10:37
As for the context, there are two arguments to change
debug_smp_processor_id() to is_percpu_thread().
-1. watchdog_ev is percpu, and migration will frustrate the attempt
which try to bind a watchdog_ev to a cpu by protecting this func inside
the pair of preempt_disable()/preempt_enable().
-2. hardlockup_detector_event_create() indirectly calls
kmem_cache_alloc_node(), which is blockable.
So here, spelling out the really planned context "is_percpu_thread()".
Signed-off-by: Pingfan Liu <redacted>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-arm-kernel@lists.infradead.org
To: linux-kernel@vger.kernel.org
---
kernel/watchdog_hld.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
@@ -165,10 +165,13 @@ static void watchdog_overflow_callback(struct perf_event *event,staticinthardlockup_detector_event_create(void){-unsignedintcpu=smp_processor_id();+unsignedintcpu;structperf_event_attr*wd_attr;structperf_event*evt;+/* This function plans to execute in cpu bound kthread */+WARN_ON(!is_percpu_thread());+cpu=raw_smp_processor_id();wd_attr=&wd_hw_attr;wd_attr->sample_period=hw_nmi_get_sample_period(watchdog_thresh);
--
2.31.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pingfan Liu <hidden> Date: 2021-09-23 14:10:42
When lockup_detector_init()->watchdog_nmi_probe(), PMU may be not ready
yet. E.g. on arm64, PMU is not ready until
device_initcall(armv8_pmu_driver_init). And it is deeply integrated
with the driver model and cpuhp. Hence it is hard to push this
initialization before smp_init().
But it is easy to take an opposite approach by enabling watchdog_hld to
get the capability of PMU async.
The async model is achieved by expanding watchdog_nmi_probe() with
-EBUSY, and a re-initializing work_struct which waits on a wait_queue_head.
Signed-off-by: Pingfan Liu <redacted>
Cc: Sumit Garg <redacted>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <redacted>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Kees Cook <redacted>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-arm-kernel@lists.infradead.org
To: linux-kernel@vger.kernel.org
---
include/linux/nmi.h | 3 +++
kernel/watchdog.c | 37 +++++++++++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 2 deletions(-)
From: Pingfan Liu <hidden> Date: 2021-09-23 14:10:50
From: Sumit Garg <redacted>
With the recent feature added to enable perf events to use pseudo NMIs
as interrupts on platforms which support GICv3 or later, its now been
possible to enable hard lockup detector (or NMI watchdog) on arm64
platforms. So enable corresponding support.
One thing to note here is that normally lockup detector is initialized
just after the early initcalls but PMU on arm64 comes up much later as
device_initcall(). So we need to re-initialize lockup detection once
PMU has been initialized.
[1]: http://lore.kernel.org/linux-arm-kernel/1610712101-14929-1-git-send-email-sumit.garg@linaro.org
Signed-off-by: Sumit Garg <redacted>
(Pingfan: adapt it to watchdog_hld async model based on [1])
Signed-off-by: Pingfan Liu <redacted>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <redacted>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Kees Cook <redacted>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-kernel@vger.kernel.org
To: linux-arm-kernel@lists.infradead.org
---
arch/arm64/Kconfig | 2 ++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/perf_event.c | 11 ++++++++--
arch/arm64/kernel/watchdog_hld.c | 36 ++++++++++++++++++++++++++++++++
drivers/perf/arm_pmu.c | 5 +++++
include/linux/perf/arm_pmu.h | 2 ++
6 files changed, 55 insertions(+), 2 deletions(-)
create mode 100644 arch/arm64/kernel/watchdog_hld.c
@@ -163,6 +163,8 @@ int arm_pmu_acpi_probe(armpmu_init_fn init_fn);staticinlineintarm_pmu_acpi_probe(armpmu_init_fninit_fn){return0;}#endif+boolarm_pmu_irq_is_nmi(void);+/* Internal functions only for core arm_pmu code */structarm_pmu*armpmu_alloc(void);structarm_pmu*armpmu_alloc_atomic(void);
--
2.31.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pingfan Liu <hidden> Date: 2021-09-23 14:29:47
On Thu, Sep 23, 2021 at 10:10 PM Pingfan Liu [off-list ref] wrote:
From: Sumit Garg <redacted>
To Sumit, I think credits should go to you and keep you as the author.
Please let me know if you dislike it.
Thanks,
Pingfan
quoted hunk
With the recent feature added to enable perf events to use pseudo NMIs
as interrupts on platforms which support GICv3 or later, its now been
possible to enable hard lockup detector (or NMI watchdog) on arm64
platforms. So enable corresponding support.
One thing to note here is that normally lockup detector is initialized
just after the early initcalls but PMU on arm64 comes up much later as
device_initcall(). So we need to re-initialize lockup detection once
PMU has been initialized.
[1]: http://lore.kernel.org/linux-arm-kernel/1610712101-14929-1-git-send-email-sumit.garg@linaro.org
Signed-off-by: Sumit Garg <redacted>
(Pingfan: adapt it to watchdog_hld async model based on [1])
Signed-off-by: Pingfan Liu <redacted>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <redacted>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Kees Cook <redacted>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-kernel@vger.kernel.org
To: linux-arm-kernel@lists.infradead.org
---
arch/arm64/Kconfig | 2 ++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/perf_event.c | 11 ++++++++--
arch/arm64/kernel/watchdog_hld.c | 36 ++++++++++++++++++++++++++++++++
drivers/perf/arm_pmu.c | 5 +++++
include/linux/perf/arm_pmu.h | 2 ++
6 files changed, 55 insertions(+), 2 deletions(-)
create mode 100644 arch/arm64/kernel/watchdog_hld.c
@@ -163,6 +163,8 @@ int arm_pmu_acpi_probe(armpmu_init_fn init_fn);staticinlineintarm_pmu_acpi_probe(armpmu_init_fninit_fn){return0;}#endif+boolarm_pmu_irq_is_nmi(void);+/* Internal functions only for core arm_pmu code */structarm_pmu*armpmu_alloc(void);structarm_pmu*armpmu_alloc_atomic(void);--
Hi Pingfan,
On Thu, 23 Sept 2021 at 19:59, Pingfan Liu [off-list ref] wrote:
On Thu, Sep 23, 2021 at 10:10 PM Pingfan Liu [off-list ref] wrote:
quoted
From: Sumit Garg <redacted>
To Sumit, I think credits should go to you and keep you as the author.
Thanks, I am fine with it. If you like then you can add your
"Co-developed-by" as well.
Please let me know if you dislike it.
Thanks,
Pingfan
quoted
With the recent feature added to enable perf events to use pseudo NMIs
as interrupts on platforms which support GICv3 or later, its now been
possible to enable hard lockup detector (or NMI watchdog) on arm64
platforms. So enable corresponding support.
One thing to note here is that normally lockup detector is initialized
just after the early initcalls but PMU on arm64 comes up much later as
device_initcall(). So we need to re-initialize lockup detection once
PMU has been initialized.
This needs to be updated to reflect delayed initialization instead.
-Sumit
quoted
[1]: http://lore.kernel.org/linux-arm-kernel/1610712101-14929-1-git-send-email-sumit.garg@linaro.org
Signed-off-by: Sumit Garg <redacted>
(Pingfan: adapt it to watchdog_hld async model based on [1])
Signed-off-by: Pingfan Liu <redacted>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <redacted>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Kees Cook <redacted>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-kernel@vger.kernel.org
To: linux-arm-kernel@lists.infradead.org
---
arch/arm64/Kconfig | 2 ++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/perf_event.c | 11 ++++++++--
arch/arm64/kernel/watchdog_hld.c | 36 ++++++++++++++++++++++++++++++++
drivers/perf/arm_pmu.c | 5 +++++
include/linux/perf/arm_pmu.h | 2 ++
6 files changed, 55 insertions(+), 2 deletions(-)
create mode 100644 arch/arm64/kernel/watchdog_hld.c
@@ -163,6 +163,8 @@ int arm_pmu_acpi_probe(armpmu_init_fn init_fn);staticinlineintarm_pmu_acpi_probe(armpmu_init_fninit_fn){return0;}#endif+boolarm_pmu_irq_is_nmi(void);+/* Internal functions only for core arm_pmu code */structarm_pmu*armpmu_alloc(void);structarm_pmu*armpmu_alloc_atomic(void);--
From: Pingfan Liu <hidden> Date: 2021-09-24 13:34:50
On Fri, Sep 24, 2021 at 1:19 PM Sumit Garg [off-list ref] wrote:
Hi Pingfan,
On Thu, 23 Sept 2021 at 19:59, Pingfan Liu [off-list ref] wrote:
quoted
On Thu, Sep 23, 2021 at 10:10 PM Pingfan Liu [off-list ref] wrote:
quoted
From: Sumit Garg <redacted>
To Sumit, I think credits should go to you and keep you as the author.
Thanks, I am fine with it. If you like then you can add your
"Co-developed-by" as well.
OK, I will.
quoted
quoted
One thing to note here is that normally lockup detector is initialized
just after the early initcalls but PMU on arm64 comes up much later as
device_initcall(). So we need to re-initialize lockup detection once
PMU has been initialized.
This needs to be updated to reflect delayed initialization instead.
From: Petr Mladek <pmladek@suse.com> Date: 2021-10-04 09:32:44
On Thu 2021-09-23 22:09:48, Pingfan Liu wrote:
quoted hunk
No reference to WATCHDOG_DEFAULT, remove it.
And nobody cares about the return value of watchdog_nmi_enable(),
changing its prototype to void.
Signed-off-by: Pingfan Liu <redacted>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-arm-kernel@lists.infradead.org
To: linux-kernel@vger.kernel.org
---
include/linux/nmi.h | 2 +-
kernel/watchdog.c | 5 +----
2 files changed, 2 insertions(+), 5 deletions(-)
It is __weak. spart specific implementation is in
arch/sparc/kernel/nmi.c. It has to be updated as well.
Best Regards,
Petr
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Petr Mladek <pmladek@suse.com> Date: 2021-10-04 12:32:54
On Thu 2021-09-23 22:09:49, Pingfan Liu wrote:
As for the context, there are two arguments to change
debug_smp_processor_id() to is_percpu_thread().
-1. watchdog_ev is percpu, and migration will frustrate the attempt
which try to bind a watchdog_ev to a cpu by protecting this func inside
the pair of preempt_disable()/preempt_enable().
-2. hardlockup_detector_event_create() indirectly calls
kmem_cache_alloc_node(), which is blockable.
So here, spelling out the really planned context "is_percpu_thread()".
The description is pretty hard to understand. I would suggest
something like:
Subject: kernel/watchdog_hld: Ensure CPU-bound context when creating
hardlockup detector event
hardlockup_detector_event_create() should create perf_event on the
current CPU. Preemption could not get disabled because
perf_event_create_kernel_counter() allocates memory. Instead,
the CPU locality is achieved by processing the code in a per-CPU
bound kthread.
Add a check to prevent mistakes when calling the code in another
code path.
quoted hunk
Signed-off-by: Pingfan Liu <redacted>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-arm-kernel@lists.infradead.org
To: linux-kernel@vger.kernel.org
---
kernel/watchdog_hld.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
@@ -165,10 +165,13 @@ static void watchdog_overflow_callback(struct perf_event *event,staticinthardlockup_detector_event_create(void){-unsignedintcpu=smp_processor_id();+unsignedintcpu;structperf_event_attr*wd_attr;structperf_event*evt;+/* This function plans to execute in cpu bound kthread */
This does not explain why it is needed. I suggest something like:
/*
* Preemption is not disabled because memory will be allocated.
* Ensure CPU-locality by calling this in per-CPU kthread.
*/
From: Petr Mladek <pmladek@suse.com> Date: 2021-10-05 07:03:24
On Thu 2021-09-23 22:09:50, Pingfan Liu wrote:
quoted hunk
When lockup_detector_init()->watchdog_nmi_probe(), PMU may be not ready
yet. E.g. on arm64, PMU is not ready until
device_initcall(armv8_pmu_driver_init). And it is deeply integrated
with the driver model and cpuhp. Hence it is hard to push this
initialization before smp_init().
But it is easy to take an opposite approach by enabling watchdog_hld to
get the capability of PMU async.
The async model is achieved by expanding watchdog_nmi_probe() with
-EBUSY, and a re-initializing work_struct which waits on a wait_queue_head.
Signed-off-by: Pingfan Liu <redacted>
Cc: Sumit Garg <redacted>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <redacted>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Kees Cook <redacted>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-arm-kernel@lists.infradead.org
To: linux-kernel@vger.kernel.org
---
include/linux/nmi.h | 3 +++
kernel/watchdog.c | 37 +++++++++++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 2 deletions(-)
@@ -103,7 +103,10 @@ void __weak watchdog_nmi_disable(unsigned int cpu)hardlockup_detector_perf_disable();}-/* Return 0, if a NMI watchdog is available. Error code otherwise */+/*+*Return0,ifaNMIwatchdogisavailable.-EBUSYifnotready.+*Othernegativevalueifnotsupport.+*/int__weak__initwatchdog_nmi_probe(void){returnhardlockup_detector_perf_init();
@@ -739,15 +742,45 @@ int proc_watchdog_cpumask(struct ctl_table *table, int write,}#endif /* CONFIG_SYSCTL */+staticvoidlockup_detector_delay_init(structwork_struct*work);+boolhld_detector_delay_initialized__initdata;++structwait_queue_headhld_detector_wait__initdata=+__WAIT_QUEUE_HEAD_INITIALIZER(hld_detector_wait);++staticstructwork_structdetector_work__initdata=+__WORK_INITIALIZER(detector_work,lockup_detector_delay_init);++staticvoid__initlockup_detector_delay_init(structwork_struct*work)+{+intret;++wait_event(hld_detector_wait,hld_detector_delay_initialized);+ret=watchdog_nmi_probe();+if(!ret){+nmi_watchdog_available=true;+lockup_detector_setup();
Is it really safe to call the entire lockup_detector_setup()
later?
It manipulates also softlockup detector. And more importantly,
the original call is before smp_init(). It means that it was
running when only single CPU was on.
It seems that x86 has some problem with hardlockup detector as
well. It later manipulates only the hardlockup detector. Also it uses
cpus_read_lock() to prevent races with CPU hotplug, see
fixup_ht_bug().
quoted hunk
+ } else {+ WARN_ON(ret == -EBUSY);+ pr_info("Perf NMI watchdog permanently disabled\n");+ }+}+ void __init lockup_detector_init(void) {+ int ret;+ if (tick_nohz_full_enabled()) pr_info("Disabling watchdog on nohz_full cores by default\n"); cpumask_copy(&watchdog_cpumask, housekeeping_cpumask(HK_FLAG_TIMER));- if (!watchdog_nmi_probe())+ ret = watchdog_nmi_probe();+ if (!ret) nmi_watchdog_available = true;+ else if (ret == -EBUSY)+ queue_work_on(smp_processor_id(), system_wq, &detector_work);
IMHO, this is not acceptable. It will block one worker until someone
wakes it. Only arm64 will have a code to wake up the work and only
when pmu is successfully initialized. In all other cases, the worker
will stay blocked forever.
The right solution is to do it the other way. Queue the work
from arm64-specific code when armv8_pmu_driver_init() succeeded.
Also I suggest to flush the work to make sure that it is finished
before __init code gets removed.
The open question is what code the work will call. As mentioned
above, I am not sure that lockup_detector_delay_init() is safe.
IMHO, we need to manipulate only hardlockup detector and
we have to serialize it against CPU hotplug.
Best Regards,
Petr
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Pingfan Liu <hidden> Date: 2021-10-08 04:04:45
On Mon, Oct 04, 2021 at 11:32:41AM +0200, Petr Mladek wrote:
On Thu 2021-09-23 22:09:48, Pingfan Liu wrote:
quoted
No reference to WATCHDOG_DEFAULT, remove it.
And nobody cares about the return value of watchdog_nmi_enable(),
changing its prototype to void.
Signed-off-by: Pingfan Liu <redacted>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-arm-kernel@lists.infradead.org
To: linux-kernel@vger.kernel.org
---
include/linux/nmi.h | 2 +-
kernel/watchdog.c | 5 +----
2 files changed, 2 insertions(+), 5 deletions(-)
From: Pingfan Liu <hidden> Date: 2021-10-08 04:11:47
On Mon, Oct 04, 2021 at 02:32:47PM +0200, Petr Mladek wrote:
On Thu 2021-09-23 22:09:49, Pingfan Liu wrote:
quoted
As for the context, there are two arguments to change
debug_smp_processor_id() to is_percpu_thread().
-1. watchdog_ev is percpu, and migration will frustrate the attempt
which try to bind a watchdog_ev to a cpu by protecting this func inside
the pair of preempt_disable()/preempt_enable().
-2. hardlockup_detector_event_create() indirectly calls
kmem_cache_alloc_node(), which is blockable.
So here, spelling out the really planned context "is_percpu_thread()".
The description is pretty hard to understand. I would suggest
something like:
Subject: kernel/watchdog_hld: Ensure CPU-bound context when creating
hardlockup detector event
hardlockup_detector_event_create() should create perf_event on the
current CPU. Preemption could not get disabled because
perf_event_create_kernel_counter() allocates memory. Instead,
the CPU locality is achieved by processing the code in a per-CPU
bound kthread.
Add a check to prevent mistakes when calling the code in another
code path.
Appreciate for that. I will use it.
quoted
Signed-off-by: Pingfan Liu <redacted>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Wang Qing <redacted>
Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
Cc: Santosh Sivaraj <redacted>
Cc: linux-arm-kernel@lists.infradead.org
To: linux-kernel@vger.kernel.org
---
kernel/watchdog_hld.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
@@ -165,10 +165,13 @@ static void watchdog_overflow_callback(struct perf_event *event,staticinthardlockup_detector_event_create(void){-unsignedintcpu=smp_processor_id();+unsignedintcpu;structperf_event_attr*wd_attr;structperf_event*evt;+/* This function plans to execute in cpu bound kthread */
This does not explain why it is needed. I suggest something like:
/*
* Preemption is not disabled because memory will be allocated.
* Ensure CPU-locality by calling this in per-CPU kthread.
*/
Is it really safe to call the entire lockup_detector_setup()
later?
It manipulates also softlockup detector. And more importantly,
the original call is before smp_init(). It means that it was
running when only single CPU was on.
For the race analysis, lockup_detector_reconfigure() is on the centre stage.
Since proc_watchdog_update() can call lockup_detector_reconfigure() to
re-initialize both soft and hard lockup detector, so the race issue
should be already taken into consideration.
It seems that x86 has some problem with hardlockup detector as
well. It later manipulates only the hardlockup detector. Also it uses
cpus_read_lock() to prevent races with CPU hotplug, see
fixup_ht_bug().
Yes. But hardlockup_detector_perf_{stop,start}() can not meet the
requirement, since no perf_event is created yet. So there is no handy
interface to re-initialize hardlockup detector directly.
quoted
+ } else {+ WARN_ON(ret == -EBUSY);+ pr_info("Perf NMI watchdog permanently disabled\n");+ }+}+ void __init lockup_detector_init(void) {+ int ret;+ if (tick_nohz_full_enabled()) pr_info("Disabling watchdog on nohz_full cores by default\n"); cpumask_copy(&watchdog_cpumask, housekeeping_cpumask(HK_FLAG_TIMER));- if (!watchdog_nmi_probe())+ ret = watchdog_nmi_probe();+ if (!ret) nmi_watchdog_available = true;+ else if (ret == -EBUSY)+ queue_work_on(smp_processor_id(), system_wq, &detector_work);
IMHO, this is not acceptable. It will block one worker until someone
wakes it. Only arm64 will have a code to wake up the work and only
when pmu is successfully initialized. In all other cases, the worker
will stay blocked forever.
What about consider -EBUSY and hld_detector_delay_initialized as a unit?
If watchdog_nmi_probe() returns -EBUSY, then
set the state of ld_detector_delay_initialized as "waiting", and then moved to state "finished".
And at the end of do_initcalls(), check the state is "finished". If not,
then throw a warning and wake up the worker.
The right solution is to do it the other way. Queue the work
from arm64-specific code when armv8_pmu_driver_init() succeeded.
Could it be better if watchdog can provide a common framework for future
extension instead of arch specific? The 2nd argument is to avoid the
message "Perf NMI watchdog permanently disabled" while later enabling
it. (Please see
lockup_detector_init()->watchdog_nmi_probe()->hardlockup_detector_perf_init(),
but if providing arch specific probe method, it can be avoided)
Also I suggest to flush the work to make sure that it is finished
before __init code gets removed.
Good point, and very interesting. I will look into it.
The open question is what code the work will call. As mentioned
above, I am not sure that lockup_detector_delay_init() is safe.
IMHO, we need to manipulate only hardlockup detector and
we have to serialize it against CPU hotplug.
As explained ahead, it has already consider the race against CPU
hotplug.
Thanks,
Pingfan
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Is it really safe to call the entire lockup_detector_setup()
later?
It manipulates also softlockup detector. And more importantly,
the original call is before smp_init(). It means that it was
running when only single CPU was on.
For the race analysis, lockup_detector_reconfigure() is on the centre stage.
Since proc_watchdog_update() can call lockup_detector_reconfigure() to
re-initialize both soft and hard lockup detector, so the race issue
should be already taken into consideration.
quoted
It seems that x86 has some problem with hardlockup detector as
well. It later manipulates only the hardlockup detector. Also it uses
cpus_read_lock() to prevent races with CPU hotplug, see
fixup_ht_bug().
Yes. But hardlockup_detector_perf_{stop,start}() can not meet the
requirement, since no perf_event is created yet. So there is no handy
interface to re-initialize hardlockup detector directly.
quoted
quoted
+ } else {+ WARN_ON(ret == -EBUSY);+ pr_info("Perf NMI watchdog permanently disabled\n");+ }+}+ void __init lockup_detector_init(void) {+ int ret;+ if (tick_nohz_full_enabled()) pr_info("Disabling watchdog on nohz_full cores by default\n"); cpumask_copy(&watchdog_cpumask, housekeeping_cpumask(HK_FLAG_TIMER));- if (!watchdog_nmi_probe())+ ret = watchdog_nmi_probe();+ if (!ret) nmi_watchdog_available = true;+ else if (ret == -EBUSY)+ queue_work_on(smp_processor_id(), system_wq, &detector_work);
IMHO, this is not acceptable. It will block one worker until someone
wakes it. Only arm64 will have a code to wake up the work and only
when pmu is successfully initialized. In all other cases, the worker
will stay blocked forever.
What about consider -EBUSY and hld_detector_delay_initialized as a unit?
^^^
unity
If watchdog_nmi_probe() returns -EBUSY, then
set the state of ld_detector_delay_initialized as "waiting", and then moved to state "finished".
And at the end of do_initcalls(), check the state is "finished". If not,
then throw a warning and wake up the worker.
quoted
The right solution is to do it the other way. Queue the work
from arm64-specific code when armv8_pmu_driver_init() succeeded.
Could it be better if watchdog can provide a common framework for future
extension instead of arch specific? The 2nd argument is to avoid the
message "Perf NMI watchdog permanently disabled" while later enabling
it. (Please see
lockup_detector_init()->watchdog_nmi_probe()->hardlockup_detector_perf_init(),
but if providing arch specific probe method, it can be avoided)
Sorry for poor expression. I have not explained it completely for the
second point.
Since using arch specific watchdog_nmi_probe() to avoid misleading
message "Perf NMI watchdog permanently disabled", then -EBUSY should be
returned. And from watchdog level, it should know how to handle error,
that is to say queue_work_on(smp_processor_id(), system_wq, &detector_work).
Thanks,
Pingfan
quoted
Also I suggest to flush the work to make sure that it is finished
before __init code gets removed.
Good point, and very interesting. I will look into it.
quoted
The open question is what code the work will call. As mentioned
above, I am not sure that lockup_detector_delay_init() is safe.
IMHO, we need to manipulate only hardlockup detector and
we have to serialize it against CPU hotplug.
As explained ahead, it has already consider the race against CPU
hotplug.
Thanks,
Pingfan