Take a reference to existing modes, rather than duplicating them to
create new ones.

Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 drivers/gpu/drm/drm_crtc_helper.c | 43 ++++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc_helper.c 
b/drivers/gpu/drm/drm_crtc_helper.c
index c23f31f..08f0367 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -301,7 +301,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
         * setting.
         */
        if (mode)
-               crtc->mode = drm_mode_duplicate(crtc->dev, mode);
+               crtc->mode = drm_mode_reference(mode);
        else
                crtc->mode = NULL;
        crtc->x = x;
@@ -421,7 +421,8 @@ done:
                crtc->x = saved_x;
                crtc->y = saved_y;
        } else {
-               drm_mode_destroy(dev, saved_mode);
+               if (saved_mode)
+                       drm_mode_destroy(dev, saved_mode);
        }

        return ret;
@@ -547,7 +548,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
        }

        save_set.crtc = set->crtc;
-       save_set.mode = set->crtc->mode;
+       if (set->crtc->mode)
+               save_set.mode = drm_mode_reference(set->crtc->mode);
+       else
+               save_set.mode = NULL;
        save_set.x = set->crtc->x;
        save_set.y = set->crtc->y;
        save_set.fb = set->crtc->primary->fb;
@@ -718,6 +722,8 @@ fail:
                                      save_set.y, save_set.fb))
                DRM_ERROR("failed to restore config after modeset failure\n");

+       if (save_set.mode)
+               drm_mode_destroy(dev, save_set.mode);
        kfree(save_connectors);
        kfree(save_encoders);
        return ret;
@@ -954,29 +960,9 @@ int drm_helper_crtc_mode_set(struct drm_crtc *crtc,
        else if (crtc->state) {
                crtc_state = kmemdup(crtc->state, sizeof(*crtc_state),
                                     GFP_KERNEL);
-               /* XXX: this is unpleasant: we should mandate dup instead */
-               if (crtc_state) {
-                       crtc_state->mode =
-                               drm_mode_duplicate(crtc->dev,
-                                                  crtc->state->mode);
-                       if (!crtc_state->mode) {
-                               kfree(crtc_state);
-                               crtc_state = NULL;
-                       }
-               }
        }
-       else {
+       else
                crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
-               if (crtc_state) {
-                       crtc_state->mode = kzalloc(sizeof(*crtc_state->mode),
-                                                  GFP_KERNEL);
-                       /* XXX: as above, but mandate a new_state */
-                       if (!crtc_state->mode) {
-                               kfree(crtc_state);
-                               crtc_state = NULL;
-                       }
-               }
-       }
        if (!crtc_state)
                return -ENOMEM;
        crtc_state->crtc = crtc;
@@ -984,7 +970,12 @@ int drm_helper_crtc_mode_set(struct drm_crtc *crtc,
        crtc_state->enable = true;
        crtc_state->planes_changed = true;
        crtc_state->mode_changed = true;
-       drm_mode_copy(crtc_state->mode, mode);
+       if (crtc_state->mode)
+               drm_mode_destroy(crtc->dev, crtc_state->mode);
+       if (mode)
+               crtc_state->mode = drm_mode_reference(mode);
+       else
+               crtc_state->mode = NULL;
        drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode);

        if (crtc_funcs->atomic_check) {
@@ -1006,7 +997,7 @@ int drm_helper_crtc_mode_set(struct drm_crtc *crtc,
                if (crtc->funcs->atomic_destroy_state)
                        crtc->funcs->atomic_destroy_state(crtc, crtc_state);
                else {
-                       kfree(crtc_state->mode);
+                       drm_mode_destroy(crtc->dev, crtc_state->mode);
                        kfree(crtc_state);
                }
        }
-- 
2.3.2

Reply via email to