|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 2/2] xen/watchdog: Identify which domain watchdog fired
On Mon, 3 Mar 2025, Andrew Cooper wrote:
> When a watchdog fires, the domain is crashed and can't dump any state.
>
> Xen allows a domain to have two separate watchdogs. Therefore, for a
> domain running multiple watchdogs (e.g. one based around network, one
> for disk), it is important for diagnostics to know which watchdog
> fired.
>
> As the printk() is in a timer callback, this is a bit awkward to
> arrange, but there are 12 spare bits in the bottom of the domain
> pointer owing to its alignment.
>
> Reuse these bits to encode the watchdog id too, so the one which fired
> is identified when the domain is crashed.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
The code looks like it would work as intended.
I checked with the MISRA rules and it looks like it would fall under the
allowed exception. Please have a run through ECLAIR to make sure it
doesn't cause regressions (especially R11.2).
> ---
> CC: Anthony PERARD <anthony.perard@xxxxxxxxxx>
> CC: Michal Orzel <michal.orzel@xxxxxxx>
> CC: Jan Beulich <jbeulich@xxxxxxxx>
> CC: Julien Grall <julien@xxxxxxx>
> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
> CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
> CC: Dario Faggioli <dfaggioli@xxxxxxxx>
> CC: Juergen Gross <jgross@xxxxxxxx>
> CC: George Dunlap <gwd@xxxxxxxxxxxxxx>
>
> v2:
> * BUILD_BUG_ON() against the alignment of d.
> ---
> xen/common/sched/core.c | 23 ++++++++++++++++++++---
> 1 file changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/xen/common/sched/core.c b/xen/common/sched/core.c
> index d6296d99fdb9..3db0fe32ccd8 100644
> --- a/xen/common/sched/core.c
> +++ b/xen/common/sched/core.c
> @@ -1534,12 +1534,19 @@ long vcpu_yield(void)
>
> static void cf_check domain_watchdog_timeout(void *data)
> {
> - struct domain *d = data;
> + /*
> + * The data parameter encodes the watchdog id in the low bits of
> + * the domain pointer.
> + */
> + struct domain *d = _p((unsigned long)data & PAGE_MASK);
> + unsigned int id = (unsigned long)data & ~PAGE_MASK;
> +
> + BUILD_BUG_ON(!(alignof(d) < PAGE_SIZE));
>
> if ( d->is_shutting_down || d->is_dying )
> return;
>
> - printk("Watchdog timer fired for domain %u\n", d->domain_id);
> + printk("Watchdog timer %u fired for %pd\n", id, d);
> domain_shutdown(d, SHUTDOWN_watchdog);
> }
>
> @@ -1593,7 +1600,17 @@ void watchdog_domain_init(struct domain *d)
> d->watchdog_inuse_map = 0;
>
> for ( i = 0; i < NR_DOMAIN_WATCHDOG_TIMERS; i++ )
> - init_timer(&d->watchdog_timer[i], domain_watchdog_timeout, d, 0);
> + {
> + void *data = d;
> +
> + BUILD_BUG_ON(NR_DOMAIN_WATCHDOG_TIMERS > alignof(d));
> +
> + /*
> + * For the timer callback parameter, encode the watchdog id in
> + * the low bits of the domain pointer.
> + */
> + init_timer(&d->watchdog_timer[i], domain_watchdog_timeout, data + i,
> 0);
> + }
> }
>
> void watchdog_domain_destroy(struct domain *d)
> --
> 2.39.5
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |