Commit 06ad7e16 authored by Mario Limonciello's avatar Mario Limonciello Committed by Alex Deucher
Browse files

drm/amd/display: Destroy DC context while keeping DML and DML2

If there is memory pressure at suspend time then dynamically
allocating a large structure as part of DC suspend code will
fail.

Instead re-use the same structures and clear all members except
those that should be maintained.

Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2362


Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f7fbf79f
Loading
Loading
Loading
Loading
+0 −37
Original line number Diff line number Diff line
@@ -4781,12 +4781,6 @@ bool dc_set_power_state(
	struct dc *dc,
	enum dc_acpi_cm_power_state power_state)
{
	struct kref refcount;
	struct display_mode_lib *dml;
#ifdef CONFIG_DRM_AMD_DC_FP
	struct dml2_context *dml2 = NULL;
#endif

	if (!dc->current_state)
		return true;

@@ -4805,40 +4799,9 @@ bool dc_set_power_state(

		break;
	default:
#ifdef CONFIG_DRM_AMD_DC_FP
		if (dc->debug.using_dml2)
			dml2 = dc->current_state->bw_ctx.dml2;
#endif
		ASSERT(dc->current_state->stream_count == 0);
		/* Zero out the current context so that on resume we start with
		 * clean state, and dc hw programming optimizations will not
		 * cause any trouble.
		 */
		dml = kzalloc(sizeof(struct display_mode_lib),
				GFP_KERNEL);

		ASSERT(dml);
		if (!dml)
			return false;

		/* Preserve refcount */
		refcount = dc->current_state->refcount;
		/* Preserve display mode lib */
		memcpy(dml, &dc->current_state->bw_ctx.dml, sizeof(struct display_mode_lib));

		dc_resource_state_destruct(dc->current_state);
		memset(dc->current_state, 0,
				sizeof(*dc->current_state));

		dc->current_state->refcount = refcount;
		dc->current_state->bw_ctx.dml = *dml;

		kfree(dml);

#ifdef CONFIG_DRM_AMD_DC_FP
		if (dc->debug.using_dml2)
			dc->current_state->bw_ctx.dml2 = dml2;
#endif

		break;
	}
+12 −0
Original line number Diff line number Diff line
@@ -4487,6 +4487,18 @@ void dc_resource_state_destruct(struct dc_state *context)
		context->streams[i] = NULL;
	}
	context->stream_count = 0;
	context->stream_mask = 0;
	memset(&context->res_ctx, 0, sizeof(context->res_ctx));
	memset(&context->pp_display_cfg, 0, sizeof(context->pp_display_cfg));
	memset(&context->dcn_bw_vars, 0, sizeof(context->dcn_bw_vars));
	context->clk_mgr = NULL;
	memset(&context->bw_ctx.bw, 0, sizeof(context->bw_ctx.bw));
	memset(context->block_sequence, 0, sizeof(context->block_sequence));
	context->block_sequence_steps = 0;
	memset(context->dc_dmub_cmd, 0, sizeof(context->dc_dmub_cmd));
	context->dmub_cmd_count = 0;
	memset(&context->perf_params, 0, sizeof(context->perf_params));
	memset(&context->scratch, 0, sizeof(context->scratch));
}

void dc_resource_state_copy_construct(