From: "Saheed O. Bolarinwa" <refactormyself@gmail.com>
To: helgaas@kernel.org
Cc: "Saheed O. Bolarinwa" <refactormyself@gmail.com>,
linux-kernel-mentees@lists.linuxfoundation.org
Subject: [Linux-kernel-mentees] [RFC PATCH v5 13/23] PCI: Initialise and Update values of pci_dev's PCIe link info
Date: Sat, 22 Aug 2020 22:03:48 +0200 [thread overview]
Message-ID: <20200822200358.252967-14-refactormyself@gmail.com> (raw)
In-Reply-To: <20200822200358.252967-1-refactormyself@gmail.com>
The PCIe link state information defined in struct pci_dev are
initialised alongside with those of struct pcie_link_state.
The redundancy introduced is cleared out in later patches.
Signed-off-by: Saheed O. Bolarinwa <refactormyself@gmail.com>
---
drivers/pci/pcie/aspm.c | 133 ++++++++++++++++++++++++++++++++--------
1 file changed, 109 insertions(+), 24 deletions(-)
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index d9c17093b250..e869e7faaac5 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -75,6 +75,7 @@ static int aspm_disabled, aspm_force;
static bool aspm_support_enabled = true;
static DEFINE_MUTEX(aspm_lock);
static LIST_HEAD(link_list);
+static LIST_HEAD(pdev_link_list);
#define POLICY_DEFAULT 0 /* BIOS default setting */
#define POLICY_PERFORMANCE 1 /* high performance */
@@ -145,6 +146,7 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable)
PCI_EXP_LNKCTL_CLKREQ_EN,
val);
link->clkpm_enabled = !!enable;
+ link->pdev->clkpm_enabled = !!enable;
}
static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
@@ -183,6 +185,10 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
link->clkpm_default = enabled;
link->clkpm_capable = capable;
link->clkpm_disable = blacklist ? 1 : 0;
+ link->pdev->clkpm_enabled = enabled;
+ link->pdev->clkpm_default = enabled;
+ link->pdev->clkpm_capable = capable;
+ link->pdev->clkpm_disable = blacklist ? 1 : 0;
}
static bool pcie_retrain_link(struct pcie_link_state *link)
@@ -374,6 +380,7 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
u32 latency, l1_switch_latency = 0;
struct aspm_latency *acceptable;
struct pcie_link_state *link;
+ struct pci_dev *pdev;
/* Device not in D0 doesn't need latency check */
if ((endpoint->current_state != PCI_D0) &&
@@ -381,18 +388,24 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
return;
link = endpoint->bus->self->link_state;
+ pdev = endpoint->bus->self;
acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)];
while (link) {
/* Check upstream direction L0s latency */
if ((link->aspm_capable & ASPM_STATE_L0S_UP) &&
- (link->latency_up.l0s > acceptable->l0s))
+ (link->latency_up.l0s > acceptable->l0s)) {
link->aspm_capable &= ~ASPM_STATE_L0S_UP;
+ pdev->aspm_capable &= ~ASPM_STATE_L0S_UP;
+ }
/* Check downstream direction L0s latency */
if ((link->aspm_capable & ASPM_STATE_L0S_DW) &&
- (link->latency_dw.l0s > acceptable->l0s))
+ (link->latency_dw.l0s > acceptable->l0s)) {
link->aspm_capable &= ~ASPM_STATE_L0S_DW;
+ pdev->aspm_capable &= ~ASPM_STATE_L0S_DW;
+ }
+
/*
* Check L1 latency.
* Every switch on the path to root complex need 1
@@ -408,11 +421,15 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
*/
latency = max_t(u32, link->latency_up.l1, link->latency_dw.l1);
if ((link->aspm_capable & ASPM_STATE_L1) &&
- (latency + l1_switch_latency > acceptable->l1))
+ (latency + l1_switch_latency > acceptable->l1)) {
link->aspm_capable &= ~ASPM_STATE_L1;
+ pdev->aspm_capable &= ~ASPM_STATE_L1;
+ }
+
l1_switch_latency += 1000;
link = link->parent;
+ pdev = pdev->parent;
}
}
@@ -496,6 +513,8 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
/* Set enabled/disable so that we will disable ASPM later */
link->aspm_enabled = ASPM_STATE_ALL;
link->aspm_disable = ASPM_STATE_ALL;
+ parent->aspm_enabled = ASPM_STATE_ALL;
+ parent->aspm_disable = ASPM_STATE_ALL;
return;
}
@@ -524,50 +543,87 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
*/
if (((parent->lnkcap & PCI_EXP_LNKCAP_ASPMS) >> 10) &
((child->lnkcap & PCI_EXP_LNKCAP_ASPMS) >> 10) &
- PCIE_LINK_STATE_L0S)
+ PCIE_LINK_STATE_L0S) {
link->aspm_support |= ASPM_STATE_L0S;
+ parent->aspm_support |= ASPM_STATE_L0S;
+ }
- if (get_aspm_enable(child) & PCIE_LINK_STATE_L0S)
+ if (get_aspm_enable(child) & PCIE_LINK_STATE_L0S) {
link->aspm_enabled |= ASPM_STATE_L0S_UP;
- if (get_aspm_enable(parent) & PCIE_LINK_STATE_L0S)
+ parent->aspm_enabled |= ASPM_STATE_L0S_UP;
+ }
+
+ if (get_aspm_enable(parent) & PCIE_LINK_STATE_L0S) {
link->aspm_enabled |= ASPM_STATE_L0S_DW;
+ parent->aspm_enabled |= ASPM_STATE_L0S_DW;
+ }
+
link->latency_up.l0s = calc_l0s_latency(parent);
link->latency_dw.l0s = calc_l0s_latency(child);
+ parent->latency_up.l0s = calc_l0s_latency(parent);
+ parent->latency_dw.l0s = calc_l0s_latency(child);
/* Setup L1 state */
if (((parent->lnkcap & PCI_EXP_LNKCAP_ASPMS) >> 10) &
((child->lnkcap & PCI_EXP_LNKCAP_ASPMS) >> 10) &
- PCIE_LINK_STATE_L1)
+ PCIE_LINK_STATE_L1) {
link->aspm_support |= ASPM_STATE_L1;
- if (get_aspm_enable(parent) & get_aspm_enable(child) & PCIE_LINK_STATE_L1)
+ parent->aspm_support |= ASPM_STATE_L1;
+ }
+
+ if (get_aspm_enable(parent) & get_aspm_enable(child) &
+ PCIE_LINK_STATE_L1) {
link->aspm_enabled |= ASPM_STATE_L1;
+ parent->aspm_enabled |= ASPM_STATE_L1;
+ }
+
link->latency_up.l1 = calc_l1_latency(parent);
link->latency_dw.l1 = calc_l1_latency(child);
+ parent->latency_up.l1 = calc_l1_latency(parent);
+ parent->latency_dw.l1 = calc_l1_latency(child);
/* Setup L1 substate */
- if (parent->l1ss_cap & child->l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1)
+ if (parent->l1ss_cap & child->l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1) {
link->aspm_support |= ASPM_STATE_L1_1;
- if (parent->l1ss_cap & child->l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2)
+ parent->aspm_support |= ASPM_STATE_L1_1;
+ }
+ if (parent->l1ss_cap & child->l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2) {
link->aspm_support |= ASPM_STATE_L1_2;
- if (parent->l1ss_cap & child->l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1)
+ parent->aspm_support |= ASPM_STATE_L1_2;
+ }
+ if (parent->l1ss_cap & child->l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1) {
link->aspm_support |= ASPM_STATE_L1_1_PCIPM;
- if (parent->l1ss_cap & child->l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2)
+ parent->aspm_support |= ASPM_STATE_L1_1_PCIPM;
+ }
+ if (parent->l1ss_cap & child->l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2) {
link->aspm_support |= ASPM_STATE_L1_2_PCIPM;
+ parent->aspm_support |= ASPM_STATE_L1_2_PCIPM;
+ }
- if (up_l1ss_ctl1 & dw_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1)
+ if (up_l1ss_ctl1 & dw_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1) {
link->aspm_enabled |= ASPM_STATE_L1_1;
- if (up_l1ss_ctl1 & dw_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2)
+ parent->aspm_enabled |= ASPM_STATE_L1_1;
+ }
+ if (up_l1ss_ctl1 & dw_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2) {
link->aspm_enabled |= ASPM_STATE_L1_2;
- if (up_l1ss_ctl1 & dw_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1)
+ parent->aspm_enabled |= ASPM_STATE_L1_2;
+ }
+ if (up_l1ss_ctl1 & dw_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1) {
link->aspm_enabled |= ASPM_STATE_L1_1_PCIPM;
- if (up_l1ss_ctl1 & dw_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2)
+ parent->aspm_enabled |= ASPM_STATE_L1_1_PCIPM;
+ }
+ if (up_l1ss_ctl1 & dw_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2) {
link->aspm_enabled |= ASPM_STATE_L1_2_PCIPM;
+ parent->aspm_enabled |= ASPM_STATE_L1_2_PCIPM;
+ }
/* Save default state */
link->aspm_default = link->aspm_enabled;
+ parent->aspm_default = parent->aspm_enabled;
/* Setup initial capable state. Will be updated later */
link->aspm_capable = link->aspm_support;
+ parent->aspm_capable = parent->aspm_support;
/* Get and check endpoint acceptable latencies */
list_for_each_entry(child, &linkbus->devices, bus_list) {
@@ -735,6 +791,7 @@ static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
pcie_config_aspm_dev(parent, upstream);
link->aspm_enabled = state;
+ parent->aspm_enabled = state;
}
static void pcie_config_aspm_path(struct pcie_link_state *link)
@@ -795,8 +852,10 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
return NULL;
INIT_LIST_HEAD(&link->sibling);
+ INIT_LIST_HEAD(&pdev->sibling);
link->pdev = pdev;
link->downstream = pci_function_0(pdev->subordinate);
+ pdev->downstream = pci_function_0(pdev->subordinate);
/*
* Root Ports and PCI/PCI-X to PCIe Bridges are roots of PCIe
@@ -809,6 +868,7 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE ||
!pdev->bus->parent->self) {
link->root = link;
+ pdev->root = pdev;
} else {
struct pcie_link_state *parent;
@@ -820,9 +880,12 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
link->parent = parent;
link->root = link->parent->root;
+ pdev->parent = pdev->bus->parent->self;
+ pdev->root = pdev->parent->root;
}
list_add(&link->sibling, &link_list);
+ list_add(&pdev->sibling, &pdev_link_list);
pdev->link_state = link;
return link;
}
@@ -913,6 +976,7 @@ static void pcie_update_aspm_capable(struct pcie_link_state *root)
if (link->root != root)
continue;
link->aspm_capable = link->aspm_support;
+ link->pdev->aspm_capable = link->aspm_support;
}
list_for_each_entry(link, &link_list, sibling) {
struct pci_dev *child;
@@ -1021,6 +1085,7 @@ static struct pcie_link_state *pcie_aspm_get_link(struct pci_dev *pdev)
static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
{
struct pcie_link_state *link = pcie_aspm_get_link(pdev);
+ struct pci_dev *bridge = link->pdev;
if (!link)
return -EINVAL;
@@ -1040,23 +1105,37 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
if (sem)
down_read(&pci_bus_sem);
mutex_lock(&aspm_lock);
- if (state & PCIE_LINK_STATE_L0S)
+ if (state & PCIE_LINK_STATE_L0S) {
link->aspm_disable |= ASPM_STATE_L0S;
- if (state & PCIE_LINK_STATE_L1)
+ bridge->aspm_disable |= ASPM_STATE_L0S;
+ }
+ if (state & PCIE_LINK_STATE_L1) {
/* L1 PM substates require L1 */
link->aspm_disable |= ASPM_STATE_L1 | ASPM_STATE_L1SS;
- if (state & PCIE_LINK_STATE_L1_1)
+ bridge->aspm_disable |= ASPM_STATE_L1 | ASPM_STATE_L1SS;
+ }
+ if (state & PCIE_LINK_STATE_L1_1) {
link->aspm_disable |= ASPM_STATE_L1_1;
- if (state & PCIE_LINK_STATE_L1_2)
+ bridge->aspm_disable |= ASPM_STATE_L1_1;
+ }
+ if (state & PCIE_LINK_STATE_L1_2) {
link->aspm_disable |= ASPM_STATE_L1_2;
- if (state & PCIE_LINK_STATE_L1_1_PCIPM)
+ bridge->aspm_disable |= ASPM_STATE_L1_2;
+ }
+ if (state & PCIE_LINK_STATE_L1_1_PCIPM) {
link->aspm_disable |= ASPM_STATE_L1_1_PCIPM;
- if (state & PCIE_LINK_STATE_L1_2_PCIPM)
+ bridge->aspm_disable |= ASPM_STATE_L1_1_PCIPM;
+ }
+ if (state & PCIE_LINK_STATE_L1_2_PCIPM) {
link->aspm_disable |= ASPM_STATE_L1_2_PCIPM;
+ bridge->aspm_disable |= ASPM_STATE_L1_2_PCIPM;
+ }
pcie_config_aspm_link(link, policy_to_aspm_state(link));
- if (state & PCIE_LINK_STATE_CLKPM)
+ if (state & PCIE_LINK_STATE_CLKPM) {
link->clkpm_disable = 1;
+ bridge->clkpm_disable = 1;
+ }
pcie_set_clkpm(link, policy_to_clkpm_state(link));
mutex_unlock(&aspm_lock);
if (sem)
@@ -1162,6 +1241,7 @@ static ssize_t aspm_attr_store_common(struct device *dev,
{
struct pci_dev *pdev = to_pci_dev(dev);
struct pcie_link_state *link = pcie_aspm_get_link(pdev);
+ struct pci_dev *bridge = link->pdev;
bool state_enable;
if (strtobool(buf, &state_enable) < 0)
@@ -1172,11 +1252,15 @@ static ssize_t aspm_attr_store_common(struct device *dev,
if (state_enable) {
link->aspm_disable &= ~state;
+ bridge->aspm_disable &= ~state;
/* need to enable L1 for substates */
- if (state & ASPM_STATE_L1SS)
+ if (state & ASPM_STATE_L1SS) {
link->aspm_disable &= ~ASPM_STATE_L1;
+ bridge->aspm_disable &= ~ASPM_STATE_L1;
+ }
} else {
link->aspm_disable |= state;
+ bridge->aspm_disable |= state;
}
pcie_config_aspm_link(link, policy_to_aspm_state(link));
@@ -1228,6 +1312,7 @@ static ssize_t clkpm_store(struct device *dev,
mutex_lock(&aspm_lock);
link->clkpm_disable = !state_enable;
+ link->pdev->clkpm_disable = !state_enable;
pcie_set_clkpm(link, policy_to_clkpm_state(link));
mutex_unlock(&aspm_lock);
--
2.18.4
_______________________________________________
Linux-kernel-mentees mailing list
Linux-kernel-mentees@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/linux-kernel-mentees
next prev parent reply other threads:[~2020-08-22 21:03 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-22 20:03 [Linux-kernel-mentees] [RFC PATCH v5 00/23] Remove struct pcie_link_state and aspm_register_info Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 01/23] PCI: Migrate ASPM info from struct pcie_link_state to struct pci_dev Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 02/23] PCI: Add l1ss_cap and l1ss_cap_ptr " Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 03/23] PCI: Rework calc_l*_latency() to take a pci_dev * Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 04/23] PCI: Compute aspm_register_info.support directly Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 05/23] PCI: Read value of aspm_register_info.l1ss_ctl1 directly Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 06/23] PCI: Replace aspm_register_info.l1ss_cap* with their pci_dev version Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 07/23] PCI: Compute aspm_register_info.enable directly Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 08/23] PCI: Remove unused aspm_calc_l1ss_info() arguments Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 09/23] PCI: Remove pcie_get_aspm_reg() and struct aspm_register_info Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 10/23] PCI: Relocate call to aspm_calc_l1ss_info Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 11/23] PCI: Rework and Rename aspm_calc_l1ss_info() Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 12/23] PCI: Add ASPM and CLOCK PM states to struct pci_dev Saheed O. Bolarinwa
2020-08-22 20:03 ` Saheed O. Bolarinwa [this message]
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 14/23] PCI: Change Return and Argument values from pcie_link_state to pci_dev Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 15/23] PCI: Replace pcie_link_state based device list with a pci_dev one Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 16/23] PCI: Remove Exit latencies from struct pcie_link_state Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 17/23] PCI: Remove .clkpm_* " Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 18/23] PCI: Remove .aspm_* " Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 19/23] PCI: Remove .parent " Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 20/23] PCI: Remove .root " Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 21/23] PCI: Remove .downstream " Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 22/23] PCI: Remove .pdev " Saheed O. Bolarinwa
2020-08-22 20:03 ` [Linux-kernel-mentees] [RFC PATCH v5 23/23] PCI: Remove " Saheed O. Bolarinwa
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=20200822200358.252967-14-refactormyself@gmail.com \
--to=refactormyself@gmail.com \
--cc=helgaas@kernel.org \
--cc=linux-kernel-mentees@lists.linuxfoundation.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).