From: Greg Kroah-Hartman Date: Thu, 22 Jul 2021 14:52:00 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v5.4.135~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4439047a964cf66ec881d30d335e9441f1f68a5e;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: dm-writecache-return-the-exact-table-values-that-were-set.patch f2fs-show-casefolding-support-only-when-supported.patch mm-slab-fix-kmem_cache_create-failed-when-sysfs-node-not-destroyed.patch usb-cdns3-enable-tdl_chk-only-for-out-ep.patch --- diff --git a/queue-5.4/dm-writecache-return-the-exact-table-values-that-were-set.patch b/queue-5.4/dm-writecache-return-the-exact-table-values-that-were-set.patch new file mode 100644 index 00000000000..dc3b3a1ade7 --- /dev/null +++ b/queue-5.4/dm-writecache-return-the-exact-table-values-that-were-set.patch @@ -0,0 +1,124 @@ +From 054bee16163df023e2589db09fd27d81f7ad9e72 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Thu, 4 Feb 2021 05:20:52 -0500 +Subject: dm writecache: return the exact table values that were set + +From: Mikulas Patocka + +commit 054bee16163df023e2589db09fd27d81f7ad9e72 upstream. + +LVM doesn't like it when the target returns different values from what +was set in the constructor. Fix dm-writecache so that the returned +table values are exactly the same as requested values. + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org # v4.18+ +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-writecache.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +--- a/drivers/md/dm-writecache.c ++++ b/drivers/md/dm-writecache.c +@@ -154,6 +154,7 @@ struct dm_writecache { + bool overwrote_committed:1; + bool memory_vmapped:1; + ++ bool start_sector_set:1; + bool high_wm_percent_set:1; + bool low_wm_percent_set:1; + bool max_writeback_jobs_set:1; +@@ -162,6 +163,10 @@ struct dm_writecache { + bool writeback_fua_set:1; + bool flush_on_suspend:1; + ++ unsigned high_wm_percent_value; ++ unsigned low_wm_percent_value; ++ unsigned autocommit_time_value; ++ + unsigned writeback_all; + struct workqueue_struct *writeback_wq; + struct work_struct writeback_work; +@@ -2069,6 +2074,7 @@ static int writecache_ctr(struct dm_targ + if (sscanf(string, "%llu%c", &start_sector, &dummy) != 1) + goto invalid_optional; + wc->start_sector = start_sector; ++ wc->start_sector_set = true; + if (wc->start_sector != start_sector || + wc->start_sector >= wc->memory_map_size >> SECTOR_SHIFT) + goto invalid_optional; +@@ -2078,6 +2084,7 @@ static int writecache_ctr(struct dm_targ + goto invalid_optional; + if (high_wm_percent < 0 || high_wm_percent > 100) + goto invalid_optional; ++ wc->high_wm_percent_value = high_wm_percent; + wc->high_wm_percent_set = true; + } else if (!strcasecmp(string, "low_watermark") && opt_params >= 1) { + string = dm_shift_arg(&as), opt_params--; +@@ -2085,6 +2092,7 @@ static int writecache_ctr(struct dm_targ + goto invalid_optional; + if (low_wm_percent < 0 || low_wm_percent > 100) + goto invalid_optional; ++ wc->low_wm_percent_value = low_wm_percent; + wc->low_wm_percent_set = true; + } else if (!strcasecmp(string, "writeback_jobs") && opt_params >= 1) { + string = dm_shift_arg(&as), opt_params--; +@@ -2104,6 +2112,7 @@ static int writecache_ctr(struct dm_targ + if (autocommit_msecs > 3600000) + goto invalid_optional; + wc->autocommit_jiffies = msecs_to_jiffies(autocommit_msecs); ++ wc->autocommit_time_value = autocommit_msecs; + wc->autocommit_time_set = true; + } else if (!strcasecmp(string, "fua")) { + if (WC_MODE_PMEM(wc)) { +@@ -2305,7 +2314,6 @@ static void writecache_status(struct dm_ + struct dm_writecache *wc = ti->private; + unsigned extra_args; + unsigned sz = 0; +- uint64_t x; + + switch (type) { + case STATUSTYPE_INFO: +@@ -2317,7 +2325,7 @@ static void writecache_status(struct dm_ + DMEMIT("%c %s %s %u ", WC_MODE_PMEM(wc) ? 'p' : 's', + wc->dev->name, wc->ssd_dev->name, wc->block_size); + extra_args = 0; +- if (wc->start_sector) ++ if (wc->start_sector_set) + extra_args += 2; + if (wc->high_wm_percent_set) + extra_args += 2; +@@ -2333,26 +2341,18 @@ static void writecache_status(struct dm_ + extra_args++; + + DMEMIT("%u", extra_args); +- if (wc->start_sector) ++ if (wc->start_sector_set) + DMEMIT(" start_sector %llu", (unsigned long long)wc->start_sector); +- if (wc->high_wm_percent_set) { +- x = (uint64_t)wc->freelist_high_watermark * 100; +- x += wc->n_blocks / 2; +- do_div(x, (size_t)wc->n_blocks); +- DMEMIT(" high_watermark %u", 100 - (unsigned)x); +- } +- if (wc->low_wm_percent_set) { +- x = (uint64_t)wc->freelist_low_watermark * 100; +- x += wc->n_blocks / 2; +- do_div(x, (size_t)wc->n_blocks); +- DMEMIT(" low_watermark %u", 100 - (unsigned)x); +- } ++ if (wc->high_wm_percent_set) ++ DMEMIT(" high_watermark %u", wc->high_wm_percent_value); ++ if (wc->low_wm_percent_set) ++ DMEMIT(" low_watermark %u", wc->low_wm_percent_value); + if (wc->max_writeback_jobs_set) + DMEMIT(" writeback_jobs %u", wc->max_writeback_jobs); + if (wc->autocommit_blocks_set) + DMEMIT(" autocommit_blocks %u", wc->autocommit_blocks); + if (wc->autocommit_time_set) +- DMEMIT(" autocommit_time %u", jiffies_to_msecs(wc->autocommit_jiffies)); ++ DMEMIT(" autocommit_time %u", wc->autocommit_time_value); + if (wc->writeback_fua_set) + DMEMIT(" %sfua", wc->writeback_fua ? "" : "no"); + break; diff --git a/queue-5.4/f2fs-show-casefolding-support-only-when-supported.patch b/queue-5.4/f2fs-show-casefolding-support-only-when-supported.patch new file mode 100644 index 00000000000..d9191890885 --- /dev/null +++ b/queue-5.4/f2fs-show-casefolding-support-only-when-supported.patch @@ -0,0 +1,45 @@ +From 39307f8ee3539478c28e71b4909b5b028cce14b1 Mon Sep 17 00:00:00 2001 +From: Daniel Rosenberg +Date: Thu, 3 Jun 2021 09:50:37 +0000 +Subject: f2fs: Show casefolding support only when supported + +From: Daniel Rosenberg + +commit 39307f8ee3539478c28e71b4909b5b028cce14b1 upstream. + +The casefolding feature is only supported when CONFIG_UNICODE is set. +This modifies the feature list f2fs presents under sysfs accordingly. + +Fixes: 5aba54302a46 ("f2fs: include charset encoding information in the superblock") +Cc: stable@vger.kernel.org # v5.4+ +Signed-off-by: Daniel Rosenberg +Reviewed-by: Eric Biggers +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/sysfs.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/f2fs/sysfs.c ++++ b/fs/f2fs/sysfs.c +@@ -499,7 +499,9 @@ F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LO + F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY); + #endif + F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM); ++#ifdef CONFIG_UNICODE + F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD); ++#endif + + #define ATTR_LIST(name) (&f2fs_attr_##name.attr) + static struct attribute *f2fs_attrs[] = { +@@ -568,7 +570,9 @@ static struct attribute *f2fs_feat_attrs + ATTR_LIST(verity), + #endif + ATTR_LIST(sb_checksum), ++#ifdef CONFIG_UNICODE + ATTR_LIST(casefold), ++#endif + NULL, + }; + ATTRIBUTE_GROUPS(f2fs_feat); diff --git a/queue-5.4/mm-slab-fix-kmem_cache_create-failed-when-sysfs-node-not-destroyed.patch b/queue-5.4/mm-slab-fix-kmem_cache_create-failed-when-sysfs-node-not-destroyed.patch new file mode 100644 index 00000000000..6c9d8325c5b --- /dev/null +++ b/queue-5.4/mm-slab-fix-kmem_cache_create-failed-when-sysfs-node-not-destroyed.patch @@ -0,0 +1,160 @@ +From sunnanyong@huawei.com Thu Jul 22 16:42:41 2021 +From: Nanyong Sun +Date: Tue, 20 Jul 2021 16:20:48 +0800 +Subject: mm: slab: fix kmem_cache_create failed when sysfs node not destroyed +To: , , , , , +Cc: , , +Message-ID: <20210720082048.2797315-1-sunnanyong@huawei.com> + +From: Nanyong Sun + +The commit d38a2b7a9c93 ("mm: memcg/slab: fix memory leak at non-root +kmem_cache destroy") introduced a problem: If one thread destroy a +kmem_cache A and another thread concurrently create a kmem_cache B, +which is mergeable with A and has same size with A, the B may fail to +create due to the duplicate sysfs node. +The scenario in detail: +1) Thread 1 uses kmem_cache_destroy() to destroy kmem_cache A which is +mergeable, it decreases A's refcount and if refcount is 0, then call +memcg_set_kmem_cache_dying() which set A->memcg_params.dying = true, +then unlock the slab_mutex and call flush_memcg_workqueue(), it may cost +a while. +Note: now the sysfs node(like '/kernel/slab/:0000248') of A is still +present, it will be deleted in shutdown_cache() which will be called +after flush_memcg_workqueue() is done and lock the slab_mutex again. +2) Now if thread 2 is coming, it use kmem_cache_create() to create B, which +is mergeable with A(their size is same), it gain the lock of slab_mutex, +then call __kmem_cache_alias() trying to find a mergeable node, because +of the below added code in commit d38a2b7a9c93 ("mm: memcg/slab: fix +memory leak at non-root kmem_cache destroy"), B is not mergeable with +A whose memcg_params.dying is true. + +int slab_unmergeable(struct kmem_cache *s) + if (s->refcount < 0) + return 1; + + /* + * Skip the dying kmem_cache. + */ + if (s->memcg_params.dying) + return 1; + + return 0; + } + +So B has to create its own sysfs node by calling: + create_cache-> + __kmem_cache_create-> + sysfs_slab_add-> + kobject_init_and_add +Because B is mergeable itself, its filename of sysfs node is based on its size, +like '/kernel/slab/:0000248', which is duplicate with A, and the sysfs +node of A is still present now, so kobject_init_and_add() will return +fail and result in kmem_cache_create() fail. + +Concurrently modprobe and rmmod the two modules below can reproduce the issue +quickly: nf_conntrack_expect, se_sess_cache. See call trace in the end. + +LTS versions of v4.19.y and v5.4.y have this problem, whereas linux versions after +v5.9 do not have this problem because the patchset: ("The new cgroup slab memory +controller") almost refactored memcg slab. + +A potential solution(this patch belongs): Just let the dying kmem_cache be mergeable, +the slab_mutex lock can prevent the race between alias kmem_cache creating thread +and root kmem_cache destroying thread. In the destroying thread, after +flush_memcg_workqueue() is done, judge the refcount again, if someone +reference it again during un-lock time, we don't need to destroy the kmem_cache +completely, we can reuse it. + +Another potential solution: revert the commit d38a2b7a9c93 ("mm: memcg/slab: +fix memory leak at non-root kmem_cache destroy"), compare to the fail of +kmem_cache_create, the memory leak in special scenario seems less harmful. + +Call trace: + sysfs: cannot create duplicate filename '/kernel/slab/:0000248' + Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 + Call trace: + dump_backtrace+0x0/0x198 + show_stack+0x24/0x30 + dump_stack+0xb0/0x100 + sysfs_warn_dup+0x6c/0x88 + sysfs_create_dir_ns+0x104/0x120 + kobject_add_internal+0xd0/0x378 + kobject_init_and_add+0x90/0xd8 + sysfs_slab_add+0x16c/0x2d0 + __kmem_cache_create+0x16c/0x1d8 + create_cache+0xbc/0x1f8 + kmem_cache_create_usercopy+0x1a0/0x230 + kmem_cache_create+0x50/0x68 + init_se_kmem_caches+0x38/0x258 [target_core_mod] + target_core_init_configfs+0x8c/0x390 [target_core_mod] + do_one_initcall+0x54/0x230 + do_init_module+0x64/0x1ec + load_module+0x150c/0x16f0 + __se_sys_finit_module+0xf0/0x108 + __arm64_sys_finit_module+0x24/0x30 + el0_svc_common+0x80/0x1c0 + el0_svc_handler+0x78/0xe0 + el0_svc+0x10/0x260 + kobject_add_internal failed for :0000248 with -EEXIST, don't try to register things with the same name in the same directory. + kmem_cache_create(se_sess_cache) failed with error -17 + Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 + Call trace: + dump_backtrace+0x0/0x198 + show_stack+0x24/0x30 + dump_stack+0xb0/0x100 + kmem_cache_create_usercopy+0xa8/0x230 + kmem_cache_create+0x50/0x68 + init_se_kmem_caches+0x38/0x258 [target_core_mod] + target_core_init_configfs+0x8c/0x390 [target_core_mod] + do_one_initcall+0x54/0x230 + do_init_module+0x64/0x1ec + load_module+0x150c/0x16f0 + __se_sys_finit_module+0xf0/0x108 + __arm64_sys_finit_module+0x24/0x30 + el0_svc_common+0x80/0x1c0 + el0_svc_handler+0x78/0xe0 + el0_svc+0x10/0x260 + +Fixes: d38a2b7a9c93 ("mm: memcg/slab: fix memory leak at non-root kmem_cache destroy") +Signed-off-by: Nanyong Sun +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + mm/slab_common.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/mm/slab_common.c ++++ b/mm/slab_common.c +@@ -325,14 +325,6 @@ int slab_unmergeable(struct kmem_cache * + if (s->refcount < 0) + return 1; + +-#ifdef CONFIG_MEMCG_KMEM +- /* +- * Skip the dying kmem_cache. +- */ +- if (s->memcg_params.dying) +- return 1; +-#endif +- + return 0; + } + +@@ -973,6 +965,16 @@ void kmem_cache_destroy(struct kmem_cach + get_online_mems(); + + mutex_lock(&slab_mutex); ++ ++ /* ++ * Another thread referenced it again ++ */ ++ if (READ_ONCE(s->refcount)) { ++ spin_lock_irq(&memcg_kmem_wq_lock); ++ s->memcg_params.dying = false; ++ spin_unlock_irq(&memcg_kmem_wq_lock); ++ goto out_unlock; ++ } + #endif + + err = shutdown_memcg_caches(s); diff --git a/queue-5.4/series b/queue-5.4/series index 70384f0be1b..1775bc94f8a 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -45,3 +45,7 @@ cifs-prevent-null-deref-in-cifs_compose_mount_option.patch arm64-dts-armada-3720-turris-mox-add-firmware-node.patch firmware-turris-mox-rwtm-add-marvell-armada-3700-rwt.patch arm64-dts-marvell-armada-37xx-move-firmware-node-to-.patch +f2fs-show-casefolding-support-only-when-supported.patch +usb-cdns3-enable-tdl_chk-only-for-out-ep.patch +mm-slab-fix-kmem_cache_create-failed-when-sysfs-node-not-destroyed.patch +dm-writecache-return-the-exact-table-values-that-were-set.patch diff --git a/queue-5.4/usb-cdns3-enable-tdl_chk-only-for-out-ep.patch b/queue-5.4/usb-cdns3-enable-tdl_chk-only-for-out-ep.patch new file mode 100644 index 00000000000..1ec29060787 --- /dev/null +++ b/queue-5.4/usb-cdns3-enable-tdl_chk-only-for-out-ep.patch @@ -0,0 +1,52 @@ +From d6eef886903c4bb5af41b9a31d4ba11dc7a6f8e8 Mon Sep 17 00:00:00 2001 +From: Sanket Parmar +Date: Mon, 17 May 2021 17:05:12 +0200 +Subject: usb: cdns3: Enable TDL_CHK only for OUT ep + +From: Sanket Parmar + +commit d6eef886903c4bb5af41b9a31d4ba11dc7a6f8e8 upstream. + +ZLP gets stuck if TDL_CHK bit is set and TDL_FROM_TRB is used +as TDL source for IN endpoints. To fix it, TDL_CHK is only +enabled for OUT endpoints. + +Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") +Reported-by: Aswath Govindraju +Signed-off-by: Sanket Parmar +Link: https://lore.kernel.org/r/1621263912-13175-1-git-send-email-sparmar@cadence.com +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/cdns3/gadget.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/usb/cdns3/gadget.c ++++ b/drivers/usb/cdns3/gadget.c +@@ -1531,7 +1531,7 @@ void cdns3_configure_dmult(struct cdns3_ + else + mask = BIT(priv_ep->num); + +- if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) { ++ if (priv_ep->type != USB_ENDPOINT_XFER_ISOC && !priv_ep->dir) { + cdns3_set_register_bit(®s->tdl_from_trb, mask); + cdns3_set_register_bit(®s->tdl_beh, mask); + cdns3_set_register_bit(®s->tdl_beh2, mask); +@@ -1569,15 +1569,13 @@ void cdns3_ep_config(struct cdns3_endpoi + case USB_ENDPOINT_XFER_INT: + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_INT); + +- if ((priv_dev->dev_ver == DEV_VER_V2 && !priv_ep->dir) || +- priv_dev->dev_ver > DEV_VER_V2) ++ if (priv_dev->dev_ver >= DEV_VER_V2 && !priv_ep->dir) + ep_cfg |= EP_CFG_TDL_CHK; + break; + case USB_ENDPOINT_XFER_BULK: + ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_BULK); + +- if ((priv_dev->dev_ver == DEV_VER_V2 && !priv_ep->dir) || +- priv_dev->dev_ver > DEV_VER_V2) ++ if (priv_dev->dev_ver >= DEV_VER_V2 && !priv_ep->dir) + ep_cfg |= EP_CFG_TDL_CHK; + break; + default: