From: Petr Mladek <pmladek@suse.com>
To: Lecopzer Chen <lecopzer.chen@mediatek.com>
Cc: linux-kernel@vger.kernel.org, acme@kernel.org,
akpm@linux-foundation.org, alexander.shishkin@linux.intel.com,
catalin.marinas@arm.com, davem@davemloft.net, jolsa@redhat.com,
jthierry@redhat.com, keescook@chromium.org, kernelfans@gmail.com,
linux-arm-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-perf-users@vger.kernel.org, mark.rutland@arm.com,
masahiroy@kernel.org, matthias.bgg@gmail.com, maz@kernel.org,
mcgrof@kernel.org, mingo@redhat.com, namhyung@kernel.org,
nixiaoming@huawei.com, peterz@infradead.org,
sparclinux@vger.kernel.org, sumit.garg@linaro.org,
wangqing@vivo.com, will@kernel.org, yj.chiang@mediatek.com
Subject: Re: [PATCH v3 4/5] kernel/watchdog: Adapt the watchdog_hld interface for async model
Date: Mon, 4 Apr 2022 16:41:13 +0200 [thread overview]
Message-ID: <20220404144113.GB26840@pathway.suse.cz> (raw)
In-Reply-To: <20220324141405.10835-5-lecopzer.chen@mediatek.com>
On Thu 2022-03-24 22:14:04, Lecopzer Chen wrote:
> 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 and try to initialize
> the watchdog once again later.
> The delayed probe is called using workqueues. It need to allocate
> memory and must be proceed in a normal context.
> The delayed probe is queued only when the early one returns -EBUSY.
> It is the return code returned when PMU is not ready yet.
>
> Provide an API - retry_lockup_detector_init() for anyone who needs
> to delayed init lockup detector.
>
> The original assumption is: nobody should use delayed probe after
> lockup_detector_check() which has __init attribute.
> That is, anyone uses this API must call between lockup_detector_init()
> and lockup_detector_check(), and the caller must have __init attribute
>
> Co-developed-by: Pingfan Liu <kernelfans@gmail.com>
> Signed-off-by: Pingfan Liu <kernelfans@gmail.com>
> Signed-off-by: Lecopzer Chen <lecopzer.chen@mediatek.com>
> Suggested-by: Petr Mladek <pmladek@suse.com>
> ---
> include/linux/nmi.h | 3 ++
> kernel/watchdog.c | 69 +++++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 70 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/nmi.h b/include/linux/nmi.h
> index b7bcd63c36b4..1d84c9a8b460 100644
> --- a/include/linux/nmi.h
> +++ b/include/linux/nmi.h
> @@ -118,6 +118,9 @@ static inline int hardlockup_detector_perf_init(void) { return 0; }
>
> void watchdog_nmi_stop(void);
> void watchdog_nmi_start(void);
> +
> +extern bool allow_lockup_detector_init_retry;
> +void retry_lockup_detector_init(void);
> int watchdog_nmi_probe(void);
> void watchdog_nmi_enable(unsigned int cpu);
> void watchdog_nmi_disable(unsigned int cpu);
> diff --git a/kernel/watchdog.c b/kernel/watchdog.c
> index b71d434cf648..308ba29f8f0f 100644
> --- a/kernel/watchdog.c
> +++ b/kernel/watchdog.c
> @@ -103,7 +103,13 @@ void __weak watchdog_nmi_disable(unsigned int cpu)
> hardlockup_detector_perf_disable();
> }
>
> -/* Return 0, if a NMI watchdog is available. Error code otherwise */
> +/*
> + * Arch specific API.
> + *
> + * Return 0 when NMI watchdog is available, negative value otherwise.
> + * The error code -EBUSY is special. It means that a deferred probe
> + * might succeed later.
> + */
> int __weak __init watchdog_nmi_probe(void)
> {
> return hardlockup_detector_perf_init();
> @@ -839,16 +845,75 @@ static void __init watchdog_sysctl_init(void)
> #define watchdog_sysctl_init() do { } while (0)
> #endif /* CONFIG_SYSCTL */
>
> +static void lockup_detector_delay_init(struct work_struct *work);
> +bool allow_lockup_detector_init_retry __initdata;
> +
> +static struct work_struct detector_work __initdata =
> + __WORK_INITIALIZER(detector_work, lockup_detector_delay_init);
> +
> +static void __init lockup_detector_delay_init(struct work_struct *work)
> +{
> + int ret;
> +
> + ret = watchdog_nmi_probe();
> + if (ret) {
> + pr_info("Delayed init of the lockup detector failed: %d\n", ret);
> + pr_info("Perf NMI watchdog permanently disabled\n");
> + return;
> + }
> +
> + nmi_watchdog_available = true;
> + lockup_detector_setup();
The name of the variable "allow_lockup_detector_init_retry" is
slightly confusing in this context. I suggest to add a comment:
/* Retry is not needed any longer. */
> + allow_lockup_detector_init_retry = false;
> +}
> +
> +/*
> + * retry_lockup_detector_init - retry init lockup detector if possible.
> + *
> + * Only take effect when allow_lockup_detector_init_retry is true, which
> + * means it must call between lockup_detector_init() and lockup_detector_check().
> + * Be aware that caller must have __init attribute, relative functions
> + * will be freed after kernel initialization.
> + */
> +void __init retry_lockup_detector_init(void)
> +{
> + if (!allow_lockup_detector_init_retry)
> + return;
> +
> + queue_work_on(__smp_processor_id(), system_wq, &detector_work);
> +}
> +
> +/* Ensure the check is called after the initialization of driver */
> +static int __init lockup_detector_check(void)
> +{
> + /* Make sure no work is pending. */
> + flush_work(&detector_work);
This is racy. We should first disable
"allow_lockup_detector_init_retry" to make sure
that retry_lockup_detector_init() will not queue
the work any longer.
> + if (!allow_lockup_detector_init_retry)
> + return 0;
> +
> + allow_lockup_detector_init_retry = false;
> + pr_info("Delayed init checking failed, please check your driver.\n");
This prints that the init failed without checking the state
of the watchdog. I guess that it works but it is far from
obvious and any further change might break it.
Is the message really needed?
Does it help?
What exact driver needs checking?
IMHO, it just makes the code more complicated and
it is not worth it.
I suggest to keep it simple:
/*
* Ensure the check is called after the initialization of driver
* and before removing init code.
*/
static int __init lockup_detector_check(void)
{
allow_lockup_detector_init_retry = false;
flush_work(&detector_work);
return 0;
}
or if you really want that message then I would do:
/*
* Ensure the check is called after the initialization of driver
* and before removing init code.
*/
static int __init lockup_detector_check(void)
{
bool delayed_init_allowed = allow_lockup_detector_init_retry;
allow_lockup_detector_init_retry = false;
flush_work(&detector_work);
if (delayed_init_allowed && !nmi_watchdog_available)
pr_info("Delayed init failed. Please, check your driver.\n");
return 0;
}
Best Regards,
Petr
next prev parent reply other threads:[~2022-04-04 14:43 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-24 14:14 [PATCH v3 0/5] Support hld delayed init based on Pseudo-NMI for arm64 Lecopzer Chen
2022-03-24 14:14 ` [PATCH v3 1/5] kernel/watchdog: remove WATCHDOG_DEFAULT Lecopzer Chen
2022-03-24 14:14 ` [PATCH v3 2/5] kernel/watchdog: change watchdog_nmi_enable() to void Lecopzer Chen
2022-03-24 14:14 ` [PATCH v3 3/5] kernel/watchdog_hld: Ensure CPU-bound context when creating hardlockup detector event Lecopzer Chen
2022-03-24 14:14 ` [PATCH v3 4/5] kernel/watchdog: Adapt the watchdog_hld interface for async model Lecopzer Chen
2022-04-04 14:41 ` Petr Mladek [this message]
2022-04-05 13:35 ` Lecopzer Chen
2022-04-05 15:19 ` Petr Mladek
2022-04-07 16:21 ` Lecopzer Chen
2022-03-24 14:14 ` [PATCH v3 5/5] arm64: Enable perf events based hard lockup detector Lecopzer Chen
2022-04-04 14:17 ` Petr Mladek
2022-04-05 12:53 ` Lecopzer Chen
2022-04-05 14:36 ` Petr Mladek
2022-04-07 16:59 ` Lecopzer Chen
2022-04-13 10:25 ` Petr Mladek
2022-04-21 16:30 ` Lecopzer Chen
2022-04-26 16:38 ` Lecopzer Chen
2022-04-28 8:27 ` Petr Mladek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220404144113.GB26840@pathway.suse.cz \
--to=pmladek@suse.com \
--cc=acme@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=catalin.marinas@arm.com \
--cc=davem@davemloft.net \
--cc=jolsa@redhat.com \
--cc=jthierry@redhat.com \
--cc=keescook@chromium.org \
--cc=kernelfans@gmail.com \
--cc=lecopzer.chen@mediatek.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=masahiroy@kernel.org \
--cc=matthias.bgg@gmail.com \
--cc=maz@kernel.org \
--cc=mcgrof@kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=nixiaoming@huawei.com \
--cc=peterz@infradead.org \
--cc=sparclinux@vger.kernel.org \
--cc=sumit.garg@linaro.org \
--cc=wangqing@vivo.com \
--cc=will@kernel.org \
--cc=yj.chiang@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).