From b2005033c76b3920c3876f94825b6f29601824cd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 5 Mar 2022 14:45:53 +0100 Subject: [PATCH] 5.16-stable patches added patches: net-dsa-microchip-fix-bridging-with-more-than-two-member-ports.patch platform-x86-amd-pmc-set-qos-during-suspend-on-czn-w-timer-wakeup.patch --- ...ging-with-more-than-two-member-ports.patch | 80 ++++++++++ ...during-suspend-on-czn-w-timer-wakeup.patch | 144 ++++++++++++++++++ queue-5.16/series | 2 + 3 files changed, 226 insertions(+) create mode 100644 queue-5.16/net-dsa-microchip-fix-bridging-with-more-than-two-member-ports.patch create mode 100644 queue-5.16/platform-x86-amd-pmc-set-qos-during-suspend-on-czn-w-timer-wakeup.patch diff --git a/queue-5.16/net-dsa-microchip-fix-bridging-with-more-than-two-member-ports.patch b/queue-5.16/net-dsa-microchip-fix-bridging-with-more-than-two-member-ports.patch new file mode 100644 index 00000000000..c4407770107 --- /dev/null +++ b/queue-5.16/net-dsa-microchip-fix-bridging-with-more-than-two-member-ports.patch @@ -0,0 +1,80 @@ +From 3d00827a90db6f79abc7cdc553887f89a2e0a184 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Svenning=20S=C3=B8rensen?= +Date: Fri, 18 Feb 2022 11:27:01 +0000 +Subject: net: dsa: microchip: fix bridging with more than two member ports +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Svenning Sørensen + +commit 3d00827a90db6f79abc7cdc553887f89a2e0a184 upstream. + +Commit b3612ccdf284 ("net: dsa: microchip: implement multi-bridge support") +plugged a packet leak between ports that were members of different bridges. +Unfortunately, this broke another use case, namely that of more than two +ports that are members of the same bridge. + +After that commit, when a port is added to a bridge, hardware bridging +between other member ports of that bridge will be cleared, preventing +packet exchange between them. + +Fix by ensuring that the Port VLAN Membership bitmap includes any existing +ports in the bridge, not just the port being added. + +Fixes: b3612ccdf284 ("net: dsa: microchip: implement multi-bridge support") +Signed-off-by: Svenning Sørensen +Tested-by: Oleksij Rempel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/dsa/microchip/ksz_common.c | 26 +++++++++++++++++++++++--- + 1 file changed, 23 insertions(+), 3 deletions(-) + +--- a/drivers/net/dsa/microchip/ksz_common.c ++++ b/drivers/net/dsa/microchip/ksz_common.c +@@ -26,7 +26,7 @@ void ksz_update_port_member(struct ksz_d + struct dsa_switch *ds = dev->ds; + u8 port_member = 0, cpu_port; + const struct dsa_port *dp; +- int i; ++ int i, j; + + if (!dsa_is_user_port(ds, port)) + return; +@@ -45,13 +45,33 @@ void ksz_update_port_member(struct ksz_d + continue; + if (!dp->bridge_dev || dp->bridge_dev != other_dp->bridge_dev) + continue; ++ if (other_p->stp_state != BR_STATE_FORWARDING) ++ continue; + +- if (other_p->stp_state == BR_STATE_FORWARDING && +- p->stp_state == BR_STATE_FORWARDING) { ++ if (p->stp_state == BR_STATE_FORWARDING) { + val |= BIT(port); + port_member |= BIT(i); + } + ++ /* Retain port [i]'s relationship to other ports than [port] */ ++ for (j = 0; j < ds->num_ports; j++) { ++ const struct dsa_port *third_dp; ++ struct ksz_port *third_p; ++ ++ if (j == i) ++ continue; ++ if (j == port) ++ continue; ++ if (!dsa_is_user_port(ds, j)) ++ continue; ++ third_p = &dev->ports[j]; ++ if (third_p->stp_state != BR_STATE_FORWARDING) ++ continue; ++ third_dp = dsa_to_port(ds, j); ++ if (third_dp->bridge_dev == dp->bridge_dev) ++ val |= BIT(j); ++ } ++ + dev->dev_ops->cfg_port_member(dev, i, val | cpu_port); + } + diff --git a/queue-5.16/platform-x86-amd-pmc-set-qos-during-suspend-on-czn-w-timer-wakeup.patch b/queue-5.16/platform-x86-amd-pmc-set-qos-during-suspend-on-czn-w-timer-wakeup.patch new file mode 100644 index 00000000000..d233f9abc54 --- /dev/null +++ b/queue-5.16/platform-x86-amd-pmc-set-qos-during-suspend-on-czn-w-timer-wakeup.patch @@ -0,0 +1,144 @@ +From 68af28426b3ca1bf9ba21c7d8bdd0ff639e5134c Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Wed, 23 Feb 2022 11:52:37 -0600 +Subject: platform/x86: amd-pmc: Set QOS during suspend on CZN w/ timer wakeup + +From: Mario Limonciello + +commit 68af28426b3ca1bf9ba21c7d8bdd0ff639e5134c upstream. + +commit 59348401ebed ("platform/x86: amd-pmc: Add special handling for +timer based S0i3 wakeup") adds support for using another platform timer +in lieu of the RTC which doesn't work properly on some systems. This path +was validated and worked well before submission. During the 5.16-rc1 merge +window other patches were merged that caused this to stop working properly. + +When this feature was used with 5.16-rc1 or later some OEM laptops with the +matching firmware requirements from that commit would shutdown instead of +program a timer based wakeup. + +This was bisected to commit 8d89835b0467 ("PM: suspend: Do not pause +cpuidle in the suspend-to-idle path"). This wasn't supposed to cause any +negative impacts and also tested well on both Intel and ARM platforms. +However this changed the semantics of when CPUs are allowed to be in the +deepest state. For the AMD systems in question it appears this causes a +firmware crash for timer based wakeup. + +It's hypothesized to be caused by the `amd-pmc` driver sending `OS_HINT` +and all the CPUs going into a deep state while the timer is still being +programmed. It's likely a firmware bug, but to avoid it don't allow setting +CPUs into the deepest state while using CZN timer wakeup path. + +If later it's discovered that this also occurs from "regular" suspends +without a timer as well or on other silicon, this may be later expanded to +run in the suspend path for more scenarios. + +Cc: stable@vger.kernel.org # 5.16+ +Suggested-by: Rafael J. Wysocki +Link: https://lore.kernel.org/linux-acpi/BL1PR12MB51570F5BD05980A0DCA1F3F4E23A9@BL1PR12MB5157.namprd12.prod.outlook.com/T/#mee35f39c41a04b624700ab2621c795367f19c90e +Fixes: 8d89835b0467 ("PM: suspend: Do not pause cpuidle in the suspend-to-idle path") +Fixes: 23f62d7ab25b ("PM: sleep: Pause cpuidle later and resume it earlier during system transitions") +Fixes: 59348401ebed ("platform/x86: amd-pmc: Add special handling for timer based S0i3 wakeup" +Reviewed-by: Rafael J. Wysocki +Signed-off-by: Mario Limonciello +Link: https://lore.kernel.org/r/20220223175237.6209-1-mario.limonciello@amd.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Greg Kroah-Hartman +--- + drivers/platform/x86/amd-pmc.c | 34 ++++++++++++++++++++++++++++++---- + 1 file changed, 30 insertions(+), 4 deletions(-) + +--- a/drivers/platform/x86/amd-pmc.c ++++ b/drivers/platform/x86/amd-pmc.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -79,6 +80,9 @@ + #define PMC_MSG_DELAY_MIN_US 50 + #define RESPONSE_REGISTER_LOOP_MAX 20000 + ++/* QoS request for letting CPUs in idle states, but not the deepest */ ++#define AMD_PMC_MAX_IDLE_STATE_LATENCY 3 ++ + #define SOC_SUBSYSTEM_IP_MAX 12 + #define DELAY_MIN_US 2000 + #define DELAY_MAX_US 3000 +@@ -123,6 +127,7 @@ struct amd_pmc_dev { + u8 rev; + struct device *dev; + struct mutex lock; /* generic mutex lock */ ++ struct pm_qos_request amd_pmc_pm_qos_req; + #if IS_ENABLED(CONFIG_DEBUG_FS) + struct dentry *dbgfs_dir; + #endif /* CONFIG_DEBUG_FS */ +@@ -459,6 +464,14 @@ static int amd_pmc_verify_czn_rtc(struct + rc = rtc_alarm_irq_enable(rtc_device, 0); + dev_dbg(pdev->dev, "wakeup timer programmed for %lld seconds\n", duration); + ++ /* ++ * Prevent CPUs from getting into deep idle states while sending OS_HINT ++ * which is otherwise generally safe to send when at least one of the CPUs ++ * is not in deep idle states. ++ */ ++ cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req, AMD_PMC_MAX_IDLE_STATE_LATENCY); ++ wake_up_all_idle_cpus(); ++ + return rc; + } + +@@ -476,17 +489,24 @@ static int __maybe_unused amd_pmc_suspen + /* Activate CZN specific RTC functionality */ + if (pdev->cpu_id == AMD_CPU_ID_CZN) { + rc = amd_pmc_verify_czn_rtc(pdev, &arg); +- if (rc < 0) +- return rc; ++ if (rc) ++ goto fail; + } + + /* Dump the IdleMask before we send hint to SMU */ + amd_pmc_idlemask_read(pdev, dev, NULL); + msg = amd_pmc_get_os_hint(pdev); + rc = amd_pmc_send_cmd(pdev, arg, NULL, msg, 0); +- if (rc) ++ if (rc) { + dev_err(pdev->dev, "suspend failed\n"); ++ goto fail; ++ } + ++ return 0; ++fail: ++ if (pdev->cpu_id == AMD_CPU_ID_CZN) ++ cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req, ++ PM_QOS_DEFAULT_VALUE); + return rc; + } + +@@ -507,7 +527,12 @@ static int __maybe_unused amd_pmc_resume + /* Dump the IdleMask to see the blockers */ + amd_pmc_idlemask_read(pdev, dev, NULL); + +- return 0; ++ /* Restore the QoS request back to defaults if it was set */ ++ if (pdev->cpu_id == AMD_CPU_ID_CZN) ++ cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req, ++ PM_QOS_DEFAULT_VALUE); ++ ++ return rc; + } + + static const struct dev_pm_ops amd_pmc_pm_ops = { +@@ -597,6 +622,7 @@ static int amd_pmc_probe(struct platform + amd_pmc_get_smu_version(dev); + platform_set_drvdata(pdev, dev); + amd_pmc_dbgfs_register(dev); ++ cpu_latency_qos_add_request(&dev->amd_pmc_pm_qos_req, PM_QOS_DEFAULT_VALUE); + return 0; + } + diff --git a/queue-5.16/series b/queue-5.16/series index 9c76671ad26..86b575af4d8 100644 --- a/queue-5.16/series +++ b/queue-5.16/series @@ -84,3 +84,5 @@ net-smc-fix-connection-leak.patch net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch btrfs-fix-enospc-failure-when-attempting-direct-io-write-into-nocow-range.patch +platform-x86-amd-pmc-set-qos-during-suspend-on-czn-w-timer-wakeup.patch +net-dsa-microchip-fix-bridging-with-more-than-two-member-ports.patch -- 2.47.2