]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Jul 2021 14:52:00 +0000 (16:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Jul 2021 14:52:00 +0000 (16:52 +0200)
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

queue-5.4/dm-writecache-return-the-exact-table-values-that-were-set.patch [new file with mode: 0644]
queue-5.4/f2fs-show-casefolding-support-only-when-supported.patch [new file with mode: 0644]
queue-5.4/mm-slab-fix-kmem_cache_create-failed-when-sysfs-node-not-destroyed.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/usb-cdns3-enable-tdl_chk-only-for-out-ep.patch [new file with mode: 0644]

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 (file)
index 0000000..dc3b3a1
--- /dev/null
@@ -0,0 +1,124 @@
+From 054bee16163df023e2589db09fd27d81f7ad9e72 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Thu, 4 Feb 2021 05:20:52 -0500
+Subject: dm writecache: return the exact table values that were set
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+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 <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org # v4.18+
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..d919189
--- /dev/null
@@ -0,0 +1,45 @@
+From 39307f8ee3539478c28e71b4909b5b028cce14b1 Mon Sep 17 00:00:00 2001
+From: Daniel Rosenberg <drosen@google.com>
+Date: Thu, 3 Jun 2021 09:50:37 +0000
+Subject: f2fs: Show casefolding support only when supported
+
+From: Daniel Rosenberg <drosen@google.com>
+
+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 <drosen@google.com>
+Reviewed-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Chao Yu <yuchao0@huawei.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..6c9d832
--- /dev/null
@@ -0,0 +1,160 @@
+From sunnanyong@huawei.com  Thu Jul 22 16:42:41 2021
+From: Nanyong Sun <sunnanyong@huawei.com>
+Date: Tue, 20 Jul 2021 16:20:48 +0800
+Subject: mm: slab: fix kmem_cache_create failed when sysfs node not destroyed
+To: <songmuchun@bytedance.com>, <cl@linux.com>, <penberg@kernel.org>, <rientjes@google.com>, <iamjoonsoo.kim@lge.com>, <akpm@linux-foundation.org>
+Cc: <linux-mm@kvack.org>, <linux-kernel@vger.kernel.org>, <stable@vger.kernel.org>
+Message-ID: <20210720082048.2797315-1-sunnanyong@huawei.com>
+
+From: Nanyong Sun <sunnanyong@huawei.com>
+
+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 <sunnanyong@huawei.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
index 70384f0be1b2488b4cdd592db51d8fe234602918..1775bc94f8a76ccba8b889c2c2bc78193b9a65fa 100644 (file)
@@ -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 (file)
index 0000000..1ec2906
--- /dev/null
@@ -0,0 +1,52 @@
+From d6eef886903c4bb5af41b9a31d4ba11dc7a6f8e8 Mon Sep 17 00:00:00 2001
+From: Sanket Parmar <sparmar@cadence.com>
+Date: Mon, 17 May 2021 17:05:12 +0200
+Subject: usb: cdns3: Enable TDL_CHK only for OUT ep
+
+From: Sanket Parmar <sparmar@cadence.com>
+
+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 <a-govindraju@ti.com>
+Signed-off-by: Sanket Parmar <sparmar@cadence.com>
+Link: https://lore.kernel.org/r/1621263912-13175-1-git-send-email-sparmar@cadence.com
+Signed-off-by: Peter Chen <peter.chen@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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(&regs->tdl_from_trb, mask);
+                       cdns3_set_register_bit(&regs->tdl_beh, mask);
+                       cdns3_set_register_bit(&regs->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: