From: Sasha Levin Date: Mon, 15 Jun 2020 03:27:38 +0000 (-0400) Subject: Fixes for 5.6 X-Git-Tag: v5.4.47~114^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e372e3acfae8268f50841776d6c51a11257ba7ae;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.6 Signed-off-by: Sasha Levin --- diff --git a/queue-5.6/drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch b/queue-5.6/drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch new file mode 100644 index 00000000000..7cb2a98352d --- /dev/null +++ b/queue-5.6/drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch @@ -0,0 +1,73 @@ +From 9533e978ba94ac42e014e5f98b294b71bc6b15e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2020 17:13:02 -0400 +Subject: drm/amd/display: Not doing optimize bandwidth if flip pending. + +From: Yongqiang Sun + +[ Upstream commit 9941b8129030c9202aaf39114477a0e58c0d6ffc ] + +[Why] +In some scenario like 1366x768 VSR enabled connected with a 4K monitor +and playing 4K video in clone mode, underflow will be observed due to +decrease dppclk when previouse surface scan isn't finished + +[How] +In this use case, surface flip is switching between 4K and 1366x768, +1366x768 needs smaller dppclk, and when decrease the clk and previous +surface scan is for 4K and scan isn't done, underflow will happen. Not +doing optimize bandwidth in case of flip pending. + +Signed-off-by: Yongqiang Sun +Reviewed-by: Tony Cheng +Acked-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 48e4eb5a37dd..fff95e6b46c7 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1362,6 +1362,26 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) + return (result == DC_OK); + } + ++static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context) ++{ ++ int i; ++ struct pipe_ctx *pipe; ++ ++ for (i = 0; i < MAX_PIPES; i++) { ++ pipe = &context->res_ctx.pipe_ctx[i]; ++ ++ if (!pipe->plane_state) ++ continue; ++ ++ /* Must set to false to start with, due to OR in update function */ ++ pipe->plane_state->status.is_flip_pending = false; ++ dc->hwss.update_pending_status(pipe); ++ if (pipe->plane_state->status.is_flip_pending) ++ return true; ++ } ++ return false; ++} ++ + bool dc_post_update_surfaces_to_stream(struct dc *dc) + { + int i; +@@ -1372,6 +1392,9 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) + + post_surface_trace(dc); + ++ if (is_flip_pending_in_pipes(dc, context)) ++ return true; ++ + for (i = 0; i < dc->res_pool->pipe_count; i++) + if (context->res_ctx.pipe_ctx[i].stream == NULL || + context->res_ctx.pipe_ctx[i].plane_state == NULL) { +-- +2.25.1 + diff --git a/queue-5.6/drm-amd-display-remove-invalid-dc_is_hw_initialized-.patch b/queue-5.6/drm-amd-display-remove-invalid-dc_is_hw_initialized-.patch new file mode 100644 index 00000000000..d7546b8c104 --- /dev/null +++ b/queue-5.6/drm-amd-display-remove-invalid-dc_is_hw_initialized-.patch @@ -0,0 +1,55 @@ +From a95b6c5d38004f5c9960c86b78f8aeba9455a6da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2020 13:27:06 -0500 +Subject: drm/amd/display: remove invalid dc_is_hw_initialized function + +From: Joseph Gravenor + +[ Upstream commit e2d533eceb1feb0b8b965c3ff11184921532a28e ] + +[why/how] +We found out that the register we read actually gets reset by SMU +after we loose power, meaning this always returns true + +Signed-off-by: Joseph Gravenor +Reviewed-by: Eric Yang +Acked-by: Bhawanpreet Lakha +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 6 ------ + drivers/gpu/drm/amd/display/dc/dc.h | 1 - + 2 files changed, 7 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 32a07665863f..48e4eb5a37dd 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1362,12 +1362,6 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) + return (result == DC_OK); + } + +-bool dc_is_hw_initialized(struct dc *dc) +-{ +- struct dc_bios *dcb = dc->ctx->dc_bios; +- return dcb->funcs->is_accelerated_mode(dcb); +-} +- + bool dc_post_update_surfaces_to_stream(struct dc *dc) + { + int i; +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index 8ff25b5dd2f6..e8d126890d7e 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -1075,7 +1075,6 @@ unsigned int dc_get_current_backlight_pwm(struct dc *dc); + unsigned int dc_get_target_backlight_pwm(struct dc *dc); + + bool dc_is_dmcu_initialized(struct dc *dc); +-bool dc_is_hw_initialized(struct dc *dc); + + enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping); + void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg); +-- +2.25.1 + diff --git a/queue-5.6/scsi-target-fix-hang-when-multiple-threads-try-to-de.patch b/queue-5.6/scsi-target-fix-hang-when-multiple-threads-try-to-de.patch new file mode 100644 index 00000000000..e07f5bf7c1c --- /dev/null +++ b/queue-5.6/scsi-target-fix-hang-when-multiple-threads-try-to-de.patch @@ -0,0 +1,258 @@ +From 47db26475d480e3b5b0d2a95e3686bd53f8fa3d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Mar 2020 18:06:55 +0100 +Subject: scsi: target: fix hang when multiple threads try to destroy the same + iscsi session + +From: Maurizio Lombardi + +[ Upstream commit 57c46e9f33da530a2485fa01aa27b6d18c28c796 ] + +A number of hangs have been reported against the target driver; they are +due to the fact that multiple threads may try to destroy the iscsi session +at the same time. This may be reproduced for example when a "targetcli +iscsi/iqn.../tpg1 disable" command is executed while a logout operation is +underway. + +When this happens, two or more threads may end up sleeping and waiting for +iscsit_close_connection() to execute "complete(session_wait_comp)". Only +one of the threads will wake up and proceed to destroy the session +structure, the remaining threads will hang forever. + +Note that if the blocked threads are somehow forced to wake up with +complete_all(), they will try to free the same iscsi session structure +destroyed by the first thread, causing double frees, memory corruptions +etc... + +With this patch, the threads that want to destroy the iscsi session will +increase the session refcount and will set the "session_close" flag to 1; +then they wait for the driver to close the remaining active connections. +When the last connection is closed, iscsit_close_connection() will wake up +all the threads and will wait for the session's refcount to reach zero; +when this happens, iscsit_close_connection() will destroy the session +structure because no one is referencing it anymore. + + INFO: task targetcli:5971 blocked for more than 120 seconds. + Tainted: P OE 4.15.0-72-generic #81~16.04.1 + "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. + targetcli D 0 5971 1 0x00000080 + Call Trace: + __schedule+0x3d6/0x8b0 + ? vprintk_func+0x44/0xe0 + schedule+0x36/0x80 + schedule_timeout+0x1db/0x370 + ? __dynamic_pr_debug+0x8a/0xb0 + wait_for_completion+0xb4/0x140 + ? wake_up_q+0x70/0x70 + iscsit_free_session+0x13d/0x1a0 [iscsi_target_mod] + iscsit_release_sessions_for_tpg+0x16b/0x1e0 [iscsi_target_mod] + iscsit_tpg_disable_portal_group+0xca/0x1c0 [iscsi_target_mod] + lio_target_tpg_enable_store+0x66/0xe0 [iscsi_target_mod] + configfs_write_file+0xb9/0x120 + __vfs_write+0x1b/0x40 + vfs_write+0xb8/0x1b0 + SyS_write+0x5c/0xe0 + do_syscall_64+0x73/0x130 + entry_SYSCALL_64_after_hwframe+0x3d/0xa2 + +Link: https://lore.kernel.org/r/20200313170656.9716-3-mlombard@redhat.com +Reported-by: Matt Coleman +Tested-by: Matt Coleman +Tested-by: Rahul Kundu +Signed-off-by: Maurizio Lombardi +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/iscsi/iscsi_target.c | 35 ++++++++++++-------- + drivers/target/iscsi/iscsi_target_configfs.c | 5 ++- + drivers/target/iscsi/iscsi_target_login.c | 5 +-- + include/target/iscsi/iscsi_target_core.h | 2 +- + 4 files changed, 30 insertions(+), 17 deletions(-) + +diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c +index 1c7514543571..59379d662626 100644 +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -4301,30 +4301,37 @@ int iscsit_close_connection( + if (!atomic_read(&sess->session_reinstatement) && + atomic_read(&sess->session_fall_back_to_erl0)) { + spin_unlock_bh(&sess->conn_lock); ++ complete_all(&sess->session_wait_comp); + iscsit_close_session(sess); + + return 0; + } else if (atomic_read(&sess->session_logout)) { + pr_debug("Moving to TARG_SESS_STATE_FREE.\n"); + sess->session_state = TARG_SESS_STATE_FREE; +- spin_unlock_bh(&sess->conn_lock); + +- if (atomic_read(&sess->sleep_on_sess_wait_comp)) +- complete(&sess->session_wait_comp); ++ if (atomic_read(&sess->session_close)) { ++ spin_unlock_bh(&sess->conn_lock); ++ complete_all(&sess->session_wait_comp); ++ iscsit_close_session(sess); ++ } else { ++ spin_unlock_bh(&sess->conn_lock); ++ } + + return 0; + } else { + pr_debug("Moving to TARG_SESS_STATE_FAILED.\n"); + sess->session_state = TARG_SESS_STATE_FAILED; + +- if (!atomic_read(&sess->session_continuation)) { +- spin_unlock_bh(&sess->conn_lock); ++ if (!atomic_read(&sess->session_continuation)) + iscsit_start_time2retain_handler(sess); +- } else +- spin_unlock_bh(&sess->conn_lock); + +- if (atomic_read(&sess->sleep_on_sess_wait_comp)) +- complete(&sess->session_wait_comp); ++ if (atomic_read(&sess->session_close)) { ++ spin_unlock_bh(&sess->conn_lock); ++ complete_all(&sess->session_wait_comp); ++ iscsit_close_session(sess); ++ } else { ++ spin_unlock_bh(&sess->conn_lock); ++ } + + return 0; + } +@@ -4429,9 +4436,9 @@ static void iscsit_logout_post_handler_closesession( + complete(&conn->conn_logout_comp); + + iscsit_dec_conn_usage_count(conn); ++ atomic_set(&sess->session_close, 1); + iscsit_stop_session(sess, sleep, sleep); + iscsit_dec_session_usage_count(sess); +- iscsit_close_session(sess); + } + + static void iscsit_logout_post_handler_samecid( +@@ -4576,8 +4583,6 @@ void iscsit_stop_session( + int is_last; + + spin_lock_bh(&sess->conn_lock); +- if (session_sleep) +- atomic_set(&sess->sleep_on_sess_wait_comp, 1); + + if (connection_sleep) { + list_for_each_entry_safe(conn, conn_tmp, &sess->sess_conn_list, +@@ -4635,12 +4640,15 @@ int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force) + spin_lock(&sess->conn_lock); + if (atomic_read(&sess->session_fall_back_to_erl0) || + atomic_read(&sess->session_logout) || ++ atomic_read(&sess->session_close) || + (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) { + spin_unlock(&sess->conn_lock); + continue; + } ++ iscsit_inc_session_usage_count(sess); + atomic_set(&sess->session_reinstatement, 1); + atomic_set(&sess->session_fall_back_to_erl0, 1); ++ atomic_set(&sess->session_close, 1); + spin_unlock(&sess->conn_lock); + + list_move_tail(&se_sess->sess_list, &free_list); +@@ -4650,8 +4658,9 @@ int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force) + list_for_each_entry_safe(se_sess, se_sess_tmp, &free_list, sess_list) { + sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; + ++ list_del_init(&se_sess->sess_list); + iscsit_stop_session(sess, 1, 1); +- iscsit_close_session(sess); ++ iscsit_dec_session_usage_count(sess); + session_count++; + } + +diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c +index 42b369fc415e..0fa1d57b26fa 100644 +--- a/drivers/target/iscsi/iscsi_target_configfs.c ++++ b/drivers/target/iscsi/iscsi_target_configfs.c +@@ -1476,20 +1476,23 @@ static void lio_tpg_close_session(struct se_session *se_sess) + spin_lock(&sess->conn_lock); + if (atomic_read(&sess->session_fall_back_to_erl0) || + atomic_read(&sess->session_logout) || ++ atomic_read(&sess->session_close) || + (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) { + spin_unlock(&sess->conn_lock); + spin_unlock_bh(&se_tpg->session_lock); + return; + } ++ iscsit_inc_session_usage_count(sess); + atomic_set(&sess->session_reinstatement, 1); + atomic_set(&sess->session_fall_back_to_erl0, 1); ++ atomic_set(&sess->session_close, 1); + spin_unlock(&sess->conn_lock); + + iscsit_stop_time2retain_timer(sess); + spin_unlock_bh(&se_tpg->session_lock); + + iscsit_stop_session(sess, 1, 1); +- iscsit_close_session(sess); ++ iscsit_dec_session_usage_count(sess); + } + + static u32 lio_tpg_get_inst_index(struct se_portal_group *se_tpg) +diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c +index f53330813207..731ee67fe914 100644 +--- a/drivers/target/iscsi/iscsi_target_login.c ++++ b/drivers/target/iscsi/iscsi_target_login.c +@@ -156,6 +156,7 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn) + spin_lock(&sess_p->conn_lock); + if (atomic_read(&sess_p->session_fall_back_to_erl0) || + atomic_read(&sess_p->session_logout) || ++ atomic_read(&sess_p->session_close) || + (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED)) { + spin_unlock(&sess_p->conn_lock); + continue; +@@ -166,6 +167,7 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn) + (sess_p->sess_ops->SessionType == sessiontype))) { + atomic_set(&sess_p->session_reinstatement, 1); + atomic_set(&sess_p->session_fall_back_to_erl0, 1); ++ atomic_set(&sess_p->session_close, 1); + spin_unlock(&sess_p->conn_lock); + iscsit_inc_session_usage_count(sess_p); + iscsit_stop_time2retain_timer(sess_p); +@@ -190,7 +192,6 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn) + if (sess->session_state == TARG_SESS_STATE_FAILED) { + spin_unlock_bh(&sess->conn_lock); + iscsit_dec_session_usage_count(sess); +- iscsit_close_session(sess); + return 0; + } + spin_unlock_bh(&sess->conn_lock); +@@ -198,7 +199,6 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn) + iscsit_stop_session(sess, 1, 1); + iscsit_dec_session_usage_count(sess); + +- iscsit_close_session(sess); + return 0; + } + +@@ -486,6 +486,7 @@ static int iscsi_login_non_zero_tsih_s2( + sess_p = (struct iscsi_session *)se_sess->fabric_sess_ptr; + if (atomic_read(&sess_p->session_fall_back_to_erl0) || + atomic_read(&sess_p->session_logout) || ++ atomic_read(&sess_p->session_close) || + (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED)) + continue; + if (!memcmp(sess_p->isid, pdu->isid, 6) && +diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h +index a49d37140a64..591cd9e4692c 100644 +--- a/include/target/iscsi/iscsi_target_core.h ++++ b/include/target/iscsi/iscsi_target_core.h +@@ -676,7 +676,7 @@ struct iscsi_session { + atomic_t session_logout; + atomic_t session_reinstatement; + atomic_t session_stop_active; +- atomic_t sleep_on_sess_wait_comp; ++ atomic_t session_close; + /* connection list */ + struct list_head sess_conn_list; + struct list_head cr_active_list; +-- +2.25.1 + diff --git a/queue-5.6/scsi-target-remove-boilerplate-code.patch b/queue-5.6/scsi-target-remove-boilerplate-code.patch new file mode 100644 index 00000000000..c7cafcc80e5 --- /dev/null +++ b/queue-5.6/scsi-target-remove-boilerplate-code.patch @@ -0,0 +1,101 @@ +From 003de54214dc94803c24de002897d3071510aa2b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Mar 2020 18:06:54 +0100 +Subject: scsi: target: remove boilerplate code + +From: Maurizio Lombardi + +[ Upstream commit e49a7d994379278d3353d7ffc7994672752fb0ad ] + +iscsit_free_session() is equivalent to iscsit_stop_session() followed by a +call to iscsit_close_session(). + +Link: https://lore.kernel.org/r/20200313170656.9716-2-mlombard@redhat.com +Tested-by: Rahul Kundu +Signed-off-by: Maurizio Lombardi +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/iscsi/iscsi_target.c | 46 ++--------------------------- + drivers/target/iscsi/iscsi_target.h | 1 - + 2 files changed, 2 insertions(+), 45 deletions(-) + +diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c +index 9fc7e374a29b..1c7514543571 100644 +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -4566,49 +4566,6 @@ void iscsit_fail_session(struct iscsi_session *sess) + sess->session_state = TARG_SESS_STATE_FAILED; + } + +-int iscsit_free_session(struct iscsi_session *sess) +-{ +- u16 conn_count = atomic_read(&sess->nconn); +- struct iscsi_conn *conn, *conn_tmp = NULL; +- int is_last; +- +- spin_lock_bh(&sess->conn_lock); +- atomic_set(&sess->sleep_on_sess_wait_comp, 1); +- +- list_for_each_entry_safe(conn, conn_tmp, &sess->sess_conn_list, +- conn_list) { +- if (conn_count == 0) +- break; +- +- if (list_is_last(&conn->conn_list, &sess->sess_conn_list)) { +- is_last = 1; +- } else { +- iscsit_inc_conn_usage_count(conn_tmp); +- is_last = 0; +- } +- iscsit_inc_conn_usage_count(conn); +- +- spin_unlock_bh(&sess->conn_lock); +- iscsit_cause_connection_reinstatement(conn, 1); +- spin_lock_bh(&sess->conn_lock); +- +- iscsit_dec_conn_usage_count(conn); +- if (is_last == 0) +- iscsit_dec_conn_usage_count(conn_tmp); +- +- conn_count--; +- } +- +- if (atomic_read(&sess->nconn)) { +- spin_unlock_bh(&sess->conn_lock); +- wait_for_completion(&sess->session_wait_comp); +- } else +- spin_unlock_bh(&sess->conn_lock); +- +- iscsit_close_session(sess); +- return 0; +-} +- + void iscsit_stop_session( + struct iscsi_session *sess, + int session_sleep, +@@ -4693,7 +4650,8 @@ int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force) + list_for_each_entry_safe(se_sess, se_sess_tmp, &free_list, sess_list) { + sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; + +- iscsit_free_session(sess); ++ iscsit_stop_session(sess, 1, 1); ++ iscsit_close_session(sess); + session_count++; + } + +diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h +index c95f56a3ce31..7409ce2a6607 100644 +--- a/drivers/target/iscsi/iscsi_target.h ++++ b/drivers/target/iscsi/iscsi_target.h +@@ -43,7 +43,6 @@ extern int iscsi_target_rx_thread(void *); + extern int iscsit_close_connection(struct iscsi_conn *); + extern int iscsit_close_session(struct iscsi_session *); + extern void iscsit_fail_session(struct iscsi_session *); +-extern int iscsit_free_session(struct iscsi_session *); + extern void iscsit_stop_session(struct iscsi_session *, int, int); + extern int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *, int); + +-- +2.25.1 + diff --git a/queue-5.6/series b/queue-5.6/series index 15dcd887014..4a69e1996de 100644 --- a/queue-5.6/series +++ b/queue-5.6/series @@ -39,3 +39,7 @@ x86-cpu-amd-make-erratum-1054-a-legacy-erratum.patch kvm-x86-only-do-l1tf-workaround-on-affected-processo.patch pci-pm-adjust-pcie_wait_for_link_delay-for-caller-de.patch kobject-make-sure-the-parent-does-not-get-released-b.patch +scsi-target-remove-boilerplate-code.patch +scsi-target-fix-hang-when-multiple-threads-try-to-de.patch +drm-amd-display-remove-invalid-dc_is_hw_initialized-.patch +drm-amd-display-not-doing-optimize-bandwidth-if-flip.patch