From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linuxfoundation.org ([140.211.169.12]:48246 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751314AbcKIIf2 (ORCPT ); Wed, 9 Nov 2016 03:35:28 -0500 Subject: Patch "drm/fb-helper: Keep references for the current set of used connectors" has been added to the 4.4-stable tree To: ville.syrjala@linux.intel.com, carlos.santa@intel.com, chris@chris-wilson.co.uk, daniel.vetter@ffwll.ch, gregkh@linuxfoundation.org, kirill@shutemov.name Cc: , From: Date: Wed, 09 Nov 2016 09:35:30 +0100 Message-ID: <1478680530225167@kroah.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org List-ID: This is a note to let you know that I've just added the patch titled drm/fb-helper: Keep references for the current set of used connectors to the 4.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: drm-fb-helper-keep-references-for-the-current-set-of-used-connectors.patch and it can be found in the queue-4.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let know about it. >>From a2889606636d135148de101fe3311dfea67baf1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 26 Oct 2016 17:41:18 +0300 Subject: drm/fb-helper: Keep references for the current set of used connectors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Ville Syrjälä commit a2889606636d135148de101fe3311dfea67baf1c upstream. The fbdev helper code keeps around two lists of connectors. One is the list of all connectors it could use, and that list already holds references for all the connectors. However the other list, or rather lists, is the one actively being used. That list is tracked per-crtc and currently doesn't hold any extra references. Let's grab those extra references to avoid oopsing when the connector vanishes. The list of all possible connectors should get updated when the hpd happens, but the list of actively used connectors would not get updated until the next time the fb-helper picks through the set of possible connectors. And so we need to hang on to the connectors until that time. Since we need to clean up in drm_fb_helper_crtc_free() as well, let's pull the code to a common place. And while at it let's pull in up the modeset->mode cleanup in there as well. The case of modeset->fb is a bit less clear. I'm thinking we should probably hold a reference to it, but for now I just slapped on a FIXME. v2: Cleanup things drm_fb_helper_crtc_free() too (Chris) v3: Don't leak modeset->connectors (Chris) Cc: Chris Wilson Cc: Carlos Santa Cc: Kirill A. Shutemov Tested-by: Carlos Santa (v1) Tested-by: Kirill A. Shutemov (v1) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97666 Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1477492878-4990-1-git-send-email-ville.syrjala@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_fb_helper.c | 57 +++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 24 deletions(-) --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -631,6 +631,24 @@ int drm_fb_helper_blank(int blank, struc } EXPORT_SYMBOL(drm_fb_helper_blank); +static void drm_fb_helper_modeset_release(struct drm_fb_helper *helper, + struct drm_mode_set *modeset) +{ + int i; + + for (i = 0; i < modeset->num_connectors; i++) { + drm_connector_unreference(modeset->connectors[i]); + modeset->connectors[i] = NULL; + } + modeset->num_connectors = 0; + + drm_mode_destroy(helper->dev, modeset->mode); + modeset->mode = NULL; + + /* FIXME should hold a ref? */ + modeset->fb = NULL; +} + static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) { int i; @@ -638,10 +656,12 @@ static void drm_fb_helper_crtc_free(stru for (i = 0; i < helper->connector_count; i++) kfree(helper->connector_info[i]); kfree(helper->connector_info); + for (i = 0; i < helper->crtc_count; i++) { - kfree(helper->crtc_info[i].mode_set.connectors); - if (helper->crtc_info[i].mode_set.mode) - drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode); + struct drm_mode_set *modeset = &helper->crtc_info[i].mode_set; + + drm_fb_helper_modeset_release(helper, modeset); + kfree(modeset->connectors); } kfree(helper->crtc_info); } @@ -1983,7 +2003,6 @@ static void drm_setup_crtcs(struct drm_f struct drm_fb_helper_crtc **crtcs; struct drm_display_mode **modes; struct drm_fb_offset *offsets; - struct drm_mode_set *modeset; bool *enabled; int width, height; int i; @@ -2031,45 +2050,35 @@ static void drm_setup_crtcs(struct drm_f /* need to set the modesets up here for use later */ /* fill out the connector<->crtc mappings into the modesets */ - for (i = 0; i < fb_helper->crtc_count; i++) { - modeset = &fb_helper->crtc_info[i].mode_set; - modeset->num_connectors = 0; - modeset->fb = NULL; - } + for (i = 0; i < fb_helper->crtc_count; i++) + drm_fb_helper_modeset_release(fb_helper, + &fb_helper->crtc_info[i].mode_set); for (i = 0; i < fb_helper->connector_count; i++) { struct drm_display_mode *mode = modes[i]; struct drm_fb_helper_crtc *fb_crtc = crtcs[i]; struct drm_fb_offset *offset = &offsets[i]; - modeset = &fb_crtc->mode_set; + struct drm_mode_set *modeset = &fb_crtc->mode_set; if (mode && fb_crtc) { + struct drm_connector *connector = + fb_helper->connector_info[i]->connector; + DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n", mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y); + fb_crtc->desired_mode = mode; fb_crtc->x = offset->x; fb_crtc->y = offset->y; - if (modeset->mode) - drm_mode_destroy(dev, modeset->mode); modeset->mode = drm_mode_duplicate(dev, fb_crtc->desired_mode); - modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector; + drm_connector_reference(connector); + modeset->connectors[modeset->num_connectors++] = connector; modeset->fb = fb_helper->fb; modeset->x = offset->x; modeset->y = offset->y; } } - - /* Clear out any old modes if there are no more connected outputs. */ - for (i = 0; i < fb_helper->crtc_count; i++) { - modeset = &fb_helper->crtc_info[i].mode_set; - if (modeset->num_connectors == 0) { - BUG_ON(modeset->fb); - if (modeset->mode) - drm_mode_destroy(dev, modeset->mode); - modeset->mode = NULL; - } - } out: kfree(crtcs); kfree(modes); Patches currently in stable-queue which might be from ville.syrjala@linux.intel.com are queue-4.4/usb-gadget-function-u_ether-don-t-starve-tx-request-queue.patch queue-4.4/drm-i915-clean-up-ddi-ddc-aux-ch-sanitation.patch queue-4.4/drm-dp-mst-check-peer-device-type-before-attempting-edid-read.patch queue-4.4/drm-fb-helper-keep-references-for-the-current-set-of-used-connectors.patch queue-4.4/drm-dp-mst-clear-port-pdt-when-tearing-down-the-i2c-adapter.patch queue-4.4/drm-fb-helper-fix-connector-ref-leak-on-error.patch