Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp2038768imm; Mon, 16 Jul 2018 00:39:26 -0700 (PDT) X-Google-Smtp-Source: AAOMgpeupvI4pPv3M0bb8xkRviHwIXygHH2WtwElKC/6FEGNiv1wy9BJ2Vv9ZLsG+CumEm48kvjR X-Received: by 2002:a17:902:622:: with SMTP id 31-v6mr15590827plg.135.1531726766286; Mon, 16 Jul 2018 00:39:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531726766; cv=none; d=google.com; s=arc-20160816; b=XlpQt3LaS79LccCyDsWfB6/5l5ka8TGunUG4XFG1Oc6i0pyVx8Zrzk2GEDY+YrbY9e e1UsuWbae8SXhy6fJM8x0SHxtncAysO+Uf2Qv9zsvYaNuH9ty5eb559VYudhs6EFKc/l mpM/W97kIf7A1UR1GAsrv4r5Y/nTuaM+O5agr5m2L60myIuH3q+FYWVdMIQVdVEbTln5 VdlLchxpShBoA9cwIU9UXr3A/DvyMv7Tm6qjL1BacJYJLokdp845Q5Q30+6xWW1LMTBr eElPDtbWJN1FBRtyB6vsop71DyT/xh8bWZF2AoAVgDNAGuxgH4+YrqBp4sZ3bfIRWgYR 8GDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=28ycFDU4jzH5TpyA5a2Znnx3SOm/2KGo+wOKNKdAr/E=; b=AzR3aaq6K5Ojbjx8EjDw3VvnP6kWlQt9ehDLpAaCtZb1bOH5WH2MAH9O015KF25a9O dHF1g1WPbKvOx6CQX77/8LoAvFqVTMSEm1RHYfPcvtjm1yFs/5OTD97HRccLNqI+8M3r rvpQj+sUM2x1L6Rf6PHv3gEQE85ruyKXmSFFn8IOroC2BXNQkhqWtU8ndqAd7us0XWX3 PVFrma4p/0hFuR8fjLJ+oqWONBCfN7tChjnNu9IY9SIeaaz2xZroafZZ54sykdqpIv6J nS5XRjsiOzpe+5Y02vRPX3Zthl+az2vKmN+1cRpH+KwY4kttqqspLm+sHtuDf3tSfKEG gQbg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x1-v6si12589676pge.521.2018.07.16.00.39.11; Mon, 16 Jul 2018 00:39:26 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730810AbeGPIEH (ORCPT + 99 others); Mon, 16 Jul 2018 04:04:07 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:46842 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728460AbeGPIEH (ORCPT ); Mon, 16 Jul 2018 04:04:07 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 43AA9CA0; Mon, 16 Jul 2018 07:38:05 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Vishal Verma , Lukasz Dorau , Dan Williams Subject: [PATCH 4.17 42/67] acpi, nfit: Fix scrub idle detection Date: Mon, 16 Jul 2018 09:35:11 +0200 Message-Id: <20180716073449.832521288@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180716073443.294323458@linuxfoundation.org> References: <20180716073443.294323458@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.17-stable review patch. If anyone has any objections, please let me know. ------------------ From: Dan Williams commit 33cc2c9667561b224215e6dfb5bf98e8fa17914e upstream. The notification of scrub completion happens within the scrub workqueue. That can clearly race someone running scrub_show() and work_busy() before the workqueue has a chance to flush the recently completed work. Add a flag to reliably indicate the idle vs busy state. Without this change applications using poll(2) to wait for scrub-completion may falsely wakeup and read ARS as being busy even though the thread is going idle and then hang indefinitely. Fixes: bc6ba8085842 ("nfit, address-range-scrub: rework and simplify ARS...") Cc: Reported-by: Vishal Verma Tested-by: Vishal Verma Reported-by: Lukasz Dorau Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/nfit/core.c | 44 +++++++++++++++++++++++++++++++++----------- drivers/acpi/nfit/nfit.h | 1 + 2 files changed, 34 insertions(+), 11 deletions(-) --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -1272,7 +1272,7 @@ static ssize_t scrub_show(struct device mutex_lock(&acpi_desc->init_mutex); rc = sprintf(buf, "%d%s", acpi_desc->scrub_count, - work_busy(&acpi_desc->dwork.work) + acpi_desc->scrub_busy && !acpi_desc->cancel ? "+\n" : "\n"); mutex_unlock(&acpi_desc->init_mutex); } @@ -2949,6 +2949,32 @@ static unsigned int __acpi_nfit_scrub(st return 0; } +static void __sched_ars(struct acpi_nfit_desc *acpi_desc, unsigned int tmo) +{ + lockdep_assert_held(&acpi_desc->init_mutex); + + acpi_desc->scrub_busy = 1; + /* note this should only be set from within the workqueue */ + if (tmo) + acpi_desc->scrub_tmo = tmo; + queue_delayed_work(nfit_wq, &acpi_desc->dwork, tmo * HZ); +} + +static void sched_ars(struct acpi_nfit_desc *acpi_desc) +{ + __sched_ars(acpi_desc, 0); +} + +static void notify_ars_done(struct acpi_nfit_desc *acpi_desc) +{ + lockdep_assert_held(&acpi_desc->init_mutex); + + acpi_desc->scrub_busy = 0; + acpi_desc->scrub_count++; + if (acpi_desc->scrub_count_state) + sysfs_notify_dirent(acpi_desc->scrub_count_state); +} + static void acpi_nfit_scrub(struct work_struct *work) { struct acpi_nfit_desc *acpi_desc; @@ -2959,14 +2985,10 @@ static void acpi_nfit_scrub(struct work_ mutex_lock(&acpi_desc->init_mutex); query_rc = acpi_nfit_query_poison(acpi_desc); tmo = __acpi_nfit_scrub(acpi_desc, query_rc); - if (tmo) { - queue_delayed_work(nfit_wq, &acpi_desc->dwork, tmo * HZ); - acpi_desc->scrub_tmo = tmo; - } else { - acpi_desc->scrub_count++; - if (acpi_desc->scrub_count_state) - sysfs_notify_dirent(acpi_desc->scrub_count_state); - } + if (tmo) + __sched_ars(acpi_desc, tmo); + else + notify_ars_done(acpi_desc); memset(acpi_desc->ars_status, 0, acpi_desc->max_ars); mutex_unlock(&acpi_desc->init_mutex); } @@ -3047,7 +3069,7 @@ static int acpi_nfit_register_regions(st break; } - queue_delayed_work(nfit_wq, &acpi_desc->dwork, 0); + sched_ars(acpi_desc); return 0; } @@ -3249,7 +3271,7 @@ int acpi_nfit_ars_rescan(struct acpi_nfi } } if (scheduled) { - queue_delayed_work(nfit_wq, &acpi_desc->dwork, 0); + sched_ars(acpi_desc); dev_dbg(dev, "ars_scan triggered\n"); } mutex_unlock(&acpi_desc->init_mutex); --- a/drivers/acpi/nfit/nfit.h +++ b/drivers/acpi/nfit/nfit.h @@ -203,6 +203,7 @@ struct acpi_nfit_desc { unsigned int max_ars; unsigned int scrub_count; unsigned int scrub_mode; + unsigned int scrub_busy:1; unsigned int cancel:1; unsigned long dimm_cmd_force_en; unsigned long bus_cmd_force_en;