summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2018-07-27 19:04:17 +0300
committerDave Jiang <dave.jiang@intel.com>2018-07-28 01:28:28 +0300
commitcc3d3458d46f702b1d118fca8647dc9157887d9b (patch)
treeaca054c0c2a0a526462fbb233b977b7af1037269
parent1e687220ef2d95a582e13d8de79932bfe32fdfa8 (diff)
downloadlinux-cc3d3458d46f702b1d118fca8647dc9157887d9b.tar.xz
acpi/nfit: queue issuing of ars when an uc error notification comes in
When the ACPI UC error notifier gets called and ARS_REQ bit is set with the passed in flag, we can receive -EBUSY if ARS_REQ bit is already set for the nfit_spa->ars_state. When that happens, the ARS request is dropped. That can potentially cause us to miss the unreported errors that the on going ARS request does not receive. Add an ARS_REQ_REDO state that will request short ARS upon ARS completion to grab any errors we missed. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
-rw-r--r--drivers/acpi/nfit/core.c12
-rw-r--r--drivers/acpi/nfit/nfit.h1
2 files changed, 10 insertions, 3 deletions
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 2be8373153ed..31f6325ab3b5 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2567,7 +2567,12 @@ static void ars_complete(struct acpi_nfit_desc *acpi_desc,
test_bit(ARS_SHORT, &nfit_spa->ars_state)
? "short" : "long");
clear_bit(ARS_SHORT, &nfit_spa->ars_state);
- set_bit(ARS_DONE, &nfit_spa->ars_state);
+ if (test_and_clear_bit(ARS_REQ_REDO, &nfit_spa->ars_state)) {
+ set_bit(ARS_SHORT, &nfit_spa->ars_state);
+ set_bit(ARS_REQ, &nfit_spa->ars_state);
+ dev_dbg(dev, "ARS: processing scrub request received while in progress\n");
+ } else
+ set_bit(ARS_DONE, &nfit_spa->ars_state);
}
static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc)
@@ -3242,9 +3247,10 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, unsigned long flags)
if (test_bit(ARS_FAILED, &nfit_spa->ars_state))
continue;
- if (test_and_set_bit(ARS_REQ, &nfit_spa->ars_state))
+ if (test_and_set_bit(ARS_REQ, &nfit_spa->ars_state)) {
busy++;
- else {
+ set_bit(ARS_REQ_REDO, &nfit_spa->ars_state);
+ } else {
if (test_bit(ARS_SHORT, &flags))
set_bit(ARS_SHORT, &nfit_spa->ars_state);
scheduled++;
diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
index 7d15856a739f..29466961426e 100644
--- a/drivers/acpi/nfit/nfit.h
+++ b/drivers/acpi/nfit/nfit.h
@@ -119,6 +119,7 @@ enum nfit_dimm_notifiers {
enum nfit_ars_state {
ARS_REQ,
+ ARS_REQ_REDO,
ARS_DONE,
ARS_SHORT,
ARS_FAILED,