Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17b3a894 authored by Stepan Moskovchenko's avatar Stepan Moskovchenko Committed by Murali Nalajala
Browse files

edac: Allow panic on correctable errors (CE)



Add an EDAC device flag and associated sysfs entries to
allow an EDAC driver to be configured to panic the kernel
if a correctable error is detected. Though correctable
errors (by definition) have no adverse system effects,
a panic may still be useful, since a correctable error may
be indicative of a marginal system state.

Change-Id: I98921469254aa7b999979c1c7d9186286f982a0c
Signed-off-by: default avatarStepan Moskovchenko <stepanm@codeaurora.org>
Signed-off-by: default avatarVenkata Narendra Kumar Gutta <vnkgutta@codeaurora.org>
[mnalajal@codeaurora.org: Make panic_on_ce as a feature
 to not to break the ABI compatability]
Signed-off-by: default avatarMurali Nalajala <mnalajal@codeaurora.org>
parent 31e5ae30
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -481,6 +481,17 @@ config EDAC_TI
	  Support for error detection and correction on the
          TI SoCs.

config EDAC_PANIC_ON_CE
	depends on EDAC
	bool "Panic on correctable errors"
	help
	  Forcibly cause a kernel panic if an correctable error (CE) is
	  detected, even though the error is (by definition) correctable and
	  would otherwise result in no adverse system effects. This feature reduce
	  debugging times on hardware which may be operating at voltages or
	  frequencies outside normal specification.
	  For production builds, you should say 'N' here.

config EDAC_QCOM
	tristate "QCOM EDAC Controller"
	depends on ARCH_QCOM && QCOM_LLCC
+15 −0
Original line number Diff line number Diff line
@@ -549,6 +549,14 @@ static inline int edac_device_get_log_ue(struct edac_device_ctl_info *edac_dev)
	return edac_dev->log_ue;
}

#ifdef CONFIG_EDAC_PANIC_ON_CE
static inline int edac_device_get_panic_on_ce(struct edac_device_ctl_info
					*edac_dev)
{
	return edac_dev->panic_on_ce;
}
#endif

static inline int edac_device_get_panic_on_ue(struct edac_device_ctl_info
					*edac_dev)
{
@@ -594,6 +602,13 @@ void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev,
				"CE: %s instance: %s block: %s '%s'\n",
				edac_dev->ctl_name, instance->name,
				block ? block->name : "N/A", msg);

#ifdef CONFIG_EDAC_PANIC_ON_CE
	if (edac_device_get_panic_on_ce(edac_dev))
		panic("EDAC %s: CE instance: %s block %s '%s'\n",
			edac_dev->ctl_name, instance->name,
			block ? block->name : "N/A", msg);
#endif
}
EXPORT_SYMBOL_GPL(edac_device_handle_ce);

+3 −0
Original line number Diff line number Diff line
@@ -159,6 +159,9 @@ struct edac_device_ctl_info {
	/* Per instance controls for this edac_device */
	int log_ue;		/* boolean for logging UEs */
	int log_ce;		/* boolean for logging CEs */
#ifdef CONFIG_EDAC_PANIC_ON_CE
	int panic_on_ce;	/* boolean for panic'ing on an CE */
#endif
	int panic_on_ue;	/* boolean for panic'ing on an UE */
	unsigned poll_msec;	/* number of milliseconds to poll interval */
	unsigned long delay;	/* number of jiffies for poll_msec */
+34 −0
Original line number Diff line number Diff line
@@ -62,6 +62,15 @@ static ssize_t edac_device_ctl_log_ce_store(struct edac_device_ctl_info
	return count;
}

#ifdef CONFIG_EDAC_PANIC_ON_CE
/* 'panic_on_ce' */
static ssize_t edac_device_ctl_panic_on_ce_show(struct edac_device_ctl_info
						*ctl_info, char *data)
{
	return snprintf(data, PAGE_SIZE, "%u\n", ctl_info->panic_on_ce);
}
#endif

/* 'panic_on_ue' */
static ssize_t edac_device_ctl_panic_on_ue_show(struct edac_device_ctl_info
						*ctl_info, char *data)
@@ -69,6 +78,23 @@ static ssize_t edac_device_ctl_panic_on_ue_show(struct edac_device_ctl_info
	return sprintf(data, "%u\n", ctl_info->panic_on_ue);
}

#ifdef CONFIG_EDAC_PANIC_ON_CE
static ssize_t edac_device_ctl_panic_on_ce_store(struct edac_device_ctl_info
						 *ctl_info, const char *data,
						 size_t count)
{
	unsigned long val;

	/* if parameter is zero, turn off flag, if non-zero turn on flag */
	if (kstrtoul(data, 0, &val) < 0)
		return -EINVAL;

	ctl_info->panic_on_ce = !!val;

	return count;
}
#endif

static ssize_t edac_device_ctl_panic_on_ue_store(struct edac_device_ctl_info
						 *ctl_info, const char *data,
						 size_t count)
@@ -156,6 +182,11 @@ CTL_INFO_ATTR(log_ue, S_IRUGO | S_IWUSR,
	edac_device_ctl_log_ue_show, edac_device_ctl_log_ue_store);
CTL_INFO_ATTR(log_ce, S_IRUGO | S_IWUSR,
	edac_device_ctl_log_ce_show, edac_device_ctl_log_ce_store);
#ifdef CONFIG_EDAC_PANIC_ON_CE
CTL_INFO_ATTR(panic_on_ce, 0644,
	edac_device_ctl_panic_on_ce_show,
	edac_device_ctl_panic_on_ce_store);
#endif
CTL_INFO_ATTR(panic_on_ue, S_IRUGO | S_IWUSR,
	edac_device_ctl_panic_on_ue_show,
	edac_device_ctl_panic_on_ue_store);
@@ -164,6 +195,9 @@ CTL_INFO_ATTR(poll_msec, S_IRUGO | S_IWUSR,

/* Base Attributes of the EDAC_DEVICE ECC object */
static struct ctl_info_attribute *device_ctrl_attr[] = {
#ifdef CONFIG_EDAC_PANIC_ON_CE
	&attr_ctl_info_panic_on_ce,
#endif
	&attr_ctl_info_panic_on_ue,
	&attr_ctl_info_log_ue,
	&attr_ctl_info_log_ce,