All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rafael@kernel.org>
To: Sinan Kaya <okaya@codeaurora.org>
Cc: ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
	Timur Tabi <timur@codeaurora.org>,
	"Rafael J. Wysocki" <rjw@rjwysocki.net>,
	linux-arm-msm@vger.kernel.org,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] ACPI / GED: unregister interrupts during shutdown
Date: Tue, 5 Dec 2017 23:18:44 +0100	[thread overview]
Message-ID: <CAJZ5v0jcFqG=Jd19ms7XQMR+rGfdKTEaN7SK91DPzBa=xcMY1w@mail.gmail.com> (raw)
In-Reply-To: <1512507705-2411-1-git-send-email-okaya@codeaurora.org>

On Tue, Dec 5, 2017 at 10:01 PM, Sinan Kaya <okaya@codeaurora.org> wrote:
> Some GED interrupts could be pending by the time we are doing a reboot.
>
> Even though GED driver uses devm_request_irq() to register the interrupt
> handler, the handler is not being freed on time during a shutdown since
> the driver is missing a shutdown callback.
>
> If the ACPI handler is no longer available, this causes an interrupt
> storm and delays shutdown.
>
> Register a shutdown callback and manually free the interrupts.
>
> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
> ---
>  drivers/acpi/evged.c | 36 +++++++++++++++++++++++++++++++++---
>  1 file changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/acpi/evged.c b/drivers/acpi/evged.c
> index 46f0603..dde50ea 100644
> --- a/drivers/acpi/evged.c
> +++ b/drivers/acpi/evged.c
> @@ -1,7 +1,7 @@
>  /*
>   * Generic Event Device for ACPI.
>   *
> - * Copyright (c) 2016, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.

Why are you changing this?

>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 and
> @@ -49,6 +49,11 @@
>
>  #define MODULE_NAME    "acpi-ged"
>
> +struct acpi_ged_device {
> +       struct device *dev;
> +       struct list_head event_list;
> +};
> +
>  struct acpi_ged_event {
>         struct list_head node;
>         struct device *dev;
> @@ -76,7 +81,8 @@ static acpi_status acpi_ged_request_interrupt(struct acpi_resource *ares,
>         unsigned int irq;
>         unsigned int gsi;
>         unsigned int irqflags = IRQF_ONESHOT;
> -       struct device *dev = context;
> +       struct acpi_ged_device *geddev = context;
> +       struct device *dev = geddev->dev;
>         acpi_handle handle = ACPI_HANDLE(dev);
>         acpi_handle evt_handle;
>         struct resource r;
> @@ -122,29 +128,53 @@ static acpi_status acpi_ged_request_interrupt(struct acpi_resource *ares,
>                 return AE_ERROR;
>         }
>
> +       dev_info(dev, "GED listening GSI %u @ IRQ %u\n", gsi, irq);

Why dev_info()?

> +       list_add_tail(&event->node, &geddev->event_list);
>         return AE_OK;
>  }
>
>  static int ged_probe(struct platform_device *pdev)
>  {
> +       struct acpi_ged_device *geddev;
>         acpi_status acpi_ret;
>
> +       geddev = devm_kzalloc(&pdev->dev, sizeof(*geddev), GFP_KERNEL);
> +       if (!geddev)
> +               return -ENOMEM;
> +
> +       geddev->dev = &pdev->dev;
> +       INIT_LIST_HEAD(&geddev->event_list);
>         acpi_ret = acpi_walk_resources(ACPI_HANDLE(&pdev->dev), "_CRS",
> -                                      acpi_ged_request_interrupt, &pdev->dev);
> +                                      acpi_ged_request_interrupt, geddev);
>         if (ACPI_FAILURE(acpi_ret)) {
>                 dev_err(&pdev->dev, "unable to parse the _CRS record\n");
>                 return -EINVAL;
>         }
> +       platform_set_drvdata(pdev, geddev);
>
>         return 0;
>  }
>
> +static void ged_remove(struct platform_device *pdev)
> +{
> +       struct acpi_ged_device *geddev = platform_get_drvdata(pdev);
> +       struct acpi_ged_event *event, *next;
> +
> +       list_for_each_entry_safe(event, next, &geddev->event_list, node) {
> +               devm_free_irq(geddev->dev, event->irq, event);
> +               list_del(&event->node);
> +               dev_info(geddev->dev, "GED releasing GSI %u @ IRQ %u\n",
> +                        event->gsi, event->irq);

dev_dbg() and that if you really need it.

> +       }
> +}
> +
>  static const struct acpi_device_id ged_acpi_ids[] = {
>         {"ACPI0013"},
>         {},
>  };
>
>  static struct platform_driver ged_driver = {
> +       .shutdown = ged_remove,

That ged_remove really should be called ged_shutdown.  It is confusing
as is, because there is a ->remove callback in the structure too.

>         .probe = ged_probe,
>         .driver = {
>                 .name = MODULE_NAME,
> --

Overall, it looks like we should just unbind the driver from all
devices on shutdown.

Thanks,
Rafael

WARNING: multiple messages have this Message-ID (diff)
From: rafael@kernel.org (Rafael J. Wysocki)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ACPI / GED: unregister interrupts during shutdown
Date: Tue, 5 Dec 2017 23:18:44 +0100	[thread overview]
Message-ID: <CAJZ5v0jcFqG=Jd19ms7XQMR+rGfdKTEaN7SK91DPzBa=xcMY1w@mail.gmail.com> (raw)
In-Reply-To: <1512507705-2411-1-git-send-email-okaya@codeaurora.org>

On Tue, Dec 5, 2017 at 10:01 PM, Sinan Kaya <okaya@codeaurora.org> wrote:
> Some GED interrupts could be pending by the time we are doing a reboot.
>
> Even though GED driver uses devm_request_irq() to register the interrupt
> handler, the handler is not being freed on time during a shutdown since
> the driver is missing a shutdown callback.
>
> If the ACPI handler is no longer available, this causes an interrupt
> storm and delays shutdown.
>
> Register a shutdown callback and manually free the interrupts.
>
> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
> ---
>  drivers/acpi/evged.c | 36 +++++++++++++++++++++++++++++++++---
>  1 file changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/acpi/evged.c b/drivers/acpi/evged.c
> index 46f0603..dde50ea 100644
> --- a/drivers/acpi/evged.c
> +++ b/drivers/acpi/evged.c
> @@ -1,7 +1,7 @@
>  /*
>   * Generic Event Device for ACPI.
>   *
> - * Copyright (c) 2016, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.

Why are you changing this?

>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 and
> @@ -49,6 +49,11 @@
>
>  #define MODULE_NAME    "acpi-ged"
>
> +struct acpi_ged_device {
> +       struct device *dev;
> +       struct list_head event_list;
> +};
> +
>  struct acpi_ged_event {
>         struct list_head node;
>         struct device *dev;
> @@ -76,7 +81,8 @@ static acpi_status acpi_ged_request_interrupt(struct acpi_resource *ares,
>         unsigned int irq;
>         unsigned int gsi;
>         unsigned int irqflags = IRQF_ONESHOT;
> -       struct device *dev = context;
> +       struct acpi_ged_device *geddev = context;
> +       struct device *dev = geddev->dev;
>         acpi_handle handle = ACPI_HANDLE(dev);
>         acpi_handle evt_handle;
>         struct resource r;
> @@ -122,29 +128,53 @@ static acpi_status acpi_ged_request_interrupt(struct acpi_resource *ares,
>                 return AE_ERROR;
>         }
>
> +       dev_info(dev, "GED listening GSI %u @ IRQ %u\n", gsi, irq);

Why dev_info()?

> +       list_add_tail(&event->node, &geddev->event_list);
>         return AE_OK;
>  }
>
>  static int ged_probe(struct platform_device *pdev)
>  {
> +       struct acpi_ged_device *geddev;
>         acpi_status acpi_ret;
>
> +       geddev = devm_kzalloc(&pdev->dev, sizeof(*geddev), GFP_KERNEL);
> +       if (!geddev)
> +               return -ENOMEM;
> +
> +       geddev->dev = &pdev->dev;
> +       INIT_LIST_HEAD(&geddev->event_list);
>         acpi_ret = acpi_walk_resources(ACPI_HANDLE(&pdev->dev), "_CRS",
> -                                      acpi_ged_request_interrupt, &pdev->dev);
> +                                      acpi_ged_request_interrupt, geddev);
>         if (ACPI_FAILURE(acpi_ret)) {
>                 dev_err(&pdev->dev, "unable to parse the _CRS record\n");
>                 return -EINVAL;
>         }
> +       platform_set_drvdata(pdev, geddev);
>
>         return 0;
>  }
>
> +static void ged_remove(struct platform_device *pdev)
> +{
> +       struct acpi_ged_device *geddev = platform_get_drvdata(pdev);
> +       struct acpi_ged_event *event, *next;
> +
> +       list_for_each_entry_safe(event, next, &geddev->event_list, node) {
> +               devm_free_irq(geddev->dev, event->irq, event);
> +               list_del(&event->node);
> +               dev_info(geddev->dev, "GED releasing GSI %u @ IRQ %u\n",
> +                        event->gsi, event->irq);

dev_dbg() and that if you really need it.

> +       }
> +}
> +
>  static const struct acpi_device_id ged_acpi_ids[] = {
>         {"ACPI0013"},
>         {},
>  };
>
>  static struct platform_driver ged_driver = {
> +       .shutdown = ged_remove,

That ged_remove really should be called ged_shutdown.  It is confusing
as is, because there is a ->remove callback in the structure too.

>         .probe = ged_probe,
>         .driver = {
>                 .name = MODULE_NAME,
> --

Overall, it looks like we should just unbind the driver from all
devices on shutdown.

Thanks,
Rafael

  reply	other threads:[~2017-12-05 22:18 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-05 21:01 [PATCH] ACPI / GED: unregister interrupts during shutdown Sinan Kaya
2017-12-05 21:01 ` Sinan Kaya
2017-12-05 22:18 ` Rafael J. Wysocki [this message]
2017-12-05 22:18   ` Rafael J. Wysocki
2017-12-05 22:18   ` Rafael J. Wysocki
2017-12-06 13:24   ` Sinan Kaya
2017-12-06 13:24     ` Sinan Kaya
2017-12-06 13:24     ` Sinan Kaya
2017-12-06 13:37     ` Rafael J. Wysocki
2017-12-06 13:37       ` Rafael J. Wysocki
2017-12-06 13:37       ` Rafael J. Wysocki
2017-12-06 14:57       ` Sinan Kaya
2017-12-06 14:57         ` Sinan Kaya
2017-12-06 14:57         ` Sinan Kaya
2017-12-06 16:11         ` Sinan Kaya
2017-12-06 16:11           ` Sinan Kaya
2017-12-06 16:11           ` Sinan Kaya
2017-12-06 16:41           ` Rafael J. Wysocki
2017-12-06 16:41             ` Rafael J. Wysocki
2017-12-06 16:41             ` Rafael J. Wysocki
2017-12-06 16:55             ` Sinan Kaya
2017-12-06 16:55               ` Sinan Kaya
2017-12-06 16:55               ` Sinan Kaya
2017-12-06 17:16               ` Rafael J. Wysocki
2017-12-06 17:16                 ` Rafael J. Wysocki
2017-12-06 17:16                 ` Rafael J. Wysocki
2017-12-06 23:19                 ` Rafael J. Wysocki
2017-12-06 23:19                   ` Rafael J. Wysocki
2017-12-06 23:19                   ` Rafael J. Wysocki
2017-12-07  8:29                   ` Greg Kroah-Hartman
2017-12-07  8:29                     ` Greg Kroah-Hartman
2017-12-07  8:29                     ` Greg Kroah-Hartman
2017-12-07 13:00                     ` Rafael J. Wysocki
2017-12-07 13:00                       ` Rafael J. Wysocki
2017-12-07 13:00                       ` Rafael J. Wysocki
2017-12-07 14:52                       ` Sinan Kaya
2017-12-07 14:52                         ` Sinan Kaya
2017-12-07 14:52                         ` Sinan Kaya
2017-12-07 17:10                         ` Rafael J. Wysocki
2017-12-07 17:10                           ` Rafael J. Wysocki
2017-12-07 17:10                           ` Rafael J. Wysocki
2017-12-07 17:18                           ` Sinan Kaya
2017-12-07 17:18                             ` Sinan Kaya
2017-12-07 17:18                             ` Sinan Kaya

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJZ5v0jcFqG=Jd19ms7XQMR+rGfdKTEaN7SK91DPzBa=xcMY1w@mail.gmail.com' \
    --to=rafael@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=okaya@codeaurora.org \
    --cc=rjw@rjwysocki.net \
    --cc=timur@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.