diff mbox

[5/6] acpi: change memory allocations to GFP_NOIO

Message ID 20170714221148.11232-6-vishal.l.verma@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Verma, Vishal L July 14, 2017, 10:11 p.m. UTC
With the ACPI NFIT 'DSM' methods, acpi can be called from IO paths.
Specifically, the DSM to clear media errors is called during writes, so
that we can provide a writes-fix-errors model.

However it is easy to imagine a scenario like:
 - write through the nvdimm driver
 - acpi allocation
 - writeback, causes more IO through the nvdimm driver
 - deadlock

Making the acpi allocations GPF_NOIO would ensure that it doesn't
trigger writeback, and avoids the above deadlock.

Cc: <linux-acpi@vger.kernel.org>
Cc: <linux-nvdimm@lists.01.org>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 include/acpi/platform/aclinuxex.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Dan Williams July 15, 2017, 5:26 a.m. UTC | #1
[ adding Bob ]

On Fri, Jul 14, 2017 at 3:11 PM, Vishal Verma <vishal.l.verma@intel.com> wrote:
> With the ACPI NFIT 'DSM' methods, acpi can be called from IO paths.
> Specifically, the DSM to clear media errors is called during writes, so
> that we can provide a writes-fix-errors model.
>
> However it is easy to imagine a scenario like:
>  - write through the nvdimm driver
>  - acpi allocation
>  - writeback, causes more IO through the nvdimm driver
>  - deadlock
>
> Making the acpi allocations GPF_NOIO would ensure that it doesn't
> trigger writeback, and avoids the above deadlock.

Another option would be to custom code an acpi_ars_clear_error()
routine that manages to issue the proper DSM without needing to
perform any memory allocations, but this will have implications for
the common ACPICA code.
Rafael J. Wysocki July 15, 2017, 12:45 p.m. UTC | #2
On Friday, July 14, 2017 10:26:42 PM Dan Williams wrote:
> [ adding Bob ]
> 
> On Fri, Jul 14, 2017 at 3:11 PM, Vishal Verma <vishal.l.verma@intel.com> wrote:
> > With the ACPI NFIT 'DSM' methods, acpi can be called from IO paths.
> > Specifically, the DSM to clear media errors is called during writes, so
> > that we can provide a writes-fix-errors model.
> >
> > However it is easy to imagine a scenario like:
> >  - write through the nvdimm driver
> >  - acpi allocation
> >  - writeback, causes more IO through the nvdimm driver
> >  - deadlock
> >
> > Making the acpi allocations GPF_NOIO would ensure that it doesn't
> > trigger writeback, and avoids the above deadlock.

Well, no.

The above is not a good enough reason to switch the entire subsystem over to
using GPF_NOIO wholesale, especially on systems that don't care about NFIT and
the related things (and that's the majority of systems shipping today AFAICS let
alone the systems already in production).

If that's one of *multiple* reasons to do the switch-over, we can talk about
that, but otherwise it just looks like an attempt to cut corners.

> Another option would be to custom code an acpi_ars_clear_error()
> routine that manages to issue the proper DSM without needing to
> perform any memory allocations, but this will have implications for
> the common ACPICA code.

But isn't that the *right* way to address the problem at hand?

I guess any OS using ACPICA will run into this problem sooner or later, so it
would not be unreasonable to request ACPICA modifications to address it IMO.

Thanks,
Rafael
diff mbox

Patch

diff --git a/include/acpi/platform/aclinuxex.h b/include/acpi/platform/aclinuxex.h
index efdff52..9bd54ec 100644
--- a/include/acpi/platform/aclinuxex.h
+++ b/include/acpi/platform/aclinuxex.h
@@ -83,12 +83,12 @@  acpi_status acpi_os_terminate(void);
  */
 static inline void *acpi_os_allocate(acpi_size size)
 {
-	return kmalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL);
+	return kmalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_NOIO);
 }
 
 static inline void *acpi_os_allocate_zeroed(acpi_size size)
 {
-	return kzalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL);
+	return kzalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_NOIO);
 }
 
 static inline void acpi_os_free(void *memory)
@@ -99,7 +99,7 @@  static inline void acpi_os_free(void *memory)
 static inline void *acpi_os_acquire_object(acpi_cache_t * cache)
 {
 	return kmem_cache_zalloc(cache,
-				 irqs_disabled()? GFP_ATOMIC : GFP_KERNEL);
+				 irqs_disabled()? GFP_ATOMIC : GFP_NOIO);
 }
 
 static inline acpi_thread_id acpi_os_get_thread_id(void)