From 86901b9eb9a446089e2e287dccb68ee9276b8712 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 1 Jul 2024 14:32:44 +0200 Subject: [PATCH] 5.10-stable patches added patches: mmc-sdhci-do-not-invert-write-protect-twice.patch mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch ocfs2-fix-dio-failure-due-to-insufficient-transaction-credits.patch --- ...ci-do-not-invert-write-protect-twice.patch | 90 +++++++++++ ...lock-spinlock-around-mmc_gpio_get_ro.patch | 53 +++++++ ...vert-pcibios_-return-codes-to-errnos.patch | 74 +++++++++ ...-to-insufficient-transaction-credits.patch | 141 ++++++++++++++++++ queue-5.10/series | 4 + 5 files changed, 362 insertions(+) create mode 100644 queue-5.10/mmc-sdhci-do-not-invert-write-protect-twice.patch create mode 100644 queue-5.10/mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch create mode 100644 queue-5.10/mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch create mode 100644 queue-5.10/ocfs2-fix-dio-failure-due-to-insufficient-transaction-credits.patch diff --git a/queue-5.10/mmc-sdhci-do-not-invert-write-protect-twice.patch b/queue-5.10/mmc-sdhci-do-not-invert-write-protect-twice.patch new file mode 100644 index 00000000000..13ddafbd63f --- /dev/null +++ b/queue-5.10/mmc-sdhci-do-not-invert-write-protect-twice.patch @@ -0,0 +1,90 @@ +From fbd64f902b93fe9658b855b9892ae59ef6ea22b9 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Fri, 14 Jun 2024 11:00:49 +0300 +Subject: mmc: sdhci: Do not invert write-protect twice + +From: Adrian Hunter + +commit fbd64f902b93fe9658b855b9892ae59ef6ea22b9 upstream. + +mmc_of_parse() reads device property "wp-inverted" and sets +MMC_CAP2_RO_ACTIVE_HIGH if it is true. MMC_CAP2_RO_ACTIVE_HIGH is used +to invert a write-protect (AKA read-only) GPIO value. + +sdhci_get_property() also reads "wp-inverted" and sets +SDHCI_QUIRK_INVERTED_WRITE_PROTECT which is used to invert the +write-protect value as well but also acts upon a value read out from the +SDHCI_PRESENT_STATE register. + +Many drivers call both mmc_of_parse() and sdhci_get_property(), +so that both MMC_CAP2_RO_ACTIVE_HIGH and +SDHCI_QUIRK_INVERTED_WRITE_PROTECT will be set if the controller has +device property "wp-inverted". + +Amend the logic in sdhci_check_ro() to allow for that possibility, +so that the write-protect value is not inverted twice. + +Also do not invert the value if it is a negative error value. Note that +callers treat an error the same as not-write-protected, so the result is +functionally the same in that case. + +Also do not invert the value if sdhci host operation ->get_ro() is used. +None of the users of that callback set SDHCI_QUIRK_INVERTED_WRITE_PROTECT +directly or indirectly, but two do call mmc_gpio_get_ro(), so leave it to +them to deal with that if they ever set SDHCI_QUIRK_INVERTED_WRITE_PROTECT +in the future. + +Fixes: 6d5cd068ee59 ("mmc: sdhci: use WP GPIO in sdhci_check_ro()") +Signed-off-by: Adrian Hunter +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240614080051.4005-2-adrian.hunter@intel.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -2492,26 +2492,34 @@ static int sdhci_get_cd(struct mmc_host + + static int sdhci_check_ro(struct sdhci_host *host) + { ++ bool allow_invert = false; + unsigned long flags; + int is_readonly; + + spin_lock_irqsave(&host->lock, flags); + +- if (host->flags & SDHCI_DEVICE_DEAD) ++ if (host->flags & SDHCI_DEVICE_DEAD) { + is_readonly = 0; +- else if (host->ops->get_ro) ++ } else if (host->ops->get_ro) { + is_readonly = host->ops->get_ro(host); +- else if (mmc_can_gpio_ro(host->mmc)) ++ } else if (mmc_can_gpio_ro(host->mmc)) { + is_readonly = mmc_gpio_get_ro(host->mmc); +- else ++ /* Do not invert twice */ ++ allow_invert = !(host->mmc->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); ++ } else { + is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE) + & SDHCI_WRITE_PROTECT); ++ allow_invert = true; ++ } + + spin_unlock_irqrestore(&host->lock, flags); + +- /* This quirk needs to be replaced by a callback-function later */ +- return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? +- !is_readonly : is_readonly; ++ if (is_readonly >= 0 && ++ allow_invert && ++ (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)) ++ is_readonly = !is_readonly; ++ ++ return is_readonly; + } + + #define SAMPLE_COUNT 5 diff --git a/queue-5.10/mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch b/queue-5.10/mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch new file mode 100644 index 00000000000..fcaa75c19d1 --- /dev/null +++ b/queue-5.10/mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch @@ -0,0 +1,53 @@ +From ab069ce125965a5e282f7b53b86aee76ab32975c Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Fri, 14 Jun 2024 11:00:50 +0300 +Subject: mmc: sdhci: Do not lock spinlock around mmc_gpio_get_ro() + +From: Adrian Hunter + +commit ab069ce125965a5e282f7b53b86aee76ab32975c upstream. + +sdhci_check_ro() can call mmc_gpio_get_ro() while holding the sdhci +host->lock spinlock. That would be a problem if the GPIO access done by +mmc_gpio_get_ro() needed to sleep. + +However, host->lock is not needed anyway. The mmc core ensures that host +operations do not race with each other, and asynchronous callbacks like the +interrupt handler, software timeouts, completion work etc, cannot affect +sdhci_check_ro(). + +So remove the locking. + +Fixes: 6d5cd068ee59 ("mmc: sdhci: use WP GPIO in sdhci_check_ro()") +Signed-off-by: Adrian Hunter +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240614080051.4005-3-adrian.hunter@intel.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -2493,11 +2493,8 @@ static int sdhci_get_cd(struct mmc_host + static int sdhci_check_ro(struct sdhci_host *host) + { + bool allow_invert = false; +- unsigned long flags; + int is_readonly; + +- spin_lock_irqsave(&host->lock, flags); +- + if (host->flags & SDHCI_DEVICE_DEAD) { + is_readonly = 0; + } else if (host->ops->get_ro) { +@@ -2512,8 +2509,6 @@ static int sdhci_check_ro(struct sdhci_h + allow_invert = true; + } + +- spin_unlock_irqrestore(&host->lock, flags); +- + if (is_readonly >= 0 && + allow_invert && + (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)) diff --git a/queue-5.10/mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch b/queue-5.10/mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch new file mode 100644 index 00000000000..3448b93d52e --- /dev/null +++ b/queue-5.10/mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch @@ -0,0 +1,74 @@ +From ebc4fc34eae8ddfbef49f2bdaced1bf4167ef80d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= +Date: Mon, 27 May 2024 16:24:41 +0300 +Subject: mmc: sdhci-pci: Convert PCIBIOS_* return codes to errnos +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +commit ebc4fc34eae8ddfbef49f2bdaced1bf4167ef80d upstream. + +jmicron_pmos() and sdhci_pci_probe() use pci_{read,write}_config_byte() +that return PCIBIOS_* codes. The return code is then returned as is by +jmicron_probe() and sdhci_pci_probe(). Similarly, the return code is +also returned as is from jmicron_resume(). Both probe and resume +functions should return normal errnos. + +Convert PCIBIOS_* returns code using pcibios_err_to_errno() into normal +errno before returning them the fix these issues. + +Fixes: 7582041ff3d4 ("mmc: sdhci-pci: fix simple_return.cocci warnings") +Fixes: 45211e215984 ("sdhci: toggle JMicron PMOS setting") +Cc: stable@vger.kernel.org +Signed-off-by: Ilpo Järvinen +Acked-by: Adrian Hunter +Link: https://lore.kernel.org/r/20240527132443.14038-1-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-pci-core.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/mmc/host/sdhci-pci-core.c ++++ b/drivers/mmc/host/sdhci-pci-core.c +@@ -1380,7 +1380,7 @@ static int jmicron_pmos(struct sdhci_pci + + ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch); + if (ret) +- return ret; ++ goto fail; + + /* + * Turn PMOS on [bit 0], set over current detection to 2.4 V +@@ -1391,7 +1391,10 @@ static int jmicron_pmos(struct sdhci_pci + else + scratch &= ~0x47; + +- return pci_write_config_byte(chip->pdev, 0xAE, scratch); ++ ret = pci_write_config_byte(chip->pdev, 0xAE, scratch); ++ ++fail: ++ return pcibios_err_to_errno(ret); + } + + static int jmicron_probe(struct sdhci_pci_chip *chip) +@@ -2308,7 +2311,7 @@ static int sdhci_pci_probe(struct pci_de + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); + if (ret) +- return ret; ++ return pcibios_err_to_errno(ret); + + slots = PCI_SLOT_INFO_SLOTS(slots) + 1; + dev_dbg(&pdev->dev, "found %d slot(s)\n", slots); +@@ -2317,7 +2320,7 @@ static int sdhci_pci_probe(struct pci_de + + ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); + if (ret) +- return ret; ++ return pcibios_err_to_errno(ret); + + first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; + diff --git a/queue-5.10/ocfs2-fix-dio-failure-due-to-insufficient-transaction-credits.patch b/queue-5.10/ocfs2-fix-dio-failure-due-to-insufficient-transaction-credits.patch new file mode 100644 index 00000000000..bc2ed108286 --- /dev/null +++ b/queue-5.10/ocfs2-fix-dio-failure-due-to-insufficient-transaction-credits.patch @@ -0,0 +1,141 @@ +From be346c1a6eeb49d8fda827d2a9522124c2f72f36 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Fri, 14 Jun 2024 16:52:43 +0200 +Subject: ocfs2: fix DIO failure due to insufficient transaction credits + +From: Jan Kara + +commit be346c1a6eeb49d8fda827d2a9522124c2f72f36 upstream. + +The code in ocfs2_dio_end_io_write() estimates number of necessary +transaction credits using ocfs2_calc_extend_credits(). This however does +not take into account that the IO could be arbitrarily large and can +contain arbitrary number of extents. + +Extent tree manipulations do often extend the current transaction but not +in all of the cases. For example if we have only single block extents in +the tree, ocfs2_mark_extent_written() will end up calling +ocfs2_replace_extent_rec() all the time and we will never extend the +current transaction and eventually exhaust all the transaction credits if +the IO contains many single block extents. Once that happens a +WARN_ON(jbd2_handle_buffer_credits(handle) <= 0) is triggered in +jbd2_journal_dirty_metadata() and subsequently OCFS2 aborts in response to +this error. This was actually triggered by one of our customers on a +heavily fragmented OCFS2 filesystem. + +To fix the issue make sure the transaction always has enough credits for +one extent insert before each call of ocfs2_mark_extent_written(). + +Heming Zhao said: + +------ +PANIC: "Kernel panic - not syncing: OCFS2: (device dm-1): panic forced after error" + +PID: xxx TASK: xxxx CPU: 5 COMMAND: "SubmitThread-CA" + #0 machine_kexec at ffffffff8c069932 + #1 __crash_kexec at ffffffff8c1338fa + #2 panic at ffffffff8c1d69b9 + #3 ocfs2_handle_error at ffffffffc0c86c0c [ocfs2] + #4 __ocfs2_abort at ffffffffc0c88387 [ocfs2] + #5 ocfs2_journal_dirty at ffffffffc0c51e98 [ocfs2] + #6 ocfs2_split_extent at ffffffffc0c27ea3 [ocfs2] + #7 ocfs2_change_extent_flag at ffffffffc0c28053 [ocfs2] + #8 ocfs2_mark_extent_written at ffffffffc0c28347 [ocfs2] + #9 ocfs2_dio_end_io_write at ffffffffc0c2bef9 [ocfs2] +#10 ocfs2_dio_end_io at ffffffffc0c2c0f5 [ocfs2] +#11 dio_complete at ffffffff8c2b9fa7 +#12 do_blockdev_direct_IO at ffffffff8c2bc09f +#13 ocfs2_direct_IO at ffffffffc0c2b653 [ocfs2] +#14 generic_file_direct_write at ffffffff8c1dcf14 +#15 __generic_file_write_iter at ffffffff8c1dd07b +#16 ocfs2_file_write_iter at ffffffffc0c49f1f [ocfs2] +#17 aio_write at ffffffff8c2cc72e +#18 kmem_cache_alloc at ffffffff8c248dde +#19 do_io_submit at ffffffff8c2ccada +#20 do_syscall_64 at ffffffff8c004984 +#21 entry_SYSCALL_64_after_hwframe at ffffffff8c8000ba + +Link: https://lkml.kernel.org/r/20240617095543.6971-1-jack@suse.cz +Link: https://lkml.kernel.org/r/20240614145243.8837-1-jack@suse.cz +Fixes: c15471f79506 ("ocfs2: fix sparse file & data ordering issue in direct io") +Signed-off-by: Jan Kara +Reviewed-by: Joseph Qi +Reviewed-by: Heming Zhao +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Gang He +Cc: Jun Piao +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + fs/ocfs2/aops.c | 5 +++++ + fs/ocfs2/journal.c | 17 +++++++++++++++++ + fs/ocfs2/journal.h | 2 ++ + fs/ocfs2/ocfs2_trace.h | 2 ++ + 4 files changed, 26 insertions(+) + +--- a/fs/ocfs2/aops.c ++++ b/fs/ocfs2/aops.c +@@ -2373,6 +2373,11 @@ static int ocfs2_dio_end_io_write(struct + } + + list_for_each_entry(ue, &dwc->dw_zero_list, ue_node) { ++ ret = ocfs2_assure_trans_credits(handle, credits); ++ if (ret < 0) { ++ mlog_errno(ret); ++ break; ++ } + ret = ocfs2_mark_extent_written(inode, &et, handle, + ue->ue_cpos, 1, + ue->ue_phys, +--- a/fs/ocfs2/journal.c ++++ b/fs/ocfs2/journal.c +@@ -450,6 +450,23 @@ bail: + } + + /* ++ * Make sure handle has at least 'nblocks' credits available. If it does not ++ * have that many credits available, we will try to extend the handle to have ++ * enough credits. If that fails, we will restart transaction to have enough ++ * credits. Similar notes regarding data consistency and locking implications ++ * as for ocfs2_extend_trans() apply here. ++ */ ++int ocfs2_assure_trans_credits(handle_t *handle, int nblocks) ++{ ++ int old_nblks = jbd2_handle_buffer_credits(handle); ++ ++ trace_ocfs2_assure_trans_credits(old_nblks); ++ if (old_nblks >= nblocks) ++ return 0; ++ return ocfs2_extend_trans(handle, nblocks - old_nblks); ++} ++ ++/* + * If we have fewer than thresh credits, extend by OCFS2_MAX_TRANS_DATA. + * If that fails, restart the transaction & regain write access for the + * buffer head which is used for metadata modifications. +--- a/fs/ocfs2/journal.h ++++ b/fs/ocfs2/journal.h +@@ -244,6 +244,8 @@ handle_t *ocfs2_start_trans(struct + int ocfs2_commit_trans(struct ocfs2_super *osb, + handle_t *handle); + int ocfs2_extend_trans(handle_t *handle, int nblocks); ++int ocfs2_assure_trans_credits(handle_t *handle, ++ int nblocks); + int ocfs2_allocate_extend_trans(handle_t *handle, + int thresh); + +--- a/fs/ocfs2/ocfs2_trace.h ++++ b/fs/ocfs2/ocfs2_trace.h +@@ -2578,6 +2578,8 @@ DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_commit + + DEFINE_OCFS2_INT_INT_EVENT(ocfs2_extend_trans); + ++DEFINE_OCFS2_INT_EVENT(ocfs2_assure_trans_credits); ++ + DEFINE_OCFS2_INT_EVENT(ocfs2_extend_trans_restart); + + DEFINE_OCFS2_INT_INT_EVENT(ocfs2_allocate_extend_trans); diff --git a/queue-5.10/series b/queue-5.10/series index 38c61d2f0e3..c1a21958abc 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -293,3 +293,7 @@ drm-panel-simple-add-missing-display-timing-flags-fo.patch gpio-davinci-validate-the-obtained-number-of-irqs.patch gpiolib-cdev-disallow-reconfiguration-without-direct.patch x86-stop-playing-stack-games-in-profile_pc.patch +ocfs2-fix-dio-failure-due-to-insufficient-transaction-credits.patch +mmc-sdhci-pci-convert-pcibios_-return-codes-to-errnos.patch +mmc-sdhci-do-not-invert-write-protect-twice.patch +mmc-sdhci-do-not-lock-spinlock-around-mmc_gpio_get_ro.patch -- 2.47.3