--- /dev/null
+From 2b1aba72076624806abd6d0c7f5fed64b5e34d96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Apr 2020 11:59:07 +0200
+Subject: ALSA: usb-audio: Add Pioneer DJ DJM-250MK2 quirk
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: František Kučera <franta-linux@frantovo.cz>
+
+[ Upstream commit 73d8c94084341e2895169a0462dbc18167f01683 ]
+
+Pioneer DJ DJM-250MK2 is a mixer that acts like a USB sound card.
+The MIDI controller part is standard but the PCM part is "vendor specific".
+Output is enabled by this quirk: 8 channels, 48 000 Hz, S24_3LE.
+Input is not working.
+
+Signed-off-by: František Kučera <franta-linux@frantovo.cz>
+Link: https://lore.kernel.org/r/20200401095907.3387-1-konference@frantovo.cz
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/quirks-table.h | 42 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index d187aa6d50db0..dcaf9eed9a415 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -3592,5 +3592,47 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
+ }
+ }
+ },
++{
++ /*
++ * Pioneer DJ DJM-250MK2
++ * PCM is 8 channels out @ 48 fixed (endpoints 0x01).
++ * The output from computer to the mixer is usable.
++ *
++ * The input (phono or line to computer) is not working.
++ * It should be at endpoint 0x82 and probably also 8 channels,
++ * but it seems that it works only with Pioneer proprietary software.
++ * Even on officially supported OS, the Audacity was unable to record
++ * and Mixxx to recognize the control vinyls.
++ */
++ USB_DEVICE_VENDOR_SPEC(0x2b73, 0x0017),
++ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++ .ifnum = QUIRK_ANY_INTERFACE,
++ .type = QUIRK_COMPOSITE,
++ .data = (const struct snd_usb_audio_quirk[]) {
++ {
++ .ifnum = 0,
++ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++ .data = &(const struct audioformat) {
++ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
++ .channels = 8, // outputs
++ .iface = 0,
++ .altsetting = 1,
++ .altset_idx = 1,
++ .endpoint = 0x01,
++ .ep_attr = USB_ENDPOINT_XFER_ISOC|
++ USB_ENDPOINT_SYNC_ASYNC,
++ .rates = SNDRV_PCM_RATE_48000,
++ .rate_min = 48000,
++ .rate_max = 48000,
++ .nr_rates = 1,
++ .rate_table = (unsigned int[]) { 48000 }
++ }
++ },
++ {
++ .ifnum = -1
++ }
++ }
++ }
++},
+
+ #undef USB_DEVICE_VENDOR_SPEC
+--
+2.20.1
+
--- /dev/null
+From 58ed8b6cf045d9a2ac1582e0ce0ed6d14a1f4d0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Apr 2020 20:53:57 +0200
+Subject: ASoC: Intel: atom: Take the drv->lock mutex before calling
+ sst_send_slot_map()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 81630dc042af998b9f58cd8e2c29dab9777ea176 ]
+
+sst_send_slot_map() uses sst_fill_and_send_cmd_unlocked() because in some
+places it is called with the drv->lock mutex already held.
+
+So it must always be called with the mutex locked. This commit adds missing
+locking in the sst_set_be_modules() code-path.
+
+Fixes: 24c8d14192cc ("ASoC: Intel: mrfld: add DSP core controls")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20200402185359.3424-1-hdegoede@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/atom/sst-atom-controls.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
+index f883c9340eeee..df8f7994d3b7a 100644
+--- a/sound/soc/intel/atom/sst-atom-controls.c
++++ b/sound/soc/intel/atom/sst-atom-controls.c
+@@ -966,7 +966,9 @@ static int sst_set_be_modules(struct snd_soc_dapm_widget *w,
+ dev_dbg(c->dev, "Enter: widget=%s\n", w->name);
+
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
++ mutex_lock(&drv->lock);
+ ret = sst_send_slot_map(drv);
++ mutex_unlock(&drv->lock);
+ if (ret)
+ return ret;
+ ret = sst_send_pipe_module_params(w, k);
+--
+2.20.1
+
--- /dev/null
+From 0bd0bd3c2503dfe9ad0725c9f5303d21001f604e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Apr 2020 15:37:26 +0200
+Subject: ASoC: Intel: bytcr_rt5640: Add quirk for MPMAN MPWIN895CL tablet
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit c8b78f24c1247b7bd0882885c672d9dec5800bc6 ]
+
+The MPMAN MPWIN895CL tablet almost fully works with out default settings.
+The only problem is that it has only 1 speaker so any sounds only playing
+on the right channel get lost.
+
+Add a quirk for this model using the default settings + MONO_SPEAKER.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20200405133726.24154-1-hdegoede@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/bytcr_rt5640.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index 6bd9ae813be28..d14d5f7db1689 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -591,6 +591,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+ BYT_RT5640_SSP0_AIF1 |
+ BYT_RT5640_MCLK_EN),
+ },
++ {
++ /* MPMAN MPWIN895CL */
++ .matches = {
++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MPMAN"),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MPWIN8900CL"),
++ },
++ .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
++ BYT_RT5640_MONO_SPEAKER |
++ BYT_RT5640_SSP0_AIF1 |
++ BYT_RT5640_MCLK_EN),
++ },
+ { /* MSI S100 tablet */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
+--
+2.20.1
+
--- /dev/null
+From 60376450f0b80f1e1255dd4ff76eeb854743a115 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Mar 2020 19:52:10 +0200
+Subject: ASoC: qcom: q6asm-dai: Add SNDRV_PCM_INFO_BATCH flag
+
+From: Stephan Gerhold <stephan@gerhold.net>
+
+[ Upstream commit 7f2430cda819a9ecb1df5a0f3ef4f1c20db3f811 ]
+
+At the moment, playing audio with PulseAudio with the qdsp6 driver
+results in distorted sound. It seems like its timer-based scheduling
+does not work properly with qdsp6 since setting tsched=0 in
+the PulseAudio configuration avoids the issue.
+
+Apparently this happens when the pointer() callback is not accurate
+enough. There is a SNDRV_PCM_INFO_BATCH flag that can be used to stop
+PulseAudio from using timer-based scheduling by default.
+
+According to https://www.alsa-project.org/pipermail/alsa-devel/2014-March/073816.html:
+
+ The flag is being used in the sense explained in the previous audio
+ meeting -- the data transfer granularity isn't fine enough but aligned
+ to the period size (or less).
+
+q6asm-dai reports the position as multiple of
+
+ prtd->pcm_count = snd_pcm_lib_period_bytes(substream)
+
+so it indeed just a multiple of the period size.
+
+Therefore adding the flag here seems appropriate and makes audio
+work out of the box.
+
+Fixes: 2a9e92d371db ("ASoC: qdsp6: q6asm: Add q6asm dai driver")
+Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
+Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20200330175210.47518-1-stephan@gerhold.net
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/qcom/qdsp6/q6asm-dai.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c
+index c0d422d0ab94f..d7dc80ede8927 100644
+--- a/sound/soc/qcom/qdsp6/q6asm-dai.c
++++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
+@@ -73,7 +73,7 @@ struct q6asm_dai_data {
+ };
+
+ static const struct snd_pcm_hardware q6asm_dai_hardware_capture = {
+- .info = (SNDRV_PCM_INFO_MMAP |
++ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+@@ -95,7 +95,7 @@ static const struct snd_pcm_hardware q6asm_dai_hardware_capture = {
+ };
+
+ static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
+- .info = (SNDRV_PCM_INFO_MMAP |
++ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BATCH |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+--
+2.20.1
+
--- /dev/null
+From fce4df5985caef0a90c6f5d87d2ec5fcfa498822 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Apr 2020 08:51:20 +0200
+Subject: block: fix busy device checking in blk_drop_partitions
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit d3ef5536274faf89e626276b833be122a16bdb81 ]
+
+bd_super is only set by get_tree_bdev and mount_bdev, and thus not by
+other openers like btrfs or the XFS realtime and log devices, as well as
+block devices directly opened from user space. Check bd_openers
+instead.
+
+Fixes: 77032ca66f86 ("Return EBUSY from BLKRRPART for mounted whole-dev fs")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/partition-generic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/block/partition-generic.c b/block/partition-generic.c
+index 564fae77711df..5f3b2a959aa51 100644
+--- a/block/partition-generic.c
++++ b/block/partition-generic.c
+@@ -468,7 +468,7 @@ int blk_drop_partitions(struct gendisk *disk, struct block_device *bdev)
+
+ if (!disk_part_scan_enabled(disk))
+ return 0;
+- if (bdev->bd_part_count || bdev->bd_super)
++ if (bdev->bd_part_count || bdev->bd_openers)
+ return -EBUSY;
+ res = invalidate_partition(disk, 0);
+ if (res)
+--
+2.20.1
+
--- /dev/null
+From 1d48088b6961d46b0d11590ffafa248d48a26736 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2020 14:31:47 +0200
+Subject: block: fix busy device checking in blk_drop_partitions again
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit cb6b771b05c3026a85ed4817c1b87c5e6f41d136 ]
+
+The previous fix had an off by one in the bd_openers checking, counting
+the callers blkdev_get.
+
+Fixes: d3ef5536274f ("block: fix busy device checking in blk_drop_partitions")
+Reported-by: Qian Cai <cai@lca.pw>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Tested-by: Qian Cai <cai@lca.pw>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/partition-generic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/block/partition-generic.c b/block/partition-generic.c
+index 5f3b2a959aa51..ebe4c2e9834bd 100644
+--- a/block/partition-generic.c
++++ b/block/partition-generic.c
+@@ -468,7 +468,7 @@ int blk_drop_partitions(struct gendisk *disk, struct block_device *bdev)
+
+ if (!disk_part_scan_enabled(disk))
+ return 0;
+- if (bdev->bd_part_count || bdev->bd_openers)
++ if (bdev->bd_part_count || bdev->bd_openers > 1)
+ return -EBUSY;
+ res = invalidate_partition(disk, 0);
+ if (res)
+--
+2.20.1
+
--- /dev/null
+From 861d04db4dfb3148723bd4316097b3c90115ddc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2020 19:34:20 +0800
+Subject: ceph: don't skip updating wanted caps when cap is stale
+
+From: Yan, Zheng <zyan@redhat.com>
+
+[ Upstream commit 0aa971b6fd3f92afef6afe24ef78d9bb14471519 ]
+
+1. try_get_cap_refs() fails to get caps and finds that mds_wanted
+ does not include what it wants. It returns -ESTALE.
+2. ceph_get_caps() calls ceph_renew_caps(). ceph_renew_caps() finds
+ that inode has cap, so it calls ceph_check_caps().
+3. ceph_check_caps() finds that issued caps (without checking if it's
+ stale) already includes caps wanted by open file, so it skips
+ updating wanted caps.
+
+Above events can cause an infinite loop inside ceph_get_caps().
+
+Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/caps.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
+index 28ae0c1347004..d050acc1fd5d9 100644
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -1973,8 +1973,12 @@ retry_locked:
+ }
+
+ /* want more caps from mds? */
+- if (want & ~(cap->mds_wanted | cap->issued))
+- goto ack;
++ if (want & ~cap->mds_wanted) {
++ if (want & ~(cap->mds_wanted | cap->issued))
++ goto ack;
++ if (!__cap_is_valid(cap))
++ goto ack;
++ }
+
+ /* things we might delay */
+ if ((cap->issued & ~retain) == 0)
+--
+2.20.1
+
--- /dev/null
+From a4e84e1feda63d4c8b8feab66622d2f9ae3f3a72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2020 09:34:20 +0800
+Subject: ceph: return ceph_mdsc_do_request() errors from __get_parent()
+
+From: Qiujun Huang <hqjagain@gmail.com>
+
+[ Upstream commit c6d50296032f0b97473eb2e274dc7cc5d0173847 ]
+
+Return the error returned by ceph_mdsc_do_request(). Otherwise,
+r_target_inode ends up being NULL this ends up returning ENOENT
+regardless of the error.
+
+Signed-off-by: Qiujun Huang <hqjagain@gmail.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/export.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/ceph/export.c b/fs/ceph/export.c
+index b6bfa94332c30..79dc06881e78e 100644
+--- a/fs/ceph/export.c
++++ b/fs/ceph/export.c
+@@ -315,6 +315,11 @@ static struct dentry *__get_parent(struct super_block *sb,
+
+ req->r_num_caps = 1;
+ err = ceph_mdsc_do_request(mdsc, NULL, req);
++ if (err) {
++ ceph_mdsc_put_request(req);
++ return ERR_PTR(err);
++ }
++
+ inode = req->r_target_inode;
+ if (inode)
+ ihold(inode);
+--
+2.20.1
+
--- /dev/null
+From b250a752270a2c01c7a954fe4294a04727a77810 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Apr 2020 10:58:36 +0530
+Subject: dma-direct: fix data truncation in dma_direct_get_required_mask()
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit cdcda0d1f8f4ab84efe7cd9921c98364398aefd7 ]
+
+The upper 32-bit physical address gets truncated inadvertently
+when dma_direct_get_required_mask() invokes phys_to_dma_direct().
+This results in dma_addressing_limited() return incorrect value
+when used in platforms with LPAE enabled.
+Fix it here by explicitly type casting 'max_pfn' to phys_addr_t
+in order to prevent overflow of intermediate value while evaluating
+'(max_pfn - 1) << PAGE_SHIFT'.
+
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/direct.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
+index ac7956c38f693..4b24275e306a4 100644
+--- a/kernel/dma/direct.c
++++ b/kernel/dma/direct.c
+@@ -39,7 +39,8 @@ static inline struct page *dma_direct_to_page(struct device *dev,
+
+ u64 dma_direct_get_required_mask(struct device *dev)
+ {
+- u64 max_dma = phys_to_dma_direct(dev, (max_pfn - 1) << PAGE_SHIFT);
++ phys_addr_t phys = (phys_addr_t)(max_pfn - 1) << PAGE_SHIFT;
++ u64 max_dma = phys_to_dma_direct(dev, phys);
+
+ return (1ULL << (fls64(max_dma) - 1)) * 2 - 1;
+ }
+--
+2.20.1
+
--- /dev/null
+From 7e4512d6429f34d9f53c3c91e8d1724a24ffccd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Apr 2020 16:40:57 -0400
+Subject: drm/amd/display: Calculate scaling ratios on every medium/full update
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 3bae20137cae6c03f58f96c0bc9f3d46f0bc17d4 ]
+
+[Why]
+If a plane isn't being actively enabled or disabled then DC won't
+always recalculate scaling rects and ratios for the primary plane.
+
+This results in only a partial or corrupted rect being displayed on
+the screen instead of scaling to fit the screen.
+
+[How]
+Add back the logic to recalculate the scaling rects into
+dc_commit_updates_for_stream since this is the expected place to
+do it in DC.
+
+This was previously removed a few years ago to fix an underscan issue
+but underscan is still functional now with this change - and it should
+be, since this is only updating to the latest plane state getting passed
+in.
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index fc25600107050..188e51600070b 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -2349,7 +2349,7 @@ void dc_commit_updates_for_stream(struct dc *dc,
+ enum surface_update_type update_type;
+ struct dc_state *context;
+ struct dc_context *dc_ctx = dc->ctx;
+- int i;
++ int i, j;
+
+ stream_status = dc_stream_get_status(stream);
+ context = dc->current_state;
+@@ -2387,6 +2387,17 @@ void dc_commit_updates_for_stream(struct dc *dc,
+
+ copy_surface_update_to_plane(surface, &srf_updates[i]);
+
++ if (update_type >= UPDATE_TYPE_MED) {
++ for (j = 0; j < dc->res_pool->pipe_count; j++) {
++ struct pipe_ctx *pipe_ctx =
++ &context->res_ctx.pipe_ctx[j];
++
++ if (pipe_ctx->plane_state != surface)
++ continue;
++
++ resource_build_scaling_params(pipe_ctx);
++ }
++ }
+ }
+
+ copy_stream_update_to_stream(dc, context, stream, stream_update);
+--
+2.20.1
+
--- /dev/null
+From 0df087b6c42fc88fcd5fdd1b18abbf795a9c67ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Apr 2020 16:41:01 -0400
+Subject: drm/amd/display: Update stream adjust in dc_stream_adjust_vmin_vmax
+
+From: Isabel Zhang <isabel.zhang@amd.com>
+
+[ Upstream commit 346d8a0a3c91888a412c2735d69daa09c00f0203 ]
+
+[Why]
+After v_total_min and max are updated in vrr structure, the changes are
+not reflected in stream adjust. When these values are read from stream
+adjust it does not reflect the actual state of the system.
+
+[How]
+Set stream adjust values equal to vrr adjust values after vrr adjust
+values are updated.
+
+Signed-off-by: Isabel Zhang <isabel.zhang@amd.com>
+Reviewed-by: Alvin Lee <Alvin.Lee2@amd.com>
+Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 04441dbcba76f..fc25600107050 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -283,6 +283,8 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
+ int i = 0;
+ bool ret = false;
+
++ stream->adjust = *adjust;
++
+ for (i = 0; i < MAX_PIPES; i++) {
+ struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+--
+2.20.1
+
--- /dev/null
+From 628e7cb9fa6f9755fb38acf2b445c716e4e9c020 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2020 14:34:13 -0700
+Subject: ipc/util.c: sysvipc_find_ipc() should increase position index
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+[ Upstream commit 89163f93c6f969da5811af5377cc10173583123b ]
+
+If seq_file .next function does not change position index, read after
+some lseek can generate unexpected output.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=206283
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Acked-by: Waiman Long <longman@redhat.com>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: Manfred Spraul <manfred@colorfullife.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: NeilBrown <neilb@suse.com>
+Cc: Peter Oberparleiter <oberpar@linux.ibm.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Link: http://lkml.kernel.org/r/b7a20945-e315-8bb0-21e6-3875c14a8494@virtuozzo.com
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ ipc/util.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ipc/util.c b/ipc/util.c
+index fe61df53775ac..2d70f25f64b83 100644
+--- a/ipc/util.c
++++ b/ipc/util.c
+@@ -764,13 +764,13 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
+ total++;
+ }
+
++ *new_pos = pos + 1;
+ if (total >= ids->in_use)
+ return NULL;
+
+ for (; pos < ipc_mni; pos++) {
+ ipc = idr_find(&ids->ipcs_idr, pos);
+ if (ipc != NULL) {
+- *new_pos = pos + 1;
+ rcu_read_lock();
+ ipc_lock_object(ipc);
+ return ipc;
+--
+2.20.1
+
--- /dev/null
+From 632481c9ff8c455d5caee3c654d1ad2add7550d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Apr 2020 11:28:03 +0200
+Subject: kconfig: qconf: Fix a few alignment issues
+
+From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+
+[ Upstream commit 60969f02f07ae1445730c7b293c421d179da729c ]
+
+There are a few items with wrong alignments. Solve them.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/kconfig/qconf.cc | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
+index 82773cc35d356..0f8c77f847114 100644
+--- a/scripts/kconfig/qconf.cc
++++ b/scripts/kconfig/qconf.cc
+@@ -627,7 +627,7 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
+ last = item;
+ continue;
+ }
+- hide:
++hide:
+ if (item && item->menu == child) {
+ last = parent->firstChild();
+ if (last == item)
+@@ -692,7 +692,7 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
+ last = item;
+ continue;
+ }
+- hide:
++hide:
+ if (item && item->menu == child) {
+ last = (ConfigItem*)parent->topLevelItem(0);
+ if (last == item)
+@@ -1225,10 +1225,11 @@ QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
+ {
+ QMenu* popup = Parent::createStandardContextMenu(pos);
+ QAction* action = new QAction("Show Debug Info", popup);
+- action->setCheckable(true);
+- connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
+- connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
+- action->setChecked(showDebug());
++
++ action->setCheckable(true);
++ connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
++ connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
++ action->setChecked(showDebug());
+ popup->addSeparator();
+ popup->addAction(action);
+ return popup;
+--
+2.20.1
+
--- /dev/null
+From 8f80e2e5cb5a1a9ccbedd7d1da777e87a73d4e66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2020 14:34:10 -0700
+Subject: kernel/gcov/fs.c: gcov_seq_next() should increase position index
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+[ Upstream commit f4d74ef6220c1eda0875da30457bef5c7111ab06 ]
+
+If seq_file .next function does not change position index, read after
+some lseek can generate unexpected output.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=206283
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Acked-by: Peter Oberparleiter <oberpar@linux.ibm.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Manfred Spraul <manfred@colorfullife.com>
+Cc: NeilBrown <neilb@suse.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Waiman Long <longman@redhat.com>
+Link: http://lkml.kernel.org/r/f65c6ee7-bd00-f910-2f8a-37cc67e4ff88@virtuozzo.com
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/gcov/fs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/gcov/fs.c b/kernel/gcov/fs.c
+index e5eb5ea7ea598..cc4ee482d3fba 100644
+--- a/kernel/gcov/fs.c
++++ b/kernel/gcov/fs.c
+@@ -108,9 +108,9 @@ static void *gcov_seq_next(struct seq_file *seq, void *data, loff_t *pos)
+ {
+ struct gcov_iterator *iter = data;
+
++ (*pos)++;
+ if (gcov_iter_next(iter))
+ return NULL;
+- (*pos)++;
+
+ return iter;
+ }
+--
+2.20.1
+
--- /dev/null
+From ec8656690f25274cea2597dd03618d2e231c8cab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Mar 2020 17:00:49 +0900
+Subject: lib/raid6/test: fix build on distros whose /bin/sh is not bash
+
+From: Masahiro Yamada <masahiroy@kernel.org>
+
+[ Upstream commit 06bd48b6cd97ef3889b68c8e09014d81dbc463f1 ]
+
+You can build a user-space test program for the raid6 library code,
+like this:
+
+ $ cd lib/raid6/test
+ $ make
+
+The command in $(shell ...) function is evaluated by /bin/sh by default.
+(or, you can specify the shell by passing SHELL=<shell> from command line)
+
+Currently '>&/dev/null' is used to sink both stdout and stderr. Because
+this code is bash-ism, it only works when /bin/sh is a symbolic link to
+bash (this is the case on RHEL etc.)
+
+This does not work on Ubuntu where /bin/sh is a symbolic link to dash.
+
+I see lots of
+
+ /bin/sh: 1: Syntax error: Bad fd number
+
+and
+
+ warning "your version of binutils lacks ... support"
+
+Replace it with portable '>/dev/null 2>&1'.
+
+Fixes: 4f8c55c5ad49 ("lib/raid6: build proper files on corresponding arch")
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Acked-by: H. Peter Anvin (Intel) <hpa@zytor.com>
+Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/raid6/test/Makefile | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/lib/raid6/test/Makefile b/lib/raid6/test/Makefile
+index 3ab8720aa2f84..b9e6c3648be1a 100644
+--- a/lib/raid6/test/Makefile
++++ b/lib/raid6/test/Makefile
+@@ -35,13 +35,13 @@ endif
+ ifeq ($(IS_X86),yes)
+ OBJS += mmx.o sse1.o sse2.o avx2.o recov_ssse3.o recov_avx2.o avx512.o recov_avx512.o
+ CFLAGS += $(shell echo "pshufb %xmm0, %xmm0" | \
+- gcc -c -x assembler - >&/dev/null && \
++ gcc -c -x assembler - >/dev/null 2>&1 && \
+ rm ./-.o && echo -DCONFIG_AS_SSSE3=1)
+ CFLAGS += $(shell echo "vpbroadcastb %xmm0, %ymm1" | \
+- gcc -c -x assembler - >&/dev/null && \
++ gcc -c -x assembler - >/dev/null 2>&1 && \
+ rm ./-.o && echo -DCONFIG_AS_AVX2=1)
+ CFLAGS += $(shell echo "vpmovm2b %k1, %zmm5" | \
+- gcc -c -x assembler - >&/dev/null && \
++ gcc -c -x assembler - >/dev/null 2>&1 && \
+ rm ./-.o && echo -DCONFIG_AS_AVX512=1)
+ else ifeq ($(HAS_NEON),yes)
+ OBJS += neon.o neon1.o neon2.o neon4.o neon8.o recov_neon.o recov_neon_inner.o
+--
+2.20.1
+
--- /dev/null
+From abe68bd590eab48366073f544b717d6982b1b6f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Apr 2020 16:43:04 +0200
+Subject: loop: Better discard support for block devices
+
+From: Evan Green <evgreen@chromium.org>
+
+[ Upstream commit c52abf563049e787c1341cdf15c7dbe1bfbc951b ]
+
+If the backing device for a loop device is itself a block device,
+then mirror the "write zeroes" capabilities of the underlying
+block device into the loop device. Copy this capability into both
+max_write_zeroes_sectors and max_discard_sectors of the loop device.
+
+The reason for this is that REQ_OP_DISCARD on a loop device translates
+into blkdev_issue_zeroout(), rather than blkdev_issue_discard(). This
+presents a consistent interface for loop devices (that discarded data
+is zeroed), regardless of the backing device type of the loop device.
+There should be no behavior change for loop devices backed by regular
+files.
+
+This change fixes blktest block/003, and removes an extraneous
+error print in block/013 when testing on a loop device backed
+by a block device that does not support discard.
+
+Signed-off-by: Evan Green <evgreen@chromium.org>
+Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
+Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+[used updated version of Evan's comment in loop_config_discard()]
+[moved backingq to local scope, removed redundant braces]
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/loop.c | 42 +++++++++++++++++++++++++++++++-----------
+ 1 file changed, 31 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index 739b372a51128..d943e713d5e34 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -427,11 +427,12 @@ static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,
+ * information.
+ */
+ struct file *file = lo->lo_backing_file;
++ struct request_queue *q = lo->lo_queue;
+ int ret;
+
+ mode |= FALLOC_FL_KEEP_SIZE;
+
+- if ((!file->f_op->fallocate) || lo->lo_encrypt_key_size) {
++ if (!blk_queue_discard(q)) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+@@ -865,28 +866,47 @@ static void loop_config_discard(struct loop_device *lo)
+ struct inode *inode = file->f_mapping->host;
+ struct request_queue *q = lo->lo_queue;
+
++ /*
++ * If the backing device is a block device, mirror its zeroing
++ * capability. Set the discard sectors to the block device's zeroing
++ * capabilities because loop discards result in blkdev_issue_zeroout(),
++ * not blkdev_issue_discard(). This maintains consistent behavior with
++ * file-backed loop devices: discarded regions read back as zero.
++ */
++ if (S_ISBLK(inode->i_mode) && !lo->lo_encrypt_key_size) {
++ struct request_queue *backingq;
++
++ backingq = bdev_get_queue(inode->i_bdev);
++ blk_queue_max_discard_sectors(q,
++ backingq->limits.max_write_zeroes_sectors);
++
++ blk_queue_max_write_zeroes_sectors(q,
++ backingq->limits.max_write_zeroes_sectors);
++
+ /*
+ * We use punch hole to reclaim the free space used by the
+ * image a.k.a. discard. However we do not support discard if
+ * encryption is enabled, because it may give an attacker
+ * useful information.
+ */
+- if ((!file->f_op->fallocate) ||
+- lo->lo_encrypt_key_size) {
++ } else if (!file->f_op->fallocate || lo->lo_encrypt_key_size) {
+ q->limits.discard_granularity = 0;
+ q->limits.discard_alignment = 0;
+ blk_queue_max_discard_sectors(q, 0);
+ blk_queue_max_write_zeroes_sectors(q, 0);
+- blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
+- return;
+- }
+
+- q->limits.discard_granularity = inode->i_sb->s_blocksize;
+- q->limits.discard_alignment = 0;
++ } else {
++ q->limits.discard_granularity = inode->i_sb->s_blocksize;
++ q->limits.discard_alignment = 0;
+
+- blk_queue_max_discard_sectors(q, UINT_MAX >> 9);
+- blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9);
+- blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
++ blk_queue_max_discard_sectors(q, UINT_MAX >> 9);
++ blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9);
++ }
++
++ if (q->limits.max_write_zeroes_sectors)
++ blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
++ else
++ blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
+ }
+
+ static void loop_unprepare_queue(struct loop_device *lo)
+--
+2.20.1
+
--- /dev/null
+From f74544c03aaf4c28a14323bf375c73fba4f4a21e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 28 Mar 2020 01:09:09 -0400
+Subject: nvme: fix compat address handling in several ioctls
+
+From: Nick Bowler <nbowler@draconx.ca>
+
+[ Upstream commit c95b708d5fa65b4e51f088ee077d127fd5a57b70 ]
+
+On a 32-bit kernel, the upper bits of userspace addresses passed via
+various ioctls are silently ignored by the nvme driver.
+
+However on a 64-bit kernel running a compat task, these upper bits are
+not ignored and are in fact required to be zero for the ioctls to work.
+
+Unfortunately, this difference matters. 32-bit smartctl submits the
+NVME_IOCTL_ADMIN_CMD ioctl with garbage in these upper bits because it
+seems the pointer value it puts into the nvme_passthru_cmd structure is
+sign extended. This works fine on 32-bit kernels but fails on a 64-bit
+one because (at least on my setup) the addresses smartctl uses are
+consistently above 2G. For example:
+
+ # smartctl -x /dev/nvme0n1
+ smartctl 7.1 2019-12-30 r5022 [x86_64-linux-5.5.11] (local build)
+ Copyright (C) 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org
+
+ Read NVMe Identify Controller failed: NVME_IOCTL_ADMIN_CMD: Bad address
+
+Since changing 32-bit kernels to actually check all of the submitted
+address bits now would break existing userspace, this patch fixes the
+compat problem by explicitly zeroing the upper bits in the compat case.
+This enables 32-bit smartctl to work on a 64-bit kernel.
+
+Signed-off-by: Nick Bowler <nbowler@draconx.ca>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index a4d8c90ee7cc4..652ca87dac949 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -6,6 +6,7 @@
+
+ #include <linux/blkdev.h>
+ #include <linux/blk-mq.h>
++#include <linux/compat.h>
+ #include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/hdreg.h>
+@@ -1248,6 +1249,18 @@ static void nvme_enable_aen(struct nvme_ctrl *ctrl)
+ queue_work(nvme_wq, &ctrl->async_event_work);
+ }
+
++/*
++ * Convert integer values from ioctl structures to user pointers, silently
++ * ignoring the upper bits in the compat case to match behaviour of 32-bit
++ * kernels.
++ */
++static void __user *nvme_to_user_ptr(uintptr_t ptrval)
++{
++ if (in_compat_syscall())
++ ptrval = (compat_uptr_t)ptrval;
++ return (void __user *)ptrval;
++}
++
+ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
+ {
+ struct nvme_user_io io;
+@@ -1271,7 +1284,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
+
+ length = (io.nblocks + 1) << ns->lba_shift;
+ meta_len = (io.nblocks + 1) * ns->ms;
+- metadata = (void __user *)(uintptr_t)io.metadata;
++ metadata = nvme_to_user_ptr(io.metadata);
+
+ if (ns->ext) {
+ length += meta_len;
+@@ -1294,7 +1307,7 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
+ c.rw.appmask = cpu_to_le16(io.appmask);
+
+ return nvme_submit_user_cmd(ns->queue, &c,
+- (void __user *)(uintptr_t)io.addr, length,
++ nvme_to_user_ptr(io.addr), length,
+ metadata, meta_len, lower_32_bits(io.slba), NULL, 0);
+ }
+
+@@ -1414,9 +1427,9 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+
+ effects = nvme_passthru_start(ctrl, ns, cmd.opcode);
+ status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
+- (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
+- (void __user *)(uintptr_t)cmd.metadata,
+- cmd.metadata_len, 0, &result, timeout);
++ nvme_to_user_ptr(cmd.addr), cmd.data_len,
++ nvme_to_user_ptr(cmd.metadata), cmd.metadata_len,
++ 0, &result, timeout);
+ nvme_passthru_end(ctrl, effects);
+
+ if (status >= 0) {
+@@ -1461,8 +1474,8 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+
+ effects = nvme_passthru_start(ctrl, ns, cmd.opcode);
+ status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c,
+- (void __user *)(uintptr_t)cmd.addr, cmd.data_len,
+- (void __user *)(uintptr_t)cmd.metadata, cmd.metadata_len,
++ nvme_to_user_ptr(cmd.addr), cmd.data_len,
++ nvme_to_user_ptr(cmd.metadata), cmd.metadata_len,
+ 0, &cmd.result, timeout);
+ nvme_passthru_end(ctrl, effects);
+
+--
+2.20.1
+
--- /dev/null
+From 6c3c4b13c7d2f1f07af560cd62a674c5c7335f35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Apr 2020 09:34:54 -0700
+Subject: nvme: fix deadlock caused by ANA update wrong locking
+
+From: Sagi Grimberg <sagi@grimberg.me>
+
+[ Upstream commit 657f1975e9d9c880fa13030e88ba6cc84964f1db ]
+
+The deadlock combines 4 flows in parallel:
+- ns scanning (triggered from reconnect)
+- request timeout
+- ANA update (triggered from reconnect)
+- I/O coming into the mpath device
+
+(1) ns scanning triggers disk revalidation -> update disk info ->
+ freeze queue -> but blocked, due to (2)
+
+(2) timeout handler reference the g_usage_counter - > but blocks in
+ the transport .timeout() handler, due to (3)
+
+(3) the transport timeout handler (indirectly) calls nvme_stop_queue() ->
+ which takes the (down_read) namespaces_rwsem - > but blocks, due to (4)
+
+(4) ANA update takes the (down_write) namespaces_rwsem -> calls
+ nvme_mpath_set_live() -> which synchronize the ns_head srcu
+ (see commit 504db087aacc) -> but blocks, due to (5)
+
+(5) I/O came into nvme_mpath_make_request -> took srcu_read_lock ->
+ direct_make_request > blk_queue_enter -> but blocked, due to (1)
+
+==> the request queue is under freeze -> deadlock.
+
+The fix is making ANA update take a read lock as the namespaces list
+is not manipulated, it is just the ns and ns->head that are being
+updated (which is protected with the ns->head lock).
+
+Fixes: 0d0b660f214dc ("nvme: add ANA support")
+Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
+Reviewed-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/multipath.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index a11900cf3a365..906dc0faa48ec 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -514,7 +514,7 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
+ if (!nr_nsids)
+ return 0;
+
+- down_write(&ctrl->namespaces_rwsem);
++ down_read(&ctrl->namespaces_rwsem);
+ list_for_each_entry(ns, &ctrl->namespaces, list) {
+ unsigned nsid = le32_to_cpu(desc->nsids[n]);
+
+@@ -525,7 +525,7 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
+ if (++n == nr_nsids)
+ break;
+ }
+- up_write(&ctrl->namespaces_rwsem);
++ up_read(&ctrl->namespaces_rwsem);
+ return 0;
+ }
+
+--
+2.20.1
+
--- /dev/null
+From 58b688d70c78cf492df1043f5cfadb3b6df86a82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Mar 2020 15:06:30 -0700
+Subject: nvme-tcp: fix possible crash in write_zeroes processing
+
+From: Sagi Grimberg <sagi@grimberg.me>
+
+[ Upstream commit 25e5cb780e62bde432b401f312bb847edc78b432 ]
+
+We cannot look at blk_rq_payload_bytes without first checking
+that the request has a mappable physical segments first (e.g.
+blk_rq_nr_phys_segments(rq) != 0) and only then to take the
+request payload bytes. This caused us to send a wrong sgl to
+the target or even dereference a non-existing buffer in case
+we actually got to the data send sequence (if it was in-capsule).
+
+Reported-by: Tony Asleson <tasleson@redhat.com>
+Suggested-by: Chaitanya Kulkarni <Chaitanya.Kulkarni@wdc.com>
+Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/tcp.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
+index 49d4373b84eb3..00e6aa59954d4 100644
+--- a/drivers/nvme/host/tcp.c
++++ b/drivers/nvme/host/tcp.c
+@@ -164,16 +164,14 @@ static inline bool nvme_tcp_async_req(struct nvme_tcp_request *req)
+ static inline bool nvme_tcp_has_inline_data(struct nvme_tcp_request *req)
+ {
+ struct request *rq;
+- unsigned int bytes;
+
+ if (unlikely(nvme_tcp_async_req(req)))
+ return false; /* async events don't have a request */
+
+ rq = blk_mq_rq_from_pdu(req);
+- bytes = blk_rq_payload_bytes(rq);
+
+- return rq_data_dir(rq) == WRITE && bytes &&
+- bytes <= nvme_tcp_inline_data_size(req->queue);
++ return rq_data_dir(rq) == WRITE && req->data_len &&
++ req->data_len <= nvme_tcp_inline_data_size(req->queue);
+ }
+
+ static inline struct page *nvme_tcp_req_cur_page(struct nvme_tcp_request *req)
+@@ -2090,7 +2088,9 @@ static blk_status_t nvme_tcp_map_data(struct nvme_tcp_queue *queue,
+
+ c->common.flags |= NVME_CMD_SGL_METABUF;
+
+- if (rq_data_dir(rq) == WRITE && req->data_len &&
++ if (!blk_rq_nr_phys_segments(rq))
++ nvme_tcp_set_sg_null(c);
++ else if (rq_data_dir(rq) == WRITE &&
+ req->data_len <= nvme_tcp_inline_data_size(queue))
+ nvme_tcp_set_sg_inline(queue, c, req->data_len);
+ else
+@@ -2117,7 +2117,8 @@ static blk_status_t nvme_tcp_setup_cmd_pdu(struct nvme_ns *ns,
+ req->data_sent = 0;
+ req->pdu_len = 0;
+ req->pdu_sent = 0;
+- req->data_len = blk_rq_payload_bytes(rq);
++ req->data_len = blk_rq_nr_phys_segments(rq) ?
++ blk_rq_payload_bytes(rq) : 0;
+ req->curr_bio = rq->bio;
+
+ if (rq_data_dir(rq) == WRITE &&
+--
+2.20.1
+
--- /dev/null
+From 1eb08870649c12cb049a2d0809e748f615fe90e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Apr 2020 16:14:27 +0200
+Subject: perf/core: Disable page faults when getting phys address
+
+From: Jiri Olsa <jolsa@kernel.org>
+
+[ Upstream commit d3296fb372bf7497b0e5d0478c4e7a677ec6f6e9 ]
+
+We hit following warning when running tests on kernel
+compiled with CONFIG_DEBUG_ATOMIC_SLEEP=y:
+
+ WARNING: CPU: 19 PID: 4472 at mm/gup.c:2381 __get_user_pages_fast+0x1a4/0x200
+ CPU: 19 PID: 4472 Comm: dummy Not tainted 5.6.0-rc6+ #3
+ RIP: 0010:__get_user_pages_fast+0x1a4/0x200
+ ...
+ Call Trace:
+ perf_prepare_sample+0xff1/0x1d90
+ perf_event_output_forward+0xe8/0x210
+ __perf_event_overflow+0x11a/0x310
+ __intel_pmu_pebs_event+0x657/0x850
+ intel_pmu_drain_pebs_nhm+0x7de/0x11d0
+ handle_pmi_common+0x1b2/0x650
+ intel_pmu_handle_irq+0x17b/0x370
+ perf_event_nmi_handler+0x40/0x60
+ nmi_handle+0x192/0x590
+ default_do_nmi+0x6d/0x150
+ do_nmi+0x2f9/0x3c0
+ nmi+0x8e/0xd7
+
+While __get_user_pages_fast() is IRQ-safe, it calls access_ok(),
+which warns on:
+
+ WARN_ON_ONCE(!in_task() && !pagefault_disabled())
+
+Peter suggested disabling page faults around __get_user_pages_fast(),
+which gets rid of the warning in access_ok() call.
+
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Jiri Olsa <jolsa@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lkml.kernel.org/r/20200407141427.3184722-1-jolsa@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 243717177f446..533c193481899 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -6734,9 +6734,12 @@ static u64 perf_virt_to_phys(u64 virt)
+ * Try IRQ-safe __get_user_pages_fast first.
+ * If failed, leave phys_addr as 0.
+ */
+- if ((current->mm != NULL) &&
+- (__get_user_pages_fast(virt, 1, 0, &p) == 1))
+- phys_addr = page_to_phys(p) + virt % PAGE_SIZE;
++ if (current->mm != NULL) {
++ pagefault_disable();
++ if (__get_user_pages_fast(virt, 1, 0, &p) == 1)
++ phys_addr = page_to_phys(p) + virt % PAGE_SIZE;
++ pagefault_enable();
++ }
+
+ if (p)
+ put_page(p);
+--
+2.20.1
+
--- /dev/null
+From 50351635fb2c1ace4a81b7e1051e079202f1289f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Mar 2020 16:31:19 +0530
+Subject: powerpc/pseries: Fix MCE handling on pseries
+
+From: Ganesh Goudar <ganeshgr@linux.ibm.com>
+
+[ Upstream commit a95a0a1654f16366360399574e10efd87e867b39 ]
+
+MCE handling on pSeries platform fails as recent rework to use common
+code for pSeries and PowerNV in machine check error handling tries to
+access per-cpu variables in realmode. The per-cpu variables may be
+outside the RMO region on pSeries platform and needs translation to be
+enabled for access. Just moving these per-cpu variable into RMO region
+did'nt help because we queue some work to workqueues in real mode, which
+again tries to touch per-cpu variables. Also fwnmi_release_errinfo()
+cannot be called when translation is not enabled.
+
+This patch fixes this by enabling translation in the exception handler
+when all required real mode handling is done. This change only affects
+the pSeries platform.
+
+Without this fix below kernel crash is seen on injecting
+SLB multihit:
+
+BUG: Unable to handle kernel data access on read at 0xc00000027b205950
+Faulting instruction address: 0xc00000000003b7e0
+Oops: Kernel access of bad area, sig: 11 [#1]
+LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
+Modules linked in: mcetest_slb(OE+) af_packet(E) xt_tcpudp(E) ip6t_rpfilter(E) ip6t_REJECT(E) ipt_REJECT(E) xt_conntrack(E) ip_set(E) nfnetlink(E) ebtable_nat(E) ebtable_broute(E) ip6table_nat(E) ip6table_mangle(E) ip6table_raw(E) ip6table_security(E) iptable_nat(E) nf_nat(E) nf_conntrack(E) nf_defrag_ipv6(E) nf_defrag_ipv4(E) iptable_mangle(E) iptable_raw(E) iptable_security(E) ebtable_filter(E) ebtables(E) ip6table_filter(E) ip6_tables(E) iptable_filter(E) ip_tables(E) x_tables(E) xfs(E) ibmveth(E) vmx_crypto(E) gf128mul(E) uio_pdrv_genirq(E) uio(E) crct10dif_vpmsum(E) rtc_generic(E) btrfs(E) libcrc32c(E) xor(E) zstd_decompress(E) zstd_compress(E) raid6_pq(E) sr_mod(E) sd_mod(E) cdrom(E) ibmvscsi(E) scsi_transport_srp(E) crc32c_vpmsum(E) dm_mod(E) sg(E) scsi_mod(E)
+CPU: 34 PID: 8154 Comm: insmod Kdump: loaded Tainted: G OE 5.5.0-mahesh #1
+NIP: c00000000003b7e0 LR: c0000000000f2218 CTR: 0000000000000000
+REGS: c000000007dcb960 TRAP: 0300 Tainted: G OE (5.5.0-mahesh)
+MSR: 8000000000001003 <SF,ME,RI,LE> CR: 28002428 XER: 20040000
+CFAR: c0000000000f2214 DAR: c00000027b205950 DSISR: 40000000 IRQMASK: 0
+GPR00: c0000000000f2218 c000000007dcbbf0 c000000001544800 c000000007dcbd70
+GPR04: 0000000000000001 c000000007dcbc98 c008000000d00258 c0080000011c0000
+GPR08: 0000000000000000 0000000300000003 c000000001035950 0000000003000048
+GPR12: 000000027a1d0000 c000000007f9c000 0000000000000558 0000000000000000
+GPR16: 0000000000000540 c008000001110000 c008000001110540 0000000000000000
+GPR20: c00000000022af10 c00000025480fd70 c008000001280000 c00000004bfbb300
+GPR24: c000000001442330 c00800000800000d c008000008000000 4009287a77000510
+GPR28: 0000000000000000 0000000000000002 c000000001033d30 0000000000000001
+NIP [c00000000003b7e0] save_mce_event+0x30/0x240
+LR [c0000000000f2218] pseries_machine_check_realmode+0x2c8/0x4f0
+Call Trace:
+Instruction dump:
+3c4c0151 38429050 7c0802a6 60000000 fbc1fff0 fbe1fff8 f821ffd1 3d42ffaf
+3fc2ffaf e98d0030 394a1150 3bdef530 <7d6a62aa> 1d2b0048 2f8b0063 380b0001
+---[ end trace 46fd63f36bbdd940 ]---
+
+Fixes: 9ca766f9891d ("powerpc/64s/pseries: machine check convert to use common event code")
+Reviewed-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
+Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Ganesh Goudar <ganeshgr@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20200320110119.10207-1-ganeshgr@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/ras.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
+index 1d7f973c647b3..43710b69e09eb 100644
+--- a/arch/powerpc/platforms/pseries/ras.c
++++ b/arch/powerpc/platforms/pseries/ras.c
+@@ -683,6 +683,17 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp)
+ #endif
+
+ out:
++ /*
++ * Enable translation as we will be accessing per-cpu variables
++ * in save_mce_event() which may fall outside RMO region, also
++ * leave it enabled because subsequently we will be queuing work
++ * to workqueues where again per-cpu variables accessed, besides
++ * fwnmi_release_errinfo() crashes when called in realmode on
++ * pseries.
++ * Note: All the realmode handling like flushing SLB entries for
++ * SLB multihit is done by now.
++ */
++ mtmsr(mfmsr() | MSR_IR | MSR_DR);
+ save_mce_event(regs, disposition == RTAS_DISP_FULLY_RECOVERED,
+ &mce_err, regs->nip, eaddr, paddr);
+
+--
+2.20.1
+
--- /dev/null
+From 597e16c0d70c4652d4c30e9f15b9b5d7786b8f36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Feb 2020 13:35:35 -0800
+Subject: pwm: bcm2835: Dynamically allocate base
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 2c25b07e5ec119cab609e41407a1fb3fa61442f5 ]
+
+The newer 2711 and 7211 chips have two PWM controllers and failure to
+dynamically allocate the PWM base would prevent the second PWM
+controller instance being probed for succeeding with an -EEXIST error
+from alloc_pwms().
+
+Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-bcm2835.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c
+index 91e24f01b54ed..d78f86f8e4621 100644
+--- a/drivers/pwm/pwm-bcm2835.c
++++ b/drivers/pwm/pwm-bcm2835.c
+@@ -166,6 +166,7 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
+
+ pc->chip.dev = &pdev->dev;
+ pc->chip.ops = &bcm2835_pwm_ops;
++ pc->chip.base = -1;
+ pc->chip.npwm = 2;
+ pc->chip.of_xlate = of_pwm_xlate_with_flags;
+ pc->chip.of_pwm_n_cells = 3;
+--
+2.20.1
+
--- /dev/null
+From 245f281e018c449b7ef16c5d2d8b3940c56bdd1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Feb 2020 22:31:06 +0100
+Subject: pwm: imx27: Fix clock handling in pwm_imx27_apply()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 15d4dbd601591858611184f9ddeb5bf21569159c ]
+
+pwm_imx27_apply() enables the clocks if the previous PWM state was
+disabled. Given that the clocks are supposed to be left on iff the PWM
+is running, the decision to disable the clocks at the end of the
+function must not depend on the previous state.
+
+Without this fix the enable count of the two affected clocks increases
+by one whenever ->apply() changes from one disabled state to another.
+
+Fixes: bd88d319abe9 ("pwm: imx27: Unconditionally write state to hardware")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-imx27.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pwm/pwm-imx27.c b/drivers/pwm/pwm-imx27.c
+index 35a7ac42269c2..7e5ed01529773 100644
+--- a/drivers/pwm/pwm-imx27.c
++++ b/drivers/pwm/pwm-imx27.c
+@@ -289,7 +289,7 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+
+ writel(cr, imx->mmio_base + MX3_PWMCR);
+
+- if (!state->enabled && cstate.enabled)
++ if (!state->enabled)
+ pwm_imx27_clk_disable_unprepare(chip);
+
+ return 0;
+--
+2.20.1
+
--- /dev/null
+From 8efc49fe9373cf5a53653f7a4df026efcee6ff4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2020 11:32:14 +0100
+Subject: pwm: rcar: Fix late Runtime PM enablement
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 1451a3eed24b5fd6a604683f0b6995e0e7e16c79 ]
+
+Runtime PM should be enabled before calling pwmchip_add(), as PWM users
+can appear immediately after the PWM chip has been added.
+Likewise, Runtime PM should be disabled after the removal of the PWM
+chip.
+
+Fixes: ed6c1476bf7f16d5 ("pwm: Add support for R-Car PWM Timer")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-rcar.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c
+index 2685577b6dd45..7ab9eb6616d95 100644
+--- a/drivers/pwm/pwm-rcar.c
++++ b/drivers/pwm/pwm-rcar.c
+@@ -229,24 +229,28 @@ static int rcar_pwm_probe(struct platform_device *pdev)
+ rcar_pwm->chip.base = -1;
+ rcar_pwm->chip.npwm = 1;
+
++ pm_runtime_enable(&pdev->dev);
++
+ ret = pwmchip_add(&rcar_pwm->chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to register PWM chip: %d\n", ret);
++ pm_runtime_disable(&pdev->dev);
+ return ret;
+ }
+
+- pm_runtime_enable(&pdev->dev);
+-
+ return 0;
+ }
+
+ static int rcar_pwm_remove(struct platform_device *pdev)
+ {
+ struct rcar_pwm_chip *rcar_pwm = platform_get_drvdata(pdev);
++ int ret;
++
++ ret = pwmchip_remove(&rcar_pwm->chip);
+
+ pm_runtime_disable(&pdev->dev);
+
+- return pwmchip_remove(&rcar_pwm->chip);
++ return ret;
+ }
+
+ static const struct of_device_id rcar_pwm_of_table[] = {
+--
+2.20.1
+
--- /dev/null
+From a93887b61cee379b46748b130858072100ebc3eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2020 11:32:15 +0100
+Subject: pwm: renesas-tpu: Fix late Runtime PM enablement
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit d5a3c7a4536e1329a758e14340efd0e65252bd3d ]
+
+Runtime PM should be enabled before calling pwmchip_add(), as PWM users
+can appear immediately after the PWM chip has been added.
+Likewise, Runtime PM should always be disabled after the removal of the
+PWM chip, even if the latter failed.
+
+Fixes: 99b82abb0a35b073 ("pwm: Add Renesas TPU PWM driver")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-renesas-tpu.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c
+index 4a855a21b782d..8032acc84161a 100644
+--- a/drivers/pwm/pwm-renesas-tpu.c
++++ b/drivers/pwm/pwm-renesas-tpu.c
+@@ -415,16 +415,17 @@ static int tpu_probe(struct platform_device *pdev)
+ tpu->chip.base = -1;
+ tpu->chip.npwm = TPU_CHANNEL_MAX;
+
++ pm_runtime_enable(&pdev->dev);
++
+ ret = pwmchip_add(&tpu->chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to register PWM chip\n");
++ pm_runtime_disable(&pdev->dev);
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "TPU PWM %d registered\n", tpu->pdev->id);
+
+- pm_runtime_enable(&pdev->dev);
+-
+ return 0;
+ }
+
+@@ -434,12 +435,10 @@ static int tpu_remove(struct platform_device *pdev)
+ int ret;
+
+ ret = pwmchip_remove(&tpu->chip);
+- if (ret)
+- return ret;
+
+ pm_runtime_disable(&pdev->dev);
+
+- return 0;
++ return ret;
+ }
+
+ #ifdef CONFIG_OF
+--
+2.20.1
+
--- /dev/null
+From 9bc107b314596526ae93f7a97561dfee67d9ee45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Apr 2020 22:04:01 +1000
+Subject: Revert "powerpc/64: irq_work avoid interrupt when called with
+ hardware irqs enabled"
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+[ Upstream commit abc3fce76adbdfa8f87272c784b388cd20b46049 ]
+
+This reverts commit ebb37cf3ffd39fdb6ec5b07111f8bb2f11d92c5f.
+
+That commit does not play well with soft-masked irq state
+manipulations in idle, interrupt replay, and possibly others due to
+tracing code sometimes using irq_work_queue (e.g., in
+trace_hardirqs_on()). That can cause PACA_IRQ_DEC to become set when
+it is not expected, and be ignored or cleared or cause warnings.
+
+The net result seems to be missing an irq_work until the next timer
+interrupt in the worst case which is usually not going to be noticed,
+however it could be a long time if the tick is disabled, which is
+against the spirit of irq_work and might cause real problems.
+
+The idea is still solid, but it would need more work. It's not really
+clear if it would be worth added complexity, so revert this for
+now (not a straight revert, but replace with a comment explaining why
+we might see interrupts happening, and gives git blame something to
+find).
+
+Fixes: ebb37cf3ffd3 ("powerpc/64: irq_work avoid interrupt when called with hardware irqs enabled")
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20200402120401.1115883-1-npiggin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/time.c | 44 +++++++++++---------------------------
+ 1 file changed, 13 insertions(+), 31 deletions(-)
+
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index 1168e8b37e306..716f8d0960a7b 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -522,35 +522,6 @@ static inline void clear_irq_work_pending(void)
+ "i" (offsetof(struct paca_struct, irq_work_pending)));
+ }
+
+-void arch_irq_work_raise(void)
+-{
+- preempt_disable();
+- set_irq_work_pending_flag();
+- /*
+- * Non-nmi code running with interrupts disabled will replay
+- * irq_happened before it re-enables interrupts, so setthe
+- * decrementer there instead of causing a hardware exception
+- * which would immediately hit the masked interrupt handler
+- * and have the net effect of setting the decrementer in
+- * irq_happened.
+- *
+- * NMI interrupts can not check this when they return, so the
+- * decrementer hardware exception is raised, which will fire
+- * when interrupts are next enabled.
+- *
+- * BookE does not support this yet, it must audit all NMI
+- * interrupt handlers to ensure they call nmi_enter() so this
+- * check would be correct.
+- */
+- if (IS_ENABLED(CONFIG_BOOKE) || !irqs_disabled() || in_nmi()) {
+- set_dec(1);
+- } else {
+- hard_irq_disable();
+- local_paca->irq_happened |= PACA_IRQ_DEC;
+- }
+- preempt_enable();
+-}
+-
+ #else /* 32-bit */
+
+ DEFINE_PER_CPU(u8, irq_work_pending);
+@@ -559,16 +530,27 @@ DEFINE_PER_CPU(u8, irq_work_pending);
+ #define test_irq_work_pending() __this_cpu_read(irq_work_pending)
+ #define clear_irq_work_pending() __this_cpu_write(irq_work_pending, 0)
+
++#endif /* 32 vs 64 bit */
++
+ void arch_irq_work_raise(void)
+ {
++ /*
++ * 64-bit code that uses irq soft-mask can just cause an immediate
++ * interrupt here that gets soft masked, if this is called under
++ * local_irq_disable(). It might be possible to prevent that happening
++ * by noticing interrupts are disabled and setting decrementer pending
++ * to be replayed when irqs are enabled. The problem there is that
++ * tracing can call irq_work_raise, including in code that does low
++ * level manipulations of irq soft-mask state (e.g., trace_hardirqs_on)
++ * which could get tangled up if we're messing with the same state
++ * here.
++ */
+ preempt_disable();
+ set_irq_work_pending_flag();
+ set_dec(1);
+ preempt_enable();
+ }
+
+-#endif /* 32 vs 64 bit */
+-
+ #else /* CONFIG_IRQ_WORK */
+
+ #define test_irq_work_pending() 0
+--
+2.20.1
+
--- /dev/null
+From ad3378f6709aa51a47853fa3ac0a184ad246eb81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Mar 2020 13:45:02 +0100
+Subject: s390/cio: avoid duplicated 'ADD' uevents
+
+From: Cornelia Huck <cohuck@redhat.com>
+
+[ Upstream commit 05ce3e53f375295c2940390b2b429e506e07655c ]
+
+The common I/O layer delays the ADD uevent for subchannels and
+delegates generating this uevent to the individual subchannel
+drivers. The io_subchannel driver will do so when the associated
+ccw_device has been registered -- but unconditionally, so more
+ADD uevents will be generated if a subchannel has been unbound
+from the io_subchannel driver and later rebound.
+
+To fix this, only generate the ADD event if uevents were still
+suppressed for the device.
+
+Fixes: fa1a8c23eb7d ("s390: cio: Delay uevents for subchannels")
+Message-Id: <20200327124503.9794-2-cohuck@redhat.com>
+Reported-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
+Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
+Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/cio/device.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
+index 0c6245fc77069..983f9c9e08deb 100644
+--- a/drivers/s390/cio/device.c
++++ b/drivers/s390/cio/device.c
+@@ -849,8 +849,10 @@ static void io_subchannel_register(struct ccw_device *cdev)
+ * Now we know this subchannel will stay, we can throw
+ * our delayed uevent.
+ */
+- dev_set_uevent_suppress(&sch->dev, 0);
+- kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
++ if (dev_get_uevent_suppress(&sch->dev)) {
++ dev_set_uevent_suppress(&sch->dev, 0);
++ kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
++ }
+ /* make it known to the system */
+ ret = ccw_device_add(cdev);
+ if (ret) {
+@@ -1058,8 +1060,11 @@ static int io_subchannel_probe(struct subchannel *sch)
+ * Throw the delayed uevent for the subchannel, register
+ * the ccw_device and exit.
+ */
+- dev_set_uevent_suppress(&sch->dev, 0);
+- kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
++ if (dev_get_uevent_suppress(&sch->dev)) {
++ /* should always be the case for the console */
++ dev_set_uevent_suppress(&sch->dev, 0);
++ kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
++ }
+ cdev = sch_get_cdev(sch);
+ rc = ccw_device_add(cdev);
+ if (rc) {
+--
+2.20.1
+
--- /dev/null
+From 00eec48697e8c519dc19645b01568e4bfb927ef8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Mar 2020 13:45:03 +0100
+Subject: s390/cio: generate delayed uevent for vfio-ccw subchannels
+
+From: Cornelia Huck <cohuck@redhat.com>
+
+[ Upstream commit 2bc55eaeb88d30accfc1b6ac2708d4e4b81ca260 ]
+
+The common I/O layer delays the ADD uevent for subchannels and
+delegates generating this uevent to the individual subchannel
+drivers. The vfio-ccw I/O subchannel driver, however, did not
+do that, and will not generate an ADD uevent for subchannels
+that had not been bound to a different driver (or none at all,
+which also triggers the uevent).
+
+Generate the ADD uevent at the end of the probe function if
+uevents were still suppressed for the device.
+
+Message-Id: <20200327124503.9794-3-cohuck@redhat.com>
+Fixes: 63f1934d562d ("vfio: ccw: basic implementation for vfio_ccw driver")
+Reviewed-by: Eric Farman <farman@linux.ibm.com>
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/cio/vfio_ccw_drv.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
+index e401a3d0aa570..339a6bc0339b0 100644
+--- a/drivers/s390/cio/vfio_ccw_drv.c
++++ b/drivers/s390/cio/vfio_ccw_drv.c
+@@ -167,6 +167,11 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
+ if (ret)
+ goto out_disable;
+
++ if (dev_get_uevent_suppress(&sch->dev)) {
++ dev_set_uevent_suppress(&sch->dev, 0);
++ kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
++ }
++
+ VFIO_CCW_MSG_EVENT(4, "bound to subchannel %x.%x.%04x\n",
+ sch->schid.cssid, sch->schid.ssid,
+ sch->schid.sch_no);
+--
+2.20.1
+
--- /dev/null
+From b3278f057a3402e4ad86025eab294750e3c5ca38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2020 15:58:50 +0800
+Subject: scsi: iscsi: Report unbind session event when the target has been
+ removed
+
+From: Wu Bo <wubo40@huawei.com>
+
+[ Upstream commit 13e60d3ba287d96eeaf1deaadba51f71578119a3 ]
+
+If the daemon is restarted or crashes while logging out of a session, the
+unbind session event sent by the kernel is not processed and is lost. When
+the daemon starts again, the session can't be unbound because the daemon is
+waiting for the event message. However, the kernel has already logged out
+and the event will not be resent.
+
+When iscsid restart is complete, logout session reports error:
+
+Logging out of session [sid: 6, target: iqn.xxxxx, portal: xx.xx.xx.xx,3260]
+iscsiadm: Could not logout of [sid: 6, target: iscsiadm -m node iqn.xxxxx, portal: xx.xx.xx.xx,3260].
+iscsiadm: initiator reported error (9 - internal error)
+iscsiadm: Could not logout of all requested sessions
+
+Make sure the unbind event is emitted.
+
+[mkp: commit desc and applied by hand since patch was mangled]
+
+Link: https://lore.kernel.org/r/4eab1771-2cb3-8e79-b31c-923652340e99@huawei.com
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Signed-off-by: Wu Bo <wubo40@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index dfc726fa34e34..443ace019852f 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -2012,7 +2012,7 @@ static void __iscsi_unbind_session(struct work_struct *work)
+ if (session->target_id == ISCSI_MAX_TARGET) {
+ spin_unlock_irqrestore(&session->lock, flags);
+ mutex_unlock(&ihost->mutex);
+- return;
++ goto unbind_session_exit;
+ }
+
+ target_id = session->target_id;
+@@ -2024,6 +2024,8 @@ static void __iscsi_unbind_session(struct work_struct *work)
+ ida_simple_remove(&iscsi_sess_ida, target_id);
+
+ scsi_remove_target(&session->dev);
++
++unbind_session_exit:
+ iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
+ ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
+ }
+--
+2.20.1
+
--- /dev/null
+From 52b44d56bf8156947eff1c23af003940d58d7354 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Mar 2020 23:02:07 -0700
+Subject: scsi: libfc: If PRLI rejected, move rport to PLOGI state
+
+From: Javed Hasan <jhasan@marvell.com>
+
+[ Upstream commit 45e544bfdab2014d11c7595b8ccc3c4715a09015 ]
+
+If PRLI reject code indicates "rejected status", move rport state machine
+back to PLOGI state.
+
+Link: https://lore.kernel.org/r/20200327060208.17104-2-skashyap@marvell.com
+Signed-off-by: Javed Hasan <jhasan@marvell.com>
+Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/libfc/fc_rport.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
+index da6e97d8dc3bb..6bb8917b99a19 100644
+--- a/drivers/scsi/libfc/fc_rport.c
++++ b/drivers/scsi/libfc/fc_rport.c
+@@ -1208,9 +1208,15 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
+ rjt = fc_frame_payload_get(fp, sizeof(*rjt));
+ if (!rjt)
+ FC_RPORT_DBG(rdata, "PRLI bad response\n");
+- else
++ else {
+ FC_RPORT_DBG(rdata, "PRLI ELS rejected, reason %x expl %x\n",
+ rjt->er_reason, rjt->er_explan);
++ if (rjt->er_reason == ELS_RJT_UNAB &&
++ rjt->er_explan == ELS_EXPL_PLOGI_REQD) {
++ fc_rport_enter_plogi(rdata);
++ goto out;
++ }
++ }
+ fc_rport_error_retry(rdata, FC_EX_ELS_RJT);
+ }
+
+--
+2.20.1
+
--- /dev/null
+From d8b8caad81724ec5cdd845c00dd6ad9e135e059a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Mar 2020 11:12:57 -0700
+Subject: scsi: lpfc: Fix crash after handling a pci error
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 4cd70891308dfb875ef31060c4a4aa8872630a2e ]
+
+Injecting EEH on a 32GB card is causing kernel oops
+
+The pci error handler is doing an IO flush and the offline code is also
+doing an IO flush. When the 1st flush is complete the hdwq is destroyed
+(freed), yet the second flush accesses the hdwq and crashes.
+
+Added a check in lpfc_sli4_fush_io_rings to check both the HBA_IOQ_FLUSH
+flag and the hdwq pointer to see if it is already set and not already
+freed.
+
+Link: https://lore.kernel.org/r/20200322181304.37655-6-jsmart2021@gmail.com
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_sli.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 5939ea0e3b1eb..de97727458fc7 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -4046,6 +4046,11 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba)
+ struct lpfc_iocbq *piocb, *next_iocb;
+
+ spin_lock_irq(&phba->hbalock);
++ if (phba->hba_flag & HBA_IOQ_FLUSH ||
++ !phba->sli4_hba.hdwq) {
++ spin_unlock_irq(&phba->hbalock);
++ return;
++ }
+ /* Indicate the I/O queues are flushed */
+ phba->hba_flag |= HBA_IOQ_FLUSH;
+ spin_unlock_irq(&phba->hbalock);
+--
+2.20.1
+
--- /dev/null
+From 3d967c8260d62d63d1cd595b8b22b287cd73b37e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Mar 2020 11:12:59 -0700
+Subject: scsi: lpfc: Fix crash in target side cable pulls hitting
+ WAIT_FOR_UNREG
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 807e7353d8a7105ce884d22b0dbc034993c6679c ]
+
+Kernel is crashing with the following stacktrace:
+
+ BUG: unable to handle kernel NULL pointer dereference at
+ 00000000000005bc
+ IP: lpfc_nvme_register_port+0x1a8/0x3a0 [lpfc]
+ ...
+ Call Trace:
+ lpfc_nlp_state_cleanup+0x2b2/0x500 [lpfc]
+ lpfc_nlp_set_state+0xd7/0x1a0 [lpfc]
+ lpfc_cmpl_prli_prli_issue+0x1f7/0x450 [lpfc]
+ lpfc_disc_state_machine+0x7a/0x1e0 [lpfc]
+ lpfc_cmpl_els_prli+0x16f/0x1e0 [lpfc]
+ lpfc_sli_sp_handle_rspiocb+0x5b2/0x690 [lpfc]
+ lpfc_sli_handle_slow_ring_event_s4+0x182/0x230 [lpfc]
+ lpfc_do_work+0x87f/0x1570 [lpfc]
+ kthread+0x10d/0x130
+ ret_from_fork+0x35/0x40
+
+During target side fault injections, it is possible to hit the
+NLP_WAIT_FOR_UNREG case in lpfc_nvme_remoteport_delete. A prior commit
+fixed a rebind and delete race condition, but called lpfc_nlp_put
+unconditionally. This triggered a deletion and the crash.
+
+Fix by movng nlp_put to inside the NLP_WAIT_FOR_UNREG case, where the nlp
+will be being unregistered/removed. Leave the reference if the flag isn't
+set.
+
+Link: https://lore.kernel.org/r/20200322181304.37655-8-jsmart2021@gmail.com
+Fixes: b15bd3e6212e ("scsi: lpfc: Fix nvme remoteport registration race conditions")
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_nvme.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
+index db4a04a207ece..cb40217d5cc14 100644
+--- a/drivers/scsi/lpfc/lpfc_nvme.c
++++ b/drivers/scsi/lpfc/lpfc_nvme.c
+@@ -382,13 +382,15 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport)
+ if (ndlp->upcall_flags & NLP_WAIT_FOR_UNREG) {
+ ndlp->nrport = NULL;
+ ndlp->upcall_flags &= ~NLP_WAIT_FOR_UNREG;
+- }
+- spin_unlock_irq(&vport->phba->hbalock);
++ spin_unlock_irq(&vport->phba->hbalock);
+
+- /* Remove original register reference. The host transport
+- * won't reference this rport/remoteport any further.
+- */
+- lpfc_nlp_put(ndlp);
++ /* Remove original register reference. The host transport
++ * won't reference this rport/remoteport any further.
++ */
++ lpfc_nlp_put(ndlp);
++ } else {
++ spin_unlock_irq(&vport->phba->hbalock);
++ }
+
+ rport_err:
+ return;
+--
+2.20.1
+
--- /dev/null
+From e602a5d492371e4e373b270e4d52f97430e66399 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Mar 2020 11:13:00 -0700
+Subject: scsi: lpfc: Fix erroneous cpu limit of 128 on I/O statistics
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 840eda9602d30342486e85e7e96499f565572e4b ]
+
+The cpu io statistics were capped by a hard define limit of 128. This
+effectively was a max number of CPUs, not an actual CPU count, nor actual
+CPU numbers which can be even larger than both of those values. This made
+stats off/misleading and on large CPU count systems, wrong.
+
+Fix the stats so that all CPUs can have a stats struct. Fix the looping
+such that it loops by hdwq, finds CPUs that used the hdwq, and sum the
+stats, then display.
+
+Link: https://lore.kernel.org/r/20200322181304.37655-9-jsmart2021@gmail.com
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc.h | 9 +-
+ drivers/scsi/lpfc/lpfc_debugfs.c | 204 ++++++++++++++++++-------------
+ drivers/scsi/lpfc/lpfc_debugfs.h | 1 -
+ drivers/scsi/lpfc/lpfc_init.c | 28 +++++
+ drivers/scsi/lpfc/lpfc_nvme.c | 45 ++++---
+ drivers/scsi/lpfc/lpfc_nvmet.c | 55 ++++-----
+ drivers/scsi/lpfc/lpfc_scsi.c | 23 +---
+ drivers/scsi/lpfc/lpfc_sli4.h | 19 +--
+ 8 files changed, 215 insertions(+), 169 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
+index 3f2cb17c4574c..828873d5b3e8a 100644
+--- a/drivers/scsi/lpfc/lpfc.h
++++ b/drivers/scsi/lpfc/lpfc.h
+@@ -482,7 +482,7 @@ struct lpfc_vport {
+ struct dentry *debug_nvmestat;
+ struct dentry *debug_scsistat;
+ struct dentry *debug_nvmektime;
+- struct dentry *debug_cpucheck;
++ struct dentry *debug_hdwqstat;
+ struct dentry *vport_debugfs_root;
+ struct lpfc_debugfs_trc *disc_trc;
+ atomic_t disc_trc_cnt;
+@@ -1176,12 +1176,11 @@ struct lpfc_hba {
+ uint16_t sfp_warning;
+
+ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+- uint16_t cpucheck_on;
++ uint16_t hdwqstat_on;
+ #define LPFC_CHECK_OFF 0
+ #define LPFC_CHECK_NVME_IO 1
+-#define LPFC_CHECK_NVMET_RCV 2
+-#define LPFC_CHECK_NVMET_IO 4
+-#define LPFC_CHECK_SCSI_IO 8
++#define LPFC_CHECK_NVMET_IO 2
++#define LPFC_CHECK_SCSI_IO 4
+ uint16_t ktime_on;
+ uint64_t ktime_data_samples;
+ uint64_t ktime_status_samples;
+diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
+index 819335b16c2e4..1b8be1006cbef 100644
+--- a/drivers/scsi/lpfc/lpfc_debugfs.c
++++ b/drivers/scsi/lpfc/lpfc_debugfs.c
+@@ -1603,42 +1603,50 @@ out:
+ }
+
+ /**
+- * lpfc_debugfs_cpucheck_data - Dump target node list to a buffer
++ * lpfc_debugfs_hdwqstat_data - Dump I/O stats to a buffer
+ * @vport: The vport to gather target node info from.
+ * @buf: The buffer to dump log into.
+ * @size: The maximum amount of data to process.
+ *
+ * Description:
+- * This routine dumps the NVME statistics associated with @vport
++ * This routine dumps the NVME + SCSI statistics associated with @vport
+ *
+ * Return Value:
+ * This routine returns the amount of bytes that were dumped into @buf and will
+ * not exceed @size.
+ **/
+ static int
+-lpfc_debugfs_cpucheck_data(struct lpfc_vport *vport, char *buf, int size)
++lpfc_debugfs_hdwqstat_data(struct lpfc_vport *vport, char *buf, int size)
+ {
+ struct lpfc_hba *phba = vport->phba;
+ struct lpfc_sli4_hdw_queue *qp;
+- int i, j, max_cnt;
+- int len = 0;
++ struct lpfc_hdwq_stat *c_stat;
++ int i, j, len;
+ uint32_t tot_xmt;
+ uint32_t tot_rcv;
+ uint32_t tot_cmpl;
++ char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
+
+- len += scnprintf(buf + len, PAGE_SIZE - len,
+- "CPUcheck %s ",
+- (phba->cpucheck_on & LPFC_CHECK_NVME_IO ?
+- "Enabled" : "Disabled"));
+- if (phba->nvmet_support) {
+- len += scnprintf(buf + len, PAGE_SIZE - len,
+- "%s\n",
+- (phba->cpucheck_on & LPFC_CHECK_NVMET_RCV ?
+- "Rcv Enabled\n" : "Rcv Disabled\n"));
+- } else {
+- len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
+- }
+- max_cnt = size - LPFC_DEBUG_OUT_LINE_SZ;
++ scnprintf(tmp, sizeof(tmp), "HDWQ Stats:\n\n");
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp), "(NVME Accounting: %s) ",
++ (phba->hdwqstat_on &
++ (LPFC_CHECK_NVME_IO | LPFC_CHECK_NVMET_IO) ?
++ "Enabled" : "Disabled"));
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp), "(SCSI Accounting: %s) ",
++ (phba->hdwqstat_on & LPFC_CHECK_SCSI_IO ?
++ "Enabled" : "Disabled"));
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
++
++ scnprintf(tmp, sizeof(tmp), "\n\n");
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
+
+ for (i = 0; i < phba->cfg_hdw_queue; i++) {
+ qp = &phba->sli4_hba.hdwq[i];
+@@ -1646,46 +1654,76 @@ lpfc_debugfs_cpucheck_data(struct lpfc_vport *vport, char *buf, int size)
+ tot_rcv = 0;
+ tot_xmt = 0;
+ tot_cmpl = 0;
+- for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) {
+- tot_xmt += qp->cpucheck_xmt_io[j];
+- tot_cmpl += qp->cpucheck_cmpl_io[j];
+- if (phba->nvmet_support)
+- tot_rcv += qp->cpucheck_rcv_io[j];
+- }
+
+- /* Only display Hardware Qs with something */
+- if (!tot_xmt && !tot_cmpl && !tot_rcv)
+- continue;
++ for_each_present_cpu(j) {
++ c_stat = per_cpu_ptr(phba->sli4_hba.c_stat, j);
++
++ /* Only display for this HDWQ */
++ if (i != c_stat->hdwq_no)
++ continue;
+
+- len += scnprintf(buf + len, PAGE_SIZE - len,
+- "HDWQ %03d: ", i);
+- for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) {
+ /* Only display non-zero counters */
+- if (!qp->cpucheck_xmt_io[j] &&
+- !qp->cpucheck_cmpl_io[j] &&
+- !qp->cpucheck_rcv_io[j])
++ if (!c_stat->xmt_io && !c_stat->cmpl_io &&
++ !c_stat->rcv_io)
+ continue;
++
++ if (!tot_xmt && !tot_cmpl && !tot_rcv) {
++ /* Print HDWQ string only the first time */
++ scnprintf(tmp, sizeof(tmp), "[HDWQ %d]:\t", i);
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
++ }
++
++ tot_xmt += c_stat->xmt_io;
++ tot_cmpl += c_stat->cmpl_io;
++ if (phba->nvmet_support)
++ tot_rcv += c_stat->rcv_io;
++
++ scnprintf(tmp, sizeof(tmp), "| [CPU %d]: ", j);
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
++
+ if (phba->nvmet_support) {
+- len += scnprintf(buf + len, PAGE_SIZE - len,
+- "CPU %03d: %x/%x/%x ", j,
+- qp->cpucheck_rcv_io[j],
+- qp->cpucheck_xmt_io[j],
+- qp->cpucheck_cmpl_io[j]);
++ scnprintf(tmp, sizeof(tmp),
++ "XMT 0x%x CMPL 0x%x RCV 0x%x |",
++ c_stat->xmt_io, c_stat->cmpl_io,
++ c_stat->rcv_io);
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
+ } else {
+- len += scnprintf(buf + len, PAGE_SIZE - len,
+- "CPU %03d: %x/%x ", j,
+- qp->cpucheck_xmt_io[j],
+- qp->cpucheck_cmpl_io[j]);
++ scnprintf(tmp, sizeof(tmp),
++ "XMT 0x%x CMPL 0x%x |",
++ c_stat->xmt_io, c_stat->cmpl_io);
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
+ }
+ }
+- len += scnprintf(buf + len, PAGE_SIZE - len,
+- "Total: %x\n", tot_xmt);
+- if (len >= max_cnt) {
+- len += scnprintf(buf + len, PAGE_SIZE - len,
+- "Truncated ...\n");
+- return len;
++
++ /* Check if nothing to display */
++ if (!tot_xmt && !tot_cmpl && !tot_rcv)
++ continue;
++
++ scnprintf(tmp, sizeof(tmp), "\t->\t[HDWQ Total: ");
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
++
++ if (phba->nvmet_support) {
++ scnprintf(tmp, sizeof(tmp),
++ "XMT 0x%x CMPL 0x%x RCV 0x%x]\n\n",
++ tot_xmt, tot_cmpl, tot_rcv);
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
++ } else {
++ scnprintf(tmp, sizeof(tmp),
++ "XMT 0x%x CMPL 0x%x]\n\n",
++ tot_xmt, tot_cmpl);
++ if (strlcat(buf, tmp, size) >= size)
++ goto buffer_done;
+ }
+ }
++
++buffer_done:
++ len = strnlen(buf, size);
+ return len;
+ }
+
+@@ -2921,7 +2959,7 @@ lpfc_debugfs_nvmeio_trc_write(struct file *file, const char __user *buf,
+ }
+
+ static int
+-lpfc_debugfs_cpucheck_open(struct inode *inode, struct file *file)
++lpfc_debugfs_hdwqstat_open(struct inode *inode, struct file *file)
+ {
+ struct lpfc_vport *vport = inode->i_private;
+ struct lpfc_debug *debug;
+@@ -2932,14 +2970,14 @@ lpfc_debugfs_cpucheck_open(struct inode *inode, struct file *file)
+ goto out;
+
+ /* Round to page boundary */
+- debug->buffer = kmalloc(LPFC_CPUCHECK_SIZE, GFP_KERNEL);
++ debug->buffer = kcalloc(1, LPFC_SCSISTAT_SIZE, GFP_KERNEL);
+ if (!debug->buffer) {
+ kfree(debug);
+ goto out;
+ }
+
+- debug->len = lpfc_debugfs_cpucheck_data(vport, debug->buffer,
+- LPFC_CPUCHECK_SIZE);
++ debug->len = lpfc_debugfs_hdwqstat_data(vport, debug->buffer,
++ LPFC_SCSISTAT_SIZE);
+
+ debug->i_private = inode->i_private;
+ file->private_data = debug;
+@@ -2950,16 +2988,16 @@ out:
+ }
+
+ static ssize_t
+-lpfc_debugfs_cpucheck_write(struct file *file, const char __user *buf,
++lpfc_debugfs_hdwqstat_write(struct file *file, const char __user *buf,
+ size_t nbytes, loff_t *ppos)
+ {
+ struct lpfc_debug *debug = file->private_data;
+ struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
+ struct lpfc_hba *phba = vport->phba;
+- struct lpfc_sli4_hdw_queue *qp;
++ struct lpfc_hdwq_stat *c_stat;
+ char mybuf[64];
+ char *pbuf;
+- int i, j;
++ int i;
+
+ if (nbytes > 64)
+ nbytes = 64;
+@@ -2972,41 +3010,39 @@ lpfc_debugfs_cpucheck_write(struct file *file, const char __user *buf,
+
+ if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
+ if (phba->nvmet_support)
+- phba->cpucheck_on |= LPFC_CHECK_NVMET_IO;
++ phba->hdwqstat_on |= LPFC_CHECK_NVMET_IO;
+ else
+- phba->cpucheck_on |= (LPFC_CHECK_NVME_IO |
++ phba->hdwqstat_on |= (LPFC_CHECK_NVME_IO |
+ LPFC_CHECK_SCSI_IO);
+ return strlen(pbuf);
+ } else if ((strncmp(pbuf, "nvme_on", sizeof("nvme_on") - 1) == 0)) {
+ if (phba->nvmet_support)
+- phba->cpucheck_on |= LPFC_CHECK_NVMET_IO;
++ phba->hdwqstat_on |= LPFC_CHECK_NVMET_IO;
+ else
+- phba->cpucheck_on |= LPFC_CHECK_NVME_IO;
++ phba->hdwqstat_on |= LPFC_CHECK_NVME_IO;
+ return strlen(pbuf);
+ } else if ((strncmp(pbuf, "scsi_on", sizeof("scsi_on") - 1) == 0)) {
+- phba->cpucheck_on |= LPFC_CHECK_SCSI_IO;
++ if (!phba->nvmet_support)
++ phba->hdwqstat_on |= LPFC_CHECK_SCSI_IO;
+ return strlen(pbuf);
+- } else if ((strncmp(pbuf, "rcv",
+- sizeof("rcv") - 1) == 0)) {
+- if (phba->nvmet_support)
+- phba->cpucheck_on |= LPFC_CHECK_NVMET_RCV;
+- else
+- return -EINVAL;
++ } else if ((strncmp(pbuf, "nvme_off", sizeof("nvme_off") - 1) == 0)) {
++ phba->hdwqstat_on &= ~(LPFC_CHECK_NVME_IO |
++ LPFC_CHECK_NVMET_IO);
++ return strlen(pbuf);
++ } else if ((strncmp(pbuf, "scsi_off", sizeof("scsi_off") - 1) == 0)) {
++ phba->hdwqstat_on &= ~LPFC_CHECK_SCSI_IO;
+ return strlen(pbuf);
+ } else if ((strncmp(pbuf, "off",
+ sizeof("off") - 1) == 0)) {
+- phba->cpucheck_on = LPFC_CHECK_OFF;
++ phba->hdwqstat_on = LPFC_CHECK_OFF;
+ return strlen(pbuf);
+ } else if ((strncmp(pbuf, "zero",
+ sizeof("zero") - 1) == 0)) {
+- for (i = 0; i < phba->cfg_hdw_queue; i++) {
+- qp = &phba->sli4_hba.hdwq[i];
+-
+- for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) {
+- qp->cpucheck_rcv_io[j] = 0;
+- qp->cpucheck_xmt_io[j] = 0;
+- qp->cpucheck_cmpl_io[j] = 0;
+- }
++ for_each_present_cpu(i) {
++ c_stat = per_cpu_ptr(phba->sli4_hba.c_stat, i);
++ c_stat->xmt_io = 0;
++ c_stat->cmpl_io = 0;
++ c_stat->rcv_io = 0;
+ }
+ return strlen(pbuf);
+ }
+@@ -5451,13 +5487,13 @@ static const struct file_operations lpfc_debugfs_op_nvmeio_trc = {
+ .release = lpfc_debugfs_release,
+ };
+
+-#undef lpfc_debugfs_op_cpucheck
+-static const struct file_operations lpfc_debugfs_op_cpucheck = {
++#undef lpfc_debugfs_op_hdwqstat
++static const struct file_operations lpfc_debugfs_op_hdwqstat = {
+ .owner = THIS_MODULE,
+- .open = lpfc_debugfs_cpucheck_open,
++ .open = lpfc_debugfs_hdwqstat_open,
+ .llseek = lpfc_debugfs_lseek,
+ .read = lpfc_debugfs_read,
+- .write = lpfc_debugfs_cpucheck_write,
++ .write = lpfc_debugfs_hdwqstat_write,
+ .release = lpfc_debugfs_release,
+ };
+
+@@ -6081,11 +6117,11 @@ nvmeio_off:
+ vport->vport_debugfs_root,
+ vport, &lpfc_debugfs_op_nvmektime);
+
+- snprintf(name, sizeof(name), "cpucheck");
+- vport->debug_cpucheck =
++ snprintf(name, sizeof(name), "hdwqstat");
++ vport->debug_hdwqstat =
+ debugfs_create_file(name, 0644,
+ vport->vport_debugfs_root,
+- vport, &lpfc_debugfs_op_cpucheck);
++ vport, &lpfc_debugfs_op_hdwqstat);
+
+ /*
+ * The following section is for additional directories/files for the
+@@ -6219,8 +6255,8 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
+ debugfs_remove(vport->debug_nvmektime); /* nvmektime */
+ vport->debug_nvmektime = NULL;
+
+- debugfs_remove(vport->debug_cpucheck); /* cpucheck */
+- vport->debug_cpucheck = NULL;
++ debugfs_remove(vport->debug_hdwqstat); /* hdwqstat */
++ vport->debug_hdwqstat = NULL;
+
+ if (vport->vport_debugfs_root) {
+ debugfs_remove(vport->vport_debugfs_root); /* vportX */
+diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
+index 20f2537af511c..6643b9bfd4f39 100644
+--- a/drivers/scsi/lpfc/lpfc_debugfs.h
++++ b/drivers/scsi/lpfc/lpfc_debugfs.h
+@@ -47,7 +47,6 @@
+ /* nvmestat output buffer size */
+ #define LPFC_NVMESTAT_SIZE 8192
+ #define LPFC_NVMEKTIME_SIZE 8192
+-#define LPFC_CPUCHECK_SIZE 8192
+ #define LPFC_NVMEIO_TRC_SIZE 8192
+
+ /* scsistat output buffer size */
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 5a605773dd0a0..d2bbcf8cae4c3 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -6935,6 +6935,17 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
+ rc = -ENOMEM;
+ goto out_free_hba_cpu_map;
+ }
++
++#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
++ phba->sli4_hba.c_stat = alloc_percpu(struct lpfc_hdwq_stat);
++ if (!phba->sli4_hba.c_stat) {
++ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
++ "3332 Failed allocating per cpu hdwq stats\n");
++ rc = -ENOMEM;
++ goto out_free_hba_eq_info;
++ }
++#endif
++
+ /*
+ * Enable sr-iov virtual functions if supported and configured
+ * through the module parameter.
+@@ -6954,6 +6965,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
+
+ return 0;
+
++#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
++out_free_hba_eq_info:
++ free_percpu(phba->sli4_hba.eq_info);
++#endif
+ out_free_hba_cpu_map:
+ kfree(phba->sli4_hba.cpu_map);
+ out_free_hba_eq_hdl:
+@@ -6992,6 +7007,9 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba)
+ struct lpfc_fcf_conn_entry *conn_entry, *next_conn_entry;
+
+ free_percpu(phba->sli4_hba.eq_info);
++#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
++ free_percpu(phba->sli4_hba.c_stat);
++#endif
+
+ /* Free memory allocated for msi-x interrupt vector to CPU mapping */
+ kfree(phba->sli4_hba.cpu_map);
+@@ -10831,6 +10849,9 @@ lpfc_cpu_affinity_check(struct lpfc_hba *phba, int vectors)
+ #ifdef CONFIG_X86
+ struct cpuinfo_x86 *cpuinfo;
+ #endif
++#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
++ struct lpfc_hdwq_stat *c_stat;
++#endif
+
+ max_phys_id = 0;
+ min_phys_id = LPFC_VECTOR_MAP_EMPTY;
+@@ -11082,10 +11103,17 @@ found_any:
+ idx = 0;
+ for_each_possible_cpu(cpu) {
+ cpup = &phba->sli4_hba.cpu_map[cpu];
++#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
++ c_stat = per_cpu_ptr(phba->sli4_hba.c_stat, cpu);
++ c_stat->hdwq_no = cpup->hdwq;
++#endif
+ if (cpup->hdwq != LPFC_VECTOR_MAP_EMPTY)
+ continue;
+
+ cpup->hdwq = idx++ % phba->cfg_hdw_queue;
++#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
++ c_stat->hdwq_no = cpup->hdwq;
++#endif
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "3340 Set Affinity: not present "
+ "CPU %d hdwq %d\n",
+diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
+index cb40217d5cc14..8403d7ceafe4c 100644
+--- a/drivers/scsi/lpfc/lpfc_nvme.c
++++ b/drivers/scsi/lpfc/lpfc_nvme.c
+@@ -1012,6 +1012,9 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,
+ uint32_t code, status, idx;
+ uint16_t cid, sqhd, data;
+ uint32_t *ptr;
++#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
++ int cpu;
++#endif
+
+ /* Sanity check on return of outstanding command */
+ if (!lpfc_ncmd) {
+@@ -1184,19 +1187,15 @@ out_err:
+ phba->ktime_last_cmd = lpfc_ncmd->ts_data_nvme;
+ lpfc_nvme_ktime(phba, lpfc_ncmd);
+ }
+- if (unlikely(phba->cpucheck_on & LPFC_CHECK_NVME_IO)) {
+- uint32_t cpu;
+- idx = lpfc_ncmd->cur_iocbq.hba_wqidx;
++ if (unlikely(phba->hdwqstat_on & LPFC_CHECK_NVME_IO)) {
+ cpu = raw_smp_processor_id();
+- if (cpu < LPFC_CHECK_CPU_CNT) {
+- if (lpfc_ncmd->cpu != cpu)
+- lpfc_printf_vlog(vport,
+- KERN_INFO, LOG_NVME_IOERR,
+- "6701 CPU Check cmpl: "
+- "cpu %d expect %d\n",
+- cpu, lpfc_ncmd->cpu);
+- phba->sli4_hba.hdwq[idx].cpucheck_cmpl_io[cpu]++;
+- }
++ this_cpu_inc(phba->sli4_hba.c_stat->cmpl_io);
++ if (lpfc_ncmd->cpu != cpu)
++ lpfc_printf_vlog(vport,
++ KERN_INFO, LOG_NVME_IOERR,
++ "6701 CPU Check cmpl: "
++ "cpu %d expect %d\n",
++ cpu, lpfc_ncmd->cpu);
+ }
+ #endif
+
+@@ -1745,19 +1744,17 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
+ if (lpfc_ncmd->ts_cmd_start)
+ lpfc_ncmd->ts_cmd_wqput = ktime_get_ns();
+
+- if (phba->cpucheck_on & LPFC_CHECK_NVME_IO) {
++ if (phba->hdwqstat_on & LPFC_CHECK_NVME_IO) {
+ cpu = raw_smp_processor_id();
+- if (cpu < LPFC_CHECK_CPU_CNT) {
+- lpfc_ncmd->cpu = cpu;
+- if (idx != cpu)
+- lpfc_printf_vlog(vport,
+- KERN_INFO, LOG_NVME_IOERR,
+- "6702 CPU Check cmd: "
+- "cpu %d wq %d\n",
+- lpfc_ncmd->cpu,
+- lpfc_queue_info->index);
+- phba->sli4_hba.hdwq[idx].cpucheck_xmt_io[cpu]++;
+- }
++ this_cpu_inc(phba->sli4_hba.c_stat->xmt_io);
++ lpfc_ncmd->cpu = cpu;
++ if (idx != cpu)
++ lpfc_printf_vlog(vport,
++ KERN_INFO, LOG_NVME_IOERR,
++ "6702 CPU Check cmd: "
++ "cpu %d wq %d\n",
++ lpfc_ncmd->cpu,
++ lpfc_queue_info->index);
+ }
+ #endif
+ return 0;
+diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
+index 9dc9afe1c2550..f3760a4827d82 100644
+--- a/drivers/scsi/lpfc/lpfc_nvmet.c
++++ b/drivers/scsi/lpfc/lpfc_nvmet.c
+@@ -707,7 +707,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
+ struct lpfc_nvmet_rcv_ctx *ctxp;
+ uint32_t status, result, op, start_clean, logerr;
+ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+- uint32_t id;
++ int id;
+ #endif
+
+ ctxp = cmdwqe->context2;
+@@ -814,16 +814,14 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
+ rsp->done(rsp);
+ }
+ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+- if (phba->cpucheck_on & LPFC_CHECK_NVMET_IO) {
++ if (phba->hdwqstat_on & LPFC_CHECK_NVMET_IO) {
+ id = raw_smp_processor_id();
+- if (id < LPFC_CHECK_CPU_CNT) {
+- if (ctxp->cpu != id)
+- lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
+- "6704 CPU Check cmdcmpl: "
+- "cpu %d expect %d\n",
+- id, ctxp->cpu);
+- phba->sli4_hba.hdwq[rsp->hwqid].cpucheck_cmpl_io[id]++;
+- }
++ this_cpu_inc(phba->sli4_hba.c_stat->cmpl_io);
++ if (ctxp->cpu != id)
++ lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
++ "6704 CPU Check cmdcmpl: "
++ "cpu %d expect %d\n",
++ id, ctxp->cpu);
+ }
+ #endif
+ }
+@@ -931,6 +929,9 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
+ struct lpfc_sli_ring *pring;
+ unsigned long iflags;
+ int rc;
++#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
++ int id;
++#endif
+
+ if (phba->pport->load_flag & FC_UNLOADING) {
+ rc = -ENODEV;
+@@ -954,16 +955,14 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport,
+ if (!ctxp->hdwq)
+ ctxp->hdwq = &phba->sli4_hba.hdwq[rsp->hwqid];
+
+- if (phba->cpucheck_on & LPFC_CHECK_NVMET_IO) {
+- int id = raw_smp_processor_id();
+- if (id < LPFC_CHECK_CPU_CNT) {
+- if (rsp->hwqid != id)
+- lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
+- "6705 CPU Check OP: "
+- "cpu %d expect %d\n",
+- id, rsp->hwqid);
+- phba->sli4_hba.hdwq[rsp->hwqid].cpucheck_xmt_io[id]++;
+- }
++ if (phba->hdwqstat_on & LPFC_CHECK_NVMET_IO) {
++ id = raw_smp_processor_id();
++ this_cpu_inc(phba->sli4_hba.c_stat->xmt_io);
++ if (rsp->hwqid != id)
++ lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
++ "6705 CPU Check OP: "
++ "cpu %d expect %d\n",
++ id, rsp->hwqid);
+ ctxp->cpu = id; /* Setup cpu for cmpl check */
+ }
+ #endif
+@@ -2270,15 +2269,13 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
+ size = nvmebuf->bytes_recv;
+
+ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+- if (phba->cpucheck_on & LPFC_CHECK_NVMET_RCV) {
+- if (current_cpu < LPFC_CHECK_CPU_CNT) {
+- if (idx != current_cpu)
+- lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
+- "6703 CPU Check rcv: "
+- "cpu %d expect %d\n",
+- current_cpu, idx);
+- phba->sli4_hba.hdwq[idx].cpucheck_rcv_io[current_cpu]++;
+- }
++ if (phba->hdwqstat_on & LPFC_CHECK_NVMET_IO) {
++ this_cpu_inc(phba->sli4_hba.c_stat->rcv_io);
++ if (idx != current_cpu)
++ lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
++ "6703 CPU Check rcv: "
++ "cpu %d expect %d\n",
++ current_cpu, idx);
+ }
+ #endif
+
+diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
+index 96ac4a154c580..ed8bcbd043c45 100644
+--- a/drivers/scsi/lpfc/lpfc_scsi.c
++++ b/drivers/scsi/lpfc/lpfc_scsi.c
+@@ -3805,9 +3805,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
+ struct Scsi_Host *shost;
+ int idx;
+ uint32_t logit = LOG_FCP;
+-#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+- int cpu;
+-#endif
+
+ /* Guard against abort handler being called at same time */
+ spin_lock(&lpfc_cmd->buf_lock);
+@@ -3826,11 +3823,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
+ phba->sli4_hba.hdwq[idx].scsi_cstat.io_cmpls++;
+
+ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+- if (unlikely(phba->cpucheck_on & LPFC_CHECK_SCSI_IO)) {
+- cpu = raw_smp_processor_id();
+- if (cpu < LPFC_CHECK_CPU_CNT && phba->sli4_hba.hdwq)
+- phba->sli4_hba.hdwq[idx].cpucheck_cmpl_io[cpu]++;
+- }
++ if (unlikely(phba->hdwqstat_on & LPFC_CHECK_SCSI_IO))
++ this_cpu_inc(phba->sli4_hba.c_stat->cmpl_io);
+ #endif
+ shost = cmd->device->host;
+
+@@ -4503,9 +4497,6 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
+ struct lpfc_io_buf *lpfc_cmd;
+ struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+ int err, idx;
+-#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+- int cpu;
+-#endif
+
+ rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
+
+@@ -4626,14 +4617,8 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
+ lpfc_scsi_prep_cmnd(vport, lpfc_cmd, ndlp);
+
+ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+- if (unlikely(phba->cpucheck_on & LPFC_CHECK_SCSI_IO)) {
+- cpu = raw_smp_processor_id();
+- if (cpu < LPFC_CHECK_CPU_CNT) {
+- struct lpfc_sli4_hdw_queue *hdwq =
+- &phba->sli4_hba.hdwq[lpfc_cmd->hdwq_no];
+- hdwq->cpucheck_xmt_io[cpu]++;
+- }
+- }
++ if (unlikely(phba->hdwqstat_on & LPFC_CHECK_SCSI_IO))
++ this_cpu_inc(phba->sli4_hba.c_stat->xmt_io);
+ #endif
+ err = lpfc_sli_issue_iocb(phba, LPFC_FCP_RING,
+ &lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB);
+diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
+index d963ca8713833..8da7429e385a5 100644
+--- a/drivers/scsi/lpfc/lpfc_sli4.h
++++ b/drivers/scsi/lpfc/lpfc_sli4.h
+@@ -697,13 +697,6 @@ struct lpfc_sli4_hdw_queue {
+ struct lpfc_lock_stat lock_conflict;
+ #endif
+
+-#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+-#define LPFC_CHECK_CPU_CNT 128
+- uint32_t cpucheck_rcv_io[LPFC_CHECK_CPU_CNT];
+- uint32_t cpucheck_xmt_io[LPFC_CHECK_CPU_CNT];
+- uint32_t cpucheck_cmpl_io[LPFC_CHECK_CPU_CNT];
+-#endif
+-
+ /* Per HDWQ pool resources */
+ struct list_head sgl_list;
+ struct list_head cmd_rsp_buf_list;
+@@ -740,6 +733,15 @@ struct lpfc_sli4_hdw_queue {
+ #define lpfc_qp_spin_lock(lock, qp, lstat) spin_lock(lock)
+ #endif
+
++#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
++struct lpfc_hdwq_stat {
++ u32 hdwq_no;
++ u32 rcv_io;
++ u32 xmt_io;
++ u32 cmpl_io;
++};
++#endif
++
+ struct lpfc_sli4_hba {
+ void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for
+ * config space registers
+@@ -921,6 +923,9 @@ struct lpfc_sli4_hba {
+ struct cpumask numa_mask;
+ uint16_t curr_disp_cpu;
+ struct lpfc_eq_intr_info __percpu *eq_info;
++#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
++ struct lpfc_hdwq_stat __percpu *c_stat;
++#endif
+ uint32_t conf_trunk;
+ #define lpfc_conf_trunk_port0_WORD conf_trunk
+ #define lpfc_conf_trunk_port0_SHIFT 0
+--
+2.20.1
+
--- /dev/null
+From 2559a60ae4ac802db6edee41bbcd89f032f9f108 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Mar 2020 11:12:53 -0700
+Subject: scsi: lpfc: Fix kasan slab-out-of-bounds error in lpfc_unreg_login
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit 38503943c89f0bafd9e3742f63f872301d44cbea ]
+
+The following kasan bug was called out:
+
+ BUG: KASAN: slab-out-of-bounds in lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ Read of size 2 at addr ffff889fc7c50a22 by task lpfc_worker_3/6676
+ ...
+ Call Trace:
+ dump_stack+0x96/0xe0
+ ? lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ print_address_description.constprop.6+0x1b/0x220
+ ? lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ ? lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ __kasan_report.cold.9+0x37/0x7c
+ ? lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ kasan_report+0xe/0x20
+ lpfc_unreg_login+0x7c/0xc0 [lpfc]
+ lpfc_sli_def_mbox_cmpl+0x334/0x430 [lpfc]
+ ...
+
+When processing the completion of a "Reg Rpi" login mailbox command in
+lpfc_sli_def_mbox_cmpl, a call may be made to lpfc_unreg_login. The vpi is
+extracted from the completing mailbox context and passed as an input for
+the next. However, the vpi stored in the mailbox command context is an
+absolute vpi, which for SLI4 represents both base + offset. When used with
+a non-zero base component, (function id > 0) this results in an
+out-of-range access beyond the allocated phba->vpi_ids array.
+
+Fix by subtracting the function's base value to get an accurate vpi number.
+
+Link: https://lore.kernel.org/r/20200322181304.37655-2-jsmart2021@gmail.com
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_sli.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 64002b0cb02d4..5939ea0e3b1eb 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -2511,6 +2511,8 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+ !pmb->u.mb.mbxStatus) {
+ rpi = pmb->u.mb.un.varWords[0];
+ vpi = pmb->u.mb.un.varRegLogin.vpi;
++ if (phba->sli_rev == LPFC_SLI_REV4)
++ vpi -= phba->sli4_hba.max_cfg_param.vpi_base;
+ lpfc_unreg_login(phba, vpi, rpi, pmb);
+ pmb->vport = vport;
+ pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+--
+2.20.1
+
--- /dev/null
+From e02336a04710dd04cf3f8b09cea66659b2a5569d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Mar 2020 11:12:54 -0700
+Subject: scsi: lpfc: Fix lockdep error - register non-static key
+
+From: James Smart <jsmart2021@gmail.com>
+
+[ Upstream commit f861f596714bed06069f1109b89e51f3855c4ddf ]
+
+The following lockdep error was reported when unloading the lpfc driver:
+
+ INFO: trying to register non-static key.
+ the code is fine but needs lockdep annotation.
+ turning off the locking correctness validator.
+ ...
+ Call Trace:
+ dump_stack+0x96/0xe0
+ register_lock_class+0x8b8/0x8c0
+ ? lockdep_hardirqs_on+0x190/0x280
+ ? is_dynamic_key+0x150/0x150
+ ? wait_for_completion_interruptible+0x2a0/0x2a0
+ ? wake_up_q+0xd0/0xd0
+ __lock_acquire+0xda/0x21a0
+ ? register_lock_class+0x8c0/0x8c0
+ ? synchronize_rcu_expedited+0x500/0x500
+ ? __call_rcu+0x850/0x850
+ lock_acquire+0xf3/0x1f0
+ ? del_timer_sync+0x5/0xb0
+ del_timer_sync+0x3c/0xb0
+ ? del_timer_sync+0x5/0xb0
+ lpfc_pci_remove_one.cold.102+0x8b7/0x935 [lpfc]
+ ...
+
+Unloading the driver resulted in a call to del_timer_sync for the
+cpuhp_poll_timer. However the call to setup the timer had never been made,
+so the timer structures used by lockdep checking were not initialized.
+
+Unconditionally call setup_timer for the cpuhp_poll_timer during driver
+initialization. Calls to start the timer remain "as needed".
+
+Link: https://lore.kernel.org/r/20200322181304.37655-3-jsmart2021@gmail.com
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_init.c | 5 ++---
+ drivers/scsi/lpfc/lpfc_sli.c | 6 ++----
+ 2 files changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index d2bbcf8cae4c3..48fde2b1ebbab 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -11203,11 +11203,9 @@ static void lpfc_cpuhp_add(struct lpfc_hba *phba)
+
+ rcu_read_lock();
+
+- if (!list_empty(&phba->poll_list)) {
+- timer_setup(&phba->cpuhp_poll_timer, lpfc_sli4_poll_hbtimer, 0);
++ if (!list_empty(&phba->poll_list))
+ mod_timer(&phba->cpuhp_poll_timer,
+ jiffies + msecs_to_jiffies(LPFC_POLL_HB));
+- }
+
+ rcu_read_unlock();
+
+@@ -13173,6 +13171,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
+ lpfc_sli4_ras_setup(phba);
+
+ INIT_LIST_HEAD(&phba->poll_list);
++ timer_setup(&phba->cpuhp_poll_timer, lpfc_sli4_poll_hbtimer, 0);
+ cpuhp_state_add_instance_nocalls(lpfc_cpuhp_state, &phba->cpuhp);
+
+ return 0;
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index de97727458fc7..396e24764a1b1 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -14457,12 +14457,10 @@ static inline void lpfc_sli4_add_to_poll_list(struct lpfc_queue *eq)
+ {
+ struct lpfc_hba *phba = eq->phba;
+
+- if (list_empty(&phba->poll_list)) {
+- timer_setup(&phba->cpuhp_poll_timer, lpfc_sli4_poll_hbtimer, 0);
+- /* kickstart slowpath processing for this eq */
++ /* kickstart slowpath processing if needed */
++ if (list_empty(&phba->poll_list))
+ mod_timer(&phba->cpuhp_poll_timer,
+ jiffies + msecs_to_jiffies(LPFC_POLL_HB));
+- }
+
+ list_add_rcu(&eq->_poll_list, &phba->poll_list);
+ synchronize_rcu();
+--
+2.20.1
+
--- /dev/null
+From 961b9ae5cce2cfe2b04745e14947d790bbc547c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Apr 2020 14:33:53 -0700
+Subject: selftests: kmod: fix handling test numbers above 9
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 6d573a07528308eb77ec072c010819c359bebf6e ]
+
+get_test_count() and get_test_enabled() were broken for test numbers
+above 9 due to awk interpreting a field specification like '$0010' as
+octal rather than decimal. Fix it by stripping the leading zeroes.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Acked-by: Luis Chamberlain <mcgrof@kernel.org>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Jeff Vander Stoep <jeffv@google.com>
+Cc: Jessica Yu <jeyu@kernel.org>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: NeilBrown <neilb@suse.com>
+Link: http://lkml.kernel.org/r/20200318230515.171692-5-ebiggers@kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kmod/kmod.sh | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/selftests/kmod/kmod.sh b/tools/testing/selftests/kmod/kmod.sh
+index 8b944cf042f6c..315a43111e046 100755
+--- a/tools/testing/selftests/kmod/kmod.sh
++++ b/tools/testing/selftests/kmod/kmod.sh
+@@ -505,18 +505,23 @@ function test_num()
+ fi
+ }
+
+-function get_test_count()
++function get_test_data()
+ {
+ test_num $1
+- TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
++ local field_num=$(echo $1 | sed 's/^0*//')
++ echo $ALL_TESTS | awk '{print $'$field_num'}'
++}
++
++function get_test_count()
++{
++ TEST_DATA=$(get_test_data $1)
+ LAST_TWO=${TEST_DATA#*:*}
+ echo ${LAST_TWO%:*}
+ }
+
+ function get_test_enabled()
+ {
+- test_num $1
+- TEST_DATA=$(echo $ALL_TESTS | awk '{print $'$1'}')
++ TEST_DATA=$(get_test_data $1)
+ echo ${TEST_DATA#*:*:}
+ }
+
+--
+2.20.1
+
mm-check-that-mm-is-still-valid-in-madvise.patch
+tools-testing-nvdimm-fix-compilation-failure-without.patch
+watchdog-reset-last_hw_keepalive-time-at-start.patch
+scsi-lpfc-fix-kasan-slab-out-of-bounds-error-in-lpfc.patch
+xfs-correctly-acount-for-reclaimable-slabs.patch
+scsi-lpfc-fix-crash-after-handling-a-pci-error.patch
+scsi-lpfc-fix-crash-in-target-side-cable-pulls-hitti.patch
+scsi-libfc-if-prli-rejected-move-rport-to-plogi-stat.patch
+ceph-return-ceph_mdsc_do_request-errors-from-__get_p.patch
+ceph-don-t-skip-updating-wanted-caps-when-cap-is-sta.patch
+pwm-imx27-fix-clock-handling-in-pwm_imx27_apply.patch
+pwm-rcar-fix-late-runtime-pm-enablement.patch
+nvme-tcp-fix-possible-crash-in-write_zeroes-processi.patch
+asoc-qcom-q6asm-dai-add-sndrv_pcm_info_batch-flag.patch
+scsi-iscsi-report-unbind-session-event-when-the-targ.patch
+tools-test-nvdimm-fix-out-of-tree-build.patch
+asoc-intel-atom-take-the-drv-lock-mutex-before-calli.patch
+nvme-fix-deadlock-caused-by-ana-update-wrong-locking.patch
+drm-amd-display-update-stream-adjust-in-dc_stream_ad.patch
+dma-direct-fix-data-truncation-in-dma_direct_get_req.patch
+kernel-gcov-fs.c-gcov_seq_next-should-increase-posit.patch
+selftests-kmod-fix-handling-test-numbers-above-9.patch
+ipc-util.c-sysvipc_find_ipc-should-increase-position.patch
+kconfig-qconf-fix-a-few-alignment-issues.patch
+lib-raid6-test-fix-build-on-distros-whose-bin-sh-is-.patch
+block-fix-busy-device-checking-in-blk_drop_partition.patch
+s390-cio-generate-delayed-uevent-for-vfio-ccw-subcha.patch
+s390-cio-avoid-duplicated-add-uevents.patch
+loop-better-discard-support-for-block-devices.patch
+revert-powerpc-64-irq_work-avoid-interrupt-when-call.patch
+powerpc-pseries-fix-mce-handling-on-pseries.patch
+nvme-fix-compat-address-handling-in-several-ioctls.patch
+pwm-renesas-tpu-fix-late-runtime-pm-enablement.patch
+pwm-bcm2835-dynamically-allocate-base.patch
+scsi-lpfc-fix-erroneous-cpu-limit-of-128-on-i-o-stat.patch
+scsi-lpfc-fix-lockdep-error-register-non-static-key.patch
+perf-core-disable-page-faults-when-getting-phys-addr.patch
+drm-amd-display-calculate-scaling-ratios-on-every-me.patch
+asoc-intel-bytcr_rt5640-add-quirk-for-mpman-mpwin895.patch
+alsa-usb-audio-add-pioneer-dj-djm-250mk2-quirk.patch
+xhci-ensure-link-state-is-u3-after-setting-usb_ss_po.patch
+xhci-wait-until-link-state-trainsits-to-u0-after-set.patch
+xhci-finetune-host-initiated-usb3-rootport-link-susp.patch
+block-fix-busy-device-checking-in-blk_drop_partition.patch-8691
--- /dev/null
+From 0fbb51faf1edb9f6e3741a97ebd3939404ee1b98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jan 2020 11:10:51 +0530
+Subject: tools/test/nvdimm: Fix out of tree build
+
+From: Santosh Sivaraj <santosh@fossix.org>
+
+[ Upstream commit 1f776799628139d0da47e710ad86eb58d987ff66 ]
+
+Out of tree build using
+
+ make M=tools/test/nvdimm O=/tmp/build -C /tmp/build
+
+fails with the following error
+
+make: Entering directory '/tmp/build'
+ CC [M] tools/testing/nvdimm/test/nfit.o
+linux/tools/testing/nvdimm/test/nfit.c:19:10: fatal error: nd-core.h: No such file or directory
+ 19 | #include <nd-core.h>
+ | ^~~~~~~~~~~
+compilation terminated.
+
+That is because the kbuild file uses $(src) which points to
+tools/testing/nvdimm, $(srctree) correctly points to root of the linux
+source tree.
+
+Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Santosh Sivaraj <santosh@fossix.org>
+Link: https://lore.kernel.org/r/20200114054051.4115790-1-santosh@fossix.org
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/nvdimm/Kbuild | 4 ++--
+ tools/testing/nvdimm/test/Kbuild | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
+index dbebf05f59313..47f9cc9dcd94b 100644
+--- a/tools/testing/nvdimm/Kbuild
++++ b/tools/testing/nvdimm/Kbuild
+@@ -21,8 +21,8 @@ DRIVERS := ../../../drivers
+ NVDIMM_SRC := $(DRIVERS)/nvdimm
+ ACPI_SRC := $(DRIVERS)/acpi/nfit
+ DAX_SRC := $(DRIVERS)/dax
+-ccflags-y := -I$(src)/$(NVDIMM_SRC)/
+-ccflags-y += -I$(src)/$(ACPI_SRC)/
++ccflags-y := -I$(srctree)/drivers/nvdimm/
++ccflags-y += -I$(srctree)/drivers/acpi/nfit/
+
+ obj-$(CONFIG_LIBNVDIMM) += libnvdimm.o
+ obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o
+diff --git a/tools/testing/nvdimm/test/Kbuild b/tools/testing/nvdimm/test/Kbuild
+index fb3c3d7cdb9bd..75baebf8f4ba1 100644
+--- a/tools/testing/nvdimm/test/Kbuild
++++ b/tools/testing/nvdimm/test/Kbuild
+@@ -1,6 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+-ccflags-y := -I$(src)/../../../../drivers/nvdimm/
+-ccflags-y += -I$(src)/../../../../drivers/acpi/nfit/
++ccflags-y := -I$(srctree)/drivers/nvdimm/
++ccflags-y += -I$(srctree)/drivers/acpi/nfit/
+
+ obj-m += nfit_test.o
+ obj-m += nfit_test_iomap.o
+--
+2.20.1
+
--- /dev/null
+From a045b3489cf61076431ee4d7d7829bcc604421c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2020 16:47:20 +0100
+Subject: tools/testing/nvdimm: Fix compilation failure without
+ CONFIG_DEV_DAX_PMEM_COMPAT
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit c0e71d602053e4e7637e4bc7d0bc9603ea77a33f ]
+
+When a kernel is configured without CONFIG_DEV_DAX_PMEM_COMPAT, the
+compilation of tools/testing/nvdimm fails with:
+
+ Building modules, stage 2.
+ MODPOST 11 modules
+ERROR: "dax_pmem_compat_test" [tools/testing/nvdimm/test/nfit_test.ko] undefined!
+
+Fix the problem by calling dax_pmem_compat_test() only if the kernel has
+the required functionality.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20200123154720.12097-1-jack@suse.cz
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/nvdimm/test/nfit.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
+index bf6422a6af7ff..a8ee5c4d41ebb 100644
+--- a/tools/testing/nvdimm/test/nfit.c
++++ b/tools/testing/nvdimm/test/nfit.c
+@@ -3164,7 +3164,9 @@ static __init int nfit_test_init(void)
+ mcsafe_test();
+ dax_pmem_test();
+ dax_pmem_core_test();
++#ifdef CONFIG_DEV_DAX_PMEM_COMPAT
+ dax_pmem_compat_test();
++#endif
+
+ nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm);
+
+--
+2.20.1
+
--- /dev/null
+From 43902927be3ed1f681ce2d460e4802aa2cc619c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Mar 2020 11:58:06 +0200
+Subject: watchdog: reset last_hw_keepalive time at start
+
+From: Tero Kristo <t-kristo@ti.com>
+
+[ Upstream commit 982bb70517aef2225bad1d802887b733db492cc0 ]
+
+Currently the watchdog core does not initialize the last_hw_keepalive
+time during watchdog startup. This will cause the watchdog to be pinged
+immediately if enough time has passed from the system boot-up time, and
+some types of watchdogs like K3 RTI does not like this.
+
+To avoid the issue, setup the last_hw_keepalive time during watchdog
+startup.
+
+Signed-off-by: Tero Kristo <t-kristo@ti.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20200302200426.6492-3-t-kristo@ti.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/watchdog_dev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
+index 8b5c742f24e81..7e4cd34a8c20e 100644
+--- a/drivers/watchdog/watchdog_dev.c
++++ b/drivers/watchdog/watchdog_dev.c
+@@ -282,6 +282,7 @@ static int watchdog_start(struct watchdog_device *wdd)
+ if (err == 0) {
+ set_bit(WDOG_ACTIVE, &wdd->status);
+ wd_data->last_keepalive = started_at;
++ wd_data->last_hw_keepalive = started_at;
+ watchdog_update_worker(wdd);
+ }
+
+--
+2.20.1
+
--- /dev/null
+From dd265d9c4b69a2025a7e6407232b398f8797f239 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Mar 2020 20:10:28 -0700
+Subject: xfs: correctly acount for reclaimable slabs
+
+From: Dave Chinner <dchinner@redhat.com>
+
+[ Upstream commit d59eadaea2b9945095d4d6d44367ebabd604395c ]
+
+The XFS inode item slab actually reclaimed by inode shrinker
+callbacks from the memory reclaim subsystem. These should be marked
+as reclaimable so the mm subsystem has the full picture of how much
+memory it can actually reclaim from the XFS slab caches.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Allison Collins <allison.henderson@oracle.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/xfs_super.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
+index 2094386af8aca..68fea439d9743 100644
+--- a/fs/xfs/xfs_super.c
++++ b/fs/xfs/xfs_super.c
+@@ -1861,7 +1861,8 @@ xfs_init_zones(void)
+
+ xfs_ili_zone = kmem_cache_create("xfs_ili",
+ sizeof(struct xfs_inode_log_item), 0,
+- SLAB_MEM_SPREAD, NULL);
++ SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
++ NULL);
+ if (!xfs_ili_zone)
+ goto out_destroy_inode_zone;
+
+--
+2.20.1
+
--- /dev/null
+From 54f07a7f0d848371459fde95e050f855285b7914 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Mar 2020 16:45:14 +0200
+Subject: xhci: Ensure link state is U3 after setting USB_SS_PORT_LS_U3
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+[ Upstream commit eb002726fac7cefb98ff39ddb89e150a1c24fe85 ]
+
+The xHCI spec doesn't specify the upper bound of U3 transition time. For
+some devices 20ms is not enough, so we need to make sure the link state
+is in U3 before further actions.
+
+I've tried to use U3 Entry Capability by setting U3 Entry Enable in
+config register, however the port change event for U3 transition
+interrupts the system suspend process.
+
+For now let's use the less ideal method by polling PLS.
+
+[use usleep_range(), and shorten the delay time while polling -Mathias]
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200312144517.1593-7-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-hub.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
+index af92b2576fe91..712cd44f05ace 100644
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -1322,7 +1322,16 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ xhci_set_link_state(xhci, ports[wIndex], link_state);
+
+ spin_unlock_irqrestore(&xhci->lock, flags);
+- msleep(20); /* wait device to enter */
++ if (link_state == USB_SS_PORT_LS_U3) {
++ int retries = 16;
++
++ while (retries--) {
++ usleep_range(4000, 8000);
++ temp = readl(ports[wIndex]->addr);
++ if ((temp & PORT_PLS_MASK) == XDEV_U3)
++ break;
++ }
++ }
+ spin_lock_irqsave(&xhci->lock, flags);
+
+ temp = readl(ports[wIndex]->addr);
+--
+2.20.1
+
--- /dev/null
+From 027f47e90ada8f9ab12a03fd9393a8126e05b24c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Mar 2020 16:45:16 +0200
+Subject: xhci: Finetune host initiated USB3 rootport link suspend and resume
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit ceca49382ac20e06ce04c21279c7f2868c4ec1d4 ]
+
+Depending on the current link state the steps to resume the link to U0
+varies. The normal case when a port is suspended (U3) we set the link
+to U0 and wait for a port event when U3exit completed and port moved to
+U0.
+
+If the port is in U1/U2, then no event is issued, just set link to U0
+
+If port is in Resume or Recovery state then the device has already
+initiated resume, and this host initiated resume is racing against it.
+Port event handler for device initiated resume will set link to U0,
+just wait for the port to reach U0 before returning.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200312144517.1593-9-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-hub.c | 36 +++++++++++++++++++++++++-----------
+ 1 file changed, 25 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
+index 02f52d4f74df8..a9c87eb8951e8 100644
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -1307,20 +1307,34 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ goto error;
+ }
+
++ /*
++ * set link to U0, steps depend on current link state.
++ * U3: set link to U0 and wait for u3exit completion.
++ * U1/U2: no PLC complete event, only set link to U0.
++ * Resume/Recovery: device initiated U0, only wait for
++ * completion
++ */
+ if (link_state == USB_SS_PORT_LS_U0) {
+- if ((temp & PORT_PLS_MASK) == XDEV_U0)
+- break;
++ u32 pls = temp & PORT_PLS_MASK;
++ bool wait_u0 = false;
+
+- if (!((temp & PORT_PLS_MASK) == XDEV_U1 ||
+- (temp & PORT_PLS_MASK) == XDEV_U2 ||
+- (temp & PORT_PLS_MASK) == XDEV_U3)) {
+- xhci_warn(xhci, "Can only set port %d to U0 from U state\n",
+- wIndex);
+- goto error;
++ /* already in U0 */
++ if (pls == XDEV_U0)
++ break;
++ if (pls == XDEV_U3 ||
++ pls == XDEV_RESUME ||
++ pls == XDEV_RECOVERY) {
++ wait_u0 = true;
++ reinit_completion(&bus_state->u3exit_done[wIndex]);
++ }
++ if (pls <= XDEV_U3) /* U1, U2, U3 */
++ xhci_set_link_state(xhci, ports[wIndex],
++ USB_SS_PORT_LS_U0);
++ if (!wait_u0) {
++ if (pls > XDEV_U3)
++ goto error;
++ break;
+ }
+- reinit_completion(&bus_state->u3exit_done[wIndex]);
+- xhci_set_link_state(xhci, ports[wIndex],
+- USB_SS_PORT_LS_U0);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ if (!wait_for_completion_timeout(&bus_state->u3exit_done[wIndex],
+ msecs_to_jiffies(100)))
+--
+2.20.1
+
--- /dev/null
+From b5fd5783e6c8618bac5fca82f25f529b67360a1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Mar 2020 16:45:15 +0200
+Subject: xhci: Wait until link state trainsits to U0 after setting
+ USB_SS_PORT_LS_U0
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+[ Upstream commit 0200b9f790b0fc9e9a42f685f5ad54b23fe959f4 ]
+
+Like U3 case, xHCI spec doesn't specify the upper bound of U0 transition
+time. The 20ms is not enough for some devices.
+
+Intead of polling PLS or PLC, we can facilitate the port change event to
+know that the link transits to U0 is completed.
+
+While at it, also separate U0 and U3 case to make the code cleaner.
+
+[variable rename to u3exit, and skip completion for usb2 ports -Mathias ]
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200312144517.1593-8-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-hub.c | 44 +++++++++++++++++++++++++-----------
+ drivers/usb/host/xhci-mem.c | 1 +
+ drivers/usb/host/xhci-ring.c | 1 +
+ drivers/usb/host/xhci.h | 1 +
+ 4 files changed, 34 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
+index 712cd44f05ace..02f52d4f74df8 100644
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -1306,7 +1306,33 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ wIndex, link_state);
+ goto error;
+ }
++
++ if (link_state == USB_SS_PORT_LS_U0) {
++ if ((temp & PORT_PLS_MASK) == XDEV_U0)
++ break;
++
++ if (!((temp & PORT_PLS_MASK) == XDEV_U1 ||
++ (temp & PORT_PLS_MASK) == XDEV_U2 ||
++ (temp & PORT_PLS_MASK) == XDEV_U3)) {
++ xhci_warn(xhci, "Can only set port %d to U0 from U state\n",
++ wIndex);
++ goto error;
++ }
++ reinit_completion(&bus_state->u3exit_done[wIndex]);
++ xhci_set_link_state(xhci, ports[wIndex],
++ USB_SS_PORT_LS_U0);
++ spin_unlock_irqrestore(&xhci->lock, flags);
++ if (!wait_for_completion_timeout(&bus_state->u3exit_done[wIndex],
++ msecs_to_jiffies(100)))
++ xhci_dbg(xhci, "missing U0 port change event for port %d\n",
++ wIndex);
++ spin_lock_irqsave(&xhci->lock, flags);
++ temp = readl(ports[wIndex]->addr);
++ break;
++ }
++
+ if (link_state == USB_SS_PORT_LS_U3) {
++ int retries = 16;
+ slot_id = xhci_find_slot_id_by_port(hcd, xhci,
+ wIndex + 1);
+ if (slot_id) {
+@@ -1317,26 +1343,18 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ xhci_stop_device(xhci, slot_id, 1);
+ spin_lock_irqsave(&xhci->lock, flags);
+ }
+- }
+-
+- xhci_set_link_state(xhci, ports[wIndex], link_state);
+-
+- spin_unlock_irqrestore(&xhci->lock, flags);
+- if (link_state == USB_SS_PORT_LS_U3) {
+- int retries = 16;
+-
++ xhci_set_link_state(xhci, ports[wIndex], USB_SS_PORT_LS_U3);
++ spin_unlock_irqrestore(&xhci->lock, flags);
+ while (retries--) {
+ usleep_range(4000, 8000);
+ temp = readl(ports[wIndex]->addr);
+ if ((temp & PORT_PLS_MASK) == XDEV_U3)
+ break;
+ }
+- }
+- spin_lock_irqsave(&xhci->lock, flags);
+-
+- temp = readl(ports[wIndex]->addr);
+- if (link_state == USB_SS_PORT_LS_U3)
++ spin_lock_irqsave(&xhci->lock, flags);
++ temp = readl(ports[wIndex]->addr);
+ bus_state->suspended_ports |= 1 << wIndex;
++ }
+ break;
+ case USB_PORT_FEAT_POWER:
+ /*
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 884c601bfa15f..9764122c9cdf2 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2552,6 +2552,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
+ xhci->usb3_rhub.bus_state.resume_done[i] = 0;
+ /* Only the USB 2.0 completions will ever be used. */
+ init_completion(&xhci->usb2_rhub.bus_state.rexit_done[i]);
++ init_completion(&xhci->usb3_rhub.bus_state.u3exit_done[i]);
+ }
+
+ if (scratchpad_alloc(xhci, flags))
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index d23f7408c81f1..c1e63af88356c 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1677,6 +1677,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
+ (portsc & PORT_PLS_MASK) == XDEV_U1 ||
+ (portsc & PORT_PLS_MASK) == XDEV_U2)) {
+ xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
++ complete(&bus_state->u3exit_done[hcd_portnum]);
+ /* We've just brought the device into U0/1/2 through either the
+ * Resume state after a device remote wakeup, or through the
+ * U3Exit state after a host-initiated resume. If it's a device
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 3ecee10fdcdc7..fb1ab63b5fe25 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1694,6 +1694,7 @@ struct xhci_bus_state {
+ /* Which ports are waiting on RExit to U0 transition. */
+ unsigned long rexit_ports;
+ struct completion rexit_done[USB_MAXCHILDREN];
++ struct completion u3exit_done[USB_MAXCHILDREN];
+ };
+
+
+--
+2.20.1
+