]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 May 2022 10:18:25 +0000 (12:18 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 May 2022 10:18:25 +0000 (12:18 +0200)
added patches:
asoc-meson-fix-event-generation-for-g12a-tohdmi-mux.patch
asoc-wm8958-fix-change-notifications-for-dsp-controls.patch
can-grcan-grcan_close-fix-deadlock.patch
can-grcan-use-ofdev-dev-when-allocating-dma-memory.patch
s390-dasd-fix-data-corruption-for-ese-devices.patch
s390-dasd-fix-read-for-ese-with-blksize-4k.patch
s390-dasd-fix-read-inconsistency-for-ese-dasd-devices.patch
s390-dasd-prevent-double-format-of-tracks-for-ese-devices.patch

queue-5.4/asoc-meson-fix-event-generation-for-g12a-tohdmi-mux.patch [new file with mode: 0644]
queue-5.4/asoc-wm8958-fix-change-notifications-for-dsp-controls.patch [new file with mode: 0644]
queue-5.4/can-grcan-grcan_close-fix-deadlock.patch [new file with mode: 0644]
queue-5.4/can-grcan-use-ofdev-dev-when-allocating-dma-memory.patch [new file with mode: 0644]
queue-5.4/s390-dasd-fix-data-corruption-for-ese-devices.patch [new file with mode: 0644]
queue-5.4/s390-dasd-fix-read-for-ese-with-blksize-4k.patch [new file with mode: 0644]
queue-5.4/s390-dasd-fix-read-inconsistency-for-ese-dasd-devices.patch [new file with mode: 0644]
queue-5.4/s390-dasd-prevent-double-format-of-tracks-for-ese-devices.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/asoc-meson-fix-event-generation-for-g12a-tohdmi-mux.patch b/queue-5.4/asoc-meson-fix-event-generation-for-g12a-tohdmi-mux.patch
new file mode 100644 (file)
index 0000000..0d68e6c
--- /dev/null
@@ -0,0 +1,35 @@
+From 12131008fc13ff7f7690d170b7a8f72d24fd7d1e Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Thu, 21 Apr 2022 13:38:03 +0100
+Subject: ASoC: meson: Fix event generation for G12A tohdmi mux
+
+From: Mark Brown <broonie@kernel.org>
+
+commit 12131008fc13ff7f7690d170b7a8f72d24fd7d1e upstream.
+
+The G12A tohdmi has a custom put() operation which returns 0 when the value
+of the mux changes, meaning that events are not generated for userspace.
+Change to return 1 in this case, the function returns early in the case
+where there is no change.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
+Link: https://lore.kernel.org/r/20220421123803.292063-4-broonie@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/meson/g12a-tohdmitx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/meson/g12a-tohdmitx.c
++++ b/sound/soc/meson/g12a-tohdmitx.c
+@@ -127,7 +127,7 @@ static int g12a_tohdmitx_i2s_mux_put_enu
+       snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL);
+-      return 0;
++      return 1;
+ }
+ static const struct snd_kcontrol_new g12a_tohdmitx_i2s_mux =
diff --git a/queue-5.4/asoc-wm8958-fix-change-notifications-for-dsp-controls.patch b/queue-5.4/asoc-wm8958-fix-change-notifications-for-dsp-controls.patch
new file mode 100644 (file)
index 0000000..3822787
--- /dev/null
@@ -0,0 +1,61 @@
+From b4f5c6b2e52b27462c0599e64e96e53b58438de1 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Sat, 16 Apr 2022 13:54:08 +0100
+Subject: ASoC: wm8958: Fix change notifications for DSP controls
+
+From: Mark Brown <broonie@kernel.org>
+
+commit b4f5c6b2e52b27462c0599e64e96e53b58438de1 upstream.
+
+The WM8958 DSP controls all return 0 on successful write, not a boolean
+value indicating if the write changed the value of the control. Fix this
+by returning 1 after a change, there is already a check at the start of
+each put() that skips the function in the case that there is no change.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/20220416125408.197440-1-broonie@kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/wm8958-dsp2.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/sound/soc/codecs/wm8958-dsp2.c
++++ b/sound/soc/codecs/wm8958-dsp2.c
+@@ -534,7 +534,7 @@ static int wm8958_mbc_put(struct snd_kco
+       wm8958_dsp_apply(component, mbc, wm8994->mbc_ena[mbc]);
+-      return 0;
++      return 1;
+ }
+ #define WM8958_MBC_SWITCH(xname, xval) {\
+@@ -660,7 +660,7 @@ static int wm8958_vss_put(struct snd_kco
+       wm8958_dsp_apply(component, vss, wm8994->vss_ena[vss]);
+-      return 0;
++      return 1;
+ }
+@@ -734,7 +734,7 @@ static int wm8958_hpf_put(struct snd_kco
+       wm8958_dsp_apply(component, hpf % 3, ucontrol->value.integer.value[0]);
+-      return 0;
++      return 1;
+ }
+ #define WM8958_HPF_SWITCH(xname, xval) {\
+@@ -828,7 +828,7 @@ static int wm8958_enh_eq_put(struct snd_
+       wm8958_dsp_apply(component, eq, ucontrol->value.integer.value[0]);
+-      return 0;
++      return 1;
+ }
+ #define WM8958_ENH_EQ_SWITCH(xname, xval) {\
diff --git a/queue-5.4/can-grcan-grcan_close-fix-deadlock.patch b/queue-5.4/can-grcan-grcan_close-fix-deadlock.patch
new file mode 100644 (file)
index 0000000..45e6a8e
--- /dev/null
@@ -0,0 +1,54 @@
+From 47f070a63e735bcc8d481de31be1b5a1aa62b31c Mon Sep 17 00:00:00 2001
+From: Duoming Zhou <duoming@zju.edu.cn>
+Date: Mon, 25 Apr 2022 12:24:00 +0800
+Subject: can: grcan: grcan_close(): fix deadlock
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+commit 47f070a63e735bcc8d481de31be1b5a1aa62b31c upstream.
+
+There are deadlocks caused by del_timer_sync(&priv->hang_timer) and
+del_timer_sync(&priv->rr_timer) in grcan_close(), one of the deadlocks
+are shown below:
+
+   (Thread 1)              |      (Thread 2)
+                           | grcan_reset_timer()
+grcan_close()              |  mod_timer()
+ spin_lock_irqsave() //(1) |  (wait a time)
+ ...                       | grcan_initiate_running_reset()
+ del_timer_sync()          |  spin_lock_irqsave() //(2)
+ (wait timer to stop)      |  ...
+
+We hold priv->lock in position (1) of thread 1 and use
+del_timer_sync() to wait timer to stop, but timer handler also need
+priv->lock in position (2) of thread 2. As a result, grcan_close()
+will block forever.
+
+This patch extracts del_timer_sync() from the protection of
+spin_lock_irqsave(), which could let timer handler to obtain the
+needed lock.
+
+Link: https://lore.kernel.org/all/20220425042400.66517-1-duoming@zju.edu.cn
+Fixes: 6cec9b07fe6a ("can: grcan: Add device driver for GRCAN and GRHCAN cores")
+Cc: stable@vger.kernel.org
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Reviewed-by: Andreas Larsson <andreas@gaisler.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/grcan.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/can/grcan.c
++++ b/drivers/net/can/grcan.c
+@@ -1113,8 +1113,10 @@ static int grcan_close(struct net_device
+       priv->closing = true;
+       if (priv->need_txbug_workaround) {
++              spin_unlock_irqrestore(&priv->lock, flags);
+               del_timer_sync(&priv->hang_timer);
+               del_timer_sync(&priv->rr_timer);
++              spin_lock_irqsave(&priv->lock, flags);
+       }
+       netif_stop_queue(dev);
+       grcan_stop_hardware(dev);
diff --git a/queue-5.4/can-grcan-use-ofdev-dev-when-allocating-dma-memory.patch b/queue-5.4/can-grcan-use-ofdev-dev-when-allocating-dma-memory.patch
new file mode 100644 (file)
index 0000000..8d2f25f
--- /dev/null
@@ -0,0 +1,63 @@
+From 101da4268626b00d16356a6bf284d66e44c46ff9 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Fri, 29 Apr 2022 10:46:54 +0200
+Subject: can: grcan: use ofdev->dev when allocating DMA memory
+
+From: Daniel Hellstrom <daniel@gaisler.com>
+
+commit 101da4268626b00d16356a6bf284d66e44c46ff9 upstream.
+
+Use the device of the device tree node should be rather than the
+device of the struct net_device when allocating DMA buffers.
+
+The driver got away with it on sparc32 until commit 53b7670e5735
+("sparc: factor the dma coherent mapping into helper") after which the
+driver oopses.
+
+Fixes: 6cec9b07fe6a ("can: grcan: Add device driver for GRCAN and GRHCAN cores")
+Link: https://lore.kernel.org/all/20220429084656.29788-2-andreas@gaisler.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+Signed-off-by: Andreas Larsson <andreas@gaisler.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/grcan.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/can/grcan.c
++++ b/drivers/net/can/grcan.c
+@@ -248,6 +248,7 @@ struct grcan_device_config {
+ struct grcan_priv {
+       struct can_priv can;    /* must be the first member */
+       struct net_device *dev;
++      struct device *ofdev_dev;
+       struct napi_struct napi;
+       struct grcan_registers __iomem *regs;   /* ioremap'ed registers */
+@@ -924,7 +925,7 @@ static void grcan_free_dma_buffers(struc
+       struct grcan_priv *priv = netdev_priv(dev);
+       struct grcan_dma *dma = &priv->dma;
+-      dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
++      dma_free_coherent(priv->ofdev_dev, dma->base_size, dma->base_buf,
+                         dma->base_handle);
+       memset(dma, 0, sizeof(*dma));
+ }
+@@ -949,7 +950,7 @@ static int grcan_allocate_dma_buffers(st
+       /* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
+       dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
+-      dma->base_buf = dma_alloc_coherent(&dev->dev,
++      dma->base_buf = dma_alloc_coherent(priv->ofdev_dev,
+                                          dma->base_size,
+                                          &dma->base_handle,
+                                          GFP_KERNEL);
+@@ -1602,6 +1603,7 @@ static int grcan_setup_netdev(struct pla
+       memcpy(&priv->config, &grcan_module_config,
+              sizeof(struct grcan_device_config));
+       priv->dev = dev;
++      priv->ofdev_dev = &ofdev->dev;
+       priv->regs = base;
+       priv->can.bittiming_const = &grcan_bittiming_const;
+       priv->can.do_set_bittiming = grcan_set_bittiming;
diff --git a/queue-5.4/s390-dasd-fix-data-corruption-for-ese-devices.patch b/queue-5.4/s390-dasd-fix-data-corruption-for-ese-devices.patch
new file mode 100644 (file)
index 0000000..a76cf52
--- /dev/null
@@ -0,0 +1,95 @@
+From 5b53a405e4658580e1faf7c217db3f55a21ba849 Mon Sep 17 00:00:00 2001
+From: Stefan Haberland <sth@linux.ibm.com>
+Date: Thu, 5 May 2022 16:17:29 +0200
+Subject: s390/dasd: fix data corruption for ESE devices
+
+From: Stefan Haberland <sth@linux.ibm.com>
+
+commit 5b53a405e4658580e1faf7c217db3f55a21ba849 upstream.
+
+For ESE devices we get an error when accessing an unformatted track.
+The handling of this error will return zero data for read requests and
+format the track on demand before writing to it. To do this the code needs
+to distinguish between read and write requests. This is done with data from
+the blocklayer request. A pointer to the blocklayer request is stored in
+the CQR.
+
+If there is an error on the device an ERP request is built to do error
+recovery. While the ERP request is mostly a copy of the original CQR the
+pointer to the blocklayer request is not copied to not accidentally pass
+it back to the blocklayer without cleanup.
+
+This leads to the error that during ESE handling after an ERP request was
+built it is not possible to determine the IO direction. This leads to the
+formatting of a track for read requests which might in turn lead to data
+corruption.
+
+Fixes: 5e2b17e712cf ("s390/dasd: Add dynamic formatting support for ESE volumes")
+Cc: stable@vger.kernel.org # 5.3+
+Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
+Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220505141733.1989450-2-sth@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/s390/block/dasd.c      |    8 +++++++-
+ drivers/s390/block/dasd_eckd.c |    2 +-
+ drivers/s390/block/dasd_int.h  |   12 ++++++++++++
+ 3 files changed, 20 insertions(+), 2 deletions(-)
+
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -1680,6 +1680,7 @@ void dasd_int_handler(struct ccw_device
+       unsigned long now;
+       int nrf_suppressed = 0;
+       int fp_suppressed = 0;
++      struct request *req;
+       u8 *sense = NULL;
+       int expires;
+@@ -1780,7 +1781,12 @@ void dasd_int_handler(struct ccw_device
+       }
+       if (dasd_ese_needs_format(cqr->block, irb)) {
+-              if (rq_data_dir((struct request *)cqr->callback_data) == READ) {
++              req = dasd_get_callback_data(cqr);
++              if (!req) {
++                      cqr->status = DASD_CQR_ERROR;
++                      return;
++              }
++              if (rq_data_dir(req) == READ) {
+                       device->discipline->ese_read(cqr, irb);
+                       cqr->status = DASD_CQR_SUCCESS;
+                       cqr->stopclk = now;
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -3088,7 +3088,7 @@ dasd_eckd_ese_format(struct dasd_device
+       sector_t curr_trk;
+       int rc;
+-      req = cqr->callback_data;
++      req = dasd_get_callback_data(cqr);
+       block = cqr->block;
+       base = block->base;
+       private = base->private;
+--- a/drivers/s390/block/dasd_int.h
++++ b/drivers/s390/block/dasd_int.h
+@@ -723,6 +723,18 @@ dasd_check_blocksize(int bsize)
+       return 0;
+ }
++/*
++ * return the callback data of the original request in case there are
++ * ERP requests build on top of it
++ */
++static inline void *dasd_get_callback_data(struct dasd_ccw_req *cqr)
++{
++      while (cqr->refers)
++              cqr = cqr->refers;
++
++      return cqr->callback_data;
++}
++
+ /* externals in dasd.c */
+ #define DASD_PROFILE_OFF       0
+ #define DASD_PROFILE_ON        1
diff --git a/queue-5.4/s390-dasd-fix-read-for-ese-with-blksize-4k.patch b/queue-5.4/s390-dasd-fix-read-for-ese-with-blksize-4k.patch
new file mode 100644 (file)
index 0000000..909e0af
--- /dev/null
@@ -0,0 +1,63 @@
+From cd68c48ea15c85f1577a442dc4c285e112ff1b37 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jan=20H=C3=B6ppner?= <hoeppner@linux.ibm.com>
+Date: Thu, 5 May 2022 16:17:31 +0200
+Subject: s390/dasd: Fix read for ESE with blksize < 4k
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jan Höppner <hoeppner@linux.ibm.com>
+
+commit cd68c48ea15c85f1577a442dc4c285e112ff1b37 upstream.
+
+When reading unformatted tracks on ESE devices, the corresponding memory
+areas are simply set to zero for each segment. This is done incorrectly
+for blocksizes < 4096.
+
+There are two problems. First, the increment of dst is done using the
+counter of the loop (off), which is increased by blksize every
+iteration. This leads to a much bigger increment for dst as actually
+intended. Second, the increment of dst is done before the memory area
+is set to 0, skipping a significant amount of bytes of memory.
+
+This leads to illegal overwriting of memory and ultimately to a kernel
+panic.
+
+This is not a problem with 4k blocksize because
+blk_queue_max_segment_size is set to PAGE_SIZE, always resulting in a
+single iteration for the inner segment loop (bv.bv_len == blksize). The
+incorrectly used 'off' value to increment dst is 0 and the correct
+memory area is used.
+
+In order to fix this for blksize < 4k, increment dst correctly using the
+blksize and only do it at the end of the loop.
+
+Fixes: 5e2b17e712cf ("s390/dasd: Add dynamic formatting support for ESE volumes")
+Cc: stable@vger.kernel.org # v5.3+
+Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
+Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220505141733.1989450-4-sth@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/s390/block/dasd_eckd.c |    7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -3228,12 +3228,11 @@ static int dasd_eckd_ese_read(struct das
+                               cqr->proc_bytes = blk_count * blksize;
+                               return 0;
+                       }
+-                      if (dst && !skip_block) {
+-                              dst += off;
++                      if (dst && !skip_block)
+                               memset(dst, 0, blksize);
+-                      } else {
++                      else
+                               skip_block--;
+-                      }
++                      dst += blksize;
+                       blk_count++;
+               }
+       }
diff --git a/queue-5.4/s390-dasd-fix-read-inconsistency-for-ese-dasd-devices.patch b/queue-5.4/s390-dasd-fix-read-inconsistency-for-ese-dasd-devices.patch
new file mode 100644 (file)
index 0000000..cb79340
--- /dev/null
@@ -0,0 +1,55 @@
+From b9c10f68e23c13f56685559a0d6fdaca9f838324 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jan=20H=C3=B6ppner?= <hoeppner@linux.ibm.com>
+Date: Thu, 5 May 2022 16:17:32 +0200
+Subject: s390/dasd: Fix read inconsistency for ESE DASD devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jan Höppner <hoeppner@linux.ibm.com>
+
+commit b9c10f68e23c13f56685559a0d6fdaca9f838324 upstream.
+
+Read requests that return with NRF error are partially completed in
+dasd_eckd_ese_read(). The function keeps track of the amount of
+processed bytes and the driver will eventually return this information
+back to the block layer for further processing via __dasd_cleanup_cqr()
+when the request is in the final stage of processing (from the driver's
+perspective).
+
+For this, blk_update_request() is used which requires the number of
+bytes to complete the request. As per documentation the nr_bytes
+parameter is described as follows:
+   "number of bytes to complete for @req".
+
+This was mistakenly interpreted as "number of bytes _left_ for @req"
+leading to new requests with incorrect data length. The consequence are
+inconsistent and completely wrong read requests as data from random
+memory areas are read back.
+
+Fix this by correctly specifying the amount of bytes that should be used
+to complete the request.
+
+Fixes: 5e6bdd37c552 ("s390/dasd: fix data corruption for thin provisioned devices")
+Cc: stable@vger.kernel.org # 5.3+
+Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
+Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220505141733.1989450-5-sth@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/s390/block/dasd.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -2812,8 +2812,7 @@ static void __dasd_cleanup_cqr(struct da
+                * complete a request partially.
+                */
+               if (proc_bytes) {
+-                      blk_update_request(req, BLK_STS_OK,
+-                                         blk_rq_bytes(req) - proc_bytes);
++                      blk_update_request(req, BLK_STS_OK, proc_bytes);
+                       blk_mq_requeue_request(req, true);
+               } else {
+                       blk_mq_complete_request(req);
diff --git a/queue-5.4/s390-dasd-prevent-double-format-of-tracks-for-ese-devices.patch b/queue-5.4/s390-dasd-prevent-double-format-of-tracks-for-ese-devices.patch
new file mode 100644 (file)
index 0000000..e7353e1
--- /dev/null
@@ -0,0 +1,123 @@
+From 71f3871657370dbbaf942a1c758f64e49a36c70f Mon Sep 17 00:00:00 2001
+From: Stefan Haberland <sth@linux.ibm.com>
+Date: Thu, 5 May 2022 16:17:30 +0200
+Subject: s390/dasd: prevent double format of tracks for ESE devices
+
+From: Stefan Haberland <sth@linux.ibm.com>
+
+commit 71f3871657370dbbaf942a1c758f64e49a36c70f upstream.
+
+For ESE devices we get an error for write operations on an unformatted
+track. Afterwards the track will be formatted and the IO operation
+restarted.
+When using alias devices a track might be accessed by multiple requests
+simultaneously and there is a race window that a track gets formatted
+twice resulting in data loss.
+
+Prevent this by remembering the amount of formatted tracks when starting
+a request and comparing this number before actually formatting a track
+on the fly. If the number has changed there is a chance that the current
+track was finally formatted in between. As a result do not format the
+track and restart the current IO to check.
+
+The number of formatted tracks does not match the overall number of
+formatted tracks on the device and it might wrap around but this is no
+problem. It is only needed to recognize that a track has been formatted at
+all in between.
+
+Fixes: 5e2b17e712cf ("s390/dasd: Add dynamic formatting support for ESE volumes")
+Cc: stable@vger.kernel.org # 5.3+
+Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
+Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220505141733.1989450-3-sth@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/s390/block/dasd.c      |    7 +++++++
+ drivers/s390/block/dasd_eckd.c |   19 +++++++++++++++++--
+ drivers/s390/block/dasd_int.h  |    2 ++
+ 3 files changed, 26 insertions(+), 2 deletions(-)
+
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -1462,6 +1462,13 @@ int dasd_start_IO(struct dasd_ccw_req *c
+               if (!cqr->lpm)
+                       cqr->lpm = dasd_path_get_opm(device);
+       }
++      /*
++       * remember the amount of formatted tracks to prevent double format on
++       * ESE devices
++       */
++      if (cqr->block)
++              cqr->trkcount = atomic_read(&cqr->block->trkcount);
++
+       if (cqr->cpmode == 1) {
+               rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
+                                        (long) cqr, cqr->lpm);
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -3026,13 +3026,24 @@ static int dasd_eckd_format_device(struc
+ }
+ static bool test_and_set_format_track(struct dasd_format_entry *to_format,
+-                                    struct dasd_block *block)
++                                    struct dasd_ccw_req *cqr)
+ {
++      struct dasd_block *block = cqr->block;
+       struct dasd_format_entry *format;
+       unsigned long flags;
+       bool rc = false;
+       spin_lock_irqsave(&block->format_lock, flags);
++      if (cqr->trkcount != atomic_read(&block->trkcount)) {
++              /*
++               * The number of formatted tracks has changed after request
++               * start and we can not tell if the current track was involved.
++               * To avoid data corruption treat it as if the current track is
++               * involved
++               */
++              rc = true;
++              goto out;
++      }
+       list_for_each_entry(format, &block->format_list, list) {
+               if (format->track == to_format->track) {
+                       rc = true;
+@@ -3052,6 +3063,7 @@ static void clear_format_track(struct da
+       unsigned long flags;
+       spin_lock_irqsave(&block->format_lock, flags);
++      atomic_inc(&block->trkcount);
+       list_del_init(&format->list);
+       spin_unlock_irqrestore(&block->format_lock, flags);
+ }
+@@ -3113,8 +3125,11 @@ dasd_eckd_ese_format(struct dasd_device
+       }
+       format->track = curr_trk;
+       /* test if track is already in formatting by another thread */
+-      if (test_and_set_format_track(format, block))
++      if (test_and_set_format_track(format, cqr)) {
++              /* this is no real error so do not count down retries */
++              cqr->retries++;
+               return ERR_PTR(-EEXIST);
++      }
+       fdata.start_unit = curr_trk;
+       fdata.stop_unit = curr_trk;
+--- a/drivers/s390/block/dasd_int.h
++++ b/drivers/s390/block/dasd_int.h
+@@ -188,6 +188,7 @@ struct dasd_ccw_req {
+       void (*callback)(struct dasd_ccw_req *, void *data);
+       void *callback_data;
+       unsigned int proc_bytes;        /* bytes for partial completion */
++      unsigned int trkcount;          /* count formatted tracks */
+ };
+ /*
+@@ -575,6 +576,7 @@ struct dasd_block {
+       struct list_head format_list;
+       spinlock_t format_lock;
++      atomic_t trkcount;
+ };
+ struct dasd_attention_data {
index 9908833aff278044a0b7c92acb47a641ccf51031..b1b22c25d519b4bc48e4b96566be1ee49e49bc1e 100644 (file)
@@ -10,3 +10,11 @@ firewire-core-extend-card-lock-in-fw_core_handle_bus_reset.patch
 acpica-always-create-namespace-nodes-using-acpi_ns_create_node.patch
 genirq-synchronize-interrupt-thread-startup.patch
 asoc-da7219-fix-change-notifications-for-tone-generator-frequency.patch
+asoc-wm8958-fix-change-notifications-for-dsp-controls.patch
+asoc-meson-fix-event-generation-for-g12a-tohdmi-mux.patch
+s390-dasd-fix-data-corruption-for-ese-devices.patch
+s390-dasd-prevent-double-format-of-tracks-for-ese-devices.patch
+s390-dasd-fix-read-for-ese-with-blksize-4k.patch
+s390-dasd-fix-read-inconsistency-for-ese-dasd-devices.patch
+can-grcan-grcan_close-fix-deadlock.patch
+can-grcan-use-ofdev-dev-when-allocating-dma-memory.patch