Procházet zdrojové kódy

disp: msm: sde: Avoid kcallocs in atomic commit path

To avoid kcalloc for the multirect plane states and plane states will now
be stored sde crtc. These states are populated momentarily and accessed in
a single context for a handful of functions then are not used. This will
clean up parameters passed between functions in the commit path as well.

Change-Id: I6a8116a43c140b3f1c0464734032b8db13c1cfb0
Signed-off-by: Samantha Tran <[email protected]>
Samantha Tran před 4 roky
rodič
revize
6886d03e4a
3 změnil soubory, kde provedl 80 přidání a 75 odebrání
  1. 52 64
      msm/sde/sde_crtc.c
  2. 27 0
      msm/sde/sde_crtc.h
  3. 1 11
      msm/sde/sde_plane.h

+ 52 - 64
msm/sde/sde_crtc.c

@@ -42,9 +42,6 @@
 #include "sde_trace.h"
 #include "msm_drv.h"
 
-#define SDE_PSTATES_MAX (SDE_STAGE_MAX * 4)
-#define SDE_MULTIRECT_PLANE_MAX (SDE_STAGE_MAX * 2)
-
 struct sde_crtc_custom_events {
 	u32 event;
 	int (*func)(struct drm_crtc *crtc, bool en,
@@ -1257,13 +1254,6 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
 		sde_cp_crtc_res_change(crtc);
 }
 
-struct plane_state {
-	struct sde_plane_state *sde_pstate;
-	const struct drm_plane_state *drm_pstate;
-	int stage;
-	u32 pipe_id;
-};
-
 static int pstate_cmp(const void *a, const void *b)
 {
 	struct plane_state *pa = (struct plane_state *)a;
@@ -1297,24 +1287,29 @@ static int pstate_cmp(const void *a, const void *b)
  * we assume that all pipes are in source split so its valid to compare
  * without taking into account left/right mixer placement
  */
-static int _sde_crtc_validate_src_split_order(struct drm_crtc *crtc,
-		struct plane_state *pstates, int cnt)
+static int _sde_crtc_validate_src_split_order(struct drm_crtc *crtc)
 {
 	struct plane_state *prv_pstate, *cur_pstate;
 	enum sde_layout prev_layout, cur_layout;
+	struct sde_crtc *sde_crtc;
 	struct sde_rect left_rect, right_rect;
 	struct sde_kms *sde_kms;
+	struct plane_state *pstates;
 	int32_t left_pid, right_pid;
 	int32_t stage;
 	int i, rc = 0;
 
+	sde_crtc = to_sde_crtc(crtc);
+
 	sde_kms = _sde_crtc_get_kms(crtc);
-	if (!sde_kms || !sde_kms->catalog) {
+	if (!sde_kms || !sde_kms->catalog || !sde_crtc) {
 		SDE_ERROR("invalid parameters\n");
 		return -EINVAL;
 	}
 
-	for (i = 1; i < cnt; i++) {
+	pstates = sde_crtc->pstates;
+
+	for (i = 1; i < sde_crtc->num_pstates; i++) {
 		prv_pstate = &pstates[i - 1];
 		cur_pstate = &pstates[i];
 		prev_layout = prv_pstate->sde_pstate->layout;
@@ -1492,7 +1487,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	struct drm_plane_state *state;
 	struct sde_crtc_state *cstate;
 	struct sde_plane_state *pstate = NULL;
-	struct plane_state *pstates = NULL;
+	struct plane_state *pstates;
 	struct sde_format *format;
 	struct sde_hw_ctl *ctl;
 	struct sde_hw_mixer *lm;
@@ -1513,11 +1508,9 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	ctl = mixer->hw_ctl;
 	lm = mixer->hw_lm;
 	cstate = to_sde_crtc_state(crtc->state);
-	pstates = kcalloc(SDE_PSTATES_MAX,
-			sizeof(struct plane_state), GFP_KERNEL);
-	if (!pstates)
-		return;
+	pstates = sde_crtc->pstates;
 
+	memset(sde_crtc->pstates, 0, sizeof(sde_crtc->pstates));
 	memset(fetch_active, 0, sizeof(fetch_active));
 	memset(zpos_cnt, 0, sizeof(zpos_cnt));
 
@@ -1550,7 +1543,7 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		format = to_sde_format(msm_framebuffer_format(pstate->base.fb));
 		if (!format) {
 			SDE_ERROR("invalid format\n");
-			goto end;
+			return;
 		}
 
 		blend_type = sde_plane_get_property(pstate,
@@ -1641,8 +1634,6 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		}
 	}
 
-end:
-	kfree(pstates);
 }
 
 static void _sde_crtc_swap_mixers_for_right_partial_update(
@@ -4523,12 +4514,19 @@ end:
 }
 
 static int _sde_crtc_check_secure_blend_config(struct drm_crtc *crtc,
-	struct drm_crtc_state *state, struct plane_state pstates[],
-	struct sde_crtc_state *cstate, struct sde_kms *sde_kms,
-	int cnt, int secure, int fb_ns, int fb_sec, int fb_sec_dir)
+	struct drm_crtc_state *state, struct sde_crtc_state *cstate,
+	struct sde_kms *sde_kms, int secure, int fb_ns,
+	int fb_sec, int fb_sec_dir)
 {
 	struct drm_plane *plane;
-	int i;
+	int i, cnt;
+	struct plane_state *pstates;
+	struct sde_crtc *sde_crtc;
+
+	sde_crtc = to_sde_crtc(crtc);
+	cnt = sde_crtc->num_pstates;
+	pstates = sde_crtc->pstates;
+
 	if (secure == SDE_DRM_SEC_ONLY) {
 		/*
 		 * validate planes - only fb_sec_dir is allowed during sec_crtc
@@ -4725,8 +4723,7 @@ static int _sde_crtc_check_secure_conn(struct drm_crtc *crtc,
 }
 
 static int _sde_crtc_check_secure_state(struct drm_crtc *crtc,
-		struct drm_crtc_state *state, struct plane_state pstates[],
-		int cnt)
+		struct drm_crtc_state *state)
 {
 	struct sde_crtc_state *cstate;
 	struct sde_kms *sde_kms;
@@ -4754,8 +4751,8 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc,
 	if (rc)
 		return rc;
 
-	rc = _sde_crtc_check_secure_blend_config(crtc, state, pstates, cstate,
-			sde_kms, cnt, secure, fb_ns, fb_sec, fb_sec_dir);
+	rc = _sde_crtc_check_secure_blend_config(crtc, state, cstate,
+			sde_kms, secure, fb_ns, fb_sec, fb_sec_dir);
 	if (rc)
 		return rc;
 
@@ -4784,10 +4781,7 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc,
 static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
 		struct drm_crtc_state *state,
 		struct drm_display_mode *mode,
-		struct plane_state *pstates,
-		struct drm_plane *plane,
-		struct sde_multirect_plane_states *multirect_plane,
-		int *cnt)
+		struct drm_plane *plane)
 {
 	struct sde_crtc *sde_crtc;
 	struct sde_crtc_state *cstate;
@@ -4796,6 +4790,9 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
 	int rc = 0, multirect_count = 0, i, mixer_width, mixer_height;
 	int inc_sde_stage = 0;
 	struct sde_kms *kms;
+	int *cnt;
+	struct plane_state *pstates;
+	struct sde_multirect_plane_states *multirect_plane;
 
 	sde_crtc = to_sde_crtc(crtc);
 	cstate = to_sde_crtc_state(state);
@@ -4806,6 +4803,13 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
 		return -EINVAL;
 	}
 
+	cnt = &sde_crtc->num_pstates;
+	pstates = sde_crtc->pstates;
+	multirect_plane = sde_crtc->multirect;
+
+	*cnt = 0;
+	memset(sde_crtc->pstates, 0, sizeof(sde_crtc->pstates));
+	memset(sde_crtc->multirect, 0, sizeof(sde_crtc->multirect));
 	memset(pipe_staged, 0, sizeof(pipe_staged));
 
 	mixer_width = sde_crtc_get_mixer_width(sde_crtc, cstate, mode);
@@ -4911,16 +4915,16 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
 
 static int _sde_crtc_check_zpos(struct drm_crtc_state *state,
 		struct sde_crtc *sde_crtc,
-		struct plane_state *pstates,
 		struct sde_crtc_state *cstate,
-		struct drm_display_mode *mode,
-		int cnt)
+		struct drm_display_mode *mode)
 {
 	int rc = 0, i, z_pos;
 	u32 zpos_cnt = 0;
 	struct drm_crtc *crtc;
 	struct sde_kms *kms;
 	enum sde_layout layout;
+	int cnt;
+	struct plane_state *pstates;
 
 	crtc = &sde_crtc->base;
 	kms = _sde_crtc_get_kms(crtc);
@@ -4930,6 +4934,9 @@ static int _sde_crtc_check_zpos(struct drm_crtc_state *state,
 		return -EINVAL;
 	}
 
+	pstates = sde_crtc->pstates;
+	cnt = sde_crtc->num_pstates;
+
 	sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL);
 
 	rc = _sde_crtc_excl_dim_layer_check(state, pstates, cnt);
@@ -4983,16 +4990,14 @@ static int _sde_crtc_check_zpos(struct drm_crtc_state *state,
 }
 
 static int _sde_crtc_atomic_check_pstates(struct drm_crtc *crtc,
-		struct drm_crtc_state *state,
-		struct plane_state *pstates,
-		struct sde_multirect_plane_states *multirect_plane)
+		struct drm_crtc_state *state)
 {
 	struct sde_crtc *sde_crtc;
 	struct sde_crtc_state *cstate;
 	struct sde_kms *kms;
 	struct drm_plane *plane = NULL;
 	struct drm_display_mode *mode;
-	int rc = 0, cnt = 0;
+	int rc = 0;
 
 	kms = _sde_crtc_get_kms(crtc);
 
@@ -5004,19 +5009,19 @@ static int _sde_crtc_atomic_check_pstates(struct drm_crtc *crtc,
 	sde_crtc = to_sde_crtc(crtc);
 	cstate = to_sde_crtc_state(state);
 	mode = &state->adjusted_mode;
+	sde_crtc->num_pstates = 0;
 
 	/* get plane state for all drm planes associated with crtc state */
-	rc = _sde_crtc_check_get_pstates(crtc, state, mode, pstates,
-			plane, multirect_plane, &cnt);
+	rc = _sde_crtc_check_get_pstates(crtc, state, mode, plane);
 	if (rc)
 		return rc;
 
 	/* assign mixer stages based on sorted zpos property */
-	rc = _sde_crtc_check_zpos(state, sde_crtc, pstates, cstate, mode, cnt);
+	rc = _sde_crtc_check_zpos(state, sde_crtc, cstate, mode);
 	if (rc)
 		return rc;
 
-	rc = _sde_crtc_check_secure_state(crtc, state, pstates, cnt);
+	rc = _sde_crtc_check_secure_state(crtc, state);
 	if (rc)
 		return rc;
 
@@ -5026,7 +5031,7 @@ static int _sde_crtc_atomic_check_pstates(struct drm_crtc *crtc,
 	 * we assume that all pipes are in source split so its valid to compare
 	 * without taking into account left/right mixer placement
 	 */
-	rc = _sde_crtc_validate_src_split_order(crtc, pstates, cnt);
+	rc = _sde_crtc_validate_src_split_order(crtc);
 	if (rc)
 		return rc;
 
@@ -5094,11 +5099,9 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
 {
 	struct drm_device *dev;
 	struct sde_crtc *sde_crtc;
-	struct plane_state *pstates = NULL;
 	struct sde_crtc_state *cstate;
 	struct drm_display_mode *mode;
 	int rc = 0;
-	struct sde_multirect_plane_states *multirect_plane = NULL;
 	struct drm_connector *conn;
 	struct drm_connector_list_iter conn_iter;
 
@@ -5117,18 +5120,6 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
 		goto end;
 	}
 
-	pstates = kcalloc(SDE_PSTATES_MAX,
-			sizeof(struct plane_state), GFP_KERNEL);
-
-	multirect_plane = kcalloc(SDE_MULTIRECT_PLANE_MAX,
-			sizeof(struct sde_multirect_plane_states),
-			GFP_KERNEL);
-
-	if (!pstates || !multirect_plane) {
-		rc = -ENOMEM;
-		goto end;
-	}
-
 	mode = &state->adjusted_mode;
 	SDE_DEBUG("%s: check", sde_crtc->name);
 
@@ -5164,8 +5155,7 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
 	_sde_crtc_setup_is_ppsplit(state);
 	_sde_crtc_setup_lm_bounds(crtc, state);
 
-	rc = _sde_crtc_atomic_check_pstates(crtc, state, pstates,
-			multirect_plane);
+	rc = _sde_crtc_atomic_check_pstates(crtc, state);
 	if (rc) {
 		SDE_ERROR("crtc%d failed pstate check %d\n", crtc->base.id, rc);
 		goto end;
@@ -5191,8 +5181,6 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
 		goto end;
 	}
 end:
-	kfree(pstates);
-	kfree(multirect_plane);
 	return rc;
 }
 

+ 27 - 0
msm/sde/sde_crtc.h

@@ -29,6 +29,9 @@
 #include "sde_core_perf.h"
 #include "sde_hw_ds.h"
 
+#define SDE_PSTATES_MAX (SDE_STAGE_MAX * 4)
+#define SDE_MULTIRECT_PLANE_MAX (SDE_STAGE_MAX * 2)
+
 #define SDE_CRTC_NAME_SIZE	12
 
 /* define the maximum number of in-flight frame events */
@@ -216,6 +219,23 @@ struct sde_crtc_misr_info {
 	u32 misr_frame_count;
 };
 
+struct plane_state {
+	struct sde_plane_state *sde_pstate;
+	const struct drm_plane_state *drm_pstate;
+	int stage;
+	u32 pipe_id;
+};
+
+/**
+ * struct sde_multirect_plane_states: Defines multirect pair of drm plane states
+ * @r0: drm plane configured on rect 0
+ * @r1: drm plane configured on rect 1
+ */
+struct sde_multirect_plane_states {
+	const struct drm_plane_state *r0;
+	const struct drm_plane_state *r1;
+};
+
 /*
  * Maximum number of free event structures to cache
  */
@@ -257,6 +277,9 @@ struct sde_crtc_misr_info {
  * @ad_dirty      : list containing ad properties that are dirty
  * @ad_active     : list containing ad properties that are active
  * @crtc_lock     : crtc lock around create, destroy and access.
+ * @pstates       : array of plane states
+ * @num_pstates   : Number of plane states
+ * @multirect     : array of multirect plane states
  * @frame_pending : Whether or not an update is pending
  * @frame_events  : static allocation of in-flight frame events
  * @frame_event_list : available frame event list
@@ -338,6 +361,10 @@ struct sde_crtc {
 	struct mutex crtc_lock;
 	struct mutex crtc_cp_lock;
 
+	struct plane_state pstates[SDE_PSTATES_MAX];
+	uint32_t num_pstates;
+	struct sde_multirect_plane_states multirect[SDE_MULTIRECT_PLANE_MAX];
+
 	atomic_t frame_pending;
 	struct sde_crtc_frame_event frame_events[SDE_CRTC_FRAME_EVENT_SIZE];
 	struct list_head frame_event_list;

+ 1 - 11
msm/sde/sde_plane.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  * Copyright (C) 2013 Red Hat
  * Author: Rob Clark <[email protected]>
  *
@@ -137,16 +137,6 @@ struct sde_plane_state {
 	struct sde_hw_pipe_cdp_cfg cdp_cfg;
 };
 
-/**
- * struct sde_multirect_plane_states: Defines multirect pair of drm plane states
- * @r0: drm plane configured on rect 0
- * @r1: drm plane configured on rect 1
- */
-struct sde_multirect_plane_states {
-	const struct drm_plane_state *r0;
-	const struct drm_plane_state *r1;
-};
-
 #define to_sde_plane_state(x) \
 	container_of(x, struct sde_plane_state, base)