lkml.org 
[lkml]   [2021]   [Oct]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
Date
SubjectRe: [RFC PATCH v2 4/4] PCI/ASPM: Remove unncessary linked list from aspm.c
On Fri, Oct 1, 2021 at 1:00 AM Bjorn Helgaas <helgaas@kernel.org> wrote:
>
> On Wed, Sep 29, 2021 at 02:43:15AM +0200, Saheed O. Bolarinwa wrote:
> > From: "Bolarinwa O. Saheed" <refactormyself@gmail.com>
> >
> > aspm.c defines a linked list - `link_list` and stores each of
> > its node in struct pcie_link_state.sibling. This linked list
> > tracks devices for which the struct pcie_link_state object
> > was successfully created. It is used to loop through the list
> > for instance to set ASPM policy or update changes. However, it
> > is possible to access these devices via existing lists defined
> > inside pci.h
> >
> > This patch:
> > - removes link_list and struct pcie_link_state.sibling
> > - accesses child devices via struct pci_dev.bust_list
> > - accesses all PCI buses via pci_root_buses on struct pci_bus.node
>
> Again, I LOVE the way this is going. I depise this extra linked list.
>
> > Signed-off-by: Bolarinwa O. Saheed <refactormyself@gmail.com>
> > ---
> > drivers/pci/pcie/aspm.c | 39 +++++++++++++++++++++------------------
> > 1 file changed, 21 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
> > index 56d4fe7d50b5..4bef652dc63c 100644
> > --- a/drivers/pci/pcie/aspm.c
> > +++ b/drivers/pci/pcie/aspm.c
> > @@ -48,7 +48,6 @@ struct aspm_latency {
> >
> > struct pcie_link_state {
> > struct pci_dev *pdev; /* Upstream component of the Link */
> > - struct list_head sibling; /* node in link_list */
> >
> > /* ASPM state */
> > u32 aspm_support:7; /* Supported ASPM state */
> > @@ -76,7 +75,6 @@ struct pcie_link_state {
> > static int aspm_disabled, aspm_force;
> > static bool aspm_support_enabled = true;
> > static DEFINE_MUTEX(aspm_lock);
> > -static LIST_HEAD(link_list);
> >
> > #define POLICY_DEFAULT 0 /* BIOS default setting */
> > #define POLICY_PERFORMANCE 1 /* high performance */
> > @@ -880,10 +878,7 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
> > if (!link)
> > return NULL;
> >
> > - INIT_LIST_HEAD(&link->sibling);
> > link->pdev = pdev;
> > -
> > - list_add(&link->sibling, &link_list);
> > pdev->link_state = link;
> > return link;
> > }
> > @@ -970,24 +965,22 @@ static void pcie_update_aspm_capable(struct pcie_link_state *root)
> > {
> > struct pcie_link_state *link;
> > struct pci_dev *dev, *root_dev;
> > + struct pci_bus *rootbus = root->pdev->bus;
> >
> > /* Ensure it is the root device */
> > root_dev = pcie_get_root(root->pdev);
> > root = root_dev ? root_dev->link_state : NULL;
> >
> > - list_for_each_entry(link, &link_list, sibling) {
> > - dev = pcie_get_root(link->pdev);
> > - if (dev->link_state != root)
> > + list_for_each_entry(dev, &rootbus->devices, bus_list) {
> > + if (!dev->link_state)
> > continue;
> >
> > - link->aspm_capable = link->aspm_support;
> > + dev->link_state->aspm_capable = link->aspm_support;
> > }
> > - list_for_each_entry(link, &link_list, sibling) {
> > +
> > + list_for_each_entry(dev, &rootbus->devices, bus_list) {
> > struct pci_dev *child;
> > - struct pci_bus *linkbus = link->pdev->subordinate;
> > - dev = pcie_get_root(link->pdev);
> > - if (dev->link_state != root)
> > - continue;
> > + struct pci_bus *linkbus = dev->subordinate;
> >
> > list_for_each_entry(child, &linkbus->devices, bus_list) {
> > if ((pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT) &&
> > @@ -1024,7 +1017,6 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
> >
> > /* All functions are removed, so just disable ASPM for the link */
> > pcie_config_aspm_link(link, 0);
> > - list_del(&link->sibling);
> > /* Clock PM is for endpoint device */
> > free_link_state(link);
> >
> > @@ -1164,6 +1156,8 @@ static int pcie_aspm_set_policy(const char *val,
> > {
> > int i;
> > struct pcie_link_state *link;
> > + struct pci_bus *bus;
> > + struct pci_dev *pdev;
> >
> > if (aspm_disabled)
> > return -EPERM;
> > @@ -1176,9 +1170,18 @@ static int pcie_aspm_set_policy(const char *val,
> > down_read(&pci_bus_sem);
> > mutex_lock(&aspm_lock);
> > aspm_policy = i;
> > - list_for_each_entry(link, &link_list, sibling) {
> > - pcie_config_aspm_link(link, policy_to_aspm_state(link));
> > - pcie_set_clkpm(link, policy_to_clkpm_state(link));
> > + list_for_each_entry(bus, &pci_root_buses, node) {
> > + list_for_each_entry(pdev, &bus->devices, bus_list) {
> > + if (!pci_is_pcie(pdev))
> > + break;
> > +
> > + link = pdev->link_state;
> > + if (!link)
> > + continue;
> > +
> > + pcie_config_aspm_link(link, policy_to_aspm_state(link));
> > + pcie_set_clkpm(link, policy_to_clkpm_state(link));
> > + }
>
> IIUC, in the existing code, link_list contains *every* pcie_link_state
> in the system, so we update the configuration of all of them.
>
> Here, iterating through pci_root_buses gives us all the root buses (in
> the case of multiple host bridges), and on each root bus we look at
> every device that has a link_state, so those would typically be Root
> Ports. But I don't think we descend the hierarchy, so in the case of
> deeper hierarchies, I don't think we update the lower levels.
>
> Example from my laptop:
>
> 00:1d.6 Root Port to [bus 06-3e]
> 06:00.0 Upstream Port (switch A) to [bus 07-3e]
> 07:01.0 Downstream Port (switch A) to [bus 09-3d]
> 09:00.0 Upstream Port (switch B) to [bus 0a-3d]
> 0a:04.0 Downstream Port (switch B) to [bus 0c-3d]
> 0c:00.0 Upstream Port (switch C) to [bus 0d-3d]
> 0d:01.0 Downstream Port (switch C) to [bus 0e]
> 0e:00.0 Upstream Port (Endpoint) USB controller
>
> Here there are four links:
>
> 00:1d.6 --- 06:00.0
> 07:01.0 --- 09:00.0
> 0a:04.0 --- 0c:00.0
> 0d:01.0 --- 0e:00.0
>
> But I think this patch only looks at the 00:1d.6 --- 06:00.0 link,
> doesn't it?
Thank you, that is correct.
I should have used pdev->subordinate to traverse the hierarchy via the bridges.
>
> > }
> > mutex_unlock(&aspm_lock);
> > up_read(&pci_bus_sem);
> > --
> > 2.20.1
> >

\
 
 \ /
  Last update: 2021-10-11 08:04    [W:0.060 / U:0.452 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site