All of lore.kernel.org
 help / color / mirror / Atom feed
From: Petri Latvala <petri.latvala@intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>
Cc: igt-dev@lists.freedesktop.org
Subject: Re: [igt-dev] [PATCH i-g-t] lib: Process kernel taints
Date: Fri, 8 Jan 2021 15:30:13 +0200	[thread overview]
Message-ID: <20210108133013.GU7444@platvala-desk.ger.corp.intel.com> (raw)
In-Reply-To: <20210108130157.4037735-1-chris@chris-wilson.co.uk>

On Fri, Jan 08, 2021 at 01:01:57PM +0000, Chris Wilson wrote:
> A small library routine to read '/proc/sys/kernel/taints' and check for
> a fatal condition. This is currently used by the runner, but is also
> useful for some tests.
> 
> v2: function docs
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Petri Latvala <petri.latvala@intel.com>
> ---
>  lib/Makefile.sources |  2 +
>  lib/igt_taints.c     | 98 ++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_taints.h     | 19 +++++++++
>  lib/meson.build      |  1 +
>  runner/executor.c    | 73 +++++++--------------------------
>  5 files changed, 134 insertions(+), 59 deletions(-)
>  create mode 100644 lib/igt_taints.c
>  create mode 100644 lib/igt_taints.h
> 
> diff --git a/lib/Makefile.sources b/lib/Makefile.sources
> index 67b386457..7102f95e7 100644
> --- a/lib/Makefile.sources
> +++ b/lib/Makefile.sources
> @@ -64,6 +64,8 @@ lib_source_list =	 	\
>  	igt_sysfs.h		\
>  	igt_sysrq.c		\
>  	igt_sysrq.h		\
> +	igt_taints.c		\
> +	igt_taints.h		\
>  	igt_thread.c		\
>  	igt_thread.h		\
>  	igt_x86.h		\
> diff --git a/lib/igt_taints.c b/lib/igt_taints.c
> new file mode 100644
> index 000000000..a5a7e6cae
> --- /dev/null
> +++ b/lib/igt_taints.c
> @@ -0,0 +1,98 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#include <stdio.h>
> +
> +#include "igt_taints.h"
> +
> +/* see Linux's include/linux/kernel.h */
> +static const struct {
> +	int bit;
> +	int bad;
> +	const char *explanation;
> +} abort_taints[] = {
> +  { 5, 1, "TAINT_BAD_PAGE: Bad page reference or an unexpected page flags." },
> +  { 7, 1, "TAINT_DIE: Kernel has died - BUG/OOPS." },
> +  { 9, 1, "TAINT_WARN: WARN_ON has happened." },
> +  { -1 }
> +};
> +
> +/**
> + * igt_explain_taints:
> + * @taints: mask of taints requiring an explanation [inout]
> + *
> + * Inspects the mask and looks up the first reason correspoding to a set
> + * bit in the mast. It returns the reason as a string constant, and removes
> + * the bit from the mask. If the mask is empty, or we have no known reason
> + * matching the match, NULL is returned.
> + *
> + * This may be used in a loop to extract all known reasons for why the
> + * kernel tained:

s/correspoding/corresponding/
s/mast/mask/
s/matching the match/matching the mask/

> + *
> + * while (reason = igt_explain_taints(&taints))
> + * 	igt_info("%s", reason);
> + *
> + * Returns the first reason corresponding to a taint bit.
> + */
> +const char *igt_explain_taints(unsigned long *taints)
> +{
> +	for (typeof(*abort_taints) *taint = abort_taints;
> +	     taint->bit >= 0;
> +	     taint++) {
> +		if (*taints & (1ul << taint->bit)) {
> +			*taints &= ~(1ul << taint->bit);
> +			return taint->explanation;
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +/**
> + * igt_bad_taints:
> + *
> + * Returns the mask of kernel taints that IGT considers fatal.
> + * Such as TAINT_WARN set when the kernel oopses.
> + */
> +unsigned long igt_bad_taints(void)
> +{
> +	static unsigned long bad_taints;
> +
> +	if (!bad_taints) {
> +		for (typeof(*abort_taints) *taint = abort_taints;
> +		     taint->bit >= 0;
> +		     taint++) {
> +			if (taint->bad)
> +				bad_taints |= 1ul << taint->bit;
> +		}
> +	}
> +
> +	return bad_taints;
> +}
> +
> +/**
> + * igt_kernel_tainted:
> + * @taints: bitmask of kernel taints [out]
> + *
> + * Reads "/prco/sys/kernel/tainted" and returns both the set of all
> + * taints reported via @taints, and the set of fatal taints as the
> + * return parameters.
> + *
> + * Returns a mask of fatal taints; 0 if untainted.
> + */

s/prco/proc/

Move the "both" word later so it's clear it's returning the same thing
with two means, instead of returning two things.


With those

Reviewed-by: Petri Latvala <petri.latvala@intel.com>


> +unsigned long igt_kernel_tainted(unsigned long *taints)
> +{
> +	FILE *f;
> +
> +	*taints = 0;
> +
> +	f = fopen("/proc/sys/kernel/tainted", "r");
> +	if (f) {
> +		fscanf(f, "%lu", taints);
> +		fclose(f);
> +	}
> +
> +	return is_tainted(*taints);
> +}
> diff --git a/lib/igt_taints.h b/lib/igt_taints.h
> new file mode 100644
> index 000000000..be4195c5a
> --- /dev/null
> +++ b/lib/igt_taints.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#ifndef __IGT_TAINTS_H__
> +#define __IGT_TAINTS_H__
> +
> +unsigned long igt_kernel_tainted(unsigned long *taints);
> +const char *igt_explain_taints(unsigned long *taints);
> +
> +unsigned long igt_bad_taints(void);
> +
> +static inline unsigned long is_tainted(unsigned long taints)
> +{
> +	return taints & igt_bad_taints();
> +}
> +
> +#endif /* __IGT_TAINTS_H__ */
> diff --git a/lib/meson.build b/lib/meson.build
> index 540facb24..3abc42cb3 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -27,6 +27,7 @@ lib_sources = [
>  	'igt_syncobj.c',
>  	'igt_sysfs.c',
>  	'igt_sysrq.c',
> +	'igt_taints.c',
>  	'igt_thread.c',
>  	'igt_vec.c',
>  	'igt_vgem.c',
> diff --git a/runner/executor.c b/runner/executor.c
> index faf272d85..93db8bb36 100644
> --- a/runner/executor.c
> +++ b/runner/executor.c
> @@ -24,6 +24,7 @@
>  
>  #include "igt_aux.h"
>  #include "igt_core.h"
> +#include "igt_taints.h"
>  #include "executor.h"
>  #include "output_strings.h"
>  
> @@ -307,70 +308,23 @@ static char *handle_lockdep(void)
>  	return NULL;
>  }
>  
> -/* see Linux's include/linux/kernel.h */
> -static const struct {
> -	unsigned long bit;
> -	const char *explanation;
> -} abort_taints[] = {
> -  {(1 << 5), "TAINT_BAD_PAGE: Bad page reference or an unexpected page flags."},
> -  {(1 << 7), "TAINT_DIE: Kernel has died - BUG/OOPS."},
> -  {(1 << 9), "TAINT_WARN: WARN_ON has happened."},
> -  {0, 0}};
> -
> -static unsigned long bad_taints(void)
> -{
> -	static unsigned long __bad_taints;
> -
> -	if (!__bad_taints) {
> -		for (typeof(*abort_taints) *taint = abort_taints;
> -		     taint->bit;
> -		     taint++)
> -			__bad_taints |= taint->bit;
> -	}
> -
> -	return __bad_taints;
> -}
> -
> -static unsigned long is_tainted(unsigned long taints)
> -{
> -	return taints & bad_taints();
> -}
> -
> -static unsigned long tainted(unsigned long *taints)
> -{
> -	FILE *f;
> -
> -	*taints = 0;
> -
> -	f = fopen("/proc/sys/kernel/tainted", "r");
> -	if (f) {
> -		fscanf(f, "%lu", taints);
> -		fclose(f);
> -	}
> -
> -	return is_tainted(*taints);
> -}
> -
>  static char *handle_taint(void)
>  {
> -	unsigned long taints;
> +	unsigned long taints, bad;
> +	char *explain;
>  	char *reason;
>  
> -	if (!tainted(&taints))
> +	bad = igt_kernel_tainted(&taints);
> +	if (!bad)
>  		return NULL;
>  
> -	asprintf(&reason, "Kernel badly tainted (%#lx) (check dmesg for details):\n",
> -		 taints);
> -
> -	for (typeof(*abort_taints) *taint = abort_taints; taint->bit; taint++) {
> -		if (taint->bit & taints) {
> -			char *old_reason = reason;
> -			asprintf(&reason, "%s\t(%#lx) %s\n",
> -					old_reason,
> -					taint->bit,
> -					taint->explanation);
> -			free(old_reason);
> -		}
> +	asprintf(&reason, "Kernel badly tainted (%#lx, %#lx) (check dmesg for details):\n",
> +		 taints, bad);
> +
> +	while ((explain = igt_explain_taints(&bad))) {
> +		char *old_reason = reason;
> +		asprintf(&reason, "%s\t%s\n", old_reason, explain);
> +		free(old_reason);
>  	}
>  
>  	return reason;
> @@ -1142,7 +1096,8 @@ static int monitor_output(pid_t child,
>  			sigfd = -1; /* we are dying, no signal handling for now */
>  		}
>  
> -		timeout_reason = need_to_timeout(settings, killed, tainted(&taints),
> +		timeout_reason = need_to_timeout(settings, killed,
> +						 igt_kernel_tainted(&taints),
>  						 igt_time_elapsed(&time_last_activity, &time_now),
>  						 igt_time_elapsed(&time_last_subtest, &time_now),
>  						 igt_time_elapsed(&time_killed, &time_now),
> -- 
> 2.30.0
> 
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  reply	other threads:[~2021-01-08 13:30 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-07 10:43 [igt-dev] [PATCH i-g-t 1/2] lib: Process kernel taints Chris Wilson
2021-01-07 10:43 ` [igt-dev] [PATCH i-g-t 2/2] lib/kmod: Check for kernel taints before/after selftests Chris Wilson
2021-01-08 12:28   ` Petri Latvala
2021-01-07 15:34 ` [igt-dev] ✓ Fi.CI.BAT: success for series starting with [i-g-t,1/2] lib: Process kernel taints Patchwork
2021-01-07 20:12 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
2021-01-08 12:26 ` [igt-dev] [PATCH i-g-t 1/2] " Petri Latvala
2021-01-08 13:01 ` [igt-dev] [PATCH i-g-t] " Chris Wilson
2021-01-08 13:30   ` Petri Latvala [this message]
2021-01-08 13:45 ` [igt-dev] ✗ Fi.CI.BAT: failure for series starting with [i-g-t] lib: Process kernel taints (rev2) Patchwork

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=20210108133013.GU7444@platvala-desk.ger.corp.intel.com \
    --to=petri.latvala@intel.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=igt-dev@lists.freedesktop.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.