From: Sasha Levin Date: Sun, 20 Feb 2022 23:55:47 +0000 (-0500) Subject: Fixes for 5.10 X-Git-Tag: v4.9.303~26^2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aa4c81772e07443688c8b4c0de426ff97cf2df7d;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/asoc-tas2770-insert-post-reset-delay.patch b/queue-5.10/asoc-tas2770-insert-post-reset-delay.patch new file mode 100644 index 00000000000..c5a2702f9a8 --- /dev/null +++ b/queue-5.10/asoc-tas2770-insert-post-reset-delay.patch @@ -0,0 +1,64 @@ +From 84351dd7a949a5edb18716765e9e1ebbdde122e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Feb 2022 10:53:01 +0100 +Subject: ASoC: tas2770: Insert post reset delay +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Martin Povišer + +[ Upstream commit 307f31452078792aab94a729fce33200c6e42dc4 ] + +Per TAS2770 datasheet there must be a 1 ms delay from reset to first +command. So insert delays into the driver where appropriate. + +Fixes: 1a476abc723e ("tas2770: add tas2770 smart PA kernel driver") +Signed-off-by: Martin Povišer +Link: https://lore.kernel.org/r/20220204095301.5554-1-povik+lin@cutebit.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tas2770.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c +index 61c3238bc2656..315fd9d971c8c 100644 +--- a/sound/soc/codecs/tas2770.c ++++ b/sound/soc/codecs/tas2770.c +@@ -38,10 +38,12 @@ static void tas2770_reset(struct tas2770_priv *tas2770) + gpiod_set_value_cansleep(tas2770->reset_gpio, 0); + msleep(20); + gpiod_set_value_cansleep(tas2770->reset_gpio, 1); ++ usleep_range(1000, 2000); + } + + snd_soc_component_write(tas2770->component, TAS2770_SW_RST, + TAS2770_RST); ++ usleep_range(1000, 2000); + } + + static int tas2770_set_bias_level(struct snd_soc_component *component, +@@ -110,6 +112,7 @@ static int tas2770_codec_resume(struct snd_soc_component *component) + + if (tas2770->sdz_gpio) { + gpiod_set_value_cansleep(tas2770->sdz_gpio, 1); ++ usleep_range(1000, 2000); + } else { + ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL, + TAS2770_PWR_CTRL_MASK, +@@ -510,8 +513,10 @@ static int tas2770_codec_probe(struct snd_soc_component *component) + + tas2770->component = component; + +- if (tas2770->sdz_gpio) ++ if (tas2770->sdz_gpio) { + gpiod_set_value_cansleep(tas2770->sdz_gpio, 1); ++ usleep_range(1000, 2000); ++ } + + tas2770_reset(tas2770); + +-- +2.34.1 + diff --git a/queue-5.10/block-wbt-fix-negative-inflight-counter-when-remove-.patch b/queue-5.10/block-wbt-fix-negative-inflight-counter-when-remove-.patch new file mode 100644 index 00000000000..15407161c7f --- /dev/null +++ b/queue-5.10/block-wbt-fix-negative-inflight-counter-when-remove-.patch @@ -0,0 +1,85 @@ +From b687439c422df871dfaf0a066d5ecbe79dacf340 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Jan 2022 19:10:45 +0800 +Subject: block/wbt: fix negative inflight counter when remove scsi device + +From: Laibin Qiu + +[ Upstream commit e92bc4cd34de2ce454bdea8cd198b8067ee4e123 ] + +Now that we disable wbt by set WBT_STATE_OFF_DEFAULT in +wbt_disable_default() when switch elevator to bfq. And when +we remove scsi device, wbt will be enabled by wbt_enable_default. +If it become false positive between wbt_wait() and wbt_track() +when submit write request. + +The following is the scenario that triggered the problem. + +T1 T2 T3 + elevator_switch_mq + bfq_init_queue + wbt_disable_default <= Set + rwb->enable_state (OFF) +Submit_bio +blk_mq_make_request +rq_qos_throttle +<= rwb->enable_state (OFF) + scsi_remove_device + sd_remove + del_gendisk + blk_unregister_queue + elv_unregister_queue + wbt_enable_default + <= Set rwb->enable_state (ON) +q_qos_track +<= rwb->enable_state (ON) +^^^^^^ this request will mark WBT_TRACKED without inflight add and will +lead to drop rqw->inflight to -1 in wbt_done() which will trigger IO hung. + +Fix this by move wbt_enable_default() from elv_unregister to +bfq_exit_queue(). Only re-enable wbt when bfq exit. + +Fixes: 76a8040817b4b ("blk-wbt: make sure throttle is enabled properly") + +Remove oneline stale comment, and kill one oneshot local variable. + +Signed-off-by: Ming Lei +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/linux-block/20211214133103.551813-1-qiulaibin@huawei.com/ +Signed-off-by: Laibin Qiu +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/bfq-iosched.c | 2 ++ + block/elevator.c | 2 -- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index b8c2ddc01aec3..8d95bf7765b19 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -6404,6 +6404,8 @@ static void bfq_exit_queue(struct elevator_queue *e) + spin_unlock_irq(&bfqd->lock); + #endif + ++ wbt_enable_default(bfqd->queue); ++ + kfree(bfqd); + } + +diff --git a/block/elevator.c b/block/elevator.c +index 2a525863d4e92..2f962662c32a1 100644 +--- a/block/elevator.c ++++ b/block/elevator.c +@@ -518,8 +518,6 @@ void elv_unregister_queue(struct request_queue *q) + kobject_del(&e->kobj); + + e->registered = 0; +- /* Re-enable throttling in case elevator disabled it */ +- wbt_enable_default(q); + } + } + +-- +2.34.1 + diff --git a/queue-5.10/drivers-hv-vmbus-fix-memory-leak-in-vmbus_add_channe.patch b/queue-5.10/drivers-hv-vmbus-fix-memory-leak-in-vmbus_add_channe.patch new file mode 100644 index 00000000000..4ca35ca5577 --- /dev/null +++ b/queue-5.10/drivers-hv-vmbus-fix-memory-leak-in-vmbus_add_channe.patch @@ -0,0 +1,57 @@ +From 7a94c886809fe6e27acfcc032f4bf6a9f64d4e8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Feb 2022 01:30:08 +0800 +Subject: Drivers: hv: vmbus: Fix memory leak in vmbus_add_channel_kobj +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Miaoqian Lin + +[ Upstream commit 8bc69f86328e87a0ffa79438430cc82f3aa6a194 ] + +kobject_init_and_add() takes reference even when it fails. +According to the doc of kobject_init_and_add(): + + If this function returns an error, kobject_put() must be called to + properly clean up the memory associated with the object. + +Fix memory leak by calling kobject_put(). + +Fixes: c2e5df616e1a ("vmbus: add per-channel sysfs info") +Signed-off-by: Miaoqian Lin +Reviewed-by: Juan Vazquez +Link: https://lore.kernel.org/r/20220203173008.43480-1-linmq006@gmail.com +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + drivers/hv/vmbus_drv.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index a5a402e776c77..362da2a83b470 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -1944,8 +1944,10 @@ int vmbus_add_channel_kobj(struct hv_device *dev, struct vmbus_channel *channel) + kobj->kset = dev->channels_kset; + ret = kobject_init_and_add(kobj, &vmbus_chan_ktype, NULL, + "%u", relid); +- if (ret) ++ if (ret) { ++ kobject_put(kobj); + return ret; ++ } + + ret = sysfs_create_group(kobj, &vmbus_chan_group); + +@@ -1954,6 +1956,7 @@ int vmbus_add_channel_kobj(struct hv_device *dev, struct vmbus_channel *channel) + * The calling functions' error handling paths will cleanup the + * empty channel directory. + */ ++ kobject_put(kobj); + dev_err(device, "Unable to set up channel sysfs files\n"); + return ret; + } +-- +2.34.1 + diff --git a/queue-5.10/kvm-x86-pmu-don-t-truncate-the-perfevtseln-msr-when-.patch b/queue-5.10/kvm-x86-pmu-don-t-truncate-the-perfevtseln-msr-when-.patch new file mode 100644 index 00000000000..2b0757d617e --- /dev/null +++ b/queue-5.10/kvm-x86-pmu-don-t-truncate-the-perfevtseln-msr-when-.patch @@ -0,0 +1,52 @@ +From befa75cf310a91e20b1ff91179a3c62181c2d205 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Feb 2022 17:48:12 -0800 +Subject: KVM: x86/pmu: Don't truncate the PerfEvtSeln MSR when creating a perf + event + +From: Jim Mattson + +[ Upstream commit b8bfee85f1307426e0242d654f3a14c06ef639c5 ] + +AMD's event select is 3 nybbles, with the high nybble in bits 35:32 of +a PerfEvtSeln MSR. Don't drop the high nybble when setting up the +config field of a perf_event_attr structure for a call to +perf_event_create_kernel_counter(). + +Fixes: ca724305a2b0 ("KVM: x86/vPMU: Implement AMD vPMU code for KVM") +Reported-by: Stephane Eranian +Signed-off-by: Jim Mattson +Message-Id: <20220203014813.2130559-1-jmattson@google.com> +Reviewed-by: David Dunn +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + arch/x86/kvm/pmu.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c +index 20092a56de8b0..2d91e39dbdf67 100644 +--- a/arch/x86/kvm/pmu.c ++++ b/arch/x86/kvm/pmu.c +@@ -95,7 +95,7 @@ static void kvm_perf_overflow_intr(struct perf_event *perf_event, + } + + static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type, +- unsigned config, bool exclude_user, ++ u64 config, bool exclude_user, + bool exclude_kernel, bool intr, + bool in_tx, bool in_tx_cp) + { +@@ -170,7 +170,8 @@ static bool pmc_resume_counter(struct kvm_pmc *pmc) + + void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel) + { +- unsigned config, type = PERF_TYPE_RAW; ++ u64 config; ++ u32 type = PERF_TYPE_RAW; + struct kvm *kvm = pmc->vcpu->kvm; + struct kvm_pmu_event_filter *filter; + int i; +-- +2.34.1 + diff --git a/queue-5.10/kvm-x86-pmu-refactoring-find_arch_event-to-pmc_perf_.patch b/queue-5.10/kvm-x86-pmu-refactoring-find_arch_event-to-pmc_perf_.patch new file mode 100644 index 00000000000..119076cfe39 --- /dev/null +++ b/queue-5.10/kvm-x86-pmu-refactoring-find_arch_event-to-pmc_perf_.patch @@ -0,0 +1,131 @@ +From 0864e573c2bc533fead9659a68511d56d5107e2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Nov 2021 15:42:17 +0800 +Subject: KVM: x86/pmu: Refactoring find_arch_event() to pmc_perf_hw_id() + +From: Like Xu + +[ Upstream commit 7c174f305cbee6bdba5018aae02b84369e7ab995 ] + +The find_arch_event() returns a "unsigned int" value, +which is used by the pmc_reprogram_counter() to +program a PERF_TYPE_HARDWARE type perf_event. + +The returned value is actually the kernel defined generic +perf_hw_id, let's rename it to pmc_perf_hw_id() with simpler +incoming parameters for better self-explanation. + +Signed-off-by: Like Xu +Message-Id: <20211130074221.93635-3-likexu@tencent.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + arch/x86/kvm/pmu.c | 8 +------- + arch/x86/kvm/pmu.h | 3 +-- + arch/x86/kvm/svm/pmu.c | 8 ++++---- + arch/x86/kvm/vmx/pmu_intel.c | 9 +++++---- + 4 files changed, 11 insertions(+), 17 deletions(-) + +diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c +index 67741d2a03085..20092a56de8b0 100644 +--- a/arch/x86/kvm/pmu.c ++++ b/arch/x86/kvm/pmu.c +@@ -171,7 +171,6 @@ static bool pmc_resume_counter(struct kvm_pmc *pmc) + void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel) + { + unsigned config, type = PERF_TYPE_RAW; +- u8 event_select, unit_mask; + struct kvm *kvm = pmc->vcpu->kvm; + struct kvm_pmu_event_filter *filter; + int i; +@@ -203,17 +202,12 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel) + if (!allow_event) + return; + +- event_select = eventsel & ARCH_PERFMON_EVENTSEL_EVENT; +- unit_mask = (eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; +- + if (!(eventsel & (ARCH_PERFMON_EVENTSEL_EDGE | + ARCH_PERFMON_EVENTSEL_INV | + ARCH_PERFMON_EVENTSEL_CMASK | + HSW_IN_TX | + HSW_IN_TX_CHECKPOINTED))) { +- config = kvm_x86_ops.pmu_ops->find_arch_event(pmc_to_pmu(pmc), +- event_select, +- unit_mask); ++ config = kvm_x86_ops.pmu_ops->pmc_perf_hw_id(pmc); + if (config != PERF_COUNT_HW_MAX) + type = PERF_TYPE_HARDWARE; + } +diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h +index 067fef51760c4..1a44e29e73330 100644 +--- a/arch/x86/kvm/pmu.h ++++ b/arch/x86/kvm/pmu.h +@@ -24,8 +24,7 @@ struct kvm_event_hw_type_mapping { + }; + + struct kvm_pmu_ops { +- unsigned (*find_arch_event)(struct kvm_pmu *pmu, u8 event_select, +- u8 unit_mask); ++ unsigned int (*pmc_perf_hw_id)(struct kvm_pmc *pmc); + unsigned (*find_fixed_event)(int idx); + bool (*pmc_is_enabled)(struct kvm_pmc *pmc); + struct kvm_pmc *(*pmc_idx_to_pmc)(struct kvm_pmu *pmu, int pmc_idx); +diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c +index 5a5c165a30ed1..4e7093bcb64b6 100644 +--- a/arch/x86/kvm/svm/pmu.c ++++ b/arch/x86/kvm/svm/pmu.c +@@ -126,10 +126,10 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr, + return &pmu->gp_counters[msr_to_index(msr)]; + } + +-static unsigned amd_find_arch_event(struct kvm_pmu *pmu, +- u8 event_select, +- u8 unit_mask) ++static unsigned int amd_pmc_perf_hw_id(struct kvm_pmc *pmc) + { ++ u8 event_select = pmc->eventsel & ARCH_PERFMON_EVENTSEL_EVENT; ++ u8 unit_mask = (pmc->eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; + int i; + + for (i = 0; i < ARRAY_SIZE(amd_event_mapping); i++) +@@ -312,7 +312,7 @@ static void amd_pmu_reset(struct kvm_vcpu *vcpu) + } + + struct kvm_pmu_ops amd_pmu_ops = { +- .find_arch_event = amd_find_arch_event, ++ .pmc_perf_hw_id = amd_pmc_perf_hw_id, + .find_fixed_event = amd_find_fixed_event, + .pmc_is_enabled = amd_pmc_is_enabled, + .pmc_idx_to_pmc = amd_pmc_idx_to_pmc, +diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c +index cdf5f34518f43..bd70c1d7f3458 100644 +--- a/arch/x86/kvm/vmx/pmu_intel.c ++++ b/arch/x86/kvm/vmx/pmu_intel.c +@@ -68,10 +68,11 @@ static void global_ctrl_changed(struct kvm_pmu *pmu, u64 data) + reprogram_counter(pmu, bit); + } + +-static unsigned intel_find_arch_event(struct kvm_pmu *pmu, +- u8 event_select, +- u8 unit_mask) ++static unsigned int intel_pmc_perf_hw_id(struct kvm_pmc *pmc) + { ++ struct kvm_pmu *pmu = pmc_to_pmu(pmc); ++ u8 event_select = pmc->eventsel & ARCH_PERFMON_EVENTSEL_EVENT; ++ u8 unit_mask = (pmc->eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; + int i; + + for (i = 0; i < ARRAY_SIZE(intel_arch_events); i++) +@@ -432,7 +433,7 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu) + } + + struct kvm_pmu_ops intel_pmu_ops = { +- .find_arch_event = intel_find_arch_event, ++ .pmc_perf_hw_id = intel_pmc_perf_hw_id, + .find_fixed_event = intel_find_fixed_event, + .pmc_is_enabled = intel_pmc_is_enabled, + .pmc_idx_to_pmc = intel_pmc_idx_to_pmc, +-- +2.34.1 + diff --git a/queue-5.10/kvm-x86-pmu-use-amd64_raw_event_mask-for-perf_type_r.patch b/queue-5.10/kvm-x86-pmu-use-amd64_raw_event_mask-for-perf_type_r.patch new file mode 100644 index 00000000000..e82cde0c31d --- /dev/null +++ b/queue-5.10/kvm-x86-pmu-use-amd64_raw_event_mask-for-perf_type_r.patch @@ -0,0 +1,39 @@ +From 3bda16f23753fa32976c42a30930a3d90749a183 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Feb 2022 17:48:13 -0800 +Subject: KVM: x86/pmu: Use AMD64_RAW_EVENT_MASK for PERF_TYPE_RAW + +From: Jim Mattson + +[ Upstream commit 710c476514313c74045c41c0571bb5178fd16e3d ] + +AMD's event select is 3 nybbles, with the high nybble in bits 35:32 of +a PerfEvtSeln MSR. Don't mask off the high nybble when configuring a +RAW perf event. + +Fixes: ca724305a2b0 ("KVM: x86/vPMU: Implement AMD vPMU code for KVM") +Signed-off-by: Jim Mattson +Message-Id: <20220203014813.2130559-2-jmattson@google.com> +Reviewed-by: David Dunn +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + arch/x86/kvm/pmu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c +index 2d91e39dbdf67..2f83b5d948b33 100644 +--- a/arch/x86/kvm/pmu.c ++++ b/arch/x86/kvm/pmu.c +@@ -214,7 +214,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel) + } + + if (type == PERF_TYPE_RAW) +- config = eventsel & X86_RAW_EVENT_MASK; ++ config = eventsel & AMD64_RAW_EVENT_MASK; + + if (pmc->current_config == eventsel && pmc_resume_counter(pmc)) + return; +-- +2.34.1 + diff --git a/queue-5.10/mtd-rawnand-brcmnand-fixed-incorrect-sub-page-ecc-st.patch b/queue-5.10/mtd-rawnand-brcmnand-fixed-incorrect-sub-page-ecc-st.patch new file mode 100644 index 00000000000..14a6179c1b5 --- /dev/null +++ b/queue-5.10/mtd-rawnand-brcmnand-fixed-incorrect-sub-page-ecc-st.patch @@ -0,0 +1,48 @@ +From 0f0d550a0ecd0347e308ebe462399348c7afe9a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Jan 2022 23:43:44 +0100 +Subject: mtd: rawnand: brcmnand: Fixed incorrect sub-page ECC status + +From: david regan + +[ Upstream commit 36415a7964711822e63695ea67fede63979054d9 ] + +The brcmnand driver contains a bug in which if a page (example 2k byte) +is read from the parallel/ONFI NAND and within that page a subpage (512 +byte) has correctable errors which is followed by a subpage with +uncorrectable errors, the page read will return the wrong status of +correctable (as opposed to the actual status of uncorrectable.) + +The bug is in function brcmnand_read_by_pio where there is a check for +uncorrectable bits which will be preempted if a previous status for +correctable bits is detected. + +The fix is to stop checking for bad bits only if we already have a bad +bits status. + +Fixes: 27c5b17cd1b1 ("mtd: nand: add NAND driver "library" for Broadcom STB NAND controller") +Signed-off-by: david regan +Reviewed-by: Florian Fainelli +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/trinity-478e0c09-9134-40e8-8f8c-31c371225eda-1643237024774@3c-app-mailcom-lxa02 +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/brcmnand/brcmnand.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +index 909b14cc8e55c..580b91cbd18de 100644 +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -2062,7 +2062,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, + mtd->oobsize / trans, + host->hwcfg.sector_size_1k); + +- if (!ret) { ++ if (ret != -EBADMSG) { + *err_addr = brcmnand_get_uncorrecc_addr(ctrl); + + if (*err_addr) +-- +2.34.1 + diff --git a/queue-5.10/mtd-rawnand-qcom-fix-clock-sequencing-in-qcom_nandc_.patch b/queue-5.10/mtd-rawnand-qcom-fix-clock-sequencing-in-qcom_nandc_.patch new file mode 100644 index 00000000000..79f0049b379 --- /dev/null +++ b/queue-5.10/mtd-rawnand-qcom-fix-clock-sequencing-in-qcom_nandc_.patch @@ -0,0 +1,96 @@ +From 3587f3ebb1d66cfafa06a559bd051aab28a8e9f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jan 2022 03:03:15 +0000 +Subject: mtd: rawnand: qcom: Fix clock sequencing in qcom_nandc_probe() + +From: Bryan O'Donoghue + +[ Upstream commit 5c23b3f965bc9ee696bf2ed4bdc54d339dd9a455 ] + +Interacting with a NAND chip on an IPQ6018 I found that the qcomsmem NAND +partition parser was returning -EPROBE_DEFER waiting for the main smem +driver to load. + +This caused the board to reset. Playing about with the probe() function +shows that the problem lies in the core clock being switched off before the +nandc_unalloc() routine has completed. + +If we look at how qcom_nandc_remove() tears down allocated resources we see +the expected order is + +qcom_nandc_unalloc(nandc); + +clk_disable_unprepare(nandc->aon_clk); +clk_disable_unprepare(nandc->core_clk); + +dma_unmap_resource(&pdev->dev, nandc->base_dma, resource_size(res), + DMA_BIDIRECTIONAL, 0); + +Tweaking probe() to both bring up and tear-down in that order removes the +reset if we end up deferring elsewhere. + +Fixes: c76b78d8ec05 ("mtd: nand: Qualcomm NAND controller driver") +Signed-off-by: Bryan O'Donoghue +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20220103030316.58301-2-bryan.odonoghue@linaro.org +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/qcom_nandc.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c +index b99d2e9d1e2c4..bb181e18c7c52 100644 +--- a/drivers/mtd/nand/raw/qcom_nandc.c ++++ b/drivers/mtd/nand/raw/qcom_nandc.c +@@ -2,7 +2,6 @@ + /* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + */ +- + #include + #include + #include +@@ -2968,10 +2967,6 @@ static int qcom_nandc_probe(struct platform_device *pdev) + if (!nandc->base_dma) + return -ENXIO; + +- ret = qcom_nandc_alloc(nandc); +- if (ret) +- goto err_nandc_alloc; +- + ret = clk_prepare_enable(nandc->core_clk); + if (ret) + goto err_core_clk; +@@ -2980,6 +2975,10 @@ static int qcom_nandc_probe(struct platform_device *pdev) + if (ret) + goto err_aon_clk; + ++ ret = qcom_nandc_alloc(nandc); ++ if (ret) ++ goto err_nandc_alloc; ++ + ret = qcom_nandc_setup(nandc); + if (ret) + goto err_setup; +@@ -2991,15 +2990,14 @@ static int qcom_nandc_probe(struct platform_device *pdev) + return 0; + + err_setup: ++ qcom_nandc_unalloc(nandc); ++err_nandc_alloc: + clk_disable_unprepare(nandc->aon_clk); + err_aon_clk: + clk_disable_unprepare(nandc->core_clk); + err_core_clk: +- qcom_nandc_unalloc(nandc); +-err_nandc_alloc: + dma_unmap_resource(dev, res->start, resource_size(res), + DMA_BIDIRECTIONAL, 0); +- + return ret; + } + +-- +2.34.1 + diff --git a/queue-5.10/nfs-do-not-report-writeback-errors-in-nfs_getattr.patch b/queue-5.10/nfs-do-not-report-writeback-errors-in-nfs_getattr.patch new file mode 100644 index 00000000000..718c7f0c55a --- /dev/null +++ b/queue-5.10/nfs-do-not-report-writeback-errors-in-nfs_getattr.patch @@ -0,0 +1,44 @@ +From afaf47295666b5763ba9bf1bf47b591cbc36f134 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Feb 2022 18:05:18 -0500 +Subject: NFS: Do not report writeback errors in nfs_getattr() + +From: Trond Myklebust + +[ Upstream commit d19e0183a88306acda07f4a01fedeeffe2a2a06b ] + +The result of the writeback, whether it is an ENOSPC or an EIO, or +anything else, does not inhibit the NFS client from reporting the +correct file timestamps. + +Fixes: 79566ef018f5 ("NFS: Getattr doesn't require data sync semantics") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/inode.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index f7929988b83bb..7e398bca952c9 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -823,12 +823,9 @@ int nfs_getattr(const struct path *path, struct kstat *stat, + } + + /* Flush out writes to the server in order to update c/mtime. */ +- if ((request_mask & (STATX_CTIME|STATX_MTIME)) && +- S_ISREG(inode->i_mode)) { +- err = filemap_write_and_wait(inode->i_mapping); +- if (err) +- goto out; +- } ++ if ((request_mask & (STATX_CTIME | STATX_MTIME)) && ++ S_ISREG(inode->i_mode)) ++ filemap_write_and_wait(inode->i_mapping); + + /* + * We may force a getattr if the user cares about atime. +-- +2.34.1 + diff --git a/queue-5.10/nfs-don-t-set-nfs_ino_invalid_xattr-if-there-is-no-x.patch b/queue-5.10/nfs-don-t-set-nfs_ino_invalid_xattr-if-there-is-no-x.patch new file mode 100644 index 00000000000..23f65a744f4 --- /dev/null +++ b/queue-5.10/nfs-don-t-set-nfs_ino_invalid_xattr-if-there-is-no-x.patch @@ -0,0 +1,51 @@ +From e495bc8cd3c94022fe3fc91ca6c8f8e6bb7ee274 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Feb 2021 16:45:49 -0500 +Subject: NFS: Don't set NFS_INO_INVALID_XATTR if there is no xattr cache + +From: Trond Myklebust + +[ Upstream commit 848fdd62399c638e65a1512616acaa5de7d5c5e8 ] + +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/inode.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 21addb78523d2..6e7fd73a264af 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -195,6 +195,18 @@ bool nfs_check_cache_invalid(struct inode *inode, unsigned long flags) + } + EXPORT_SYMBOL_GPL(nfs_check_cache_invalid); + ++#ifdef CONFIG_NFS_V4_2 ++static bool nfs_has_xattr_cache(const struct nfs_inode *nfsi) ++{ ++ return nfsi->xattr_cache != NULL; ++} ++#else ++static bool nfs_has_xattr_cache(const struct nfs_inode *nfsi) ++{ ++ return false; ++} ++#endif ++ + static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) + { + struct nfs_inode *nfsi = NFS_I(inode); +@@ -210,6 +222,8 @@ static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) + } else if (flags & NFS_INO_REVAL_PAGECACHE) + flags |= NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_SIZE; + ++ if (!nfs_has_xattr_cache(nfsi)) ++ flags &= ~NFS_INO_INVALID_XATTR; + if (inode->i_mapping->nrpages == 0) + flags &= ~(NFS_INO_INVALID_DATA|NFS_INO_DATA_INVAL_DEFER); + nfsi->cache_validity |= flags; +-- +2.34.1 + diff --git a/queue-5.10/nfs-don-t-set-nfs_ino_reval_pagecache-in-the-inode-c.patch b/queue-5.10/nfs-don-t-set-nfs_ino_reval_pagecache-in-the-inode-c.patch new file mode 100644 index 00000000000..b3fc98cebe5 --- /dev/null +++ b/queue-5.10/nfs-don-t-set-nfs_ino_reval_pagecache-in-the-inode-c.patch @@ -0,0 +1,75 @@ +From b46ff3921099cb7a9a905a772cc0896c64932e98 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Mar 2021 21:20:32 -0400 +Subject: NFS: Don't set NFS_INO_REVAL_PAGECACHE in the inode cache validity + +From: Trond Myklebust + +[ Upstream commit 36a9346c225270262d9f34e66c91aa1723fa903f ] + +It is no longer necessary to preserve the NFS_INO_REVAL_PAGECACHE flag. + +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/inode.c | 6 ++---- + fs/nfs/nfs4proc.c | 1 - + 2 files changed, 2 insertions(+), 5 deletions(-) + +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 1d2c1add7b7a2..0fdc7cf994a0f 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -217,11 +217,12 @@ static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) + flags &= ~NFS_INO_INVALID_OTHER; + flags &= ~(NFS_INO_INVALID_CHANGE + | NFS_INO_INVALID_SIZE +- | NFS_INO_REVAL_PAGECACHE + | NFS_INO_INVALID_XATTR); + } else if (flags & NFS_INO_REVAL_PAGECACHE) + flags |= NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_SIZE; + ++ flags &= ~NFS_INO_REVAL_PAGECACHE; ++ + if (!nfs_has_xattr_cache(nfsi)) + flags &= ~NFS_INO_INVALID_XATTR; + if (inode->i_mapping->nrpages == 0) +@@ -1904,7 +1905,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) + nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR + | NFS_INO_INVALID_ATIME + | NFS_INO_REVAL_FORCED +- | NFS_INO_REVAL_PAGECACHE + | NFS_INO_INVALID_BLOCKS); + + /* Do atomic weak cache consistency updates */ +@@ -1942,7 +1942,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) + } else { + nfsi->cache_validity |= save_cache_validity & + (NFS_INO_INVALID_CHANGE +- | NFS_INO_REVAL_PAGECACHE + | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } +@@ -1988,7 +1987,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) + } else { + nfsi->cache_validity |= save_cache_validity & + (NFS_INO_INVALID_SIZE +- | NFS_INO_REVAL_PAGECACHE + | NFS_INO_REVAL_FORCED); + cache_revalidated = false; + } +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 916513c3be8d5..48ed61e5ac0f3 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1197,7 +1197,6 @@ nfs4_update_changeattr_locked(struct inode *inode, + cache_validity |= NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME; + + if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(inode)) { +- nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; + nfsi->attrtimeo_timestamp = jiffies; + } else { + if (S_ISDIR(inode->i_mode)) { +-- +2.34.1 + diff --git a/queue-5.10/nfs-fix-open-coded-versions-of-nfs_set_cache_invalid.patch b/queue-5.10/nfs-fix-open-coded-versions-of-nfs_set_cache_invalid.patch new file mode 100644 index 00000000000..7304aba6a9b --- /dev/null +++ b/queue-5.10/nfs-fix-open-coded-versions-of-nfs_set_cache_invalid.patch @@ -0,0 +1,138 @@ +From 1794fa7a1a33cc24c9402dce84f7a59fd38d5707 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Mar 2021 14:42:55 -0500 +Subject: NFS: Fix open coded versions of nfs_set_cache_invalid() in NFSv4 + +From: Trond Myklebust + +[ Upstream commit b6f80a2ebb97f184c4679518ac83074598bf9bf4 ] + +nfs_set_cache_invalid() has code to handle delegations, and other +optimisations, so let's use it when appropriate. + +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/inode.c | 1 + + fs/nfs/nfs42proc.c | 12 +++++++----- + fs/nfs/nfs4proc.c | 28 ++++++++++++---------------- + 3 files changed, 20 insertions(+), 21 deletions(-) + +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 6e7fd73a264af..1d2c1add7b7a2 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -230,6 +230,7 @@ static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) + if (flags & NFS_INO_INVALID_DATA) + nfs_fscache_invalidate(inode); + } ++EXPORT_SYMBOL_GPL(nfs_set_cache_invalid); + + /* + * Invalidate the local caches +diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c +index 2587b1b8e2ef7..0bebfb3ec3b68 100644 +--- a/fs/nfs/nfs42proc.c ++++ b/fs/nfs/nfs42proc.c +@@ -366,13 +366,15 @@ static ssize_t _nfs42_proc_copy(struct file *src, + pos_dst >> PAGE_SHIFT, + (pos_dst + res->write_res.count - 1) >> PAGE_SHIFT)); + spin_lock(&dst_inode->i_lock); +- NFS_I(dst_inode)->cache_validity |= (NFS_INO_REVAL_PAGECACHE | +- NFS_INO_REVAL_FORCED | NFS_INO_INVALID_SIZE | +- NFS_INO_INVALID_ATTR | NFS_INO_INVALID_DATA); ++ nfs_set_cache_invalid( ++ dst_inode, NFS_INO_REVAL_PAGECACHE | NFS_INO_REVAL_FORCED | ++ NFS_INO_INVALID_SIZE | NFS_INO_INVALID_ATTR | ++ NFS_INO_INVALID_DATA); + spin_unlock(&dst_inode->i_lock); + spin_lock(&src_inode->i_lock); +- NFS_I(src_inode)->cache_validity |= (NFS_INO_REVAL_PAGECACHE | +- NFS_INO_REVAL_FORCED | NFS_INO_INVALID_ATIME); ++ nfs_set_cache_invalid(src_inode, NFS_INO_REVAL_PAGECACHE | ++ NFS_INO_REVAL_FORCED | ++ NFS_INO_INVALID_ATIME); + spin_unlock(&src_inode->i_lock); + status = res->write_res.count; + out: +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index d222a980164b7..916513c3be8d5 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1176,14 +1176,14 @@ int nfs4_call_sync(struct rpc_clnt *clnt, + static void + nfs4_inc_nlink_locked(struct inode *inode) + { +- NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER; ++ nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER); + inc_nlink(inode); + } + + static void + nfs4_dec_nlink_locked(struct inode *inode) + { +- NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER; ++ nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER); + drop_nlink(inode); + } + +@@ -1194,35 +1194,31 @@ nfs4_update_changeattr_locked(struct inode *inode, + { + struct nfs_inode *nfsi = NFS_I(inode); + +- nfsi->cache_validity |= NFS_INO_INVALID_CTIME +- | NFS_INO_INVALID_MTIME +- | cache_validity; ++ cache_validity |= NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME; + + if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(inode)) { + nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; + nfsi->attrtimeo_timestamp = jiffies; + } else { + if (S_ISDIR(inode->i_mode)) { +- nfsi->cache_validity |= NFS_INO_INVALID_DATA; ++ cache_validity |= NFS_INO_INVALID_DATA; + nfs_force_lookup_revalidate(inode); + } else { + if (!NFS_PROTO(inode)->have_delegation(inode, + FMODE_READ)) +- nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; ++ cache_validity |= NFS_INO_REVAL_PAGECACHE; + } + + if (cinfo->before != inode_peek_iversion_raw(inode)) +- nfsi->cache_validity |= NFS_INO_INVALID_ACCESS | +- NFS_INO_INVALID_ACL | +- NFS_INO_INVALID_XATTR; ++ cache_validity |= NFS_INO_INVALID_ACCESS | ++ NFS_INO_INVALID_ACL | ++ NFS_INO_INVALID_XATTR; + } + inode_set_iversion_raw(inode, cinfo->after); + nfsi->read_cache_jiffies = timestamp; + nfsi->attr_gencount = nfs_inc_attr_generation_counter(); ++ nfs_set_cache_invalid(inode, cache_validity); + nfsi->cache_validity &= ~NFS_INO_INVALID_CHANGE; +- +- if (nfsi->cache_validity & NFS_INO_INVALID_DATA) +- nfs_fscache_invalidate(inode); + } + + void +@@ -5931,9 +5927,9 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl + * so mark the attribute cache invalid. + */ + spin_lock(&inode->i_lock); +- NFS_I(inode)->cache_validity |= NFS_INO_INVALID_CHANGE +- | NFS_INO_INVALID_CTIME +- | NFS_INO_REVAL_FORCED; ++ nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE | ++ NFS_INO_INVALID_CTIME | ++ NFS_INO_REVAL_FORCED); + spin_unlock(&inode->i_lock); + nfs_access_zap_cache(inode); + nfs_zap_acl_cache(inode); +-- +2.34.1 + diff --git a/queue-5.10/nfs-lookup_directory-is-also-ok-with-symlinks.patch b/queue-5.10/nfs-lookup_directory-is-also-ok-with-symlinks.patch new file mode 100644 index 00000000000..cb253e33066 --- /dev/null +++ b/queue-5.10/nfs-lookup_directory-is-also-ok-with-symlinks.patch @@ -0,0 +1,48 @@ +From cf987c44afab63a144400a8aee796a58a13f0a2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Feb 2022 13:38:23 -0500 +Subject: NFS: LOOKUP_DIRECTORY is also ok with symlinks + +From: Trond Myklebust + +[ Upstream commit e0caaf75d443e02e55e146fd75fe2efc8aed5540 ] + +Commit ac795161c936 (NFSv4: Handle case where the lookup of a directory +fails) [1], part of Linux since 5.17-rc2, introduced a regression, where +a symbolic link on an NFS mount to a directory on another NFS does not +resolve(?) the first time it is accessed: + +Reported-by: Paul Menzel +Fixes: ac795161c936 ("NFSv4: Handle case where the lookup of a directory fails") +Signed-off-by: Trond Myklebust +Tested-by: Donald Buczek +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/dir.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c +index 682c7b45d8b71..2ad56ff4752c7 100644 +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -1780,14 +1780,14 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, + if (!res) { + inode = d_inode(dentry); + if ((lookup_flags & LOOKUP_DIRECTORY) && inode && +- !S_ISDIR(inode->i_mode)) ++ !(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) + res = ERR_PTR(-ENOTDIR); + else if (inode && S_ISREG(inode->i_mode)) + res = ERR_PTR(-EOPENSTALE); + } else if (!IS_ERR(res)) { + inode = d_inode(res); + if ((lookup_flags & LOOKUP_DIRECTORY) && inode && +- !S_ISDIR(inode->i_mode)) { ++ !(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) { + dput(res); + res = ERR_PTR(-ENOTDIR); + } else if (inode && S_ISREG(inode->i_mode)) { +-- +2.34.1 + diff --git a/queue-5.10/nfs-remove-an-incorrect-revalidation-in-nfs4_update_.patch b/queue-5.10/nfs-remove-an-incorrect-revalidation-in-nfs4_update_.patch new file mode 100644 index 00000000000..234181f72a8 --- /dev/null +++ b/queue-5.10/nfs-remove-an-incorrect-revalidation-in-nfs4_update_.patch @@ -0,0 +1,44 @@ +From 0926c5769c40461d69d9d3d1507b793ed9e62b5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Feb 2022 12:14:44 -0500 +Subject: NFS: Remove an incorrect revalidation in + nfs4_update_changeattr_locked() + +From: Trond Myklebust + +[ Upstream commit 9d047bf68fe8cdb4086deaf4edd119731a9481ed ] + +In nfs4_update_changeattr_locked(), we don't need to set the +NFS_INO_REVAL_PAGECACHE flag, because we already know the value of the +change attribute, and we're already flagging the size. In fact, this +forces us to revalidate the change attribute a second time for no good +reason. +This extra flag appears to have been introduced as part of the xattr +feature, when update_changeattr_locked() was converted for use by the +xattr code. + +Fixes: 1b523ca972ed ("nfs: modify update_changeattr to deal with regular files") +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs4proc.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 4c80369e0a837..1e91643970a46 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1219,8 +1219,7 @@ nfs4_update_changeattr_locked(struct inode *inode, + NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL | + NFS_INO_INVALID_SIZE | NFS_INO_INVALID_OTHER | + NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_NLINK | +- NFS_INO_INVALID_MODE | NFS_INO_INVALID_XATTR | +- NFS_INO_REVAL_PAGECACHE; ++ NFS_INO_INVALID_MODE | NFS_INO_INVALID_XATTR; + nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); + } + nfsi->attrtimeo_timestamp = jiffies; +-- +2.34.1 + diff --git a/queue-5.10/nfs-use-information-about-the-change-attribute-to-op.patch b/queue-5.10/nfs-use-information-about-the-change-attribute-to-op.patch new file mode 100644 index 00000000000..39300eaf494 --- /dev/null +++ b/queue-5.10/nfs-use-information-about-the-change-attribute-to-op.patch @@ -0,0 +1,222 @@ +From bd3871990f502faaa518e3683258db2e8c703ad2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Mar 2021 11:01:19 -0400 +Subject: NFS: Use information about the change attribute to optimise updates + +From: Trond Myklebust + +[ Upstream commit 6f9be83d07615e6af8838a1d489080b399f42a08 ] + +If the NFSv4.2 server supports the 'change_attr_type' attribute, then +allow the client to optimise its attribute cache update strategy. + +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/inode.c | 111 ++++++++++++++++++++++++++++++++++++++-------- + fs/nfs/nfs4proc.c | 20 +++++++-- + 2 files changed, 110 insertions(+), 21 deletions(-) + +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 0fdc7cf994a0f..f7929988b83bb 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -1643,25 +1643,20 @@ EXPORT_SYMBOL_GPL(_nfs_display_fhandle); + #endif + + /** +- * nfs_inode_attrs_need_update - check if the inode attributes need updating +- * @inode: pointer to inode ++ * nfs_inode_attrs_cmp_generic - compare attributes + * @fattr: attributes ++ * @inode: pointer to inode + * + * Attempt to divine whether or not an RPC call reply carrying stale + * attributes got scheduled after another call carrying updated ones. +- * +- * To do so, the function first assumes that a more recent ctime means +- * that the attributes in fattr are newer, however it also attempt to +- * catch the case where ctime either didn't change, or went backwards +- * (if someone reset the clock on the server) by looking at whether +- * or not this RPC call was started after the inode was last updated. + * Note also the check for wraparound of 'attr_gencount' + * +- * The function returns 'true' if it thinks the attributes in 'fattr' are +- * more recent than the ones cached in the inode. +- * ++ * The function returns '1' if it thinks the attributes in @fattr are ++ * more recent than the ones cached in @inode. Otherwise it returns ++ * the value '0'. + */ +-static int nfs_inode_attrs_need_update(const struct inode *inode, const struct nfs_fattr *fattr) ++static int nfs_inode_attrs_cmp_generic(const struct nfs_fattr *fattr, ++ const struct inode *inode) + { + unsigned long attr_gencount = NFS_I(inode)->attr_gencount; + +@@ -1669,15 +1664,93 @@ static int nfs_inode_attrs_need_update(const struct inode *inode, const struct n + (long)(attr_gencount - nfs_read_attr_generation_counter()) > 0; + } + +-static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr) ++/** ++ * nfs_inode_attrs_cmp_monotonic - compare attributes ++ * @fattr: attributes ++ * @inode: pointer to inode ++ * ++ * Attempt to divine whether or not an RPC call reply carrying stale ++ * attributes got scheduled after another call carrying updated ones. ++ * ++ * We assume that the server observes monotonic semantics for ++ * the change attribute, so a larger value means that the attributes in ++ * @fattr are more recent, in which case the function returns the ++ * value '1'. ++ * A return value of '0' indicates no measurable change ++ * A return value of '-1' means that the attributes in @inode are ++ * more recent. ++ */ ++static int nfs_inode_attrs_cmp_monotonic(const struct nfs_fattr *fattr, ++ const struct inode *inode) + { +- int ret; ++ s64 diff = fattr->change_attr - inode_peek_iversion_raw(inode); ++ if (diff > 0) ++ return 1; ++ return diff == 0 ? 0 : -1; ++} ++ ++/** ++ * nfs_inode_attrs_cmp_strict_monotonic - compare attributes ++ * @fattr: attributes ++ * @inode: pointer to inode ++ * ++ * Attempt to divine whether or not an RPC call reply carrying stale ++ * attributes got scheduled after another call carrying updated ones. ++ * ++ * We assume that the server observes strictly monotonic semantics for ++ * the change attribute, so a larger value means that the attributes in ++ * @fattr are more recent, in which case the function returns the ++ * value '1'. ++ * A return value of '-1' means that the attributes in @inode are ++ * more recent or unchanged. ++ */ ++static int nfs_inode_attrs_cmp_strict_monotonic(const struct nfs_fattr *fattr, ++ const struct inode *inode) ++{ ++ return nfs_inode_attrs_cmp_monotonic(fattr, inode) > 0 ? 1 : -1; ++} ++ ++/** ++ * nfs_inode_attrs_cmp - compare attributes ++ * @fattr: attributes ++ * @inode: pointer to inode ++ * ++ * This function returns '1' if it thinks the attributes in @fattr are ++ * more recent than the ones cached in @inode. It returns '-1' if ++ * the attributes in @inode are more recent than the ones in @fattr, ++ * and it returns 0 if not sure. ++ */ ++static int nfs_inode_attrs_cmp(const struct nfs_fattr *fattr, ++ const struct inode *inode) ++{ ++ if (nfs_inode_attrs_cmp_generic(fattr, inode) > 0) ++ return 1; ++ switch (NFS_SERVER(inode)->change_attr_type) { ++ case NFS4_CHANGE_TYPE_IS_UNDEFINED: ++ break; ++ case NFS4_CHANGE_TYPE_IS_TIME_METADATA: ++ if (!(fattr->valid & NFS_ATTR_FATTR_CHANGE)) ++ break; ++ return nfs_inode_attrs_cmp_monotonic(fattr, inode); ++ default: ++ if (!(fattr->valid & NFS_ATTR_FATTR_CHANGE)) ++ break; ++ return nfs_inode_attrs_cmp_strict_monotonic(fattr, inode); ++ } ++ return 0; ++} ++ ++static int nfs_refresh_inode_locked(struct inode *inode, ++ struct nfs_fattr *fattr) ++{ ++ int attr_cmp = nfs_inode_attrs_cmp(fattr, inode); ++ int ret = 0; + + trace_nfs_refresh_inode_enter(inode); + +- if (nfs_inode_attrs_need_update(inode, fattr)) ++ if (attr_cmp > 0) + ret = nfs_update_inode(inode, fattr); +- else ++ else if (attr_cmp == 0) + ret = nfs_check_inode_attributes(inode, fattr); + + trace_nfs_refresh_inode_exit(inode, ret); +@@ -1762,11 +1835,13 @@ EXPORT_SYMBOL_GPL(nfs_post_op_update_inode); + */ + int nfs_post_op_update_inode_force_wcc_locked(struct inode *inode, struct nfs_fattr *fattr) + { ++ int attr_cmp = nfs_inode_attrs_cmp(fattr, inode); + int status; + + /* Don't do a WCC update if these attributes are already stale */ +- if ((fattr->valid & NFS_ATTR_FATTR) == 0 || +- !nfs_inode_attrs_need_update(inode, fattr)) { ++ if (attr_cmp < 0) ++ return 0; ++ if ((fattr->valid & NFS_ATTR_FATTR) == 0 || !attr_cmp) { + fattr->valid &= ~(NFS_ATTR_FATTR_PRECHANGE + | NFS_ATTR_FATTR_PRESIZE + | NFS_ATTR_FATTR_PREMTIME +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 48ed61e5ac0f3..eda7d7fc84ad0 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1193,10 +1193,23 @@ nfs4_update_changeattr_locked(struct inode *inode, + unsigned long timestamp, unsigned long cache_validity) + { + struct nfs_inode *nfsi = NFS_I(inode); ++ u64 change_attr = inode_peek_iversion_raw(inode); + + cache_validity |= NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME; + +- if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(inode)) { ++ switch (NFS_SERVER(inode)->change_attr_type) { ++ case NFS4_CHANGE_TYPE_IS_UNDEFINED: ++ break; ++ case NFS4_CHANGE_TYPE_IS_TIME_METADATA: ++ if ((s64)(change_attr - cinfo->after) > 0) ++ goto out; ++ break; ++ default: ++ if ((s64)(change_attr - cinfo->after) >= 0) ++ goto out; ++ } ++ ++ if (cinfo->atomic && cinfo->before == change_attr) { + nfsi->attrtimeo_timestamp = jiffies; + } else { + if (S_ISDIR(inode->i_mode)) { +@@ -1208,7 +1221,7 @@ nfs4_update_changeattr_locked(struct inode *inode, + cache_validity |= NFS_INO_REVAL_PAGECACHE; + } + +- if (cinfo->before != inode_peek_iversion_raw(inode)) ++ if (cinfo->before != change_attr) + cache_validity |= NFS_INO_INVALID_ACCESS | + NFS_INO_INVALID_ACL | + NFS_INO_INVALID_XATTR; +@@ -1216,8 +1229,9 @@ nfs4_update_changeattr_locked(struct inode *inode, + inode_set_iversion_raw(inode, cinfo->after); + nfsi->read_cache_jiffies = timestamp; + nfsi->attr_gencount = nfs_inc_attr_generation_counter(); +- nfs_set_cache_invalid(inode, cache_validity); + nfsi->cache_validity &= ~NFS_INO_INVALID_CHANGE; ++out: ++ nfs_set_cache_invalid(inode, cache_validity); + } + + void +-- +2.34.1 + diff --git a/queue-5.10/nfsv4-fix-handling-of-non-atomic-change-attrbute-upd.patch b/queue-5.10/nfsv4-fix-handling-of-non-atomic-change-attrbute-upd.patch new file mode 100644 index 00000000000..62dc5588b77 --- /dev/null +++ b/queue-5.10/nfsv4-fix-handling-of-non-atomic-change-attrbute-upd.patch @@ -0,0 +1,83 @@ +From 9885d62e392ac7eebd6bf99a30ba00278abf54f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Jun 2021 15:49:31 -0400 +Subject: NFSv4: Fix handling of non-atomic change attrbute updates + +From: Trond Myklebust + +[ Upstream commit 20cf7d4ea4ad7d9830b01ff7444f6ac64a727a23 ] + +If the change attribute update is declared to be non-atomic by the +server, or our cached value does not match the server's value before the +operation was performed, then we should declare the inode cache invalid. + +On the other hand, if the change to the directory raced with a lookup or +getattr which already updated the change attribute, then optimise away +the revalidation. + +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs4proc.c | 33 +++++++++++++++------------------ + 1 file changed, 15 insertions(+), 18 deletions(-) + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index eda7d7fc84ad0..4c80369e0a837 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1196,12 +1196,12 @@ nfs4_update_changeattr_locked(struct inode *inode, + u64 change_attr = inode_peek_iversion_raw(inode); + + cache_validity |= NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME; ++ if (S_ISDIR(inode->i_mode)) ++ cache_validity |= NFS_INO_INVALID_DATA; + + switch (NFS_SERVER(inode)->change_attr_type) { + case NFS4_CHANGE_TYPE_IS_UNDEFINED: +- break; +- case NFS4_CHANGE_TYPE_IS_TIME_METADATA: +- if ((s64)(change_attr - cinfo->after) > 0) ++ if (cinfo->after == change_attr) + goto out; + break; + default: +@@ -1209,24 +1209,21 @@ nfs4_update_changeattr_locked(struct inode *inode, + goto out; + } + +- if (cinfo->atomic && cinfo->before == change_attr) { +- nfsi->attrtimeo_timestamp = jiffies; +- } else { +- if (S_ISDIR(inode->i_mode)) { +- cache_validity |= NFS_INO_INVALID_DATA; ++ inode_set_iversion_raw(inode, cinfo->after); ++ if (!cinfo->atomic || cinfo->before != change_attr) { ++ if (S_ISDIR(inode->i_mode)) + nfs_force_lookup_revalidate(inode); +- } else { +- if (!NFS_PROTO(inode)->have_delegation(inode, +- FMODE_READ)) +- cache_validity |= NFS_INO_REVAL_PAGECACHE; +- } + +- if (cinfo->before != change_attr) +- cache_validity |= NFS_INO_INVALID_ACCESS | +- NFS_INO_INVALID_ACL | +- NFS_INO_INVALID_XATTR; ++ if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) ++ cache_validity |= ++ NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL | ++ NFS_INO_INVALID_SIZE | NFS_INO_INVALID_OTHER | ++ NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_NLINK | ++ NFS_INO_INVALID_MODE | NFS_INO_INVALID_XATTR | ++ NFS_INO_REVAL_PAGECACHE; ++ nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); + } +- inode_set_iversion_raw(inode, cinfo->after); ++ nfsi->attrtimeo_timestamp = jiffies; + nfsi->read_cache_jiffies = timestamp; + nfsi->attr_gencount = nfs_inc_attr_generation_counter(); + nfsi->cache_validity &= ~NFS_INO_INVALID_CHANGE; +-- +2.34.1 + diff --git a/queue-5.10/series b/queue-5.10/series index 8a2f037857d..368f3c0e6a8 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -77,3 +77,20 @@ mtd-rawnand-gpmi-don-t-leak-pm-reference-in-error-path.patch kvm-svm-never-reject-emulation-due-to-smap-errata-for-sev-guests.patch tee-export-teedev_open-and-teedev_close_context.patch optee-use-driver-internal-tee_context-for-some-rpc.patch +mtd-rawnand-qcom-fix-clock-sequencing-in-qcom_nandc_.patch +mtd-rawnand-brcmnand-fixed-incorrect-sub-page-ecc-st.patch +drivers-hv-vmbus-fix-memory-leak-in-vmbus_add_channe.patch +asoc-tas2770-insert-post-reset-delay.patch +kvm-x86-pmu-refactoring-find_arch_event-to-pmc_perf_.patch +kvm-x86-pmu-don-t-truncate-the-perfevtseln-msr-when-.patch +kvm-x86-pmu-use-amd64_raw_event_mask-for-perf_type_r.patch +nfs-don-t-set-nfs_ino_invalid_xattr-if-there-is-no-x.patch +nfs-fix-open-coded-versions-of-nfs_set_cache_invalid.patch +nfs-don-t-set-nfs_ino_reval_pagecache-in-the-inode-c.patch +nfs-use-information-about-the-change-attribute-to-op.patch +nfsv4-fix-handling-of-non-atomic-change-attrbute-upd.patch +nfs-remove-an-incorrect-revalidation-in-nfs4_update_.patch +nfs-lookup_directory-is-also-ok-with-symlinks.patch +tty-n_tty-do-not-look-ahead-for-eol-character-past-t.patch +nfs-do-not-report-writeback-errors-in-nfs_getattr.patch +block-wbt-fix-negative-inflight-counter-when-remove-.patch diff --git a/queue-5.10/tty-n_tty-do-not-look-ahead-for-eol-character-past-t.patch b/queue-5.10/tty-n_tty-do-not-look-ahead-for-eol-character-past-t.patch new file mode 100644 index 00000000000..f227d6ea82c --- /dev/null +++ b/queue-5.10/tty-n_tty-do-not-look-ahead-for-eol-character-past-t.patch @@ -0,0 +1,112 @@ +From 60c275cf799ebbbf9a4cbac6aaad301946db5676 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Feb 2022 15:28:00 -0800 +Subject: tty: n_tty: do not look ahead for EOL character past the end of the + buffer + +From: Linus Torvalds + +[ Upstream commit 3593030761630e09200072a4bd06468892c27be3 ] + +Daniel Gibson reports that the n_tty code gets line termination wrong in +very specific cases: + + "If you feed a line with exactly 64 chars + terminating newline, and + directly afterwards (without reading) another line into a pseudo + terminal, the the first read() on the other side will return the 64 + char line *without* terminating newline, and the next read() will + return the missing terminating newline AND the complete next line (if + it fits in the buffer)" + +and bisected the behavior to commit 3b830a9c34d5 ("tty: convert +tty_ldisc_ops 'read()' function to take a kernel pointer"). + +Now, digging deeper, it turns out that the behavior isn't exactly new: +what changed in commit 3b830a9c34d5 was that the tty line discipline +.read() function is now passed an intermediate kernel buffer rather than +the final user space buffer. + +And that intermediate kernel buffer is 64 bytes in size - thus that +special case with exactly 64 bytes plus terminating newline. + +The same problem did exist before, but historically the boundary was not +the 64-byte chunk, but the user-supplied buffer size, which is obviously +generally bigger (and potentially bigger than N_TTY_BUF_SIZE, which +would hide the issue entirely). + +The reason is that the n_tty canon_copy_from_read_buf() code would look +ahead for the EOL character one byte further than it would actually +copy. It would then decide that it had found the terminator, and unmark +it as an EOL character - which in turn explains why the next read +wouldn't then be terminated by it. + +Now, the reason it did all this in the first place is related to some +historical and pretty obscure EOF behavior, see commit ac8f3bf8832a +("n_tty: Fix poll() after buffer-limited eof push read") and commit +40d5e0905a03 ("n_tty: Fix EOF push handling"). + +And the reason for the EOL confusion is that we treat EOF as a special +EOL condition, with the EOL character being NUL (aka "__DISABLED_CHAR" +in the kernel sources). + +So that EOF look-ahead also affects the normal EOL handling. + +This patch just removes the look-ahead that causes problems, because EOL +is much more critical than the historical "EOF in the middle of a line +that coincides with the end of the buffer" handling ever was. + +Now, it is possible that we should indeed re-introduce the "look at next +character to see if it's a EOF" behavior, but if so, that should be done +not at the kernel buffer chunk boundary in canon_copy_from_read_buf(), +but at a higher level, when we run out of the user buffer. + +In particular, the place to do that would be at the top of +'n_tty_read()', where we check if it's a continuation of a previously +started read, and there is no more buffer space left, we could decide to +just eat the __DISABLED_CHAR at that point. + +But that would be a separate patch, because I suspect nobody actually +cares, and I'd like to get a report about it before bothering. + +Fixes: 3b830a9c34d5 ("tty: convert tty_ldisc_ops 'read()' function to take a kernel pointer") +Fixes: ac8f3bf8832a ("n_tty: Fix poll() after buffer-limited eof push read") +Fixes: 40d5e0905a03 ("n_tty: Fix EOF push handling") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=215611 +Reported-and-tested-by: Daniel Gibson +Cc: Peter Hurley +Cc: Greg Kroah-Hartman +Cc: Jiri Slaby +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + drivers/tty/n_tty.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c +index 128461bd04bb9..58190135efb7d 100644 +--- a/drivers/tty/n_tty.c ++++ b/drivers/tty/n_tty.c +@@ -2024,7 +2024,7 @@ static bool canon_copy_from_read_buf(struct tty_struct *tty, + return false; + + canon_head = smp_load_acquire(&ldata->canon_head); +- n = min(*nr + 1, canon_head - ldata->read_tail); ++ n = min(*nr, canon_head - ldata->read_tail); + + tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1); + size = min_t(size_t, tail + n, N_TTY_BUF_SIZE); +@@ -2046,10 +2046,8 @@ static bool canon_copy_from_read_buf(struct tty_struct *tty, + n += N_TTY_BUF_SIZE; + c = n + found; + +- if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) { +- c = min(*nr, c); ++ if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) + n = c; +- } + + n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu tail:%zu more:%zu\n", + __func__, eol, found, n, c, tail, more); +-- +2.34.1 +