From: Sasha Levin Date: Wed, 21 Jun 2023 16:39:41 +0000 (-0400) Subject: Fixes for 6.3 X-Git-Tag: v4.14.320~84 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4b0fc6c80894832e6f9cb08b5c7d018cf49eac44;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.3 Signed-off-by: Sasha Levin --- diff --git a/queue-6.3/ata-libata-scsi-avoid-deadlock-on-rescan-after-devic.patch b/queue-6.3/ata-libata-scsi-avoid-deadlock-on-rescan-after-devic.patch new file mode 100644 index 00000000000..45ede86609b --- /dev/null +++ b/queue-6.3/ata-libata-scsi-avoid-deadlock-on-rescan-after-devic.patch @@ -0,0 +1,143 @@ +From 4401b0474f49e3fa6e9911938136f7b5c26e1cab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Jun 2023 17:18:53 +0900 +Subject: ata: libata-scsi: Avoid deadlock on rescan after device resume + +From: Damien Le Moal + +[ Upstream commit 6aa0365a3c8512587fffd42fe438768709ddef8e ] + +When an ATA port is resumed from sleep, the port is reset and a power +management request issued to libata EH to reset the port and rescanning +the device(s) attached to the port. Device rescanning is done by +scheduling an ata_scsi_dev_rescan() work, which will execute +scsi_rescan_device(). + +However, scsi_rescan_device() takes the generic device lock, which is +also taken by dpm_resume() when the SCSI device is resumed as well. If +a device rescan execution starts before the completion of the SCSI +device resume, the rcu locking used to refresh the cached VPD pages of +the device, combined with the generic device locking from +scsi_rescan_device() and from dpm_resume() can cause a deadlock. + +Avoid this situation by changing struct ata_port scsi_rescan_task to be +a delayed work instead of a simple work_struct. ata_scsi_dev_rescan() is +modified to check if the SCSI device associated with the ATA device that +must be rescanned is not suspended. If the SCSI device is still +suspended, ata_scsi_dev_rescan() returns early and reschedule itself for +execution after an arbitrary delay of 5ms. + +Reported-by: Kai-Heng Feng +Reported-by: Joe Breuer +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217530 +Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management") +Signed-off-by: Damien Le Moal +Reviewed-by: Hannes Reinecke +Tested-by: Kai-Heng Feng +Tested-by: Joe Breuer +Signed-off-by: Sasha Levin +--- + drivers/ata/libata-core.c | 3 ++- + drivers/ata/libata-eh.c | 2 +- + drivers/ata/libata-scsi.c | 22 +++++++++++++++++++++- + include/linux/libata.h | 2 +- + 4 files changed, 25 insertions(+), 4 deletions(-) + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 14c17c3bda4e6..d37df499c9fa6 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -5348,7 +5348,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) + + mutex_init(&ap->scsi_scan_mutex); + INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); +- INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); ++ INIT_DELAYED_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); + INIT_LIST_HEAD(&ap->eh_done_q); + init_waitqueue_head(&ap->eh_wait_q); + init_completion(&ap->park_req_pending); +@@ -5954,6 +5954,7 @@ static void ata_port_detach(struct ata_port *ap) + WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED)); + + cancel_delayed_work_sync(&ap->hotplug_task); ++ cancel_delayed_work_sync(&ap->scsi_rescan_task); + + skip_eh: + /* clean up zpodd on port removal */ +diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c +index a6c9018118027..6f8d141915939 100644 +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2984,7 +2984,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, + ehc->i.flags |= ATA_EHI_SETMODE; + + /* schedule the scsi_rescan_device() here */ +- schedule_work(&(ap->scsi_rescan_task)); ++ schedule_delayed_work(&ap->scsi_rescan_task, 0); + } else if (dev->class == ATA_DEV_UNKNOWN && + ehc->tries[dev->devno] && + ata_class_enabled(ehc->classes[dev->devno])) { +diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c +index a9e768fdae4e3..51673d95e5b22 100644 +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -4597,10 +4597,11 @@ int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, + void ata_scsi_dev_rescan(struct work_struct *work) + { + struct ata_port *ap = +- container_of(work, struct ata_port, scsi_rescan_task); ++ container_of(work, struct ata_port, scsi_rescan_task.work); + struct ata_link *link; + struct ata_device *dev; + unsigned long flags; ++ bool delay_rescan = false; + + mutex_lock(&ap->scsi_scan_mutex); + spin_lock_irqsave(ap->lock, flags); +@@ -4614,6 +4615,21 @@ void ata_scsi_dev_rescan(struct work_struct *work) + if (scsi_device_get(sdev)) + continue; + ++ /* ++ * If the rescan work was scheduled because of a resume ++ * event, the port is already fully resumed, but the ++ * SCSI device may not yet be fully resumed. In such ++ * case, executing scsi_rescan_device() may cause a ++ * deadlock with the PM code on device_lock(). Prevent ++ * this by giving up and retrying rescan after a short ++ * delay. ++ */ ++ delay_rescan = sdev->sdev_gendev.power.is_suspended; ++ if (delay_rescan) { ++ scsi_device_put(sdev); ++ break; ++ } ++ + spin_unlock_irqrestore(ap->lock, flags); + scsi_rescan_device(&(sdev->sdev_gendev)); + scsi_device_put(sdev); +@@ -4623,4 +4639,8 @@ void ata_scsi_dev_rescan(struct work_struct *work) + + spin_unlock_irqrestore(ap->lock, flags); + mutex_unlock(&ap->scsi_scan_mutex); ++ ++ if (delay_rescan) ++ schedule_delayed_work(&ap->scsi_rescan_task, ++ msecs_to_jiffies(5)); + } +diff --git a/include/linux/libata.h b/include/linux/libata.h +index a759dfbdcc91a..bb5dda3ec2db5 100644 +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -836,7 +836,7 @@ struct ata_port { + + struct mutex scsi_scan_mutex; + struct delayed_work hotplug_task; +- struct work_struct scsi_rescan_task; ++ struct delayed_work scsi_rescan_task; + + unsigned int hsm_task_state; + +-- +2.39.2 + diff --git a/queue-6.3/cifs-fix-status-checks-in-cifs_tree_connect.patch b/queue-6.3/cifs-fix-status-checks-in-cifs_tree_connect.patch new file mode 100644 index 00000000000..af151967c74 --- /dev/null +++ b/queue-6.3/cifs-fix-status-checks-in-cifs_tree_connect.patch @@ -0,0 +1,79 @@ +From 28a2d62a8ea32062f7b49c8bfa0b7842309065c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Jun 2023 17:46:54 +0000 +Subject: cifs: fix status checks in cifs_tree_connect + +From: Shyam Prasad N + +[ Upstream commit 91f4480c41f56f7c723323cf7f581f1d95d9ffbc ] + +The ordering of status checks at the beginning of +cifs_tree_connect is wrong. As a result, a tcon +which is good may stay marked as needing reconnect +infinitely. + +Fixes: 2f0e4f034220 ("cifs: check only tcon status on tcon related functions") +Cc: stable@vger.kernel.org # 6.3 +Signed-off-by: Shyam Prasad N +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/cifs/connect.c | 9 +++++---- + fs/cifs/dfs.c | 9 +++++---- + 2 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 8e9a672320ab7..1250d156619b7 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -4086,16 +4086,17 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru + + /* only send once per connect */ + spin_lock(&tcon->tc_lock); ++ if (tcon->status == TID_GOOD) { ++ spin_unlock(&tcon->tc_lock); ++ return 0; ++ } ++ + if (tcon->status != TID_NEW && + tcon->status != TID_NEED_TCON) { + spin_unlock(&tcon->tc_lock); + return -EHOSTDOWN; + } + +- if (tcon->status == TID_GOOD) { +- spin_unlock(&tcon->tc_lock); +- return 0; +- } + tcon->status = TID_IN_TCON; + spin_unlock(&tcon->tc_lock); + +diff --git a/fs/cifs/dfs.c b/fs/cifs/dfs.c +index 2f93bf8c3325a..2390b2fedd6a3 100644 +--- a/fs/cifs/dfs.c ++++ b/fs/cifs/dfs.c +@@ -575,16 +575,17 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru + + /* only send once per connect */ + spin_lock(&tcon->tc_lock); ++ if (tcon->status == TID_GOOD) { ++ spin_unlock(&tcon->tc_lock); ++ return 0; ++ } ++ + if (tcon->status != TID_NEW && + tcon->status != TID_NEED_TCON) { + spin_unlock(&tcon->tc_lock); + return -EHOSTDOWN; + } + +- if (tcon->status == TID_GOOD) { +- spin_unlock(&tcon->tc_lock); +- return 0; +- } + tcon->status = TID_IN_TCON; + spin_unlock(&tcon->tc_lock); + +-- +2.39.2 + diff --git a/queue-6.3/drm-amd-display-add-wrapper-to-call-planes-and-strea.patch b/queue-6.3/drm-amd-display-add-wrapper-to-call-planes-and-strea.patch new file mode 100644 index 00000000000..4d443958944 --- /dev/null +++ b/queue-6.3/drm-amd-display-add-wrapper-to-call-planes-and-strea.patch @@ -0,0 +1,107 @@ +From 11578320110dee01b03d87faeecfb4758ee97b6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Feb 2023 11:36:08 -0700 +Subject: drm/amd/display: Add wrapper to call planes and stream update + +From: Rodrigo Siqueira + +[ Upstream commit 81f743a08f3b214638aa389e252ae5e6c3592e7c ] + +[Why & How] +This commit is part of a sequence of changes that replaces the commit +sequence used in the DC with a new one. As a result of this transition, +we moved some specific parts from the commit sequence and brought them +to amdgpu_dm. This commit adds a wrapper inside DM that enable our +drivers to do any necessary preparation or change before we offload the +plane/stream update to DC. + +Reviewed-by: Harry Wentland +Acked-by: Qingqing Zhuo +Signed-off-by: Rodrigo Siqueira +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Stable-dep-of: ea2062dd1f03 ("drm/amd/display: fix the system hang while disable PSR") +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 51 +++++++++++++++---- + 1 file changed, 41 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index ae58f24be511c..51a3130f607e0 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -350,6 +350,35 @@ static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state, + return false; + } + ++/** ++ * update_planes_and_stream_adapter() - Send planes to be updated in DC ++ * ++ * DC has a generic way to update planes and stream via ++ * dc_update_planes_and_stream function; however, DM might need some ++ * adjustments and preparation before calling it. This function is a wrapper ++ * for the dc_update_planes_and_stream that does any required configuration ++ * before passing control to DC. ++ */ ++static inline bool update_planes_and_stream_adapter(struct dc *dc, ++ int update_type, ++ int planes_count, ++ struct dc_stream_state *stream, ++ struct dc_stream_update *stream_update, ++ struct dc_surface_update *array_of_surface_update) ++{ ++ /* ++ * Previous frame finished and HW is ready for optimization. ++ */ ++ if (update_type == UPDATE_TYPE_FAST) ++ dc_post_update_surfaces_to_stream(dc); ++ ++ return dc_update_planes_and_stream(dc, ++ array_of_surface_update, ++ planes_count, ++ stream, ++ stream_update); ++} ++ + /** + * dm_pflip_high_irq() - Handle pageflip interrupt + * @interrupt_params: ignored +@@ -2684,11 +2713,12 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, + true; + } + +- dc_update_planes_and_stream(dm->dc, +- bundle->surface_updates, +- dc_state->stream_status->plane_count, +- dc_state->streams[k], +- &bundle->stream_update); ++ update_planes_and_stream_adapter(dm->dc, ++ UPDATE_TYPE_FULL, ++ dc_state->stream_status->plane_count, ++ dc_state->streams[k], ++ &bundle->stream_update, ++ bundle->surface_updates); + } + + cleanup: +@@ -8200,11 +8230,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + acrtc_state->stream->link->psr_settings.psr_allow_active) + amdgpu_dm_psr_disable(acrtc_state->stream); + +- dc_update_planes_and_stream(dm->dc, +- bundle->surface_updates, +- planes_count, +- acrtc_state->stream, +- &bundle->stream_update); ++ update_planes_and_stream_adapter(dm->dc, ++ acrtc_state->update_type, ++ planes_count, ++ acrtc_state->stream, ++ &bundle->stream_update, ++ bundle->surface_updates); + + /** + * Enable or disable the interrupts on the backend. +-- +2.39.2 + diff --git a/queue-6.3/drm-amd-display-fix-the-system-hang-while-disable-ps.patch b/queue-6.3/drm-amd-display-fix-the-system-hang-while-disable-ps.patch new file mode 100644 index 00000000000..6b51f81ebbd --- /dev/null +++ b/queue-6.3/drm-amd-display-fix-the-system-hang-while-disable-ps.patch @@ -0,0 +1,61 @@ +From 2902a6a2fe404780d51fac1c1bf9a4aee95988c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 May 2023 18:00:09 +0800 +Subject: drm/amd/display: fix the system hang while disable PSR + +From: Tom Chung + +[ Upstream commit ea2062dd1f0384ae1b136d333ee4ced15bedae38 ] + +[Why] +When the PSR enabled. If you try to adjust the timing parameters, +it may cause system hang. Because the timing mismatch with the +DMCUB settings. + +[How] +Disable the PSR before adjusting timing parameters. + +Cc: Mario Limonciello +Cc: Alex Deucher +Cc: stable@vger.kernel.org +Acked-by: Stylon Wang +Signed-off-by: Tom Chung +Reviewed-by: Wayne Lin +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 51a3130f607e0..2cbd6949804f5 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -8213,6 +8213,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + if (acrtc_state->abm_level != dm_old_crtc_state->abm_level) + bundle->stream_update.abm_level = &acrtc_state->abm_level; + ++ mutex_lock(&dm->dc_lock); ++ if ((acrtc_state->update_type > UPDATE_TYPE_FAST) && ++ acrtc_state->stream->link->psr_settings.psr_allow_active) ++ amdgpu_dm_psr_disable(acrtc_state->stream); ++ mutex_unlock(&dm->dc_lock); ++ + /* + * If FreeSync state on the stream has changed then we need to + * re-adjust the min/max bounds now that DC doesn't handle this +@@ -8226,10 +8232,6 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags); + } + mutex_lock(&dm->dc_lock); +- if ((acrtc_state->update_type > UPDATE_TYPE_FAST) && +- acrtc_state->stream->link->psr_settings.psr_allow_active) +- amdgpu_dm_psr_disable(acrtc_state->stream); +- + update_planes_and_stream_adapter(dm->dc, + acrtc_state->update_type, + planes_count, +-- +2.39.2 + diff --git a/queue-6.3/drm-amd-display-use-dc_update_planes_and_stream.patch b/queue-6.3/drm-amd-display-use-dc_update_planes_and_stream.patch new file mode 100644 index 00000000000..a69f19900b1 --- /dev/null +++ b/queue-6.3/drm-amd-display-use-dc_update_planes_and_stream.patch @@ -0,0 +1,87 @@ +From aa92d8b37e0a1df4b6fb96b73b4f9bae18bd5008 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Oct 2022 16:40:55 -0400 +Subject: drm/amd/display: Use dc_update_planes_and_stream + +From: Rodrigo Siqueira + +[ Upstream commit f7511289821ffccc07579406d6ab520aa11049f5 ] + +[Why & How] +The old dc_commit_updates_for_stream lacks manipulation for many corner +cases where the DC feature requires special attention; as a result, it +starts to show its limitation (e.g., the SubVP feature is not supported +by it, among other cases). To modernize and unify our internal API, this +commit replaces the old dc_commit_updates_for_stream with +dc_update_planes_and_stream, which has more features. + +Reviewed-by: Harry Wentland +Acked-by: Qingqing Zhuo +Signed-off-by: Rodrigo Siqueira +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Stable-dep-of: ea2062dd1f03 ("drm/amd/display: fix the system hang while disable PSR") +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 +++++++++---------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 289c261ffe876..ae58f24be511c 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -2683,10 +2683,12 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, + bundle->surface_updates[m].surface->force_full_update = + true; + } +- dc_commit_updates_for_stream( +- dm->dc, bundle->surface_updates, ++ ++ dc_update_planes_and_stream(dm->dc, ++ bundle->surface_updates, + dc_state->stream_status->plane_count, +- dc_state->streams[k], &bundle->stream_update, dc_state); ++ dc_state->streams[k], ++ &bundle->stream_update); + } + + cleanup: +@@ -8198,12 +8200,11 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + acrtc_state->stream->link->psr_settings.psr_allow_active) + amdgpu_dm_psr_disable(acrtc_state->stream); + +- dc_commit_updates_for_stream(dm->dc, +- bundle->surface_updates, +- planes_count, +- acrtc_state->stream, +- &bundle->stream_update, +- dc_state); ++ dc_update_planes_and_stream(dm->dc, ++ bundle->surface_updates, ++ planes_count, ++ acrtc_state->stream, ++ &bundle->stream_update); + + /** + * Enable or disable the interrupts on the backend. +@@ -8741,12 +8742,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) + + + mutex_lock(&dm->dc_lock); +- dc_commit_updates_for_stream(dm->dc, +- dummy_updates, +- status->plane_count, +- dm_new_crtc_state->stream, +- &stream_update, +- dc_state); ++ dc_update_planes_and_stream(dm->dc, ++ dummy_updates, ++ status->plane_count, ++ dm_new_crtc_state->stream, ++ &stream_update); + mutex_unlock(&dm->dc_lock); + } + +-- +2.39.2 + diff --git a/queue-6.3/series b/queue-6.3/series new file mode 100644 index 00000000000..cea5f55a552 --- /dev/null +++ b/queue-6.3/series @@ -0,0 +1,5 @@ +cifs-fix-status-checks-in-cifs_tree_connect.patch +drm-amd-display-use-dc_update_planes_and_stream.patch +drm-amd-display-add-wrapper-to-call-planes-and-strea.patch +drm-amd-display-fix-the-system-hang-while-disable-ps.patch +ata-libata-scsi-avoid-deadlock-on-rescan-after-devic.patch