From: Sasha Levin Date: Fri, 6 Oct 2023 13:29:51 +0000 (-0400) Subject: Fixes for 6.5 X-Git-Tag: v4.14.327~91 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a7a23ca4c104ea752963796b13bf43cadb745557;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.5 Signed-off-by: Sasha Levin --- 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 index 00000000000..7d6d815fb87 --- /dev/null +++ b/queue-6.5/alsa-hda-realtek-add-quirk-for-hp-victus-16-d1xxx-to.patch @@ -0,0 +1,79 @@ +From 8a354d8b6952e9b4949d0c0cd618abd764cc9f48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ Upstream commit 93dc18e11b1ab2d485b69f91c973e6b83e47ebd0 ] + +This quirk enables mute LED on HP Victus 16-d1xxx (8A25) laptops, which +use ALC245 codec. + +Signed-off-by: SungHwan Jung +Link: https://lore.kernel.org/r/20230823114051.3921-1-onenowy@gmail.com +Signed-off-by: Takashi Iwai +Stable-dep-of: 41b07476da38 ("ALSA: hda/realtek - ALC287 Realtek I2S speaker platform support") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ab31cccd61c --- /dev/null +++ b/queue-6.5/alsa-hda-realtek-add-quirk-for-mute-leds-on-hp-envy-.patch @@ -0,0 +1,58 @@ +From eadc5fca3515ed944bad90e2403d0742ad11cf93 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/2693091.mvXUDI8C0e@fabians-envy +Signed-off-by: Takashi Iwai +Stable-dep-of: 41b07476da38 ("ALSA: hda/realtek - ALC287 Realtek I2S speaker platform support") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..736092a306b --- /dev/null +++ b/queue-6.5/alsa-hda-realtek-alc287-i2s-speaker-platform-support.patch @@ -0,0 +1,89 @@ +From 96533eb59bc801c55a4a632c135e321c2134ca9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 16:50:41 +0800 +Subject: ALSA: hda/realtek - ALC287 I2S speaker platform support + +From: Kailang Yang + +[ 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 +Signed-off-by: Kailang Yang +Link: https://lore.kernel.org/r/4e4cfa1b3b4c46838aecafc6e8b6f876@realtek.com +Signed-off-by: Takashi Iwai +Stable-dep-of: 41b07476da38 ("ALSA: hda/realtek - ALC287 Realtek I2S speaker platform support") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..afd4bf6f3f5 --- /dev/null +++ b/queue-6.5/alsa-hda-realtek-alc287-realtek-i2s-speaker-platform.patch @@ -0,0 +1,43 @@ +From 097eb22c1cce349594a0c43edfd5dcd2af10813a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 16:27:16 +0800 +Subject: ALSA: hda/realtek - ALC287 Realtek I2S speaker platform support + +From: Kailang Yang + +[ 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 +Cc: +Link: https://lore.kernel.org/r/8d63c6e360124e3ea2523753050e6f05@realtek.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..fbe1b6a564a --- /dev/null +++ b/queue-6.5/alsa-hda-tas2781-add-tas2781-hda-driver.patch @@ -0,0 +1,180 @@ +From 49ae5f8082daf33e220fd5c14df7c14565971741 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Aug 2023 16:58:35 +0800 +Subject: ALSA: hda/tas2781: Add tas2781 HDA driver + +From: Shenghao Ding + +[ 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 +Link: https://lore.kernel.org/r/20230818085836.1442-1-shenghao-ding@ti.com +Signed-off-by: Takashi Iwai +Stable-dep-of: 41b07476da38 ("ALSA: hda/realtek - ALC287 Realtek I2S speaker platform support") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..163390995b7 --- /dev/null +++ b/queue-6.5/arm64-add-hwcap-for-feat_hbc-hinted-conditional-bran.patch @@ -0,0 +1,85 @@ +From 8057be5d7ac578722af942d2455258d2e2e07944 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Aug 2023 15:37:45 +0100 +Subject: arm64: add HWCAP for FEAT_HBC (hinted conditional branches) + +From: Joey Gouly + +[ 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 +Cc: Catalin Marinas +Cc: Will Deacon +Link: https://lore.kernel.org/r/20230804143746.3900803-2-joey.gouly@arm.com +Signed-off-by: Will Deacon +Stable-dep-of: 479965a2b7ec ("arm64: cpufeature: Fix CLRBHB and BC detection") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..34b875ebbf3 --- /dev/null +++ b/queue-6.5/arm64-cpufeature-fix-clrbhb-and-bc-detection.patch @@ -0,0 +1,80 @@ +From 8a5c763da5aa12beba942da05d306c48437f5812 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 14:34:29 +0100 +Subject: arm64: cpufeature: Fix CLRBHB and BC detection + +From: Kristina Martsenko + +[ 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 +Reviewed-by: Mark Brown +Link: https://lore.kernel.org/r/20230912133429.2606875-1-kristina.martsenko@arm.com +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..40d24a45aca --- /dev/null +++ b/queue-6.5/asoc-soc-utils-export-snd_soc_dai_is_dummy-symbol.patch @@ -0,0 +1,35 @@ +From bbf28b5526628d8e025a8666998314d62f87b0e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 20:32:24 +0530 +Subject: ASoC: soc-utils: Export snd_soc_dai_is_dummy() symbol + +From: Sameer Pujar + +[ 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 +Link: https://lore.kernel.org/r/1694098945-32760-2-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0cc2f540338 --- /dev/null +++ b/queue-6.5/asoc-tegra-fix-redundant-plla-and-plla_out0-updates.patch @@ -0,0 +1,90 @@ +From 37c0e1b564a800ace7afd64aa91ce9d910323b6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 20:32:25 +0530 +Subject: ASoC: tegra: Fix redundant PLLA and PLLA_OUT0 updates + +From: Sameer Pujar + +[ 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 +Link: https://lore.kernel.org/r/1694098945-32760-3-git-send-email-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + + #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 index 00000000000..1466a47b195 --- /dev/null +++ b/queue-6.5/ata-libata-scsi-fix-delayed-scsi_rescan_device-execu.patch @@ -0,0 +1,152 @@ +From f803e78617823ec1d571f40a115fe9b1a054a0de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Sep 2023 09:06:23 +0900 +Subject: ata: libata-scsi: Fix delayed scsi_rescan_device() execution + +From: Damien Le Moal + +[ 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 +Reviewed-by: Hannes Reinecke +Reviewed-by: Niklas Cassel +Tested-by: Geert Uytterhoeven +Reviewed-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..32034057cdb --- /dev/null +++ b/queue-6.5/btrfs-don-t-clear-uptodate-on-write-errors.patch @@ -0,0 +1,126 @@ +From 4c332287a5cd2f41bffe3f092df54326d02a0a02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Sep 2023 15:31:39 -0400 +Subject: btrfs: don't clear uptodate on write errors + +From: Josef Bacik + +[ 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 +Signed-off-by: Josef Bacik +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..241d3c38e3c --- /dev/null +++ b/queue-6.5/btrfs-remove-btrfs_writepage_endio_finish_ordered.patch @@ -0,0 +1,145 @@ +From c5b0c5a4299d91df651782d99eacf0465c9cf450 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Jun 2023 17:31:25 +0200 +Subject: btrfs: remove btrfs_writepage_endio_finish_ordered + +From: Christoph Hellwig + +[ 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 +Signed-off-by: Christoph Hellwig +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: b595d2599632 ("btrfs: don't clear uptodate on write errors") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2fd3df7ca3e --- /dev/null +++ b/queue-6.5/btrfs-remove-end_extent_writepage.patch @@ -0,0 +1,216 @@ +From f5d4b635889de5aa70af38ef7158b770893c4dd3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Jun 2023 17:31:26 +0200 +Subject: btrfs: remove end_extent_writepage + +From: Christoph Hellwig + +[ 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 +Signed-off-by: Christoph Hellwig +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: b595d2599632 ("btrfs: don't clear uptodate on write errors") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..72bd0bd31c0 --- /dev/null +++ b/queue-6.5/maple_tree-add-mas_is_active-to-detect-in-tree-walks.patch @@ -0,0 +1,61 @@ +From 264d5a8c32f6ed81eb35ccd399db0183fe0bb583 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Pedro Falcato +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a30a8316bc6 --- /dev/null +++ b/queue-6.5/mptcp-fix-dangling-connection-hang-up.patch @@ -0,0 +1,266 @@ +From 478a93d24919d2f0f0ea93ad83738bcd9e927670 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 16 Sep 2023 12:52:49 +0200 +Subject: mptcp: fix dangling connection hang-up + +From: Paolo Abeni + +[ 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 +Reviewed-by: Matthieu Baerts +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..b061f67c426 --- /dev/null +++ b/queue-6.5/mptcp-remove-unnecessary-test-for-__mptcp_init_sock.patch @@ -0,0 +1,66 @@ +From 93b36859e5aae1d636bcbf0dff13bf760a12593b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Aug 2023 17:57:27 +0200 +Subject: mptcp: Remove unnecessary test for __mptcp_init_sock() + +From: Kuniyuki Iwashima + +[ 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 +Reviewed-by: Matthieu Baerts +Signed-off-by: Matthieu Baerts +Signed-off-by: David S. Miller +Stable-dep-of: 27e5ccc2d5a5 ("mptcp: fix dangling connection hang-up") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a1cec5672f6 --- /dev/null +++ b/queue-6.5/mptcp-rename-timer-related-helper-to-less-confusing-.patch @@ -0,0 +1,210 @@ +From c6282c64ad6465a60cbf840926c938dbf002db2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 16 Sep 2023 12:52:48 +0200 +Subject: mptcp: rename timer related helper to less confusing names + +From: Paolo Abeni + +[ 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 +Reviewed-by: Matthieu Baerts +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts +Signed-off-by: David S. Miller +Stable-dep-of: 27e5ccc2d5a5 ("mptcp: fix dangling connection hang-up") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..b6571593529 --- /dev/null +++ b/queue-6.5/scsi-core-improve-type-safety-of-scsi_rescan_device.patch @@ -0,0 +1,198 @@ +From 6baea050e37d2c14a86c1f2715caa919b73e5352 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Aug 2023 08:30:41 -0700 +Subject: scsi: core: Improve type safety of scsi_rescan_device() + +From: Bart Van Assche + +[ 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 . + +Reviewed-by: Hannes Reinecke +Reviewed-by: Damien Le Moal +Reviewed-by: John Garry +Cc: Mike Christie +Cc: Ming Lei +Signed-off-by: Bart Van Assche +Link: https://lore.kernel.org/r/20230822153043.4046244-1-bvanassche@acm.org +Signed-off-by: Martin K. Petersen +Stable-dep-of: 8b4d9469d0b0 ("ata: libata-scsi: Fix delayed scsi_rescan_device() execution") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c02996a27ac --- /dev/null +++ b/queue-6.5/scsi-do-not-attempt-to-rescan-suspended-devices.patch @@ -0,0 +1,98 @@ +From 0c62f5a5665b1cb55824c1cf96f44be41b1ba176 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 15:00:13 +0900 +Subject: scsi: Do not attempt to rescan suspended devices + +From: Damien Le Moal + +[ 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 +Reviewed-by: Hannes Reinecke +Reviewed-by: Niklas Cassel +Tested-by: Geert Uytterhoeven +Reviewed-by: Martin K. Petersen +Reviewed-by: Bart Van Assche +Stable-dep-of: 8b4d9469d0b0 ("ata: libata-scsi: Fix delayed scsi_rescan_device() execution") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..3e5de618262 --- /dev/null +++ b/queue-6.5/series @@ -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