On 10/15/2018 02:00 PM, Dan Williams wrote: > In addition to not allowing ARS start while the background thread is > actively running, prevent ARS start while any scrub request is pending. > > This aligns the window for ARS start submission with the status of ARS > reported via sysfs. Previously userspace could sneak its own ARS start > requests in while sysfs reported -EBUSY. > > Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx> Reviewed-by: Dave Jiang <dave.jiang@xxxxxxxxx> > --- > Changes in v2: > * Require acpi_desc->scrub_spa to be NULL to prevent requests being sent > while a scrub is active, or whose results are waiting to be reaped. > > drivers/acpi/nfit/core.c | 19 ++++++++++++++----- > 1 file changed, 14 insertions(+), 5 deletions(-) > > diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c > index f7efcd9843e0..253c0e85554d 100644 > --- a/drivers/acpi/nfit/core.c > +++ b/drivers/acpi/nfit/core.c > @@ -3364,6 +3364,8 @@ static int __acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc, > struct nvdimm *nvdimm, unsigned int cmd) > { > struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc); > + struct nfit_spa *nfit_spa; > + int rc = 0; > > if (nvdimm) > return 0; > @@ -3373,13 +3375,20 @@ static int __acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc, > /* > * The kernel and userspace may race to initiate a scrub, but > * the scrub thread is prepared to lose that initial race. It > - * just needs guarantees that any ars it initiates are not > - * interrupted by any intervening start reqeusts from userspace. > + * just needs guarantees that any ARS it initiates are not > + * interrupted by any intervening start requests from userspace. > */ > - if (work_busy(&acpi_desc->dwork.work)) > - return -EBUSY; > + mutex_lock(&acpi_desc->init_mutex); > + list_for_each_entry(nfit_spa, &acpi_desc->spas, list) > + if (acpi_desc->scrub_spa > + || test_bit(ARS_REQ_SHORT, &nfit_spa->ars_state) > + || test_bit(ARS_REQ_LONG, &nfit_spa->ars_state)) { > + rc = -EBUSY; > + break; > + } > + mutex_unlock(&acpi_desc->init_mutex); > > - return 0; > + return rc; > } > > /* prevent security commands from being issued via ioctl */ >