During an S4 resume, the system first performs a cold power-on. The
kernel image is initially loaded to a random linear address, and the
FRED MSRs are initialized. Subsequently, the S4 image is loaded,
and the kernel image is relocated to its original address from before
the S4 suspend. Due to changes in the kernel text and data mappings,
the FRED MSRs must be reinitialized.
Reported-by: Xi Pardee <xi.pardee(a)intel.com>
Reported-and-Tested-by: Todd Brandt <todd.e.brandt(a)intel.com>
Suggested-by: H. Peter Anvin (Intel) <hpa(a)zytor.com>
Signed-off-by: Xin Li (Intel) <xin(a)zytor.com>
Cc: stable(a)kernel.org # 6.9+
---
arch/x86/power/cpu.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 63230ff8cf4f..ef3c152c319c 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -27,6 +27,7 @@
#include <asm/mmu_context.h>
#include <asm/cpu_device_id.h>
#include <asm/microcode.h>
+#include <asm/fred.h>
#ifdef CONFIG_X86_32
__visible unsigned long saved_context_ebx;
@@ -231,6 +232,21 @@ static void notrace __restore_processor_state(struct saved_context *ctxt)
*/
#ifdef CONFIG_X86_64
wrmsrl(MSR_GS_BASE, ctxt->kernelmode_gs_base);
+
+ /*
+ * Restore FRED configs.
+ *
+ * FRED configs are completely derived from current kernel text and
+ * data mappings, thus nothing needs to be saved and restored.
+ *
+ * As such, simply re-initialize FRED to restore FRED configs.
+ *
+ * Note, FRED RSPs setup needs to access percpu data structures.
+ */
+ if (ctxt->cr4 & X86_CR4_FRED) {
+ cpu_init_fred_exceptions();
+ cpu_init_fred_rsps();
+ }
#else
loadsegment(fs, __KERNEL_PERCPU);
#endif
--
2.48.1
The current implementation uses bias_pad_enable as a reference count to
manage the shared bias pad for all UTMI PHYs. However, during system
suspension with connected USB devices, multiple power-down requests for
the UTMI pad result in a mismatch in the reference count, which in turn
produces warnings such as:
[ 237.762967] WARNING: CPU: 10 PID: 1618 at tegra186_utmi_pad_power_down+0x160/0x170
[ 237.763103] Call trace:
[ 237.763104] tegra186_utmi_pad_power_down+0x160/0x170
[ 237.763107] tegra186_utmi_phy_power_off+0x10/0x30
[ 237.763110] phy_power_off+0x48/0x100
[ 237.763113] tegra_xusb_enter_elpg+0x204/0x500
[ 237.763119] tegra_xusb_suspend+0x48/0x140
[ 237.763122] platform_pm_suspend+0x2c/0xb0
[ 237.763125] dpm_run_callback.isra.0+0x20/0xa0
[ 237.763127] __device_suspend+0x118/0x330
[ 237.763129] dpm_suspend+0x10c/0x1f0
[ 237.763130] dpm_suspend_start+0x88/0xb0
[ 237.763132] suspend_devices_and_enter+0x120/0x500
[ 237.763135] pm_suspend+0x1ec/0x270
The root cause was traced back to the dynamic power-down changes
introduced in commit a30951d31b25 ("xhci: tegra: USB2 pad power controls"),
where the UTMI pad was being powered down without verifying its current
state. This unbalanced behavior led to discrepancies in the reference
count.
To rectify this issue, this patch replaces the single reference counter
with a bitmask, renamed to utmi_pad_enabled. Each bit in the mask
corresponds to one of the four USB2 PHYs, allowing us to track each pad's
enablement status individually.
With this change:
- The bias pad is powered on only when the mask is clear.
- Each UTMI pad is powered on or down based on its corresponding bit
in the mask, preventing redundant operations.
- The overall power state of the shared bias pad is maintained
correctly during suspend/resume cycles.
Cc: stable(a)vger.kernel.org
Fixes: a30951d31b25 ("xhci: tegra: USB2 pad power controls")
Signed-off-by: Wayne Chang <waynec(a)nvidia.com>
---
drivers/phy/tegra/xusb-tegra186.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c
index fae6242aa730..77bb27a34738 100644
--- a/drivers/phy/tegra/xusb-tegra186.c
+++ b/drivers/phy/tegra/xusb-tegra186.c
@@ -237,6 +237,8 @@
#define DATA0_VAL_PD BIT(1)
#define USE_XUSB_AO BIT(4)
+#define TEGRA_UTMI_PAD_MAX 4
+
#define TEGRA186_LANE(_name, _offset, _shift, _mask, _type) \
{ \
.name = _name, \
@@ -269,7 +271,7 @@ struct tegra186_xusb_padctl {
/* UTMI bias and tracking */
struct clk *usb2_trk_clk;
- unsigned int bias_pad_enable;
+ DECLARE_BITMAP(utmi_pad_enabled, TEGRA_UTMI_PAD_MAX);
/* padctl context */
struct tegra186_xusb_padctl_context context;
@@ -605,7 +607,7 @@ static void tegra186_utmi_bias_pad_power_on(struct tegra_xusb_padctl *padctl)
mutex_lock(&padctl->lock);
- if (priv->bias_pad_enable++ > 0) {
+ if (!bitmap_empty(priv->utmi_pad_enabled, TEGRA_UTMI_PAD_MAX)) {
mutex_unlock(&padctl->lock);
return;
}
@@ -669,12 +671,7 @@ static void tegra186_utmi_bias_pad_power_off(struct tegra_xusb_padctl *padctl)
mutex_lock(&padctl->lock);
- if (WARN_ON(priv->bias_pad_enable == 0)) {
- mutex_unlock(&padctl->lock);
- return;
- }
-
- if (--priv->bias_pad_enable > 0) {
+ if (!bitmap_empty(priv->utmi_pad_enabled, TEGRA_UTMI_PAD_MAX)) {
mutex_unlock(&padctl->lock);
return;
}
@@ -697,6 +694,7 @@ static void tegra186_utmi_pad_power_on(struct phy *phy)
{
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+ struct tegra186_xusb_padctl *priv = to_tegra186_xusb_padctl(padctl);
struct tegra_xusb_usb2_port *port;
struct device *dev = padctl->dev;
unsigned int index = lane->index;
@@ -705,6 +703,9 @@ static void tegra186_utmi_pad_power_on(struct phy *phy)
if (!phy)
return;
+ if (test_bit(index, priv->utmi_pad_enabled))
+ return;
+
port = tegra_xusb_find_usb2_port(padctl, index);
if (!port) {
dev_err(dev, "no port found for USB2 lane %u\n", index);
@@ -724,18 +725,24 @@ static void tegra186_utmi_pad_power_on(struct phy *phy)
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
value &= ~USB2_OTG_PD_DR;
padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
+
+ set_bit(index, priv->utmi_pad_enabled);
}
static void tegra186_utmi_pad_power_down(struct phy *phy)
{
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+ struct tegra186_xusb_padctl *priv = to_tegra186_xusb_padctl(padctl);
unsigned int index = lane->index;
u32 value;
if (!phy)
return;
+ if (!test_bit(index, priv->utmi_pad_enabled))
+ return;
+
dev_dbg(padctl->dev, "power down UTMI pad %u\n", index);
value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index));
@@ -748,6 +755,8 @@ static void tegra186_utmi_pad_power_down(struct phy *phy)
udelay(2);
+ clear_bit(index, priv->utmi_pad_enabled);
+
tegra186_utmi_bias_pad_power_off(padctl);
}
--
2.25.1
On Tue, Apr 01, 2025 at 03:01:19AM +0000, Kang, Wenlin wrote:
> Ping ......
Context-less pings in html format for a change you sent a week ago
during the middle of the merge window is not going to get you very far,
sorry.
During the High-Speed Isochronous Audio transfers, xHCI
controller on certain AMD platforms experiences momentary data
loss. This results in Missed Service Errors (MSE) being
generated by the xHCI.
The root cause of the MSE is attributed to the ISOC OUT endpoint
being omitted from scheduling. This can happen when an IN
endpoint with a 64ms service interval either is pre-scheduled
prior to the ISOC OUT endpoint or the interval of the ISOC OUT
endpoint is shorter than that of the IN endpoint. Consequently,
the OUT service is neglected when an IN endpoint with a service
interval exceeding 32ms is scheduled concurrently (every 64ms in
this scenario).
This issue is particularly seen on certain older AMD platforms.
To mitigate this problem, it is recommended to adjust the service
interval of the IN endpoint to not exceed 32ms (interval 8). This
adjustment ensures that the OUT endpoint will not be bypassed,
even if a smaller interval value is utilized.
Cc: stable(a)vger.kernel.org
Signed-off-by: Raju Rangoju <Raju.Rangoju(a)amd.com>
---
Changes since v4:
- reword the commit message.
- handle the potential corner case with ISOC IN ep with 64ms ESIT
Changes since v3:
- Bump up the enum number XHCI_LIMIT_ENDPOINT_INTERVAL_9
Changes since v2:
- added stable tag to backport to all stable kernels
Changes since v1:
- replaced hex values with pci device names
- corrected the commit message
---
drivers/usb/host/xhci-mem.c | 4 ++++
drivers/usb/host/xhci-pci.c | 25 +++++++++++++++++++++++++
drivers/usb/host/xhci.h | 1 +
3 files changed, 30 insertions(+)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index fdf0c1008225..364b5a9e7c3e 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1420,6 +1420,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
/* Periodic endpoint bInterval limit quirk */
if (usb_endpoint_xfer_int(&ep->desc) ||
usb_endpoint_xfer_isoc(&ep->desc)) {
+ if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_9) &&
+ interval >= 9) {
+ interval = 8;
+ }
if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_7) &&
udev->speed >= USB_SPEED_HIGH &&
interval >= 7) {
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 54460d11f7ee..6c15b4158f06 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -71,12 +71,22 @@
#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_XHCI 0x15ec
#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI 0x15f0
+#define PCI_DEVICE_ID_AMD_ARIEL_TYPEC_XHCI 0x13ed
+#define PCI_DEVICE_ID_AMD_ARIEL_TYPEA_XHCI 0x13ee
+#define PCI_DEVICE_ID_AMD_STARSHIP_XHCI 0x148c
+#define PCI_DEVICE_ID_AMD_FIREFLIGHT_15D4_XHCI 0x15d4
+#define PCI_DEVICE_ID_AMD_FIREFLIGHT_15D5_XHCI 0x15d5
+#define PCI_DEVICE_ID_AMD_RAVEN_15E0_XHCI 0x15e0
+#define PCI_DEVICE_ID_AMD_RAVEN_15E1_XHCI 0x15e1
+#define PCI_DEVICE_ID_AMD_RAVEN2_XHCI 0x15e5
#define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639
#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9
#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba
#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb
#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc
+#define PCI_DEVICE_ID_ATI_NAVI10_7316_XHCI 0x7316
+
#define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042
#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
#define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242
@@ -280,6 +290,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
if (pdev->vendor == PCI_VENDOR_ID_NEC)
xhci->quirks |= XHCI_NEC_HOST;
+ if (pdev->vendor == PCI_VENDOR_ID_AMD &&
+ (pdev->device == PCI_DEVICE_ID_AMD_ARIEL_TYPEC_XHCI ||
+ pdev->device == PCI_DEVICE_ID_AMD_ARIEL_TYPEA_XHCI ||
+ pdev->device == PCI_DEVICE_ID_AMD_STARSHIP_XHCI ||
+ pdev->device == PCI_DEVICE_ID_AMD_FIREFLIGHT_15D4_XHCI ||
+ pdev->device == PCI_DEVICE_ID_AMD_FIREFLIGHT_15D5_XHCI ||
+ pdev->device == PCI_DEVICE_ID_AMD_RAVEN_15E0_XHCI ||
+ pdev->device == PCI_DEVICE_ID_AMD_RAVEN_15E1_XHCI ||
+ pdev->device == PCI_DEVICE_ID_AMD_RAVEN2_XHCI))
+ xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_9;
+
+ if (pdev->vendor == PCI_VENDOR_ID_ATI &&
+ pdev->device == PCI_DEVICE_ID_ATI_NAVI10_7316_XHCI)
+ xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_9;
+
if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version == 0x96)
xhci->quirks |= XHCI_AMD_0x96_HOST;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 779b01dee068..6de1164e2e53 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1637,6 +1637,7 @@ struct xhci_hcd {
#define XHCI_WRITE_64_HI_LO BIT_ULL(47)
#define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48)
#define XHCI_ETRON_HOST BIT_ULL(49)
+#define XHCI_LIMIT_ENDPOINT_INTERVAL_9 BIT_ULL(50)
unsigned int num_active_eps;
unsigned int limit_active_eps;
--
2.34.1
From: Da Xue <da(a)libre.computer>
This bit is necessary to enable packets on the interface. Without this
bit set, ethernet behaves as if it is working, but no activity occurs.
The vendor SDK sets this bit along with the PHY_ID bits. U-boot also
sets this bit, but if u-boot is not compiled with networking support
the interface will not work.
Fixes: 9a24e1ff4326 ("net: mdio: add amlogic gxl mdio mux support");
Signed-off-by: Da Xue <da(a)libre.computer>
Signed-off-by: Christian Hewitt <christianshewitt(a)gmail.com>
---
Resending on behalf of Da Xue who has email sending issues.
Changes since v1 [0]:
- Remove blank line between Fixes and SoB tags
- Submit without mail server mangling the patch
- Minor tweaks to subject line and commit message
- CC to stable(a)vger.kernel.org
[0] https://patchwork.kernel.org/project/linux-amlogic/patch/CACqvRUbx-KsrMwCHY…
drivers/net/mdio/mdio-mux-meson-gxl.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/mdio/mdio-mux-meson-gxl.c b/drivers/net/mdio/mdio-mux-meson-gxl.c
index 00c66240136b..fc5883387718 100644
--- a/drivers/net/mdio/mdio-mux-meson-gxl.c
+++ b/drivers/net/mdio/mdio-mux-meson-gxl.c
@@ -17,6 +17,7 @@
#define REG2_LEDACT GENMASK(23, 22)
#define REG2_LEDLINK GENMASK(25, 24)
#define REG2_DIV4SEL BIT(27)
+#define REG2_RESERVED_28 BIT(28)
#define REG2_ADCBYPASS BIT(30)
#define REG2_CLKINSEL BIT(31)
#define ETH_REG3 0x4
@@ -65,7 +66,7 @@ static void gxl_enable_internal_mdio(struct gxl_mdio_mux *priv)
* The only constraint is that it must match the one in
* drivers/net/phy/meson-gxl.c to properly match the PHY.
*/
- writel(FIELD_PREP(REG2_PHYID, EPHY_GXL_ID),
+ writel(REG2_RESERVED_28 | FIELD_PREP(REG2_PHYID, EPHY_GXL_ID),
priv->regs + ETH_REG2);
/* Enable the internal phy */
--
2.34.1
Here are 4 unrelated patches:
- Patch 1: fix a NULL pointer when two SYN-ACK for the same request are
handled in parallel. A fix for up to v5.9.
- Patch 2: selftests: fix check for the wrong FD. A fix for up to v5.17.
- Patch 3: selftests: close all FDs in case of error. A fix for up to
v5.17.
- Patch 4: selftests: ignore a new generated file. A fix for 6.15-rc0.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe(a)kernel.org>
---
Cong Liu (1):
selftests: mptcp: fix incorrect fd checks in main_loop
Gang Yan (1):
mptcp: fix NULL pointer in can_accept_new_subflow
Geliang Tang (1):
selftests: mptcp: close fd_in before returning in main_loop
Matthieu Baerts (NGI0) (1):
selftests: mptcp: ignore mptcp_diag binary
net/mptcp/subflow.c | 15 ++++++++-------
tools/testing/selftests/net/mptcp/.gitignore | 1 +
tools/testing/selftests/net/mptcp/mptcp_connect.c | 11 +++++++----
3 files changed, 16 insertions(+), 11 deletions(-)
---
base-commit: 2ea396448f26d0d7d66224cb56500a6789c7ed07
change-id: 20250328-net-mptcp-misc-fixes-6-15-98bfbeaa15ac
Best regards,
--
Matthieu Baerts (NGI0) <matttbe(a)kernel.org>
From: Paulo Alcantara <pc(a)cjr.nz>
commit 7ad54b98fc1f141cfb70cfe2a3d6def5a85169ff upstream.
Use TCP_Server_Info::origin_fullpath instead of cifs_tcon::tree_name
when building source paths for automounts as it will be useful for
domain-based DFS referrals where the connections and referrals would
get either re-used from the cache or re-created when chasing the dfs
link.
Signed-off-by: Paulo Alcantara (SUSE) <pc(a)cjr.nz>
Signed-off-by: Steve French <stfrench(a)microsoft.com>
[apanyaki: backport to v6.1-stable]
Signed-off-by: Andrew Paniakin <apanyaki(a)amazon.com>
---
Please do not include follow-up fix d5a863a153e9 ("cifs: avoid dup
prefix path in dfs_get_automount_devname()"). It works correctly only
when all patches applied in a following order:
1. 7ad54b98fc1f1 ("cifs: use origin fullpath for automounts")
2. a1c0d00572fc ("cifs: share dfs connections and supers") (not ported to linux-6.1)
3. d5a863a153e9 ("cifs: avoid dup prefix path in dfs_get_automount_devname()")
The reason is that patch a1c0d00572fc ("cifs: share dfs connections and
supers") changes origin_fullpath contents from just a namespace root to
a full path eg. from '//corp.fsxtest.local/namespace/' to
'//corp.fsxtest.local/namespace/folderA/fs1-folder/'. But the prefix
path '/folderA/' is also stored in a cifs superblock info and it was
copied twice. With patch d5a863a153e9 ("cifs: avoid dup prefix path in
dfs_get_automount_devname()") prepath string from superblock info is not
used in path construction and result is correct.
But the patch a1c0d00572fc ("cifs: share dfs connections and supers")
was not ported to linux-6.1, probably because it's a part of huge cifs
driver update series merged in linux-6.2, not just a bug fix. So if we
apply patches in following order:
1. 7ad54b98fc1f1 ("cifs: use origin fullpath for automounts")
2. d5a863a153e9 ("cifs: avoid dup prefix path in dfs_get_automount_devname()")
then constructed fullpath will be '//corp.fsxtest.local/namespace/fs1-folder/'
instead of '//corp.fsxtest.local/namespace/folderA/fs1-folder/' because prefix
path was not copied from the superblock info.
Changelog:
v2:
- added CONFIG_CIFS_DFS_UPCALL wrapper to fix build issue [1]
v1: (updates made to upstream version of this patch)
- set_dest_addr() converts DFS address to sockaddr differently: in
kernel 6.1 dns_resolve_server_name_to_ip() returns a string which
needs to be converted to sockaddr with cifs_convert_address().
- removed hunk to init tmp.leaf_fullpath, it was introduced later in
a1c0d00572fc ("cifs: share dfs connections and supers")
- __build_path_from_dentry_optional_prefix() and
dfs_get_automount_devname() functions were added to
fs/smb/client/cifsproto.h instead of fs/cifs/dfs.h as it doesn't exist
in 6.1
- Link to v1: https://lore.kernel.org/all/20240713031147.20332-1-apanyaki@amazon.com/
Testing:
1. tested that these steps do not work without this backport and work
with it:
- mount DFS namespace root:
mount -t cifs -o cred=/mnt/creds,noserverino //corp.fsxtest.local
- shutdown the namespace server that is in use
- access DFS link (triggers automount):
ls /mnt/dfs-namespace/fs1-folder
Reported verbose logs which demonstrate backport correctness in
regression ML thread [2].
2. build kernel with debug options listed in the patch submission
checklist[3], executed cifs test suite of the xfstests [4], no errors.
3. confirmed compilation works with all y/m/n combinations for
CONFIG_CIFS and CONFIG_CIFS_DFS_UPCALL.
4. confirmed allmodconfig and allnoconfig cross-compilation works on
arm, arm64, mips, powerpc, risc.
[1] https://lore.kernel.org/all/aaccd8cc-2bfe-4b2e-b690-be50540f9965@gmail.com/
[2] https://lore.kernel.org/all/Z9cZuBxOscqybcMy@3c06303d853a.ant.amazon.com/
[3] https://www.kernel.org/doc/html/latest/process/submit-checklist.html
[4] https://web.git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
fs/smb/client/cifs_dfs_ref.c | 34 ++++++++++++++++++++++++++++++++--
fs/smb/client/cifsproto.h | 21 +++++++++++++++++++++
fs/smb/client/dir.c | 21 +++++++++++++++------
3 files changed, 68 insertions(+), 8 deletions(-)
diff --git a/fs/smb/client/cifs_dfs_ref.c b/fs/smb/client/cifs_dfs_ref.c
index 020e71fe1454..876f9a43a99d 100644
--- a/fs/smb/client/cifs_dfs_ref.c
+++ b/fs/smb/client/cifs_dfs_ref.c
@@ -258,6 +258,31 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
goto compose_mount_options_out;
}
+static int set_dest_addr(struct smb3_fs_context *ctx, const char *full_path)
+{
+ struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
+ char *str_addr = NULL;
+ int rc;
+
+ rc = dns_resolve_server_name_to_ip(full_path, &str_addr, NULL);
+ if (rc < 0)
+ goto out;
+
+ rc = cifs_convert_address(addr, str_addr, strlen(str_addr));
+ if (!rc) {
+ cifs_dbg(FYI, "%s: failed to convert ip address\n", __func__);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ cifs_set_port(addr, ctx->port);
+ rc = 0;
+
+out:
+ kfree(str_addr);
+ return rc;
+}
+
/*
* Create a vfsmount that we can automount
*/
@@ -295,8 +320,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct path *path)
ctx = smb3_fc2context(fc);
page = alloc_dentry_path();
- /* always use tree name prefix */
- full_path = build_path_from_dentry_optional_prefix(mntpt, page, true);
+ full_path = dfs_get_automount_devname(mntpt, page);
if (IS_ERR(full_path)) {
mnt = ERR_CAST(full_path);
goto out;
@@ -315,6 +339,12 @@ static struct vfsmount *cifs_dfs_do_automount(struct path *path)
goto out;
}
+ rc = set_dest_addr(ctx, full_path);
+ if (rc) {
+ mnt = ERR_PTR(rc);
+ goto out;
+ }
+
rc = smb3_parse_devname(full_path, ctx);
if (!rc)
mnt = fc_mount(fc);
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index f37e4da0fe40..81d2761cd00a 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -57,8 +57,29 @@ extern void exit_cifs_idmap(void);
extern int init_cifs_spnego(void);
extern void exit_cifs_spnego(void);
extern const char *build_path_from_dentry(struct dentry *, void *);
+char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
+ const char *tree, int tree_len,
+ bool prefix);
extern char *build_path_from_dentry_optional_prefix(struct dentry *direntry,
void *page, bool prefix);
+
+#ifdef CONFIG_CIFS_DFS_UPCALL
+static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page)
+{
+ struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct TCP_Server_Info *server = tcon->ses->server;
+
+ if (unlikely(!server->origin_fullpath))
+ return ERR_PTR(-EREMOTE);
+
+ return __build_path_from_dentry_optional_prefix(dentry, page,
+ server->origin_fullpath,
+ strlen(server->origin_fullpath),
+ true);
+}
+#endif
+
static inline void *alloc_dentry_path(void)
{
return __getname();
diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c
index 863c7bc3db86..477302157ab3 100644
--- a/fs/smb/client/dir.c
+++ b/fs/smb/client/dir.c
@@ -78,14 +78,13 @@ build_path_from_dentry(struct dentry *direntry, void *page)
prefix);
}
-char *
-build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
- bool prefix)
+char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
+ const char *tree, int tree_len,
+ bool prefix)
{
int dfsplen;
int pplen = 0;
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
- struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
char dirsep = CIFS_DIR_SEP(cifs_sb);
char *s;
@@ -93,7 +92,7 @@ build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
return ERR_PTR(-ENOMEM);
if (prefix)
- dfsplen = strnlen(tcon->tree_name, MAX_TREE_SIZE + 1);
+ dfsplen = strnlen(tree, tree_len + 1);
else
dfsplen = 0;
@@ -123,7 +122,7 @@ build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
}
if (dfsplen) {
s -= dfsplen;
- memcpy(s, tcon->tree_name, dfsplen);
+ memcpy(s, tree, dfsplen);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
int i;
for (i = 0; i < dfsplen; i++) {
@@ -135,6 +134,16 @@ build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
return s;
}
+char *build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
+ bool prefix)
+{
+ struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+
+ return __build_path_from_dentry_optional_prefix(direntry, page, tcon->tree_name,
+ MAX_TREE_SIZE, prefix);
+}
+
/*
* Don't allow path components longer than the server max.
* Don't allow the separator character in a path component.
base-commit: 8e60a714ba3bb083b7321385054fa39ceb876914
--
2.43.0
In a rare case of gfs2 spectator mount the ls->ls_recover_spin is being
held. In this case we cannot call msleep_interruptible() as we a in a
non-sleepable context. Replace it with mdelay() to busy wait for 1
second.
Cc: stable(a)vger.kernel.org
Fixes: 4a7727725dc7 ("GFS2: Fix recovery issues for spectators")
Signed-off-by: Alexander Aring <aahringo(a)redhat.com>
---
fs/gfs2/lock_dlm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
index 58aeeae7ed8c..ac0afedff49b 100644
--- a/fs/gfs2/lock_dlm.c
+++ b/fs/gfs2/lock_dlm.c
@@ -996,7 +996,7 @@ static int control_mount(struct gfs2_sbd *sdp)
if (sdp->sd_args.ar_spectator) {
fs_info(sdp, "Recovery is required. Waiting for a "
"non-spectator to mount.\n");
- msleep_interruptible(1000);
+ mdelay(1000);
} else {
fs_info(sdp, "control_mount wait1 block %u start %u "
"mount %u lvb %u flags %lx\n", block_gen,
--
2.43.0
From: Imre Deak <imre.deak(a)intel.com>
[ Upstream commit e9b36c5be2e7fdef2cc933c1dac50bd81881e9b8 ]
Factor out a function to queue a work for probing the topology, also
used by the next patch.
Cc: Lyude Paul <lyude(a)redhat.com>
Cc: dri-devel(a)lists.freedesktop.org
Reviewed-by: Lyude Paul <lyude(a)redhat.com>
Signed-off-by: Imre Deak <imre.deak(a)intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240722165503.2084999-2-imre…
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo(a)igalia.com>
---
drivers/gpu/drm/display/drm_dp_mst_topology.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 08f8a22431fe..2a6feb83f786 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -2692,6 +2692,11 @@ static void drm_dp_mst_link_probe_work(struct work_struct *work)
drm_kms_helper_hotplug_event(dev);
}
+static void drm_dp_mst_queue_probe_work(struct drm_dp_mst_topology_mgr *mgr)
+{
+ queue_work(system_long_wq, &mgr->work);
+}
+
static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
u8 *guid)
{
@@ -3643,7 +3648,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
/* Write reset payload */
drm_dp_dpcd_write_payload(mgr, 0, 0, 0x3f);
- queue_work(system_long_wq, &mgr->work);
+ drm_dp_mst_queue_probe_work(mgr);
ret = 0;
} else {
@@ -3766,7 +3771,7 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr,
* state of our in-memory topology back into sync with reality. So,
* restart the probing process as if we're probing a new hub
*/
- queue_work(system_long_wq, &mgr->work);
+ drm_dp_mst_queue_probe_work(mgr);
mutex_unlock(&mgr->lock);
if (sync) {
--
2.47.2