[PATCH 03/12] PCI/ACPI: Add aux power grant notifier

Gupta, Anshuman anshuman.gupta at intel.com
Thu Apr 3 07:56:56 UTC 2025



> -----Original Message-----
> From: Bjorn Helgaas <helgaas at kernel.org>
> Sent: Wednesday, April 2, 2025 1:44 AM
> To: Gupta, Anshuman <anshuman.gupta at intel.com>
> Cc: intel-xe at lists.freedesktop.org; linux-acpi at vger.kernel.org; linux-
> pci at vger.kernel.org; rafael at kernel.org; lenb at kernel.org;
> bhelgaas at google.com; ilpo.jarvinen at linux.intel.com; De Marchi, Lucas
> <lucas.demarchi at intel.com>; Vivi, Rodrigo <rodrigo.vivi at intel.com>; Nilawar,
> Badal <badal.nilawar at intel.com>; Gupta, Varun <varun.gupta at intel.com>;
> ville.syrjala at linux.intel.com; Shankar, Uma <uma.shankar at intel.com>
> Subject: Re: [PATCH 03/12] PCI/ACPI: Add aux power grant notifier
> 
> On Tue, Apr 01, 2025 at 09:02:16PM +0530, Anshuman Gupta wrote:
> > Adding a notifier to notify all PCIe child devices about the block
> > main power removal. It is needed because theoretically multiple PCIe
> > Endpoint devices on same Root Port can request for AUX power and _DSM
> > method can return with 80000000h signifies that the hierarchy
> > connected via the slot cannot support main power removal when in
> > D3Cold.
> 
> I wish the spec used different language here.  "D3cold" *means* "main power
> is removed" (PCIe r6.0, sec 5.3.1.4.2), so it doesn't make sense to say that
> "the slot cannot support main power removal when in D3cold".  If a device is
> in D3cold, its main power has been removed by definition.
> 
> I suppose the spec is trying to say if the driver has called this _DSM with
> 80000000h, it means the platform must not remove main power from the
> device while the system is in S0?  Is that what you think it means?
Thanks for review.
what I understand here, S0 term essentially means here PCIe Runtime PM or s2idle 
(both refers system is S0 state). AFAIU during both Runtime PM and s2ilde path 
Root Port can transition  to D3Cold if it support _PR3. 
I observed Root Port either have D0 or D3Cold state.
/sys/bus/pci0/devices/$root_port_bdf/firmware_node/real_power_state

