]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.5
authorSasha Levin <sashal@kernel.org>
Fri, 6 Oct 2023 13:29:51 +0000 (09:29 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 6 Oct 2023 13:29:51 +0000 (09:29 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
20 files changed:
queue-6.5/alsa-hda-realtek-add-quirk-for-hp-victus-16-d1xxx-to.patch [new file with mode: 0644]
queue-6.5/alsa-hda-realtek-add-quirk-for-mute-leds-on-hp-envy-.patch [new file with mode: 0644]
queue-6.5/alsa-hda-realtek-alc287-i2s-speaker-platform-support.patch [new file with mode: 0644]
queue-6.5/alsa-hda-realtek-alc287-realtek-i2s-speaker-platform.patch [new file with mode: 0644]
queue-6.5/alsa-hda-tas2781-add-tas2781-hda-driver.patch [new file with mode: 0644]
queue-6.5/arm64-add-hwcap-for-feat_hbc-hinted-conditional-bran.patch [new file with mode: 0644]
queue-6.5/arm64-cpufeature-fix-clrbhb-and-bc-detection.patch [new file with mode: 0644]
queue-6.5/asoc-soc-utils-export-snd_soc_dai_is_dummy-symbol.patch [new file with mode: 0644]
queue-6.5/asoc-tegra-fix-redundant-plla-and-plla_out0-updates.patch [new file with mode: 0644]
queue-6.5/ata-libata-scsi-fix-delayed-scsi_rescan_device-execu.patch [new file with mode: 0644]
queue-6.5/btrfs-don-t-clear-uptodate-on-write-errors.patch [new file with mode: 0644]
queue-6.5/btrfs-remove-btrfs_writepage_endio_finish_ordered.patch [new file with mode: 0644]
queue-6.5/btrfs-remove-end_extent_writepage.patch [new file with mode: 0644]
queue-6.5/maple_tree-add-mas_is_active-to-detect-in-tree-walks.patch [new file with mode: 0644]
queue-6.5/mptcp-fix-dangling-connection-hang-up.patch [new file with mode: 0644]
queue-6.5/mptcp-remove-unnecessary-test-for-__mptcp_init_sock.patch [new file with mode: 0644]
queue-6.5/mptcp-rename-timer-related-helper-to-less-confusing-.patch [new file with mode: 0644]
queue-6.5/scsi-core-improve-type-safety-of-scsi_rescan_device.patch [new file with mode: 0644]
queue-6.5/scsi-do-not-attempt-to-rescan-suspended-devices.patch [new file with mode: 0644]
queue-6.5/series [new file with mode: 0644]

diff --git a/queue-6.5/alsa-hda-realtek-add-quirk-for-hp-victus-16-d1xxx-to.patch b/queue-6.5/alsa-hda-realtek-add-quirk-for-hp-victus-16-d1xxx-to.patch
new file mode 100644 (file)
index 0000000..7d6d815
--- /dev/null
@@ -0,0 +1,79 @@
+From 8a354d8b6952e9b4949d0c0cd618abd764cc9f48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Aug 2023 20:40:51 +0900
+Subject: ALSA: hda/realtek: Add quirk for HP Victus 16-d1xxx to enable mute
+ LED
+
+From: SungHwan Jung <onenowy@gmail.com>
+
+[ Upstream commit 93dc18e11b1ab2d485b69f91c973e6b83e47ebd0 ]
+
+This quirk enables mute LED on HP Victus 16-d1xxx (8A25) laptops, which
+use ALC245 codec.
+
+Signed-off-by: SungHwan Jung <onenowy@gmail.com>
+Link: https://lore.kernel.org/r/20230823114051.3921-1-onenowy@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 41b07476da38 ("ALSA: hda/realtek - ALC287 Realtek I2S speaker platform support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index ccf99f881cc4f..00051c14e263a 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -4639,6 +4639,22 @@ static void alc236_fixup_hp_mute_led_coefbit2(struct hda_codec *codec,
+       }
+ }
++static void alc245_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
++                                        const struct hda_fixup *fix,
++                                        int action)
++{
++      struct alc_spec *spec = codec->spec;
++
++      if (action == HDA_FIXUP_ACT_PRE_PROBE) {
++              spec->mute_led_polarity = 0;
++              spec->mute_led_coef.idx = 0x0b;
++              spec->mute_led_coef.mask = 3 << 2;
++              spec->mute_led_coef.on = 2 << 2;
++              spec->mute_led_coef.off = 1 << 2;
++              snd_hda_gen_add_mute_led_cdev(codec, coef_mute_led_set);
++      }
++}
++
+ /* turn on/off mic-mute LED per capture hook by coef bit */
+ static int coef_micmute_led_set(struct led_classdev *led_cdev,
+                               enum led_brightness brightness)
+@@ -7293,6 +7309,7 @@ enum {
+       ALC236_FIXUP_DELL_DUAL_CODECS,
+       ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
+       ALC287_FIXUP_TAS2781_I2C,
++      ALC245_FIXUP_HP_MUTE_LED_COEFBIT,
+ };
+ /* A special fixup for Lenovo C940 and Yoga Duet 7;
+@@ -9377,6 +9394,10 @@ static const struct hda_fixup alc269_fixups[] = {
+               .chained = true,
+               .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
+       },
++      [ALC245_FIXUP_HP_MUTE_LED_COEFBIT] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc245_fixup_hp_mute_led_coefbit,
++      },
+ };
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -9650,6 +9671,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+       SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
++      SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
+       SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x103c, 0x8aa0, "HP ProBook 440 G9 (MB 8A9E)", ALC236_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED),
+-- 
+2.40.1
+
diff --git a/queue-6.5/alsa-hda-realtek-add-quirk-for-mute-leds-on-hp-envy-.patch b/queue-6.5/alsa-hda-realtek-add-quirk-for-mute-leds-on-hp-envy-.patch
new file mode 100644 (file)
index 0000000..ab31ccc
--- /dev/null
@@ -0,0 +1,58 @@
+From eadc5fca3515ed944bad90e2403d0742ad11cf93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Aug 2023 20:39:48 +0200
+Subject: ALSA: hda/realtek: Add quirk for mute LEDs on HP ENVY x360 15-eu0xxx
+
+From: Fabian Vogt <fabian@ritter-vogt.de>
+
+[ Upstream commit c99c26b16c1544534ebd6a5f27a034f3e44d2597 ]
+
+The LED for the mic mute button is controlled by GPIO2.
+The mute button LED is slightly more complex, it's controlled by two bits
+in coeff 0x0b.
+
+Signed-off-by: Fabian Vogt <fabian@ritter-vogt.de>
+Link: https://lore.kernel.org/r/2693091.mvXUDI8C0e@fabians-envy
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 41b07476da38 ("ALSA: hda/realtek - ALC287 Realtek I2S speaker platform support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 00051c14e263a..57bd11c6057d5 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -7310,6 +7310,7 @@ enum {
+       ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
+       ALC287_FIXUP_TAS2781_I2C,
+       ALC245_FIXUP_HP_MUTE_LED_COEFBIT,
++      ALC245_FIXUP_HP_X360_MUTE_LEDS,
+ };
+ /* A special fixup for Lenovo C940 and Yoga Duet 7;
+@@ -9398,6 +9399,12 @@ static const struct hda_fixup alc269_fixups[] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc245_fixup_hp_mute_led_coefbit,
+       },
++      [ALC245_FIXUP_HP_X360_MUTE_LEDS] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc245_fixup_hp_mute_led_coefbit,
++              .chained = true,
++              .chain_id = ALC245_FIXUP_HP_GPIO_LED
++      },
+ };
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -9640,6 +9647,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
+       SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
+       SND_PCI_QUIRK(0x103c, 0x887a, "HP Laptop 15s-eq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
++      SND_PCI_QUIRK(0x103c, 0x888a, "HP ENVY x360 Convertible 15-eu0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS),
+       SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8895, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED),
+       SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),
+-- 
+2.40.1
+
diff --git a/queue-6.5/alsa-hda-realtek-alc287-i2s-speaker-platform-support.patch b/queue-6.5/alsa-hda-realtek-alc287-i2s-speaker-platform-support.patch
new file mode 100644 (file)
index 0000000..736092a
--- /dev/null
@@ -0,0 +1,89 @@
+From 96533eb59bc801c55a4a632c135e321c2134ca9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 16:50:41 +0800
+Subject: ALSA: hda/realtek - ALC287 I2S speaker platform support
+
+From: Kailang Yang <kailang@realtek.com>
+
+[ Upstream commit e43252db7e207a2e194e6a4883a43a31a776a968 ]
+
+0x17 was only speaker pin, DAC assigned will be 0x03. Headphone
+assigned to 0x02.
+Playback via headphone will get EQ filter processing. So,it needs to
+swap DAC.
+
+Tested-by: Mark Pearson <mpearson@lenovo.com>
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Link: https://lore.kernel.org/r/4e4cfa1b3b4c46838aecafc6e8b6f876@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 41b07476da38 ("ALSA: hda/realtek - ALC287 Realtek I2S speaker platform support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 57bd11c6057d5..b040889b22880 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -7049,6 +7049,27 @@ static void alc295_fixup_dell_inspiron_top_speakers(struct hda_codec *codec,
+       }
+ }
++/* Forcibly assign NID 0x03 to HP while NID 0x02 to SPK */
++static void alc287_fixup_bind_dacs(struct hda_codec *codec,
++                                  const struct hda_fixup *fix, int action)
++{
++      struct alc_spec *spec = codec->spec;
++      static const hda_nid_t conn[] = { 0x02, 0x03 }; /* exclude 0x06 */
++      static const hda_nid_t preferred_pairs[] = {
++              0x17, 0x02, 0x21, 0x03, 0
++      };
++
++      if (action != HDA_FIXUP_ACT_PRE_PROBE)
++              return;
++
++      snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
++      spec->gen.preferred_dacs = preferred_pairs;
++      spec->gen.auto_mute_via_amp = 1;
++      snd_hda_codec_write_cache(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
++                          0x0); /* Make sure 0x14 was disable */
++}
++
++
+ enum {
+       ALC269_FIXUP_GPIO2,
+       ALC269_FIXUP_SONY_VAIO,
+@@ -7311,6 +7332,7 @@ enum {
+       ALC287_FIXUP_TAS2781_I2C,
+       ALC245_FIXUP_HP_MUTE_LED_COEFBIT,
+       ALC245_FIXUP_HP_X360_MUTE_LEDS,
++      ALC287_FIXUP_THINKPAD_I2S_SPK,
+ };
+ /* A special fixup for Lenovo C940 and Yoga Duet 7;
+@@ -9405,6 +9427,10 @@ static const struct hda_fixup alc269_fixups[] = {
+               .chained = true,
+               .chain_id = ALC245_FIXUP_HP_GPIO_LED
+       },
++      [ALC287_FIXUP_THINKPAD_I2S_SPK] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc287_fixup_bind_dacs,
++      },
+ };
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -10537,6 +10563,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+               {0x17, 0x90170111},
+               {0x19, 0x03a11030},
+               {0x21, 0x03211020}),
++      SND_HDA_PIN_QUIRK(0x10ec0287, 0x17aa, "Lenovo", ALC287_FIXUP_THINKPAD_I2S_SPK,
++              {0x17, 0x90170110},
++              {0x19, 0x03a11030},
++              {0x21, 0x03211020}),
+       SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
+               {0x12, 0x90a60130},
+               {0x17, 0x90170110},
+-- 
+2.40.1
+
diff --git a/queue-6.5/alsa-hda-realtek-alc287-realtek-i2s-speaker-platform.patch b/queue-6.5/alsa-hda-realtek-alc287-realtek-i2s-speaker-platform.patch
new file mode 100644 (file)
index 0000000..afd4bf6
--- /dev/null
@@ -0,0 +1,43 @@
+From 097eb22c1cce349594a0c43edfd5dcd2af10813a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 16:27:16 +0800
+Subject: ALSA: hda/realtek - ALC287 Realtek I2S speaker platform support
+
+From: Kailang Yang <kailang@realtek.com>
+
+[ Upstream commit 41b07476da38ac2878a14e5b8fe0312c41ea36e3 ]
+
+New platform SSID:0x231f.
+
+0x17 was only speaker pin, DAC assigned will be 0x03. Headphone
+assigned to 0x02.
+Playback via headphone will get EQ filter processing.
+So, it needs to swap DAC.
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/8d63c6e360124e3ea2523753050e6f05@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index b040889b22880..45fa102060cef 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10567,6 +10567,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+               {0x17, 0x90170110},
+               {0x19, 0x03a11030},
+               {0x21, 0x03211020}),
++      SND_HDA_PIN_QUIRK(0x10ec0287, 0x17aa, "Lenovo", ALC287_FIXUP_THINKPAD_I2S_SPK,
++              {0x17, 0x90170110}, /* 0x231f with RTK I2S AMP */
++              {0x19, 0x04a11040},
++              {0x21, 0x04211020}),
+       SND_HDA_PIN_QUIRK(0x10ec0286, 0x1025, "Acer", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE,
+               {0x12, 0x90a60130},
+               {0x17, 0x90170110},
+-- 
+2.40.1
+
diff --git a/queue-6.5/alsa-hda-tas2781-add-tas2781-hda-driver.patch b/queue-6.5/alsa-hda-tas2781-add-tas2781-hda-driver.patch
new file mode 100644 (file)
index 0000000..fbe1b6a
--- /dev/null
@@ -0,0 +1,180 @@
+From 49ae5f8082daf33e220fd5c14df7c14565971741 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 16:58:35 +0800
+Subject: ALSA: hda/tas2781: Add tas2781 HDA driver
+
+From: Shenghao Ding <shenghao-ding@ti.com>
+
+[ Upstream commit 3babae915f4c15d76a5134e55806a1c1588e2865 ]
+
+Integrate tas2781 configs for Lenovo Laptops. All of the tas2781s in the
+laptop will be aggregated as one audio device. The code support realtek
+as the primary codec. Rename "struct cs35l41_dev_name" to
+"struct scodec_dev_name" for all other side codecs instead of the certain
+one.
+
+Signed-off-by: Shenghao Ding <shenghao-ding@ti.com>
+Link: https://lore.kernel.org/r/20230818085836.1442-1-shenghao-ding@ti.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 41b07476da38 ("ALSA: hda/realtek - ALC287 Realtek I2S speaker platform support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 88 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 85 insertions(+), 3 deletions(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 4a13747b2b0f3..ccf99f881cc4f 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6721,7 +6721,7 @@ static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_
+       }
+ }
+-struct cs35l41_dev_name {
++struct scodec_dev_name {
+       const char *bus;
+       const char *hid;
+       int index;
+@@ -6730,7 +6730,7 @@ struct cs35l41_dev_name {
+ /* match the device name in a slightly relaxed manner */
+ static int comp_match_cs35l41_dev_name(struct device *dev, void *data)
+ {
+-      struct cs35l41_dev_name *p = data;
++      struct scodec_dev_name *p = data;
+       const char *d = dev_name(dev);
+       int n = strlen(p->bus);
+       char tmp[32];
+@@ -6746,12 +6746,32 @@ static int comp_match_cs35l41_dev_name(struct device *dev, void *data)
+       return !strcmp(d + n, tmp);
+ }
++static int comp_match_tas2781_dev_name(struct device *dev,
++      void *data)
++{
++      struct scodec_dev_name *p = data;
++      const char *d = dev_name(dev);
++      int n = strlen(p->bus);
++      char tmp[32];
++
++      /* check the bus name */
++      if (strncmp(d, p->bus, n))
++              return 0;
++      /* skip the bus number */
++      if (isdigit(d[n]))
++              n++;
++      /* the rest must be exact matching */
++      snprintf(tmp, sizeof(tmp), "-%s:00", p->hid);
++
++      return !strcmp(d + n, tmp);
++}
++
+ static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char *bus,
+                                 const char *hid, int count)
+ {
+       struct device *dev = hda_codec_dev(cdc);
+       struct alc_spec *spec = cdc->spec;
+-      struct cs35l41_dev_name *rec;
++      struct scodec_dev_name *rec;
+       int ret, i;
+       switch (action) {
+@@ -6779,6 +6799,41 @@ static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char
+       }
+ }
++static void tas2781_generic_fixup(struct hda_codec *cdc, int action,
++      const char *bus, const char *hid)
++{
++      struct device *dev = hda_codec_dev(cdc);
++      struct alc_spec *spec = cdc->spec;
++      struct scodec_dev_name *rec;
++      int ret;
++
++      switch (action) {
++      case HDA_FIXUP_ACT_PRE_PROBE:
++              rec = devm_kmalloc(dev, sizeof(*rec), GFP_KERNEL);
++              if (!rec)
++                      return;
++              rec->bus = bus;
++              rec->hid = hid;
++              rec->index = 0;
++              spec->comps[0].codec = cdc;
++              component_match_add(dev, &spec->match,
++                      comp_match_tas2781_dev_name, rec);
++              ret = component_master_add_with_match(dev, &comp_master_ops,
++                      spec->match);
++              if (ret)
++                      codec_err(cdc,
++                              "Fail to register component aggregator %d\n",
++                              ret);
++              else
++                      spec->gen.pcm_playback_hook =
++                              comp_generic_playback_hook;
++              break;
++      case HDA_FIXUP_ACT_FREE:
++              component_master_del(dev, &comp_master_ops);
++              break;
++      }
++}
++
+ static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
+ {
+       cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 2);
+@@ -6806,6 +6861,12 @@ static void alc287_fixup_legion_16ithg6_speakers(struct hda_codec *cdc, const st
+       cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0101", 2);
+ }
++static void tas2781_fixup_i2c(struct hda_codec *cdc,
++      const struct hda_fixup *fix, int action)
++{
++       tas2781_generic_fixup(cdc, action, "i2c", "TIAS2781");
++}
++
+ /* for alc295_fixup_hp_top_speakers */
+ #include "hp_x360_helper.c"
+@@ -7231,6 +7292,7 @@ enum {
+       ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,
+       ALC236_FIXUP_DELL_DUAL_CODECS,
+       ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
++      ALC287_FIXUP_TAS2781_I2C,
+ };
+ /* A special fixup for Lenovo C940 and Yoga Duet 7;
+@@ -9309,6 +9371,12 @@ static const struct hda_fixup alc269_fixups[] = {
+               .chained = true,
+               .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
+       },
++      [ALC287_FIXUP_TAS2781_I2C] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = tas2781_fixup_i2c,
++              .chained = true,
++              .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
++      },
+ };
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -9890,6 +9958,20 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
+       SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
+       SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
++      SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual powe mode2 YC", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x3884, "Y780 YG DUAL", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x38bf, "Yoga S980-14.5 proX LX Dual", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x38c3, "Y980 DUAL", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x38cb, "Y790 YG DUAL", ALC287_FIXUP_TAS2781_I2C),
++      SND_PCI_QUIRK(0x17aa, 0x38cd, "Y790 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
+       SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
+       SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
+-- 
+2.40.1
+
diff --git a/queue-6.5/arm64-add-hwcap-for-feat_hbc-hinted-conditional-bran.patch b/queue-6.5/arm64-add-hwcap-for-feat_hbc-hinted-conditional-bran.patch
new file mode 100644 (file)
index 0000000..1633909
--- /dev/null
@@ -0,0 +1,85 @@
+From 8057be5d7ac578722af942d2455258d2e2e07944 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 15:37:45 +0100
+Subject: arm64: add HWCAP for FEAT_HBC (hinted conditional branches)
+
+From: Joey Gouly <joey.gouly@arm.com>
+
+[ Upstream commit 7f86d128e437990fd08d9e66ae7c1571666cff8a ]
+
+Add a HWCAP for FEAT_HBC, so that userspace can make a decision on using
+this feature.
+
+Signed-off-by: Joey Gouly <joey.gouly@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20230804143746.3900803-2-joey.gouly@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Stable-dep-of: 479965a2b7ec ("arm64: cpufeature: Fix CLRBHB and BC detection")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/hwcap.h      | 1 +
+ arch/arm64/include/uapi/asm/hwcap.h | 1 +
+ arch/arm64/kernel/cpufeature.c      | 3 ++-
+ arch/arm64/kernel/cpuinfo.c         | 1 +
+ 4 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
+index 692b1ec663b27..521267478d187 100644
+--- a/arch/arm64/include/asm/hwcap.h
++++ b/arch/arm64/include/asm/hwcap.h
+@@ -138,6 +138,7 @@
+ #define KERNEL_HWCAP_SME_B16B16               __khwcap2_feature(SME_B16B16)
+ #define KERNEL_HWCAP_SME_F16F16               __khwcap2_feature(SME_F16F16)
+ #define KERNEL_HWCAP_MOPS             __khwcap2_feature(MOPS)
++#define KERNEL_HWCAP_HBC              __khwcap2_feature(HBC)
+ /*
+  * This yields a mask that user programs can use to figure out what
+diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
+index a2cac4305b1e0..53026f45a5092 100644
+--- a/arch/arm64/include/uapi/asm/hwcap.h
++++ b/arch/arm64/include/uapi/asm/hwcap.h
+@@ -103,5 +103,6 @@
+ #define HWCAP2_SME_B16B16     (1UL << 41)
+ #define HWCAP2_SME_F16F16     (1UL << 42)
+ #define HWCAP2_MOPS           (1UL << 43)
++#define HWCAP2_HBC            (1UL << 44)
+ #endif /* _UAPI__ASM_HWCAP_H */
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index f9d456fe132d8..ac764c1dac363 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -222,7 +222,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
+ static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0),
+-      ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0),
++      ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_MOPS_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
+                      FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0),
+@@ -2844,6 +2844,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
+       HWCAP_CAP(ID_AA64ISAR2_EL1, RPRES, IMP, CAP_HWCAP, KERNEL_HWCAP_RPRES),
+       HWCAP_CAP(ID_AA64ISAR2_EL1, WFxT, IMP, CAP_HWCAP, KERNEL_HWCAP_WFXT),
+       HWCAP_CAP(ID_AA64ISAR2_EL1, MOPS, IMP, CAP_HWCAP, KERNEL_HWCAP_MOPS),
++      HWCAP_CAP(ID_AA64ISAR2_EL1, BC, IMP, CAP_HWCAP, KERNEL_HWCAP_HBC),
+ #ifdef CONFIG_ARM64_SME
+       HWCAP_CAP(ID_AA64PFR1_EL1, SME, IMP, CAP_HWCAP, KERNEL_HWCAP_SME),
+       HWCAP_CAP(ID_AA64SMFR0_EL1, FA64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_FA64),
+diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
+index 58622dc859177..98fda85005353 100644
+--- a/arch/arm64/kernel/cpuinfo.c
++++ b/arch/arm64/kernel/cpuinfo.c
+@@ -126,6 +126,7 @@ static const char *const hwcap_str[] = {
+       [KERNEL_HWCAP_SME_B16B16]       = "smeb16b16",
+       [KERNEL_HWCAP_SME_F16F16]       = "smef16f16",
+       [KERNEL_HWCAP_MOPS]             = "mops",
++      [KERNEL_HWCAP_HBC]              = "hbc",
+ };
+ #ifdef CONFIG_COMPAT
+-- 
+2.40.1
+
diff --git a/queue-6.5/arm64-cpufeature-fix-clrbhb-and-bc-detection.patch b/queue-6.5/arm64-cpufeature-fix-clrbhb-and-bc-detection.patch
new file mode 100644 (file)
index 0000000..34b875e
--- /dev/null
@@ -0,0 +1,80 @@
+From 8a5c763da5aa12beba942da05d306c48437f5812 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 14:34:29 +0100
+Subject: arm64: cpufeature: Fix CLRBHB and BC detection
+
+From: Kristina Martsenko <kristina.martsenko@arm.com>
+
+[ Upstream commit 479965a2b7ec481737df0cadf553331063b9c343 ]
+
+ClearBHB support is indicated by the CLRBHB field in ID_AA64ISAR2_EL1.
+Following some refactoring the kernel incorrectly checks the BC field
+instead. Fix the detection to use the right field.
+
+(Note: The original ClearBHB support had it as FTR_HIGHER_SAFE, but this
+patch uses FTR_LOWER_SAFE, which seems more correct.)
+
+Also fix the detection of BC (hinted conditional branches) to use
+FTR_LOWER_SAFE, so that it is not reported on mismatched systems.
+
+Fixes: 356137e68a9f ("arm64/sysreg: Make BHB clear feature defines match the architecture")
+Fixes: 8fcc8285c0e3 ("arm64/sysreg: Convert ID_AA64ISAR2_EL1 to automatic generation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20230912133429.2606875-1-kristina.martsenko@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/cpufeature.h | 2 +-
+ arch/arm64/kernel/cpufeature.c      | 3 ++-
+ arch/arm64/tools/sysreg             | 6 +++++-
+ 3 files changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
+index 96e50227f940e..5bba393760557 100644
+--- a/arch/arm64/include/asm/cpufeature.h
++++ b/arch/arm64/include/asm/cpufeature.h
+@@ -663,7 +663,7 @@ static inline bool supports_clearbhb(int scope)
+               isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
+       return cpuid_feature_extract_unsigned_field(isar2,
+-                                                  ID_AA64ISAR2_EL1_BC_SHIFT);
++                                                  ID_AA64ISAR2_EL1_CLRBHB_SHIFT);
+ }
+ const struct cpumask *system_32bit_el0_cpumask(void);
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index ac764c1dac363..2c0b8444fea67 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -222,7 +222,8 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
+ static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0),
+-      ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0),
++      ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CLRBHB_SHIFT, 4, 0),
++      ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_MOPS_SHIFT, 4, 0),
+       ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
+                      FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0),
+diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
+index 65866bf819c33..ffc81afa6caca 100644
+--- a/arch/arm64/tools/sysreg
++++ b/arch/arm64/tools/sysreg
+@@ -1347,7 +1347,11 @@ UnsignedEnum    51:48   RPRFM
+       0b0000  NI
+       0b0001  IMP
+ EndEnum
+-Res0  47:28
++Res0  47:32
++UnsignedEnum  31:28   CLRBHB
++      0b0000  NI
++      0b0001  IMP
++EndEnum
+ UnsignedEnum  27:24   PAC_frac
+       0b0000  NI
+       0b0001  IMP
+-- 
+2.40.1
+
diff --git a/queue-6.5/asoc-soc-utils-export-snd_soc_dai_is_dummy-symbol.patch b/queue-6.5/asoc-soc-utils-export-snd_soc_dai_is_dummy-symbol.patch
new file mode 100644 (file)
index 0000000..40d24a4
--- /dev/null
@@ -0,0 +1,35 @@
+From bbf28b5526628d8e025a8666998314d62f87b0e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Sep 2023 20:32:24 +0530
+Subject: ASoC: soc-utils: Export snd_soc_dai_is_dummy() symbol
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+[ Upstream commit f101583fa9f8c3f372d4feb61d67da0ccbf4d9a5 ]
+
+Export symbol snd_soc_dai_is_dummy() for usage outside core driver
+modules. This is required by Tegra ASoC machine driver.
+
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Link: https://lore.kernel.org/r/1694098945-32760-2-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-utils.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
+index 11607c5f5d5a8..9c746e4edef71 100644
+--- a/sound/soc/soc-utils.c
++++ b/sound/soc/soc-utils.c
+@@ -217,6 +217,7 @@ int snd_soc_dai_is_dummy(struct snd_soc_dai *dai)
+               return 1;
+       return 0;
+ }
++EXPORT_SYMBOL_GPL(snd_soc_dai_is_dummy);
+ int snd_soc_component_is_dummy(struct snd_soc_component *component)
+ {
+-- 
+2.40.1
+
diff --git a/queue-6.5/asoc-tegra-fix-redundant-plla-and-plla_out0-updates.patch b/queue-6.5/asoc-tegra-fix-redundant-plla-and-plla_out0-updates.patch
new file mode 100644 (file)
index 0000000..0cc2f54
--- /dev/null
@@ -0,0 +1,90 @@
+From 37c0e1b564a800ace7afd64aa91ce9d910323b6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Sep 2023 20:32:25 +0530
+Subject: ASoC: tegra: Fix redundant PLLA and PLLA_OUT0 updates
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+[ Upstream commit e765886249c533e1bb5cbc3cd741bad677417312 ]
+
+Tegra audio graph card has many DAI links which connects internal
+AHUB modules and external audio codecs. Since these are DPCM links,
+hw_params() call in the machine driver happens for each connected
+BE link and PLLA is updated every time. This is not really needed
+for all links as only I/O link DAIs derive respective clocks from
+PLLA_OUT0 and thus from PLLA. Hence add checks to limit the clock
+updates to DAIs over I/O links.
+
+This found to be fixing a DMIC clock discrepancy which is suspected
+to happen because of back to back quick PLLA and PLLA_OUT0 rate
+updates. This was observed on Jetson TX2 platform where DMIC clock
+ended up with unexpected value.
+
+Fixes: 202e2f774543 ("ASoC: tegra: Add audio graph based card driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Link: https://lore.kernel.org/r/1694098945-32760-3-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/tegra/tegra_audio_graph_card.c | 30 ++++++++++++++----------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+diff --git a/sound/soc/tegra/tegra_audio_graph_card.c b/sound/soc/tegra/tegra_audio_graph_card.c
+index 1f2c5018bf5ac..4737e776d3837 100644
+--- a/sound/soc/tegra/tegra_audio_graph_card.c
++++ b/sound/soc/tegra/tegra_audio_graph_card.c
+@@ -10,6 +10,7 @@
+ #include <linux/platform_device.h>
+ #include <sound/graph_card.h>
+ #include <sound/pcm_params.h>
++#include <sound/soc-dai.h>
+ #define MAX_PLLA_OUT0_DIV 128
+@@ -44,6 +45,21 @@ struct tegra_audio_cdata {
+       unsigned int plla_out0_rates[NUM_RATE_TYPE];
+ };
++static bool need_clk_update(struct snd_soc_dai *dai)
++{
++      if (snd_soc_dai_is_dummy(dai) ||
++          !dai->driver->ops ||
++          !dai->driver->name)
++              return false;
++
++      if (strstr(dai->driver->name, "I2S") ||
++          strstr(dai->driver->name, "DMIC") ||
++          strstr(dai->driver->name, "DSPK"))
++              return true;
++
++      return false;
++}
++
+ /* Setup PLL clock as per the given sample rate */
+ static int tegra_audio_graph_update_pll(struct snd_pcm_substream *substream,
+                                       struct snd_pcm_hw_params *params)
+@@ -140,19 +156,7 @@ static int tegra_audio_graph_hw_params(struct snd_pcm_substream *substream,
+       struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+       int err;
+-      /*
+-       * This gets called for each DAI link (FE or BE) when DPCM is used.
+-       * We may not want to update PLLA rate for each call. So PLLA update
+-       * must be restricted to external I/O links (I2S, DMIC or DSPK) since
+-       * they actually depend on it. I/O modules update their clocks in
+-       * hw_param() of their respective component driver and PLLA rate
+-       * update here helps them to derive appropriate rates.
+-       *
+-       * TODO: When more HW accelerators get added (like sample rate
+-       * converter, volume gain controller etc., which don't really
+-       * depend on PLLA) we need a better way to filter here.
+-       */
+-      if (cpu_dai->driver->ops && rtd->dai_link->no_pcm) {
++      if (need_clk_update(cpu_dai)) {
+               err = tegra_audio_graph_update_pll(substream, params);
+               if (err)
+                       return err;
+-- 
+2.40.1
+
diff --git a/queue-6.5/ata-libata-scsi-fix-delayed-scsi_rescan_device-execu.patch b/queue-6.5/ata-libata-scsi-fix-delayed-scsi_rescan_device-execu.patch
new file mode 100644 (file)
index 0000000..1466a47
--- /dev/null
@@ -0,0 +1,152 @@
+From f803e78617823ec1d571f40a115fe9b1a054a0de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Sep 2023 09:06:23 +0900
+Subject: ata: libata-scsi: Fix delayed scsi_rescan_device() execution
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+[ Upstream commit 8b4d9469d0b0e553208ee6f62f2807111fde18b9 ]
+
+Commit 6aa0365a3c85 ("ata: libata-scsi: Avoid deadlock on rescan after
+device resume") modified ata_scsi_dev_rescan() to check the scsi device
+"is_suspended" power field to ensure that the scsi device associated
+with an ATA device is fully resumed when scsi_rescan_device() is
+executed. However, this fix is problematic as:
+1) It relies on a PM internal field that should not be used without PM
+   device locking protection.
+2) The check for is_suspended and the call to scsi_rescan_device() are
+   not atomic and a suspend PM event may be triggered between them,
+   casuing scsi_rescan_device() to be called on a suspended device and
+   in that function blocking while holding the scsi device lock. This
+   would deadlock a following resume operation.
+These problems can trigger PM deadlocks on resume, especially with
+resume operations triggered quickly after or during suspend operations.
+E.g., a simple bash script like:
+
+for (( i=0; i<10; i++ )); do
+       echo "+2 > /sys/class/rtc/rtc0/wakealarm
+       echo mem > /sys/power/state
+done
+
+that triggers a resume 2 seconds after starting suspending a system can
+quickly lead to a PM deadlock preventing the system from correctly
+resuming.
+
+Fix this by replacing the check on is_suspended with a check on the
+return value given by scsi_rescan_device() as that function will fail if
+called against a suspended device. Also make sure rescan tasks already
+scheduled are first cancelled before suspending an ata port.
+
+Fixes: 6aa0365a3c85 ("ata: libata-scsi: Avoid deadlock on rescan after device resume")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/libata-core.c | 16 ++++++++++++++++
+ drivers/ata/libata-scsi.c | 33 +++++++++++++++------------------
+ 2 files changed, 31 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 76bf185a73c65..6ae9cff6b50c5 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -5245,11 +5245,27 @@ static const unsigned int ata_port_suspend_ehi = ATA_EHI_QUIET
+ static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg)
+ {
++      /*
++       * We are about to suspend the port, so we do not care about
++       * scsi_rescan_device() calls scheduled by previous resume operations.
++       * The next resume will schedule the rescan again. So cancel any rescan
++       * that is not done yet.
++       */
++      cancel_delayed_work_sync(&ap->scsi_rescan_task);
++
+       ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false);
+ }
+ static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg)
+ {
++      /*
++       * We are about to suspend the port, so we do not care about
++       * scsi_rescan_device() calls scheduled by previous resume operations.
++       * The next resume will schedule the rescan again. So cancel any rescan
++       * that is not done yet.
++       */
++      cancel_delayed_work_sync(&ap->scsi_rescan_task);
++
+       ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true);
+ }
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index 22d7c26297889..ed3146c460910 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -4900,7 +4900,7 @@ void ata_scsi_dev_rescan(struct work_struct *work)
+       struct ata_link *link;
+       struct ata_device *dev;
+       unsigned long flags;
+-      bool delay_rescan = false;
++      int ret = 0;
+       mutex_lock(&ap->scsi_scan_mutex);
+       spin_lock_irqsave(ap->lock, flags);
+@@ -4909,37 +4909,34 @@ void ata_scsi_dev_rescan(struct work_struct *work)
+               ata_for_each_dev(dev, link, ENABLED) {
+                       struct scsi_device *sdev = dev->sdev;
++                      /*
++                       * If the port was suspended before this was scheduled,
++                       * bail out.
++                       */
++                      if (ap->pflags & ATA_PFLAG_SUSPENDED)
++                              goto unlock;
++
+                       if (!sdev)
+                               continue;
+                       if (scsi_device_get(sdev))
+                               continue;
+-                      /*
+-                       * If the rescan work was scheduled because of a resume
+-                       * event, the port is already fully resumed, but the
+-                       * SCSI device may not yet be fully resumed. In such
+-                       * case, executing scsi_rescan_device() may cause a
+-                       * deadlock with the PM code on device_lock(). Prevent
+-                       * this by giving up and retrying rescan after a short
+-                       * delay.
+-                       */
+-                      delay_rescan = sdev->sdev_gendev.power.is_suspended;
+-                      if (delay_rescan) {
+-                              scsi_device_put(sdev);
+-                              break;
+-                      }
+-
+                       spin_unlock_irqrestore(ap->lock, flags);
+-                      scsi_rescan_device(sdev);
++                      ret = scsi_rescan_device(sdev);
+                       scsi_device_put(sdev);
+                       spin_lock_irqsave(ap->lock, flags);
++
++                      if (ret)
++                              goto unlock;
+               }
+       }
++unlock:
+       spin_unlock_irqrestore(ap->lock, flags);
+       mutex_unlock(&ap->scsi_scan_mutex);
+-      if (delay_rescan)
++      /* Reschedule with a delay if scsi_rescan_device() returned an error */
++      if (ret)
+               schedule_delayed_work(&ap->scsi_rescan_task,
+                                     msecs_to_jiffies(5));
+ }
+-- 
+2.40.1
+
diff --git a/queue-6.5/btrfs-don-t-clear-uptodate-on-write-errors.patch b/queue-6.5/btrfs-don-t-clear-uptodate-on-write-errors.patch
new file mode 100644 (file)
index 0000000..3203405
--- /dev/null
@@ -0,0 +1,126 @@
+From 4c332287a5cd2f41bffe3f092df54326d02a0a02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Sep 2023 15:31:39 -0400
+Subject: btrfs: don't clear uptodate on write errors
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit b595d25996329427b2c09d4b90395a165fb3ef8e ]
+
+We have been consistently seeing hangs with generic/648 in our subpage
+GitHub CI setup.  This is a classic deadlock, we are calling
+btrfs_read_folio() on a folio, which requires holding the folio lock on
+the folio, and then finding a ordered extent that overlaps that range
+and calling btrfs_start_ordered_extent(), which then tries to write out
+the dirty page, which requires taking the folio lock and then we
+deadlock.
+
+The hang happens because we're writing to range [1271750656, 1271767040),
+page index [77621, 77622], and page 77621 is !Uptodate.  It is also Dirty,
+so we call btrfs_read_folio() for 77621 and which does
+btrfs_lock_and_flush_ordered_range() for that range, and we find an ordered
+extent which is [1271644160, 1271746560), page index [77615, 77621].
+The page indexes overlap, but the actual bytes don't overlap.  We're
+holding the page lock for 77621, then call
+btrfs_lock_and_flush_ordered_range() which tries to flush the dirty
+page, and tries to lock 77621 again and then we deadlock.
+
+The byte ranges do not overlap, but with subpage support if we clear
+uptodate on any portion of the page we mark the entire thing as not
+uptodate.
+
+We have been clearing page uptodate on write errors, but no other file
+system does this, and is in fact incorrect.  This doesn't hurt us in the
+!subpage case because we can't end up with overlapped ranges that don't
+also overlap on the page.
+
+Fix this by not clearing uptodate when we have a write error.  The only
+thing we should be doing in this case is setting the mapping error and
+carrying on.  This makes it so we would no longer call
+btrfs_read_folio() on the page as it's uptodate and eliminates the
+deadlock.
+
+With this patch we're now able to make it through a full fstests run on
+our subpage blocksize VMs.
+
+Note for stable backports: this probably goes beyond 6.1 but the code
+has been cleaned up and clearing the uptodate bit must be verified on
+each version independently.
+
+CC: stable@vger.kernel.org # 6.1+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/extent_io.c | 9 +--------
+ fs/btrfs/inode.c     | 4 ----
+ 2 files changed, 1 insertion(+), 12 deletions(-)
+
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index 009c322c5418d..d8461c9aa2445 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -533,10 +533,8 @@ static void end_bio_extent_writepage(struct btrfs_bio *bbio)
+                                  bvec->bv_offset, bvec->bv_len);
+               btrfs_finish_ordered_extent(bbio->ordered, page, start, len, !error);
+-              if (error) {
+-                      btrfs_page_clear_uptodate(fs_info, page, start, len);
++              if (error)
+                       mapping_set_error(page->mapping, error);
+-              }
+               btrfs_page_clear_writeback(fs_info, page, start, len);
+       }
+@@ -1508,8 +1506,6 @@ static int __extent_writepage(struct page *page, struct btrfs_bio_ctrl *bio_ctrl
+       if (ret) {
+               btrfs_mark_ordered_io_finished(BTRFS_I(inode), page, page_start,
+                                              PAGE_SIZE, !ret);
+-              btrfs_page_clear_uptodate(btrfs_sb(inode->i_sb), page,
+-                                        page_start, PAGE_SIZE);
+               mapping_set_error(page->mapping, ret);
+       }
+       unlock_page(page);
+@@ -1676,8 +1672,6 @@ static void extent_buffer_write_end_io(struct btrfs_bio *bbio)
+               struct page *page = bvec->bv_page;
+               u32 len = bvec->bv_len;
+-              if (!uptodate)
+-                      btrfs_page_clear_uptodate(fs_info, page, start, len);
+               btrfs_page_clear_writeback(fs_info, page, start, len);
+               bio_offset += len;
+       }
+@@ -2256,7 +2250,6 @@ int extent_write_locked_range(struct inode *inode, u64 start, u64 end,
+               if (ret) {
+                       btrfs_mark_ordered_io_finished(BTRFS_I(inode), page,
+                                                      cur, cur_len, !ret);
+-                      btrfs_page_clear_uptodate(fs_info, page, cur, cur_len);
+                       mapping_set_error(page->mapping, ret);
+               }
+               btrfs_page_unlock_writer(fs_info, page, cur, cur_len);
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index b126394ca3dde..0f4498dfa30c9 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -1162,9 +1162,6 @@ static int submit_uncompressed_range(struct btrfs_inode *inode,
+                       btrfs_mark_ordered_io_finished(inode, locked_page,
+                                                      page_start, PAGE_SIZE,
+                                                      !ret);
+-                      btrfs_page_clear_uptodate(inode->root->fs_info,
+-                                                locked_page, page_start,
+-                                                PAGE_SIZE);
+                       mapping_set_error(locked_page->mapping, ret);
+                       unlock_page(locked_page);
+               }
+@@ -2951,7 +2948,6 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
+               mapping_set_error(page->mapping, ret);
+               btrfs_mark_ordered_io_finished(inode, page, page_start,
+                                              PAGE_SIZE, !ret);
+-              btrfs_page_clear_uptodate(fs_info, page, page_start, PAGE_SIZE);
+               clear_page_dirty_for_io(page);
+       }
+       btrfs_page_clear_checked(fs_info, page, page_start, PAGE_SIZE);
+-- 
+2.40.1
+
diff --git a/queue-6.5/btrfs-remove-btrfs_writepage_endio_finish_ordered.patch b/queue-6.5/btrfs-remove-btrfs_writepage_endio_finish_ordered.patch
new file mode 100644 (file)
index 0000000..241d3c3
--- /dev/null
@@ -0,0 +1,145 @@
+From c5b0c5a4299d91df651782d99eacf0465c9cf450 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Jun 2023 17:31:25 +0200
+Subject: btrfs: remove btrfs_writepage_endio_finish_ordered
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 6648cedd86135db197410e56b5372b2945f2b311 ]
+
+btrfs_writepage_endio_finish_ordered is a small wrapper around
+btrfs_mark_ordered_io_finished that just changs the argument passing
+slightly, and adds a tracepoint.
+
+Move the tracpoint to btrfs_mark_ordered_io_finished, which means
+it now also covers the error handling in btrfs_cleanup_ordered_extent
+and switch all callers to just call btrfs_mark_ordered_io_finished
+directly.
+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: b595d2599632 ("btrfs: don't clear uptodate on write errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/btrfs_inode.h  |  3 ---
+ fs/btrfs/extent_io.c    | 17 ++++++++---------
+ fs/btrfs/inode.c        |  9 ---------
+ fs/btrfs/ordered-data.c |  4 ++++
+ 4 files changed, 12 insertions(+), 21 deletions(-)
+
+diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
+index d47a927b3504d..90e60ad9db620 100644
+--- a/fs/btrfs/btrfs_inode.h
++++ b/fs/btrfs/btrfs_inode.h
+@@ -501,9 +501,6 @@ int btrfs_run_delalloc_range(struct btrfs_inode *inode, struct page *locked_page
+                            u64 start, u64 end, int *page_started,
+                            unsigned long *nr_written, struct writeback_control *wbc);
+ int btrfs_writepage_cow_fixup(struct page *page);
+-void btrfs_writepage_endio_finish_ordered(struct btrfs_inode *inode,
+-                                        struct page *page, u64 start,
+-                                        u64 end, bool uptodate);
+ int btrfs_encoded_io_compression_from_extent(struct btrfs_fs_info *fs_info,
+                                            int compress_type);
+ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode,
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index 7cc0ed7532793..b051b6e52022c 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -504,17 +504,15 @@ void end_extent_writepage(struct page *page, int err, u64 start, u64 end)
+       struct btrfs_inode *inode;
+       const bool uptodate = (err == 0);
+       int ret = 0;
++      u32 len = end + 1 - start;
++      ASSERT(end + 1 - start <= U32_MAX);
+       ASSERT(page && page->mapping);
+       inode = BTRFS_I(page->mapping->host);
+-      btrfs_writepage_endio_finish_ordered(inode, page, start, end, uptodate);
++      btrfs_mark_ordered_io_finished(inode, page, start, len, uptodate);
+       if (!uptodate) {
+               const struct btrfs_fs_info *fs_info = inode->root->fs_info;
+-              u32 len;
+-
+-              ASSERT(end + 1 - start <= U32_MAX);
+-              len = end + 1 - start;
+               btrfs_page_clear_uptodate(fs_info, page, start, len);
+               ret = err < 0 ? err : -EIO;
+@@ -1382,6 +1380,7 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
+       bio_ctrl->end_io_func = end_bio_extent_writepage;
+       while (cur <= end) {
++              u32 len = end - cur + 1;
+               u64 disk_bytenr;
+               u64 em_end;
+               u64 dirty_range_start = cur;
+@@ -1389,8 +1388,8 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
+               u32 iosize;
+               if (cur >= i_size) {
+-                      btrfs_writepage_endio_finish_ordered(inode, page, cur,
+-                                                           end, true);
++                      btrfs_mark_ordered_io_finished(inode, page, cur, len,
++                                                     true);
+                       /*
+                        * This range is beyond i_size, thus we don't need to
+                        * bother writing back.
+@@ -1399,7 +1398,7 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
+                        * writeback the sectors with subpage dirty bits,
+                        * causing writeback without ordered extent.
+                        */
+-                      btrfs_page_clear_dirty(fs_info, page, cur, end + 1 - cur);
++                      btrfs_page_clear_dirty(fs_info, page, cur, len);
+                       break;
+               }
+@@ -1410,7 +1409,7 @@ static noinline_for_stack int __extent_writepage_io(struct btrfs_inode *inode,
+                       continue;
+               }
+-              em = btrfs_get_extent(inode, NULL, 0, cur, end - cur + 1);
++              em = btrfs_get_extent(inode, NULL, 0, cur, len);
+               if (IS_ERR(em)) {
+                       ret = PTR_ERR_OR_ZERO(em);
+                       goto out_error;
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index d5c112f6091b1..e0bb4018ddb28 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -3391,15 +3391,6 @@ int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered)
+       return btrfs_finish_one_ordered(ordered);
+ }
+-void btrfs_writepage_endio_finish_ordered(struct btrfs_inode *inode,
+-                                        struct page *page, u64 start,
+-                                        u64 end, bool uptodate)
+-{
+-      trace_btrfs_writepage_end_io_hook(inode, start, end, uptodate);
+-
+-      btrfs_mark_ordered_io_finished(inode, page, start, end + 1 - start, uptodate);
+-}
+-
+ /*
+  * Verify the checksum for a single sector without any extra action that depend
+  * on the type of I/O.
+diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
+index 5b1aac3fc8e4a..eea5215280dfe 100644
+--- a/fs/btrfs/ordered-data.c
++++ b/fs/btrfs/ordered-data.c
+@@ -410,6 +410,10 @@ void btrfs_mark_ordered_io_finished(struct btrfs_inode *inode,
+       unsigned long flags;
+       u64 cur = file_offset;
++      trace_btrfs_writepage_end_io_hook(inode, file_offset,
++                                        file_offset + num_bytes - 1,
++                                        uptodate);
++
+       spin_lock_irqsave(&tree->lock, flags);
+       while (cur < file_offset + num_bytes) {
+               u64 entry_end;
+-- 
+2.40.1
+
diff --git a/queue-6.5/btrfs-remove-end_extent_writepage.patch b/queue-6.5/btrfs-remove-end_extent_writepage.patch
new file mode 100644 (file)
index 0000000..2fd3df7
--- /dev/null
@@ -0,0 +1,216 @@
+From f5d4b635889de5aa70af38ef7158b770893c4dd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Jun 2023 17:31:26 +0200
+Subject: btrfs: remove end_extent_writepage
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 9783e4deed7291996459858a1a16f41a8988dd60 ]
+
+end_extent_writepage is a small helper that combines a call to
+btrfs_mark_ordered_io_finished with conditional error-only calls to
+btrfs_page_clear_uptodate and mapping_set_error with a somewhat
+unfortunate calling convention that passes and inclusive end instead
+of the len expected by the underlying functions.
+
+Remove end_extent_writepage and open code it in the 4 callers. Out
+of those two already are error-only and thus don't need the extra
+conditional, and one already has the mapping_set_error, so a duplicate
+call can be avoided.
+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: b595d2599632 ("btrfs: don't clear uptodate on write errors")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/extent_io.c | 44 +++++++++++++++-----------------------------
+ fs/btrfs/extent_io.h |  2 --
+ fs/btrfs/inode.c     | 42 ++++++++++++++++++++++--------------------
+ 3 files changed, 37 insertions(+), 51 deletions(-)
+
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index b051b6e52022c..009c322c5418d 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -497,29 +497,6 @@ static void end_page_read(struct page *page, bool uptodate, u64 start, u32 len)
+               btrfs_subpage_end_reader(fs_info, page, start, len);
+ }
+-/* lots and lots of room for performance fixes in the end_bio funcs */
+-
+-void end_extent_writepage(struct page *page, int err, u64 start, u64 end)
+-{
+-      struct btrfs_inode *inode;
+-      const bool uptodate = (err == 0);
+-      int ret = 0;
+-      u32 len = end + 1 - start;
+-
+-      ASSERT(end + 1 - start <= U32_MAX);
+-      ASSERT(page && page->mapping);
+-      inode = BTRFS_I(page->mapping->host);
+-      btrfs_mark_ordered_io_finished(inode, page, start, len, uptodate);
+-
+-      if (!uptodate) {
+-              const struct btrfs_fs_info *fs_info = inode->root->fs_info;
+-
+-              btrfs_page_clear_uptodate(fs_info, page, start, len);
+-              ret = err < 0 ? err : -EIO;
+-              mapping_set_error(page->mapping, ret);
+-      }
+-}
+-
+ /*
+  * after a writepage IO is done, we need to:
+  * clear the uptodate bits on error
+@@ -1485,7 +1462,6 @@ static int __extent_writepage(struct page *page, struct btrfs_bio_ctrl *bio_ctrl
+       struct folio *folio = page_folio(page);
+       struct inode *inode = page->mapping->host;
+       const u64 page_start = page_offset(page);
+-      const u64 page_end = page_start + PAGE_SIZE - 1;
+       int ret;
+       int nr = 0;
+       size_t pg_offset;
+@@ -1529,8 +1505,13 @@ static int __extent_writepage(struct page *page, struct btrfs_bio_ctrl *bio_ctrl
+               set_page_writeback(page);
+               end_page_writeback(page);
+       }
+-      if (ret)
+-              end_extent_writepage(page, ret, page_start, page_end);
++      if (ret) {
++              btrfs_mark_ordered_io_finished(BTRFS_I(inode), page, page_start,
++                                             PAGE_SIZE, !ret);
++              btrfs_page_clear_uptodate(btrfs_sb(inode->i_sb), page,
++                                        page_start, PAGE_SIZE);
++              mapping_set_error(page->mapping, ret);
++      }
+       unlock_page(page);
+       ASSERT(ret <= 0);
+       return ret;
+@@ -2248,6 +2229,7 @@ int extent_write_locked_range(struct inode *inode, u64 start, u64 end,
+       while (cur <= end) {
+               u64 cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
++              u32 cur_len = cur_end + 1 - cur;
+               struct page *page;
+               int nr = 0;
+@@ -2271,9 +2253,13 @@ int extent_write_locked_range(struct inode *inode, u64 start, u64 end,
+                       set_page_writeback(page);
+                       end_page_writeback(page);
+               }
+-              if (ret)
+-                      end_extent_writepage(page, ret, cur, cur_end);
+-              btrfs_page_unlock_writer(fs_info, page, cur, cur_end + 1 - cur);
++              if (ret) {
++                      btrfs_mark_ordered_io_finished(BTRFS_I(inode), page,
++                                                     cur, cur_len, !ret);
++                      btrfs_page_clear_uptodate(fs_info, page, cur, cur_len);
++                      mapping_set_error(page->mapping, ret);
++              }
++              btrfs_page_unlock_writer(fs_info, page, cur, cur_len);
+               if (ret < 0) {
+                       found_error = true;
+                       first_error = ret;
+diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
+index f61b7896320a1..e7b293717dc14 100644
+--- a/fs/btrfs/extent_io.h
++++ b/fs/btrfs/extent_io.h
+@@ -284,8 +284,6 @@ void btrfs_clear_buffer_dirty(struct btrfs_trans_handle *trans,
+ int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array);
+-void end_extent_writepage(struct page *page, int err, u64 start, u64 end);
+-
+ #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
+ bool find_lock_delalloc_range(struct inode *inode,
+                            struct page *locked_page, u64 *start,
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index e0bb4018ddb28..b126394ca3dde 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -423,11 +423,10 @@ static inline void btrfs_cleanup_ordered_extents(struct btrfs_inode *inode,
+       while (index <= end_index) {
+               /*
+-               * For locked page, we will call end_extent_writepage() on it
+-               * in run_delalloc_range() for the error handling.  That
+-               * end_extent_writepage() function will call
+-               * btrfs_mark_ordered_io_finished() to clear page Ordered and
+-               * run the ordered extent accounting.
++               * For locked page, we will call btrfs_mark_ordered_io_finished
++               * through btrfs_mark_ordered_io_finished() on it
++               * in run_delalloc_range() for the error handling, which will
++               * clear page Ordered and run the ordered extent accounting.
+                *
+                * Here we can't just clear the Ordered bit, or
+                * btrfs_mark_ordered_io_finished() would skip the accounting
+@@ -1157,11 +1156,16 @@ static int submit_uncompressed_range(struct btrfs_inode *inode,
+               btrfs_cleanup_ordered_extents(inode, locked_page, start, end - start + 1);
+               if (locked_page) {
+                       const u64 page_start = page_offset(locked_page);
+-                      const u64 page_end = page_start + PAGE_SIZE - 1;
+                       set_page_writeback(locked_page);
+                       end_page_writeback(locked_page);
+-                      end_extent_writepage(locked_page, ret, page_start, page_end);
++                      btrfs_mark_ordered_io_finished(inode, locked_page,
++                                                     page_start, PAGE_SIZE,
++                                                     !ret);
++                      btrfs_page_clear_uptodate(inode->root->fs_info,
++                                                locked_page, page_start,
++                                                PAGE_SIZE);
++                      mapping_set_error(locked_page->mapping, ret);
+                       unlock_page(locked_page);
+               }
+               return ret;
+@@ -2840,23 +2844,19 @@ struct btrfs_writepage_fixup {
+ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
+ {
+-      struct btrfs_writepage_fixup *fixup;
++      struct btrfs_writepage_fixup *fixup =
++              container_of(work, struct btrfs_writepage_fixup, work);
+       struct btrfs_ordered_extent *ordered;
+       struct extent_state *cached_state = NULL;
+       struct extent_changeset *data_reserved = NULL;
+-      struct page *page;
+-      struct btrfs_inode *inode;
+-      u64 page_start;
+-      u64 page_end;
++      struct page *page = fixup->page;
++      struct btrfs_inode *inode = fixup->inode;
++      struct btrfs_fs_info *fs_info = inode->root->fs_info;
++      u64 page_start = page_offset(page);
++      u64 page_end = page_offset(page) + PAGE_SIZE - 1;
+       int ret = 0;
+       bool free_delalloc_space = true;
+-      fixup = container_of(work, struct btrfs_writepage_fixup, work);
+-      page = fixup->page;
+-      inode = fixup->inode;
+-      page_start = page_offset(page);
+-      page_end = page_offset(page) + PAGE_SIZE - 1;
+-
+       /*
+        * This is similar to page_mkwrite, we need to reserve the space before
+        * we take the page lock.
+@@ -2949,10 +2949,12 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
+                * to reflect the errors and clean the page.
+                */
+               mapping_set_error(page->mapping, ret);
+-              end_extent_writepage(page, ret, page_start, page_end);
++              btrfs_mark_ordered_io_finished(inode, page, page_start,
++                                             PAGE_SIZE, !ret);
++              btrfs_page_clear_uptodate(fs_info, page, page_start, PAGE_SIZE);
+               clear_page_dirty_for_io(page);
+       }
+-      btrfs_page_clear_checked(inode->root->fs_info, page, page_start, PAGE_SIZE);
++      btrfs_page_clear_checked(fs_info, page, page_start, PAGE_SIZE);
+       unlock_page(page);
+       put_page(page);
+       kfree(fixup);
+-- 
+2.40.1
+
diff --git a/queue-6.5/maple_tree-add-mas_is_active-to-detect-in-tree-walks.patch b/queue-6.5/maple_tree-add-mas_is_active-to-detect-in-tree-walks.patch
new file mode 100644 (file)
index 0000000..72bd0bd
--- /dev/null
@@ -0,0 +1,61 @@
+From 264d5a8c32f6ed81eb35ccd399db0183fe0bb583 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Sep 2023 14:12:35 -0400
+Subject: maple_tree: add mas_is_active() to detect in-tree walks
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+[ Upstream commit 5c590804b6b0ff933ed4e5cee5d76de3a5048d9f ]
+
+Patch series "maple_tree: Fix mas_prev() state regression".
+
+Pedro Falcato retported an mprotect regression [1] which was bisected back
+to the iterator changes for maple tree.  Root cause analysis showed the
+mas_prev() running off the end of the VMA space (previous from 0) followed
+by mas_find(), would skip the first value.
+
+This patchset introduces maple state underflow/overflow so the sequence of
+calls on the maple state will return what the user expects.
+
+Users who encounter this bug may see mprotect(), userfaultfd_register(),
+and mlock() fail on VMAs mapped with address 0.
+
+This patch (of 2):
+
+Instead of constantly checking each possibility of the maple state,
+create a fast path that will skip over checking unlikely states.
+
+Link: https://lkml.kernel.org/r/20230921181236.509072-1-Liam.Howlett@oracle.com
+Link: https://lkml.kernel.org/r/20230921181236.509072-2-Liam.Howlett@oracle.com
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Cc: Pedro Falcato <pedro.falcato@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/maple_tree.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h
+index 295548cca8b36..e1e5f38384b20 100644
+--- a/include/linux/maple_tree.h
++++ b/include/linux/maple_tree.h
+@@ -503,6 +503,15 @@ static inline bool mas_is_paused(const struct ma_state *mas)
+       return mas->node == MAS_PAUSE;
+ }
++/* Check if the mas is pointing to a node or not */
++static inline bool mas_is_active(struct ma_state *mas)
++{
++      if ((unsigned long)mas->node >= MAPLE_RESERVED_RANGE)
++              return true;
++
++      return false;
++}
++
+ /**
+  * mas_reset() - Reset a Maple Tree operation state.
+  * @mas: Maple Tree operation state.
+-- 
+2.40.1
+
diff --git a/queue-6.5/mptcp-fix-dangling-connection-hang-up.patch b/queue-6.5/mptcp-fix-dangling-connection-hang-up.patch
new file mode 100644 (file)
index 0000000..a30a831
--- /dev/null
@@ -0,0 +1,266 @@
+From 478a93d24919d2f0f0ea93ad83738bcd9e927670 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Sep 2023 12:52:49 +0200
+Subject: mptcp: fix dangling connection hang-up
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 27e5ccc2d5a50ed61bb73153edb1066104b108b3 ]
+
+According to RFC 8684 section 3.3:
+
+  A connection is not closed unless [...] or an implementation-specific
+  connection-level send timeout.
+
+Currently the MPTCP protocol does not implement such timeout, and
+connection timing-out at the TCP-level never move to close state.
+
+Introduces a catch-up condition at subflow close time to move the
+MPTCP socket to close, too.
+
+That additionally allows removing similar existing inside the worker.
+
+Finally, allow some additional timeout for plain ESTABLISHED mptcp
+sockets, as the protocol allows creating new subflows even at that
+point and making the connection functional again.
+
+This issue is actually present since the beginning, but it is basically
+impossible to solve without a long chain of functional pre-requisites
+topped by commit bbd49d114d57 ("mptcp: consolidate transition to
+TCP_CLOSE in mptcp_do_fastclose()"). When backporting this current
+patch, please also backport this other commit as well.
+
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/430
+Fixes: e16163b6e2b7 ("mptcp: refactor shutdown and close")
+Cc: stable@vger.kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/protocol.c | 86 ++++++++++++++++++++++----------------------
+ net/mptcp/protocol.h | 22 ++++++++++++
+ net/mptcp/subflow.c  |  1 +
+ 3 files changed, 65 insertions(+), 44 deletions(-)
+
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index 3c85b4c107b2a..3a08ad4ec5d2c 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -894,6 +894,7 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
+       mptcp_subflow_ctx(ssk)->subflow_id = msk->subflow_id++;
+       mptcp_sockopt_sync_locked(msk, ssk);
+       mptcp_subflow_joined(msk, ssk);
++      mptcp_stop_tout_timer(sk);
+       return true;
+ }
+@@ -2357,18 +2358,14 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+       bool dispose_it, need_push = false;
+       /* If the first subflow moved to a close state before accept, e.g. due
+-       * to an incoming reset, mptcp either:
+-       * - if either the subflow or the msk are dead, destroy the context
+-       *   (the subflow socket is deleted by inet_child_forget) and the msk
+-       * - otherwise do nothing at the moment and take action at accept and/or
+-       *   listener shutdown - user-space must be able to accept() the closed
+-       *   socket.
++       * to an incoming reset or listener shutdown, the subflow socket is
++       * already deleted by inet_child_forget() and the mptcp socket can't
++       * survive too.
+        */
+-      if (msk->in_accept_queue && msk->first == ssk) {
+-              if (!sock_flag(sk, SOCK_DEAD) && !sock_flag(ssk, SOCK_DEAD))
+-                      return;
+-
++      if (msk->in_accept_queue && msk->first == ssk &&
++          (sock_flag(sk, SOCK_DEAD) || sock_flag(ssk, SOCK_DEAD))) {
+               /* ensure later check in mptcp_worker() will dispose the msk */
++              mptcp_set_close_tout(sk, tcp_jiffies32 - (TCP_TIMEWAIT_LEN + 1));
+               sock_set_flag(sk, SOCK_DEAD);
+               lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
+               mptcp_subflow_drop_ctx(ssk);
+@@ -2435,6 +2432,22 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+       if (need_push)
+               __mptcp_push_pending(sk, 0);
++
++      /* Catch every 'all subflows closed' scenario, including peers silently
++       * closing them, e.g. due to timeout.
++       * For established sockets, allow an additional timeout before closing,
++       * as the protocol can still create more subflows.
++       */
++      if (list_is_singular(&msk->conn_list) && msk->first &&
++          inet_sk_state_load(msk->first) == TCP_CLOSE) {
++              if (sk->sk_state != TCP_ESTABLISHED ||
++                  msk->in_accept_queue || sock_flag(sk, SOCK_DEAD)) {
++                      inet_sk_state_store(sk, TCP_CLOSE);
++                      mptcp_close_wake_up(sk);
++              } else {
++                      mptcp_start_tout_timer(sk);
++              }
++      }
+ }
+ void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+@@ -2478,23 +2491,14 @@ static void __mptcp_close_subflow(struct sock *sk)
+ }
+-static bool mptcp_should_close(const struct sock *sk)
++static bool mptcp_close_tout_expired(const struct sock *sk)
+ {
+-      s32 delta = tcp_jiffies32 - inet_csk(sk)->icsk_mtup.probe_timestamp;
+-      struct mptcp_subflow_context *subflow;
+-
+-      if (delta >= TCP_TIMEWAIT_LEN || mptcp_sk(sk)->in_accept_queue)
+-              return true;
++      if (!inet_csk(sk)->icsk_mtup.probe_timestamp ||
++          sk->sk_state == TCP_CLOSE)
++              return false;
+-      /* if all subflows are in closed status don't bother with additional
+-       * timeout
+-       */
+-      mptcp_for_each_subflow(mptcp_sk(sk), subflow) {
+-              if (inet_sk_state_load(mptcp_subflow_tcp_sock(subflow)) !=
+-                  TCP_CLOSE)
+-                      return false;
+-      }
+-      return true;
++      return time_after32(tcp_jiffies32,
++                inet_csk(sk)->icsk_mtup.probe_timestamp + TCP_TIMEWAIT_LEN);
+ }
+ static void mptcp_check_fastclose(struct mptcp_sock *msk)
+@@ -2619,15 +2623,16 @@ void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout)
+       struct sock *sk = (struct sock *)msk;
+       unsigned long timeout, close_timeout;
+-      if (!fail_tout && !sock_flag(sk, SOCK_DEAD))
++      if (!fail_tout && !inet_csk(sk)->icsk_mtup.probe_timestamp)
+               return;
+-      close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies + TCP_TIMEWAIT_LEN;
++      close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies +
++                      TCP_TIMEWAIT_LEN;
+       /* the close timeout takes precedence on the fail one, and here at least one of
+        * them is active
+        */
+-      timeout = sock_flag(sk, SOCK_DEAD) ? close_timeout : fail_tout;
++      timeout = inet_csk(sk)->icsk_mtup.probe_timestamp ? close_timeout : fail_tout;
+       sk_reset_timer(sk, &sk->sk_timer, timeout);
+ }
+@@ -2646,8 +2651,6 @@ static void mptcp_mp_fail_no_response(struct mptcp_sock *msk)
+       mptcp_subflow_reset(ssk);
+       WRITE_ONCE(mptcp_subflow_ctx(ssk)->fail_tout, 0);
+       unlock_sock_fast(ssk, slow);
+-
+-      mptcp_reset_tout_timer(msk, 0);
+ }
+ static void mptcp_do_fastclose(struct sock *sk)
+@@ -2684,18 +2687,14 @@ static void mptcp_worker(struct work_struct *work)
+       if (test_and_clear_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags))
+               __mptcp_close_subflow(sk);
+-      /* There is no point in keeping around an orphaned sk timedout or
+-       * closed, but we need the msk around to reply to incoming DATA_FIN,
+-       * even if it is orphaned and in FIN_WAIT2 state
+-       */
+-      if (sock_flag(sk, SOCK_DEAD)) {
+-              if (mptcp_should_close(sk))
+-                      mptcp_do_fastclose(sk);
++      if (mptcp_close_tout_expired(sk)) {
++              mptcp_do_fastclose(sk);
++              mptcp_close_wake_up(sk);
++      }
+-              if (sk->sk_state == TCP_CLOSE) {
+-                      __mptcp_destroy_sock(sk);
+-                      goto unlock;
+-              }
++      if (sock_flag(sk, SOCK_DEAD) && sk->sk_state == TCP_CLOSE) {
++              __mptcp_destroy_sock(sk);
++              goto unlock;
+       }
+       if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags))
+@@ -2987,7 +2986,6 @@ bool __mptcp_close(struct sock *sk, long timeout)
+ cleanup:
+       /* orphan all the subflows */
+-      inet_csk(sk)->icsk_mtup.probe_timestamp = tcp_jiffies32;
+       mptcp_for_each_subflow(msk, subflow) {
+               struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+               bool slow = lock_sock_fast_nested(ssk);
+@@ -3024,7 +3022,7 @@ bool __mptcp_close(struct sock *sk, long timeout)
+               __mptcp_destroy_sock(sk);
+               do_cancel_work = true;
+       } else {
+-              mptcp_reset_tout_timer(msk, 0);
++              mptcp_start_tout_timer(sk);
+       }
+       return do_cancel_work;
+@@ -3088,7 +3086,7 @@ static int mptcp_disconnect(struct sock *sk, int flags)
+       inet_sk_state_store(sk, TCP_CLOSE);
+       mptcp_stop_rtx_timer(sk);
+-      sk_stop_timer(sk, &sk->sk_timer);
++      mptcp_stop_tout_timer(sk);
+       if (msk->token)
+               mptcp_event(MPTCP_EVENT_CLOSED, msk, NULL, GFP_KERNEL);
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index 4e31b5cf48299..0a2d9d3df522e 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -700,6 +700,28 @@ void mptcp_get_options(const struct sk_buff *skb,
+ void mptcp_finish_connect(struct sock *sk);
+ void __mptcp_set_connected(struct sock *sk);
+ void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout);
++
++static inline void mptcp_stop_tout_timer(struct sock *sk)
++{
++      if (!inet_csk(sk)->icsk_mtup.probe_timestamp)
++              return;
++
++      sk_stop_timer(sk, &sk->sk_timer);
++      inet_csk(sk)->icsk_mtup.probe_timestamp = 0;
++}
++
++static inline void mptcp_set_close_tout(struct sock *sk, unsigned long tout)
++{
++      /* avoid 0 timestamp, as that means no close timeout */
++      inet_csk(sk)->icsk_mtup.probe_timestamp = tout ? : 1;
++}
++
++static inline void mptcp_start_tout_timer(struct sock *sk)
++{
++      mptcp_set_close_tout(sk, tcp_jiffies32);
++      mptcp_reset_tout_timer(mptcp_sk(sk), 0);
++}
++
+ static inline bool mptcp_is_fully_established(struct sock *sk)
+ {
+       return inet_sk_state_load(sk) == TCP_ESTABLISHED &&
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 0506d33177f3d..40ac67b854074 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -1552,6 +1552,7 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
+       mptcp_sock_graft(ssk, sk->sk_socket);
+       iput(SOCK_INODE(sf));
+       WRITE_ONCE(msk->allow_infinite_fallback, false);
++      mptcp_stop_tout_timer(sk);
+       return 0;
+ failed_unlink:
+-- 
+2.40.1
+
diff --git a/queue-6.5/mptcp-remove-unnecessary-test-for-__mptcp_init_sock.patch b/queue-6.5/mptcp-remove-unnecessary-test-for-__mptcp_init_sock.patch
new file mode 100644 (file)
index 0000000..b061f67
--- /dev/null
@@ -0,0 +1,66 @@
+From 93b36859e5aae1d636bcbf0dff13bf760a12593b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 17:57:27 +0200
+Subject: mptcp: Remove unnecessary test for __mptcp_init_sock()
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit e263691773cd67d7c824eeee8b802f50c6e0c118 ]
+
+__mptcp_init_sock() always returns 0 because mptcp_init_sock() used
+to return the value directly.
+
+But after commit 18b683bff89d ("mptcp: queue data for mptcp level
+retransmission"), __mptcp_init_sock() need not return value anymore.
+
+Let's remove the unnecessary test for __mptcp_init_sock() and make
+it return void.
+
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 27e5ccc2d5a5 ("mptcp: fix dangling connection hang-up")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/protocol.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index 6947b4b2519c9..0aae76f1465b8 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2710,7 +2710,7 @@ static void mptcp_worker(struct work_struct *work)
+       sock_put(sk);
+ }
+-static int __mptcp_init_sock(struct sock *sk)
++static void __mptcp_init_sock(struct sock *sk)
+ {
+       struct mptcp_sock *msk = mptcp_sk(sk);
+@@ -2737,8 +2737,6 @@ static int __mptcp_init_sock(struct sock *sk)
+       /* re-use the csk retrans timer for MPTCP-level retrans */
+       timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer, 0);
+       timer_setup(&sk->sk_timer, mptcp_timeout_timer, 0);
+-
+-      return 0;
+ }
+ static void mptcp_ca_reset(struct sock *sk)
+@@ -2756,11 +2754,8 @@ static void mptcp_ca_reset(struct sock *sk)
+ static int mptcp_init_sock(struct sock *sk)
+ {
+       struct net *net = sock_net(sk);
+-      int ret;
+-      ret = __mptcp_init_sock(sk);
+-      if (ret)
+-              return ret;
++      __mptcp_init_sock(sk);
+       if (!mptcp_is_enabled(net))
+               return -ENOPROTOOPT;
+-- 
+2.40.1
+
diff --git a/queue-6.5/mptcp-rename-timer-related-helper-to-less-confusing-.patch b/queue-6.5/mptcp-rename-timer-related-helper-to-less-confusing-.patch
new file mode 100644 (file)
index 0000000..a1cec56
--- /dev/null
@@ -0,0 +1,210 @@
+From c6282c64ad6465a60cbf840926c938dbf002db2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Sep 2023 12:52:48 +0200
+Subject: mptcp: rename timer related helper to less confusing names
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit f6909dc1c1f4452879278128012da6c76bc186a5 ]
+
+The msk socket uses to different timeout to track close related
+events and retransmissions. The existing helpers do not indicate
+clearly which timer they actually touch, making the related code
+quite confusing.
+
+Change the existing helpers name to avoid such confusion. No
+functional change intended.
+
+This patch is linked to the next one ("mptcp: fix dangling connection
+hang-up"). The two patches are supposed to be backported together.
+
+Cc: stable@vger.kernel.org # v5.11+
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 27e5ccc2d5a5 ("mptcp: fix dangling connection hang-up")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/protocol.c | 42 +++++++++++++++++++++---------------------
+ net/mptcp/protocol.h |  2 +-
+ net/mptcp/subflow.c  |  2 +-
+ 3 files changed, 23 insertions(+), 23 deletions(-)
+
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index 0aae76f1465b8..3c85b4c107b2a 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -407,7 +407,7 @@ static bool __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,
+       return false;
+ }
+-static void mptcp_stop_timer(struct sock *sk)
++static void mptcp_stop_rtx_timer(struct sock *sk)
+ {
+       struct inet_connection_sock *icsk = inet_csk(sk);
+@@ -913,12 +913,12 @@ static void __mptcp_flush_join_list(struct sock *sk, struct list_head *join_list
+       }
+ }
+-static bool mptcp_timer_pending(struct sock *sk)
++static bool mptcp_rtx_timer_pending(struct sock *sk)
+ {
+       return timer_pending(&inet_csk(sk)->icsk_retransmit_timer);
+ }
+-static void mptcp_reset_timer(struct sock *sk)
++static void mptcp_reset_rtx_timer(struct sock *sk)
+ {
+       struct inet_connection_sock *icsk = inet_csk(sk);
+       unsigned long tout;
+@@ -1052,10 +1052,10 @@ static void __mptcp_clean_una(struct sock *sk)
+ out:
+       if (snd_una == READ_ONCE(msk->snd_nxt) &&
+           snd_una == READ_ONCE(msk->write_seq)) {
+-              if (mptcp_timer_pending(sk) && !mptcp_data_fin_enabled(msk))
+-                      mptcp_stop_timer(sk);
++              if (mptcp_rtx_timer_pending(sk) && !mptcp_data_fin_enabled(msk))
++                      mptcp_stop_rtx_timer(sk);
+       } else {
+-              mptcp_reset_timer(sk);
++              mptcp_reset_rtx_timer(sk);
+       }
+ }
+@@ -1606,8 +1606,8 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags)
+ out:
+       /* ensure the rtx timer is running */
+-      if (!mptcp_timer_pending(sk))
+-              mptcp_reset_timer(sk);
++      if (!mptcp_rtx_timer_pending(sk))
++              mptcp_reset_rtx_timer(sk);
+       if (do_check_data_fin)
+               mptcp_check_send_data_fin(sk);
+ }
+@@ -1663,8 +1663,8 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk, bool
+       if (copied) {
+               tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle,
+                        info.size_goal);
+-              if (!mptcp_timer_pending(sk))
+-                      mptcp_reset_timer(sk);
++              if (!mptcp_rtx_timer_pending(sk))
++                      mptcp_reset_rtx_timer(sk);
+               if (msk->snd_data_fin_enable &&
+                   msk->snd_nxt + 1 == msk->write_seq)
+@@ -2235,7 +2235,7 @@ static void mptcp_retransmit_timer(struct timer_list *t)
+       sock_put(sk);
+ }
+-static void mptcp_timeout_timer(struct timer_list *t)
++static void mptcp_tout_timer(struct timer_list *t)
+ {
+       struct sock *sk = from_timer(sk, t, sk_timer);
+@@ -2607,14 +2607,14 @@ static void __mptcp_retrans(struct sock *sk)
+ reset_timer:
+       mptcp_check_and_set_pending(sk);
+-      if (!mptcp_timer_pending(sk))
+-              mptcp_reset_timer(sk);
++      if (!mptcp_rtx_timer_pending(sk))
++              mptcp_reset_rtx_timer(sk);
+ }
+ /* schedule the timeout timer for the relevant event: either close timeout
+  * or mp_fail timeout. The close timeout takes precedence on the mp_fail one
+  */
+-void mptcp_reset_timeout(struct mptcp_sock *msk, unsigned long fail_tout)
++void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout)
+ {
+       struct sock *sk = (struct sock *)msk;
+       unsigned long timeout, close_timeout;
+@@ -2647,7 +2647,7 @@ static void mptcp_mp_fail_no_response(struct mptcp_sock *msk)
+       WRITE_ONCE(mptcp_subflow_ctx(ssk)->fail_tout, 0);
+       unlock_sock_fast(ssk, slow);
+-      mptcp_reset_timeout(msk, 0);
++      mptcp_reset_tout_timer(msk, 0);
+ }
+ static void mptcp_do_fastclose(struct sock *sk)
+@@ -2736,7 +2736,7 @@ static void __mptcp_init_sock(struct sock *sk)
+       /* re-use the csk retrans timer for MPTCP-level retrans */
+       timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer, 0);
+-      timer_setup(&sk->sk_timer, mptcp_timeout_timer, 0);
++      timer_setup(&sk->sk_timer, mptcp_tout_timer, 0);
+ }
+ static void mptcp_ca_reset(struct sock *sk)
+@@ -2821,8 +2821,8 @@ void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how)
+               } else {
+                       pr_debug("Sending DATA_FIN on subflow %p", ssk);
+                       tcp_send_ack(ssk);
+-                      if (!mptcp_timer_pending(sk))
+-                              mptcp_reset_timer(sk);
++                      if (!mptcp_rtx_timer_pending(sk))
++                              mptcp_reset_rtx_timer(sk);
+               }
+               break;
+       }
+@@ -2905,7 +2905,7 @@ static void __mptcp_destroy_sock(struct sock *sk)
+       might_sleep();
+-      mptcp_stop_timer(sk);
++      mptcp_stop_rtx_timer(sk);
+       sk_stop_timer(sk, &sk->sk_timer);
+       msk->pm.status = 0;
+@@ -3024,7 +3024,7 @@ bool __mptcp_close(struct sock *sk, long timeout)
+               __mptcp_destroy_sock(sk);
+               do_cancel_work = true;
+       } else {
+-              mptcp_reset_timeout(msk, 0);
++              mptcp_reset_tout_timer(msk, 0);
+       }
+       return do_cancel_work;
+@@ -3087,7 +3087,7 @@ static int mptcp_disconnect(struct sock *sk, int flags)
+       mptcp_check_listen_stop(sk);
+       inet_sk_state_store(sk, TCP_CLOSE);
+-      mptcp_stop_timer(sk);
++      mptcp_stop_rtx_timer(sk);
+       sk_stop_timer(sk, &sk->sk_timer);
+       if (msk->token)
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index ba2a873a4d2e6..4e31b5cf48299 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -699,7 +699,7 @@ void mptcp_get_options(const struct sk_buff *skb,
+ void mptcp_finish_connect(struct sock *sk);
+ void __mptcp_set_connected(struct sock *sk);
+-void mptcp_reset_timeout(struct mptcp_sock *msk, unsigned long fail_tout);
++void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout);
+ static inline bool mptcp_is_fully_established(struct sock *sk)
+ {
+       return inet_sk_state_load(sk) == TCP_ESTABLISHED &&
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index c7bd99b8e7b7a..0506d33177f3d 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -1226,7 +1226,7 @@ static void mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk)
+       WRITE_ONCE(subflow->fail_tout, fail_tout);
+       tcp_send_ack(ssk);
+-      mptcp_reset_timeout(msk, subflow->fail_tout);
++      mptcp_reset_tout_timer(msk, subflow->fail_tout);
+ }
+ static bool subflow_check_data_avail(struct sock *ssk)
+-- 
+2.40.1
+
diff --git a/queue-6.5/scsi-core-improve-type-safety-of-scsi_rescan_device.patch b/queue-6.5/scsi-core-improve-type-safety-of-scsi_rescan_device.patch
new file mode 100644 (file)
index 0000000..b657159
--- /dev/null
@@ -0,0 +1,198 @@
+From 6baea050e37d2c14a86c1f2715caa919b73e5352 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Aug 2023 08:30:41 -0700
+Subject: scsi: core: Improve type safety of scsi_rescan_device()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 79519528a180c64a90863db2ce70887de6c49d16 ]
+
+Most callers of scsi_rescan_device() have the scsi_device pointer readily
+available. Pass a struct scsi_device pointer to scsi_rescan_device()
+instead of a struct device pointer. This change prevents that a pointer to
+another struct device would be passed accidentally to scsi_rescan_device().
+
+Remove the scsi_rescan_device() declaration from the scsi_priv.h header
+file since it duplicates the declaration in <scsi/scsi_host.h>.
+
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Cc: Mike Christie <michael.christie@oracle.com>
+Cc: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20230822153043.4046244-1-bvanassche@acm.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 8b4d9469d0b0 ("ata: libata-scsi: Fix delayed scsi_rescan_device() execution")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/libata-scsi.c             | 2 +-
+ drivers/scsi/aacraid/commsup.c        | 2 +-
+ drivers/scsi/mvumi.c                  | 2 +-
+ drivers/scsi/scsi_lib.c               | 2 +-
+ drivers/scsi/scsi_priv.h              | 1 -
+ drivers/scsi/scsi_scan.c              | 4 ++--
+ drivers/scsi/scsi_sysfs.c             | 4 ++--
+ drivers/scsi/smartpqi/smartpqi_init.c | 2 +-
+ drivers/scsi/storvsc_drv.c            | 2 +-
+ drivers/scsi/virtio_scsi.c            | 2 +-
+ include/scsi/scsi_host.h              | 2 +-
+ 11 files changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index 702812285d8f0..22d7c26297889 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -4930,7 +4930,7 @@ void ata_scsi_dev_rescan(struct work_struct *work)
+                       }
+                       spin_unlock_irqrestore(ap->lock, flags);
+-                      scsi_rescan_device(&(sdev->sdev_gendev));
++                      scsi_rescan_device(sdev);
+                       scsi_device_put(sdev);
+                       spin_lock_irqsave(ap->lock, flags);
+               }
+diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
+index 3f062e4013ab6..013a9a334972e 100644
+--- a/drivers/scsi/aacraid/commsup.c
++++ b/drivers/scsi/aacraid/commsup.c
+@@ -1451,7 +1451,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
+ #endif
+                               break;
+                       }
+-                      scsi_rescan_device(&device->sdev_gendev);
++                      scsi_rescan_device(device);
+                       break;
+               default:
+diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c
+index 73aa7059b5569..6cfbac518085d 100644
+--- a/drivers/scsi/mvumi.c
++++ b/drivers/scsi/mvumi.c
+@@ -1500,7 +1500,7 @@ static void mvumi_rescan_devices(struct mvumi_hba *mhba, int id)
+       sdev = scsi_device_lookup(mhba->shost, 0, id, 0);
+       if (sdev) {
+-              scsi_rescan_device(&sdev->sdev_gendev);
++              scsi_rescan_device(sdev);
+               scsi_device_put(sdev);
+       }
+ }
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index ad9afae49544a..ca5eb058d5c7e 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -2458,7 +2458,7 @@ static void scsi_evt_emit(struct scsi_device *sdev, struct scsi_event *evt)
+               envp[idx++] = "SDEV_MEDIA_CHANGE=1";
+               break;
+       case SDEV_EVT_INQUIRY_CHANGE_REPORTED:
+-              scsi_rescan_device(&sdev->sdev_gendev);
++              scsi_rescan_device(sdev);
+               envp[idx++] = "SDEV_UA=INQUIRY_DATA_HAS_CHANGED";
+               break;
+       case SDEV_EVT_CAPACITY_CHANGE_REPORTED:
+diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
+index f42388ecb0248..65c993c979095 100644
+--- a/drivers/scsi/scsi_priv.h
++++ b/drivers/scsi/scsi_priv.h
+@@ -138,7 +138,6 @@ extern int scsi_complete_async_scans(void);
+ extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
+                                  unsigned int, u64, enum scsi_scan_mode);
+ extern void scsi_forget_host(struct Scsi_Host *);
+-extern void scsi_rescan_device(struct device *);
+ /* scsi_sysctl.c */
+ #ifdef CONFIG_SYSCTL
+diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
+index 97669657a9976..eaa972bee6c00 100644
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -1619,9 +1619,9 @@ int scsi_add_device(struct Scsi_Host *host, uint channel,
+ }
+ EXPORT_SYMBOL(scsi_add_device);
+-void scsi_rescan_device(struct device *dev)
++void scsi_rescan_device(struct scsi_device *sdev)
+ {
+-      struct scsi_device *sdev = to_scsi_device(dev);
++      struct device *dev = &sdev->sdev_gendev;
+       device_lock(dev);
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index 60317676e45f1..24f6eefb68030 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -747,7 +747,7 @@ static ssize_t
+ store_rescan_field (struct device *dev, struct device_attribute *attr,
+                   const char *buf, size_t count)
+ {
+-      scsi_rescan_device(dev);
++      scsi_rescan_device(to_scsi_device(dev));
+       return count;
+ }
+ static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field);
+@@ -840,7 +840,7 @@ store_state_field(struct device *dev, struct device_attribute *attr,
+                * waiting for pending I/O to finish.
+                */
+               blk_mq_run_hw_queues(sdev->request_queue, true);
+-              scsi_rescan_device(dev);
++              scsi_rescan_device(sdev);
+       }
+       return ret == 0 ? count : -EINVAL;
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 6aaaa7ebca377..ed694d9399648 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -2257,7 +2257,7 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
+                       device->advertised_queue_depth = device->queue_depth;
+                       scsi_change_queue_depth(device->sdev, device->advertised_queue_depth);
+                       if (device->rescan) {
+-                              scsi_rescan_device(&device->sdev->sdev_gendev);
++                              scsi_rescan_device(device->sdev);
+                               device->rescan = false;
+                       }
+               }
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+index 047ffaf7d42a9..a80a9e27ff9ee 100644
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -472,7 +472,7 @@ static void storvsc_device_scan(struct work_struct *work)
+       sdev = scsi_device_lookup(wrk->host, 0, wrk->tgt_id, wrk->lun);
+       if (!sdev)
+               goto done;
+-      scsi_rescan_device(&sdev->sdev_gendev);
++      scsi_rescan_device(sdev);
+       scsi_device_put(sdev);
+ done:
+diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
+index bd5633667d015..9d1bdcdc13312 100644
+--- a/drivers/scsi/virtio_scsi.c
++++ b/drivers/scsi/virtio_scsi.c
+@@ -325,7 +325,7 @@ static void virtscsi_handle_param_change(struct virtio_scsi *vscsi,
+       /* Handle "Parameters changed", "Mode parameters changed", and
+          "Capacity data has changed".  */
+       if (asc == 0x2a && (ascq == 0x00 || ascq == 0x01 || ascq == 0x09))
+-              scsi_rescan_device(&sdev->sdev_gendev);
++              scsi_rescan_device(sdev);
+       scsi_device_put(sdev);
+ }
+diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
+index a2b8d30c4c803..49f768d0ff370 100644
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -764,7 +764,7 @@ scsi_template_proc_dir(const struct scsi_host_template *sht);
+ #define scsi_template_proc_dir(sht) NULL
+ #endif
+ extern void scsi_scan_host(struct Scsi_Host *);
+-extern void scsi_rescan_device(struct device *);
++extern void scsi_rescan_device(struct scsi_device *);
+ extern void scsi_remove_host(struct Scsi_Host *);
+ extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
+ extern int scsi_host_busy(struct Scsi_Host *shost);
+-- 
+2.40.1
+
diff --git a/queue-6.5/scsi-do-not-attempt-to-rescan-suspended-devices.patch b/queue-6.5/scsi-do-not-attempt-to-rescan-suspended-devices.patch
new file mode 100644 (file)
index 0000000..c02996a
--- /dev/null
@@ -0,0 +1,98 @@
+From 0c62f5a5665b1cb55824c1cf96f44be41b1ba176 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 15:00:13 +0900
+Subject: scsi: Do not attempt to rescan suspended devices
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+[ Upstream commit ff48b37802e5c134e2dfc4d091f10b2eb5065a72 ]
+
+scsi_rescan_device() takes a scsi device lock before executing a device
+handler and device driver rescan methods. Waiting for the completion of
+any command issued to the device by these methods will thus be done with
+the device lock held. As a result, there is a risk of deadlocking within
+the power management code if scsi_rescan_device() is called to handle a
+device resume with the associated scsi device not yet resumed.
+
+Avoid such situation by checking that the target scsi device is in the
+running state, that is, fully capable of executing commands, before
+proceeding with the rescan and bailout returning -EWOULDBLOCK otherwise.
+With this error return, the caller can retry rescaning the device after
+a delay.
+
+The state check is done with the device lock held and is thus safe
+against incoming suspend power management operations.
+
+Fixes: 6aa0365a3c85 ("ata: libata-scsi: Avoid deadlock on rescan after device resume")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Stable-dep-of: 8b4d9469d0b0 ("ata: libata-scsi: Fix delayed scsi_rescan_device() execution")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_scan.c | 18 +++++++++++++++++-
+ include/scsi/scsi_host.h |  2 +-
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
+index eaa972bee6c00..902655d759476 100644
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -1619,12 +1619,24 @@ int scsi_add_device(struct Scsi_Host *host, uint channel,
+ }
+ EXPORT_SYMBOL(scsi_add_device);
+-void scsi_rescan_device(struct scsi_device *sdev)
++int scsi_rescan_device(struct scsi_device *sdev)
+ {
+       struct device *dev = &sdev->sdev_gendev;
++      int ret = 0;
+       device_lock(dev);
++      /*
++       * Bail out if the device is not running. Otherwise, the rescan may
++       * block waiting for commands to be executed, with us holding the
++       * device lock. This can result in a potential deadlock in the power
++       * management core code when system resume is on-going.
++       */
++      if (sdev->sdev_state != SDEV_RUNNING) {
++              ret = -EWOULDBLOCK;
++              goto unlock;
++      }
++
+       scsi_attach_vpd(sdev);
+       scsi_cdl_check(sdev);
+@@ -1638,7 +1650,11 @@ void scsi_rescan_device(struct scsi_device *sdev)
+                       drv->rescan(dev);
+               module_put(dev->driver->owner);
+       }
++
++unlock:
+       device_unlock(dev);
++
++      return ret;
+ }
+ EXPORT_SYMBOL(scsi_rescan_device);
+diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
+index 49f768d0ff370..4c2dc8150c6d7 100644
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -764,7 +764,7 @@ scsi_template_proc_dir(const struct scsi_host_template *sht);
+ #define scsi_template_proc_dir(sht) NULL
+ #endif
+ extern void scsi_scan_host(struct Scsi_Host *);
+-extern void scsi_rescan_device(struct scsi_device *);
++extern int scsi_rescan_device(struct scsi_device *sdev);
+ extern void scsi_remove_host(struct Scsi_Host *);
+ extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
+ extern int scsi_host_busy(struct Scsi_Host *shost);
+-- 
+2.40.1
+
diff --git a/queue-6.5/series b/queue-6.5/series
new file mode 100644 (file)
index 0000000..3e5de61
--- /dev/null
@@ -0,0 +1,19 @@
+alsa-hda-tas2781-add-tas2781-hda-driver.patch
+alsa-hda-realtek-add-quirk-for-hp-victus-16-d1xxx-to.patch
+alsa-hda-realtek-add-quirk-for-mute-leds-on-hp-envy-.patch
+alsa-hda-realtek-alc287-i2s-speaker-platform-support.patch
+alsa-hda-realtek-alc287-realtek-i2s-speaker-platform.patch
+asoc-soc-utils-export-snd_soc_dai_is_dummy-symbol.patch
+asoc-tegra-fix-redundant-plla-and-plla_out0-updates.patch
+maple_tree-add-mas_is_active-to-detect-in-tree-walks.patch
+mptcp-remove-unnecessary-test-for-__mptcp_init_sock.patch
+mptcp-rename-timer-related-helper-to-less-confusing-.patch
+mptcp-fix-dangling-connection-hang-up.patch
+scsi-core-improve-type-safety-of-scsi_rescan_device.patch
+scsi-do-not-attempt-to-rescan-suspended-devices.patch
+ata-libata-scsi-fix-delayed-scsi_rescan_device-execu.patch
+btrfs-remove-btrfs_writepage_endio_finish_ordered.patch
+btrfs-remove-end_extent_writepage.patch
+btrfs-don-t-clear-uptodate-on-write-errors.patch
+arm64-add-hwcap-for-feat_hbc-hinted-conditional-bran.patch
+arm64-cpufeature-fix-clrbhb-and-bc-detection.patch