]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.16-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Mar 2022 13:45:53 +0000 (14:45 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Mar 2022 13:45:53 +0000 (14:45 +0100)
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

queue-5.16/net-dsa-microchip-fix-bridging-with-more-than-two-member-ports.patch [new file with mode: 0644]
queue-5.16/platform-x86-amd-pmc-set-qos-during-suspend-on-czn-w-timer-wakeup.patch [new file with mode: 0644]
queue-5.16/series

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 (file)
index 0000000..c440777
--- /dev/null
@@ -0,0 +1,80 @@
+From 3d00827a90db6f79abc7cdc553887f89a2e0a184 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Svenning=20S=C3=B8rensen?= <sss@secomea.com>
+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 <sss@secomea.com>
+
+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 <sss@secomea.com>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..d233f9a
--- /dev/null
@@ -0,0 +1,144 @@
+From 68af28426b3ca1bf9ba21c7d8bdd0ff639e5134c Mon Sep 17 00:00:00 2001
+From: Mario Limonciello <mario.limonciello@amd.com>
+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 <mario.limonciello@amd.com>
+
+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 <rafael.j.wysocki@intel.com>
+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 <rafael.j.wysocki@intel.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Link: https://lore.kernel.org/r/20220223175237.6209-1-mario.limonciello@amd.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/platform_device.h>
++#include <linux/pm_qos.h>
+ #include <linux/rtc.h>
+ #include <linux/suspend.h>
+ #include <linux/seq_file.h>
+@@ -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;
+ }
index 9c76671ad264d59bc1b7d623c92dce4edc4ce106..86b575af4d8bd6719dea46bcaf3c6856247a5b52 100644 (file)
@@ -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