From: Peter Wu <peter-VTkQYDcBqhK7DlmcbJSQ7g@public.gmane.org>
To: Emil Velikov <emil.l.velikov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ML nouveau
<nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org>,
ML dri-devel
<dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org>,
Bjorn Helgaas <helgaas-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Dave Airlie <airlied-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
Mika Westerberg
<mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Subject: Re: [PATCH 4/4] drm/nouveau/acpi: fix lockup with PCIe runtime PM
Date: Fri, 27 May 2016 23:31:23 +0200 [thread overview]
Message-ID: <20160527213123.GB1777@al> (raw)
In-Reply-To: <CACvgo514AB=rkRGWrwmPHTX=hhEF8Jhzdg1hQkX1_C4A_zYkzg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Fri, May 27, 2016 at 02:01:39PM +0100, Emil Velikov wrote:
> Hi Peter,
>
> On 24 May 2016 at 23:53, Peter Wu <peter@lekensteyn.nl> wrote:
> > Since "PCI: Add runtime PM support for PCIe ports", the parent PCIe port
> > can be runtime-suspended which disables power resources via ACPI. This
> > is incompatible with DSM, resulting in a GPU device which is still in D3
> > and locks up the kernel on resume.
> >
> > Mirror the behavior of Windows 8 and newer[1] (as observed via an AMLi
> > debugger trace) and stop using the DSM functions for D3cold when power
> > resources are available on the parent PCIe port.
> >
> > [1]: https://msdn.microsoft.com/windows/hardware/drivers/bringup/firmware-requirements-for-d3cold
> >
> > Signed-off-by: Peter Wu <peter@lekensteyn.nl>
> > ---
> > drivers/gpu/drm/nouveau/nouveau_acpi.c | 34 ++++++++++++++++++++++++++++++----
> > 1 file changed, 30 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
> > index df9f73e..e469df7 100644
> > --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
> > +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
> > @@ -46,6 +46,7 @@ static struct nouveau_dsm_priv {
> > bool dsm_detected;
> > bool optimus_detected;
> > bool optimus_flags_detected;
> > + bool optimus_skip_dsm;
> > acpi_handle dhandle;
> > acpi_handle rom_handle;
> > } nouveau_dsm_priv;
> > @@ -212,8 +213,26 @@ static const struct vga_switcheroo_handler nouveau_dsm_handler = {
> > .get_client_id = nouveau_dsm_get_client_id,
> > };
> >
> > +/* Firmware supporting Windows 8 or later do not use _DSM to put the device into
> > + * D3cold, they instead rely on disabling power resources on the parent. */
> > +static bool nouveau_pr3_present(struct pci_dev *pdev)
> > +{
> > + struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
> > + struct acpi_device *ad;
> > +
> > + if (!parent_pdev)
> > + return false;
> > +
> > + ad = ACPI_COMPANION(&parent_pdev->dev);
> > + if (!ad)
> > + return false;
> > +
> > + return ad->power.flags.power_resources;
> > +}
> > +
> > static void nouveau_dsm_pci_probe(struct pci_dev *pdev, bool *has_mux,
> > - bool *has_opt, bool *has_opt_flags)
> > + bool *has_opt, bool *has_opt_flags,
> > + bool *has_power_resources)
> > {
> > acpi_handle dhandle;
> > bool supports_mux;
> > @@ -238,6 +257,7 @@ static void nouveau_dsm_pci_probe(struct pci_dev *pdev, bool *has_mux,
> > *has_mux = supports_mux;
> > *has_opt = !!optimus_funcs;
> > *has_opt_flags = optimus_funcs & (1 << NOUVEAU_DSM_OPTIMUS_FLAGS);
> > + *has_power_resources = false;
> >
> > if (optimus_funcs) {
> > uint32_t result;
> > @@ -247,6 +267,8 @@ static void nouveau_dsm_pci_probe(struct pci_dev *pdev, bool *has_mux,
> > (result & OPTIMUS_ENABLED) ? "enabled" : "disabled",
> > (result & OPTIMUS_DYNAMIC_PWR_CAP) ? "dynamic power, " : "",
> > (result & OPTIMUS_HDA_CODEC_MASK) ? "hda bios codec supported" : "");
> > +
> > + *has_power_resources = nouveau_pr3_present(pdev);
> > }
> > }
> >
> > @@ -258,6 +280,7 @@ static bool nouveau_dsm_detect(void)
> > bool has_mux = false;
> > bool has_optimus = false;
> > bool has_optimus_flags = false;
> > + bool has_power_resources = false;
> > int vga_count = 0;
> > bool guid_valid;
> > bool ret = false;
> > @@ -273,14 +296,14 @@ static bool nouveau_dsm_detect(void)
> > vga_count++;
> >
> > nouveau_dsm_pci_probe(pdev, &has_mux, &has_optimus,
> > - &has_optimus_flags);
> > + &has_optimus_flags, &has_power_resources);
> > }
> >
> > while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_3D << 8, pdev)) != NULL) {
> > vga_count++;
> >
> > nouveau_dsm_pci_probe(pdev, &has_mux, &has_optimus,
> > - &has_optimus_flags);
> > + &has_optimus_flags, &has_power_resources);
> > }
> >
> This and earlier patch break things in a subtle way.
>
> Namely: upon the second (and any later) call into the
> nouveau_dsm_pci_probe() function, the had_foo flags are reset. Thus
> only the specifics of the _final_ device are being used (at a later
> stage). IMHO one should change that to "_any_ device", which will
> match the original code and the actual intent further down in the
> file.
The flags are only reset if any of the MUX or Optimus handles are found.
If both are missing, the flags are not overridden. This is from patch 1:
+ /* Does not look like a Nvidia device. */
+ if (!supports_mux && !supports_opt)
+ return;
The reason why later calls override early ones is because some Optimus
laptops have the _DSM method on both the Intel GPU (00:02.0) and the
Nvidia one (01:00.0).
The previous detection method would fail in this scenario:
1. One device reports support for X and Y (has_x = 1, has_y = 1). Write
ACPI handle A to nouveau_dsm_priv.dhandle.
2. Another device reports support for X only (has_x = 1). Write
ACPI handle B to nouveau_dsm_priv.dhandle.
3. End result: has_x = 1, has_y = 1, dhandle = B. But ACPI handle B
does not really support Y!
This is theoretical since I don't think that such firmware occurs in
practice, but then imo it would be better to enforce in code that the
case cannot occur (as is done in patch 1). Unless the MUX DSM has some
magic I am not aware of.
--
Kind regards,
Peter Wu
https://lekensteyn.nl
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau
next prev parent reply other threads:[~2016-05-27 21:31 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-24 22:52 [PATCH 0/4] nouveau fixes for RPM/Optimus-related hangs Peter Wu
[not found] ` <1464130381-4797-1-git-send-email-peter-VTkQYDcBqhK7DlmcbJSQ7g@public.gmane.org>
2016-05-24 22:53 ` [PATCH 4/4] drm/nouveau/acpi: fix lockup with PCIe runtime PM Peter Wu
2016-05-25 13:55 ` Mika Westerberg
[not found] ` <20160525135535.GN1789-3PARRvDOhMZrdx17CPfAsdBPR1lH4CV8@public.gmane.org>
2016-05-27 11:10 ` Peter Wu
2016-05-27 11:55 ` [Nouveau] " Hans de Goede
2016-05-30 9:57 ` Mika Westerberg
[not found] ` <20160530095709.GK1789-3PARRvDOhMZrdx17CPfAsdBPR1lH4CV8@public.gmane.org>
2016-05-30 12:20 ` Peter Wu
2016-05-30 13:09 ` Mika Westerberg
[not found] ` <20160530130909.GA1743-3PARRvDOhMZrdx17CPfAsdBPR1lH4CV8@public.gmane.org>
2016-05-30 16:13 ` Peter Wu
2016-05-31 8:43 ` Mika Westerberg
[not found] ` <20160531084356.GH1743-3PARRvDOhMZrdx17CPfAsdBPR1lH4CV8@public.gmane.org>
2016-05-31 11:02 ` Peter Wu
2016-06-01 9:28 ` Mika Westerberg
[not found] ` <20160601092847.GQ1743-3PARRvDOhMZrdx17CPfAsdBPR1lH4CV8@public.gmane.org>
2016-06-01 17:21 ` Peter Wu
2016-05-31 12:20 ` Lukas Wunner
[not found] ` <20160531122026.GA14129-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
2016-06-01 16:51 ` Peter Wu
2016-06-01 17:40 ` [Nouveau] " Lukas Wunner
2016-05-27 13:01 ` Emil Velikov
[not found] ` <CACvgo514AB=rkRGWrwmPHTX=hhEF8Jhzdg1hQkX1_C4A_zYkzg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-05-27 21:31 ` Peter Wu [this message]
2016-05-28 12:27 ` Lukas Wunner
2016-05-30 10:48 ` [Nouveau] " Emil Velikov
[not found] ` <CACvgo50db1KEuH3yZ75K-MtCeKAsQKXJbQQxiXm+82qkjZsvDA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-05-30 11:23 ` Peter Wu
2016-05-30 12:41 ` Emil Velikov
2016-05-25 9:08 ` [Nouveau] [PATCH 0/4] nouveau fixes for RPM/Optimus-related hangs Hans de Goede
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=20160527213123.GB1777@al \
--to=peter-vtkqydcbqhk7dlmcbjsq7g@public.gmane.org \
--cc=airlied-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=emil.l.velikov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=helgaas-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org \
--cc=nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).