Driver can disable the D3cold by pci_d3cold_disable(), so I wonder there is no use
case driver calling _DSM 0xa with 80000000h.  
PCIe specs shall be simplified by removal of value 80000000h from _DSM 0xa Arg.
> 
> The 2h return value description says it "indicates that the platform will not
> remove main power from the slot while the system is in S0,"
> so I guess that must be it.
> 
> In this series, pci_acpi_aux_power_setup() only supplies a 16-bit
> aux_pwr_limit value, so the driver cannot *request* that the platform not
> remove main power.
Yeah but that value Xe driver received from GPU firmware.
> 
> So I guess the only scenario where the _DSM returns 80000000h is when the
> platform itself or other devices prevent the removal of main power.  And the
> point of the notifier is to tell devices that their main power will never be
> removed while the system is in S0.  Is that right?
Yes the notifier will safeguard against the use case if some other PCIe device
calls _DSM 0xa with Arg3 Value of 80000000h or its request return with 0x2h.
> 
> > This may disrupt functionality of other child device.
> 
> What sort of disruption could happen?  I would think that if the _DSM returns
> 80000000h, it just means the device will not have main power removed, so it
> won't see that power state transition.  The only "disruption" would be that
> we're using more power.
Let's say during Xe Driver initialization BIOS firmware grants the Xe driver 
Aux power request successfully.
Xe driver will prepare to transition D3Cold state with VRAM Self Refresh.
VRAM Self Refresh relies on vram shall derive power from Aux power.
But later at any point if some other PCIe device under same root port 
Calls _DSM either with 080000000h or _DSM returns with 02h, will
Block the main power removal. But Xe driver is unaware of it can still
program the VRAM Self Refresh and that make VRAM to derive power 
from Aux and that will disrupt the GPU VRAM as there is no switch to Aux
Power.
Thanks,
Anshuman
> 
> > Let's notify all PCIe devices requested Aux power resource and Let
> > PCIe End Point driver handle it in its callback.
> 
> Wrap to fill 75 columns.
> 
> s/Adding/Add/
> s/Let's notify/Notify/
> s/and Let/and let/
> s/End Point/Endpoint/ (several places here and below)
> 
> > Signed-off-by: Anshuman Gupta <anshuman.gupta at intel.com>
> > ---
> >  drivers/pci/pci-acpi.c   | 34 +++++++++++++++++++++++++++++++---
> >  include/linux/pci-acpi.h | 13 +++++++++++++
> >  2 files changed, 44 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index
> > 04149f037664..d1ca1649e6e8 100644
> > --- a/drivers/pci/pci-acpi.c
> > +++ b/drivers/pci/pci-acpi.c
> > @@ -1421,6 +1421,32 @@ static void pci_acpi_optimize_delay(struct
> pci_dev *pdev,
> >  	ACPI_FREE(obj);
> >  }
> >
> > +static BLOCKING_NOTIFIER_HEAD(pci_acpi_aux_power_notify_list);
> > +
> > +/**
> > + * pci_acpi_register_aux_power_notifier - Register driver notifier
> > + * @nb: notifier block
> > + *
> > + * This function shall be called by PCIe End Point device requested
> > +the Aux
> > + * power resource in order to handle the any scenario gracefully when
> > +other
> > + * child PCIe devices Aux power request returns with No main power
> removal.
> > + * PCIe devices which register this notifier shall handle No main
> > +power
> > + * removal scenario accordingly.
> 
> This would actually be called by the *driver* (not by the device).
> 
> Reword in imperative mood if possible.
> 
> > + *
> > + * Return: Returns 0 on success and errno on failure.
> > + */
> > +int pci_acpi_register_aux_power_notifier(struct notifier_block *nb) {
> > +	return
> > +blocking_notifier_chain_register(&pci_acpi_aux_power_notify_list,
> > +nb); } EXPORT_SYMBOL_GPL(pci_acpi_register_aux_power_notifier);
> > +
> > +void pci_acpi_unregister_aux_power_notifier(struct notifier_block
> > +*nb) {
> > +	blocking_notifier_chain_unregister(&pci_acpi_aux_power_notify_list,
> > +nb); } EXPORT_SYMBOL_GPL(pci_acpi_unregister_aux_power_notifier);
> > +
> >  /**
> >   * pci_acpi_request_d3cold_aux_power - Request D3cold aux power via
> ACPI DSM
> >   * @dev: PCI device instance
> > @@ -1466,17 +1492,19 @@ int
> pci_acpi_request_d3cold_aux_power(struct pci_dev *dev, u32
> requested_power)
> >  	result = out_obj->integer.value;
> >
> >  	switch (result) {
> > -	case 0x0:
> > +	case ACPI_AUX_PW_DENIED:
> 
> Add these constants in the patch that adds the _DSM.  Then this patch will be
> just notifier-related code.
> 
> >  		dev_dbg(&dev->dev, "D3cold Aux Power %umW request
> denied\n",
> >  			requested_power);
> >  		break;
> > -	case 0x1:
> > +	case ACPI_AUX_PW_GRANTED:
> >  		dev_info(&dev->dev, "D3cold Aux Power request granted:
> %umW\n",
> >  			 requested_power);
> >  		ret = 0;
> >  		break;
> > -	case 0x2:
> > +	case ACPI_NO_MAIN_PW_REMOVAL:
> >  		dev_info(&dev->dev, "D3cold Aux Power: Main power won't
> be
> > removed\n");
> > +		blocking_notifier_call_chain(&pci_acpi_aux_power_notify_list,
> > +					     ACPI_NO_MAIN_PW_REMOVAL,
> dev);
> >  		ret = -EBUSY;
> >  		break;
> >  	default:
> > diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index
> > 4b7373f91a9a..793b979af98b 100644
> > --- a/include/linux/pci-acpi.h
> > +++ b/include/linux/pci-acpi.h
> > @@ -124,6 +124,10 @@ extern const guid_t pci_acpi_dsm_guid;
> >  #define DSM_PCI_D3COLD_AUX_POWER_LIMIT		0x0A
> >  #define DSM_PCI_PERST_ASSERTION_DELAY		0x0B
> >
> > +#define ACPI_AUX_PW_DENIED			0x0
> > +#define ACPI_AUX_PW_GRANTED			0x1
> > +#define ACPI_NO_MAIN_PW_REMOVAL			0x2
> > +
> >  #ifdef CONFIG_PCIE_EDR
> >  void pci_acpi_add_edr_notifier(struct pci_dev *pdev);  void
> > pci_acpi_remove_edr_notifier(struct pci_dev *pdev); @@ -134,12 +138,21
> > @@ static inline void pci_acpi_remove_edr_notifier(struct pci_dev
> > *pdev) { }
> >
> >  int pci_acpi_set_companion_lookup_hook(struct acpi_device
> > *(*func)(struct pci_dev *));  void
> > pci_acpi_clear_companion_lookup_hook(void);
> > +int pci_acpi_register_aux_power_notifier(struct notifier_block *nb);
> > +void pci_acpi_unregister_aux_power_notifier(struct notifier_block
> > +*nb);
> >  int pci_acpi_request_d3cold_aux_power(struct pci_dev *dev, u32
> > requested_power);  int pci_acpi_add_perst_assertion_delay(struct
> > pci_dev *dev, u32 delay_us);
> >
> >  #else	/* CONFIG_ACPI */
> >  static inline void acpi_pci_add_bus(struct pci_bus *bus) { }  static
> > inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
> > +int pci_acpi_register_aux_power_notifier(struct notifier_block *nb) {
> > +	return -EOPNOTSUPP;
> > +}
> > +
> > +void pci_acpi_unregister_aux_power_notifier(struct notifier_block
> > +*nb) { }
> > +
> >  int pci_acpi_request_d3cold_aux_power(struct pci_dev *dev, u32
> > requested_power)  {
> >  	return -EOPNOTSUPP;
> > --
> > 2.43.0
> >


More information about the Intel-xe mailing list