diff options
author | Dave Jiang <dave.jiang@intel.com> | 2018-07-27 09:04:17 -0700 |
---|---|---|
committer | Dave Jiang <dave.jiang@intel.com> | 2018-07-27 15:28:28 -0700 |
commit | cc3d3458d46f702b1d118fca8647dc9157887d9b (patch) | |
tree | aca054c0c2a0a526462fbb233b977b7af1037269 | |
parent | 1e687220ef2d95a582e13d8de79932bfe32fdfa8 (diff) | |
download | linux-cc3d3458d46f702b1d118fca8647dc9157887d9b.tar.bz2 |
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.c | 12 | ||||
-rw-r--r-- | drivers/acpi/nfit/nfit.h | 1 |
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, |