On Sat, Nov 10, 2018 at 09:47:12AM -0800, Dan Williams wrote: > commit d3abaf43bab8d5b0a3c6b982100d9e2be96de4ad upstream. > > The Address Range Scrub implementation tried to skip running scrubs > against ranges that were already scrubbed by the BIOS. Unfortunately > that support also resulted in early scrub completions as evidenced by > this debug output from nfit_test: > > nd_region region9: ARS: range 1 short complete > nd_region region3: ARS: range 1 short complete > nd_region region4: ARS: range 2 ARS start (0) > nd_region region4: ARS: range 2 short complete > > ...i.e. completions without any indications that the scrub was started. > > This state of affairs was hard to see in the code due to the > proliferation of state bits and mistakenly trying to track done state > per-range when the completion is a global property of the bus. > > So, kill the four ARS state bits (ARS_REQ, ARS_REQ_REDO, ARS_DONE, and > ARS_SHORT), and replace them with just 2 request flags ARS_REQ_SHORT and > ARS_REQ_LONG. The implementation will still complete and reap the > results of BIOS initiated ARS, but it will not attempt to use that > information to affect the completion status of scrubbing the ranges from > a Linux perspective. > > Instead, try to synchronously run a short ARS per range at init time and > schedule a long scrub in the background. If ARS is busy with an ARS > request, schedule both a short and a long scrub for when ARS returns to > idle. This logic also satisfies the intent of what ARS_REQ_REDO was > trying to achieve. The new rule is that the REQ flag stays set until the > next successful ars_start() for that range. > > With the new policy that the REQ flags are not cleared until the next > start, the implementation no longer loses requests as can be seen from > the following log: > > nd_region region3: ARS: range 1 ARS start short (0) > nd_region region9: ARS: range 1 ARS start short (0) > nd_region region3: ARS: range 1 complete > nd_region region4: ARS: range 2 ARS start short (0) > nd_region region9: ARS: range 1 complete > nd_region region9: ARS: range 1 ARS start long (0) > nd_region region4: ARS: range 2 complete > nd_region region3: ARS: range 1 ARS start long (0) > nd_region region9: ARS: range 1 complete > nd_region region3: ARS: range 1 complete > nd_region region4: ARS: range 2 ARS start long (0) > nd_region region4: ARS: range 2 complete > > ...note that the nfit_test emulated driver provides 2 buses, that is why > some of the range indices are duplicated. Notice that each range > now successfully completes a short and long scrub. > > Cc: <stable@xxxxxxxxxxxxxxx> > Fixes: 14c73f997a5e ("nfit, address-range-scrub: introduce nfit_spa->ars_state") > Fixes: cc3d3458d46f ("acpi/nfit: queue issuing of ars when an uc error...") > Reported-by: Jacek Zloch <jacek.zloch@xxxxxxxxx> > Reported-by: Krzysztof Rusocki <krzysztof.rusocki@xxxxxxxxx> > Reviewed-by: Dave Jiang <dave.jiang@xxxxxxxxx> > Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx> > --- > drivers/acpi/nfit/core.c | 163 +++++++++++++++++++++++++++------------------- > drivers/acpi/nfit/nfit.h | 9 +-- > 2 files changed, 101 insertions(+), 71 deletions(-) thanks, now queued up. greg k-h