From 9522cd138240ee52f884f5975911385d8c8be42d Mon Sep 17 00:00:00 2001 From: Rajkumar Subbiah Date: Fri, 10 Jul 2020 22:20:20 -0400 Subject: [PATCH] disp: msm: dp: use base connector properties for mst connectors When DRM property objects are created, the DRM framework attaches a dellocator which can eventually free the object when the last reference is removed from it. The framework can only do this before the driver is registered. If a property is created after the registration then the framework is unable to attach a deallocator causing a memory leak during tear down. The current DP driver creates a new colorspace property whenever a new dp connector is initialized. It creates a base connector at probe time prior to registration. But then it also creates new connectors, post registration, whenever a new MST dongle is attached to the topology, causing memory leaks. This change limits the property creation to the base connector and attaches the same object to MST connectors to avoid memory leak. Change-Id: Ib97dc7aac260b4f3f96c1097f58bd276c68501f8 Signed-off-by: Rajkumar Subbiah --- msm/dp/dp_drm.c | 31 +++++++++++++++++++++++++++++++ msm/dp/dp_drm.h | 14 ++++++++++++++ msm/dp/dp_mst_drm.c | 1 + msm/sde/sde_connector.c | 6 ++---- msm/sde/sde_connector.h | 8 ++++++++ msm/sde/sde_kms.c | 3 +++ 6 files changed, 59 insertions(+), 4 deletions(-) diff --git a/msm/dp/dp_drm.c b/msm/dp/dp_drm.c index 43bd72ad68..3abe14e916 100644 --- a/msm/dp/dp_drm.c +++ b/msm/dp/dp_drm.c @@ -702,3 +702,34 @@ int dp_connector_update_pps(struct drm_connector *connector, dp_disp = display; return dp_disp->update_pps(dp_disp, connector, pps_cmd); } + +int dp_connector_install_properties(void *display, struct drm_connector *conn) +{ + struct dp_display *dp_display = display; + struct drm_connector *base_conn; + int rc; + + if (!display || !conn) { + DP_ERR("invalid params\n"); + return -EINVAL; + } + + base_conn = dp_display->base_connector; + + /* + * Create the property on the base connector during probe time and then + * attach the same property onto new connector objects created for MST + */ + if (!base_conn->colorspace_property) { + /* This is the base connector. create the drm property */ + rc = drm_mode_create_dp_colorspace_property(base_conn); + if (rc) + return rc; + } else { + conn->colorspace_property = base_conn->colorspace_property; + } + + drm_object_attach_property(&conn->base, conn->colorspace_property, 0); + + return 0; +} diff --git a/msm/dp/dp_drm.h b/msm/dp/dp_drm.h index 5e3fdf19a3..5d7462cd20 100644 --- a/msm/dp/dp_drm.h +++ b/msm/dp/dp_drm.h @@ -158,6 +158,14 @@ void convert_to_drm_mode(const struct dp_display_mode *dp_mode, int dp_connector_update_pps(struct drm_connector *connector, char *pps_cmd, void *display); +/** + * dp_connector_install_properties - install drm properties + * @display: Pointer to private display structure + * @conn: Pointer to connector + */ +int dp_connector_install_properties(void *display, + struct drm_connector *conn); + #else static inline int dp_connector_config_hdr(struct drm_connector *connector, void *display, struct sde_connector_state *c_state) @@ -239,6 +247,12 @@ static inline void convert_to_drm_mode(const struct dp_display_mode *dp_mode, struct drm_display_mode *drm_mode) { } + +static int dp_connector_install_properties(void *display, + struct drm_connector *conn) +{ + return 0; +} #endif /* CONFIG_DRM_MSM_DP */ #endif /* _DP_DRM_H_ */ diff --git a/msm/dp/dp_mst_drm.c b/msm/dp/dp_mst_drm.c index 77ece8fbcf..a8b6617efe 100644 --- a/msm/dp/dp_mst_drm.c +++ b/msm/dp/dp_mst_drm.c @@ -1747,6 +1747,7 @@ dp_mst_add_connector(struct drm_dp_mst_topology_mgr *mgr, .config_hdr = dp_mst_connector_config_hdr, .pre_destroy = dp_mst_connector_pre_destroy, .update_pps = dp_connector_update_pps, + .install_properties = dp_connector_install_properties, }; struct dp_mst_private *dp_mst; struct drm_device *dev; diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 759b1bf5b3..77c3a45ea0 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -2729,10 +2729,8 @@ static int _sde_connector_install_properties(struct drm_device *dev, sizeof(hdr), CONNECTOR_PROP_EXT_HDR_INFO); - /* create and attach colorspace property for DP */ - if (!drm_mode_create_dp_colorspace_property(connector)) - drm_object_attach_property(&connector->base, - connector->colorspace_property, 0); + if (c_conn->ops.install_properties) + c_conn->ops.install_properties(display, connector); } msm_property_install_volatile_range(&c_conn->property_info, diff --git a/msm/sde/sde_connector.h b/msm/sde/sde_connector.h index 41407892db..03c7f306d1 100644 --- a/msm/sde/sde_connector.h +++ b/msm/sde/sde_connector.h @@ -351,6 +351,14 @@ struct sde_connector_ops { */ int (*prepare_commit)(void *display, struct msm_display_conn_params *params); + + /** + * install_properties - install connector properties + * @display: Pointer to private display structure + * @conn: Pointer to drm connector structure + * Returns: Zero on success + */ + int (*install_properties)(void *display, struct drm_connector *conn); }; /** diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index a47b043d56..5c8c7417ca 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1665,6 +1665,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, .get_panel_vfp = dsi_display_get_panel_vfp, .get_default_lms = dsi_display_get_default_lms, .cmd_receive = dsi_display_cmd_receive, + .install_properties = NULL, }; static const struct sde_connector_ops wb_ops = { .post_init = sde_wb_connector_post_init, @@ -1681,6 +1682,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, .cont_splash_config = NULL, .get_panel_vfp = NULL, .cmd_receive = NULL, + .install_properties = NULL, }; static const struct sde_connector_ops dp_ops = { .post_init = dp_connector_post_init, @@ -1699,6 +1701,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, .get_panel_vfp = NULL, .update_pps = dp_connector_update_pps, .cmd_receive = NULL, + .install_properties = dp_connector_install_properties, }; struct msm_display_info info; struct drm_encoder *encoder;