From patchwork Fri Jul 25 22:51:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 4626071 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E85CC9F36A for ; Fri, 25 Jul 2014 22:51:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BEECC201F4 for ; Fri, 25 Jul 2014 22:51:20 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 7E9ED20172 for ; Fri, 25 Jul 2014 22:51:19 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 059A96E0B0; Fri, 25 Jul 2014 15:51:18 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qg0-f41.google.com (mail-qg0-f41.google.com [209.85.192.41]) by gabe.freedesktop.org (Postfix) with ESMTP id A1CFF6E0B5 for ; Fri, 25 Jul 2014 15:51:16 -0700 (PDT) Received: by mail-qg0-f41.google.com with SMTP id q107so5789698qgd.0 for ; Fri, 25 Jul 2014 15:51:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=c2ssUdJYdqE1Wi64HqNmViYzgXFEWLS0TiRb+0ZGZk0=; b=yUo5xYw2IgW5p38fvKqcNDS+04bbH3d3a8/OaNaQ06t6IWaOtWbYDLLTPFaTEybw+S Av6powo2qlicp1FMPSFHfBdZfOg4Cg/Q/qZ3xxyf/uL2ATmdtn9aI5WTI9r9Z4OxwzMI obvHn2WE3145PqoW/YK0vv34KYLljZIYdQ1iG+VCTRywsQx7qzqF36G9REOxySjsW0/l R+r7TjOEaabh0JvTAv3HGuOlS9hVsHOpDUyJT0drNfnX5sz6l/RiUuz2MA7Lk4g05koq bkS3YVaoiz06d6HtVDSdCSMEO895gaId5nlMkt7jRwJo/CYwJ5Bmpa4thDzy9GUCM6Cp Pecg== X-Received: by 10.140.30.73 with SMTP id c67mr31706887qgc.16.1406328675902; Fri, 25 Jul 2014 15:51:15 -0700 (PDT) Received: from localhost (pool-108-20-250-182.bstnma.east.verizon.net. [108.20.250.182]) by mx.google.com with ESMTPSA id 106sm12771779qgo.16.2014.07.25.15.51.14 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 25 Jul 2014 15:51:15 -0700 (PDT) From: Rob Clark To: dri-devel@lists.freedesktop.org Subject: [PATCH] drm: refcnt drm_display_mode Date: Fri, 25 Jul 2014 18:51:10 -0400 Message-Id: <1406328670-1186-1-git-send-email-robdclark@gmail.com> X-Mailer: git-send-email 1.9.3 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We're going to need this for atomic. Signed-off-by: Rob Clark --- drivers/gpu/drm/drm_crtc.c | 4 +-- drivers/gpu/drm/drm_crtc_helper.c | 2 +- drivers/gpu/drm/drm_edid.c | 6 ++-- drivers/gpu/drm/drm_fb_helper.c | 6 ++-- drivers/gpu/drm/drm_modes.c | 41 ++++++++++++++++++++------- drivers/gpu/drm/exynos/exynos_drm_connector.c | 2 +- drivers/gpu/drm/gma500/psb_intel_sdvo.c | 3 +- drivers/gpu/drm/i915/intel_panel.c | 8 ++---- drivers/gpu/drm/i915/intel_sdvo.c | 3 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 2 +- drivers/gpu/drm/omapdrm/omap_connector.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 +-- include/drm/drm_modes.h | 5 +++- 13 files changed, 52 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 1ccf5cb..7a7fced 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -822,7 +822,7 @@ static void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode) { list_del(&mode->head); - drm_mode_destroy(connector->dev, mode); + drm_mode_unreference(mode); } /** @@ -2602,7 +2602,7 @@ out: drm_framebuffer_unreference(fb); kfree(connector_set); - drm_mode_destroy(dev, mode); + drm_mode_unreference(mode); drm_modeset_unlock_all(dev); return ret; } diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 6c65a0a..757de8b 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -384,7 +384,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, /* FIXME: add subpixel order */ done: - drm_mode_destroy(dev, adjusted_mode); + drm_mode_unreference(adjusted_mode); if (!ret) { crtc->enabled = saved_enabled; crtc->mode = saved_mode; diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 087d608..cbc021d 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1705,7 +1705,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid, if (!mode) return NULL; if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) { - drm_mode_destroy(dev, mode); + drm_mode_unreference(mode); mode = drm_gtf_mode_complex(dev, hsize, vsize, vrefresh_rate, 0, 0, drm_gtf2_m(edid), @@ -2021,7 +2021,7 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, fixup_mode_1366x768(newmode); if (!mode_in_range(newmode, edid, timing) || !valid_inferred_mode(connector, newmode)) { - drm_mode_destroy(dev, newmode); + drm_mode_unreference(newmode); continue; } @@ -2050,7 +2050,7 @@ drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid, fixup_mode_1366x768(newmode); if (!mode_in_range(newmode, edid, timing) || !valid_inferred_mode(connector, newmode)) { - drm_mode_destroy(dev, newmode); + drm_mode_unreference(newmode); continue; } diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 3144db9..5c96a6a 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -588,7 +588,7 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) 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); + drm_mode_unreference(helper->crtc_info[i].mode_set.mode); } kfree(helper->crtc_info); } @@ -1606,7 +1606,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) mode->name, fb_crtc->mode_set.crtc->base.id); fb_crtc->desired_mode = mode; if (modeset->mode) - drm_mode_destroy(dev, modeset->mode); + drm_mode_unreference(modeset->mode); modeset->mode = drm_mode_duplicate(dev, fb_crtc->desired_mode); modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector; @@ -1621,7 +1621,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) BUG_ON(modeset->fb); BUG_ON(modeset->num_connectors); if (modeset->mode) - drm_mode_destroy(dev, modeset->mode); + drm_mode_unreference(modeset->mode); modeset->mode = NULL; } } diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index bedf189..55d51ed 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -82,27 +82,46 @@ struct drm_display_mode *drm_mode_create(struct drm_device *dev) return NULL; } + kref_init(&nmode->refcount); + nmode->dev = dev; + return nmode; } EXPORT_SYMBOL(drm_mode_create); /** - * drm_mode_destroy - remove a mode - * @dev: DRM device + * drm_mode_reference - incr the mode's refcnt + * @mode: display mode + * + * This functions increments the mode's refcount. + */ +void drm_mode_reference(struct drm_display_mode *mode) +{ + kref_get(&mode->refcount); +} +EXPORT_SYMBOL(drm_mode_reference); + +static void drm_mode_free(struct kref *kref) +{ + struct drm_display_mode *mode = + container_of(kref, struct drm_display_mode, refcount); + drm_mode_object_put(mode->dev, &mode->base); + kfree(mode); +} + +/** + * drm_mode_unreference - decrement the mode's refcnt * @mode: mode to remove * - * Release @mode's unique ID, then free it @mode structure itself using kfree. + * Decrement the mode's refcount, freeing it after last ref is dropped. */ -void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode) +void drm_mode_unreference(struct drm_display_mode *mode) { if (!mode) return; - - drm_mode_object_put(dev, &mode->base); - - kfree(mode); + kref_put(&mode->refcount, drm_mode_free); } -EXPORT_SYMBOL(drm_mode_destroy); +EXPORT_SYMBOL(drm_mode_unreference); /** * drm_mode_probed_add - add a mode to a connector's probed_mode list @@ -957,7 +976,7 @@ void drm_mode_prune_invalid(struct drm_device *dev, DRM_DEBUG_KMS("Not using %s mode %d\n", mode->name, mode->status); } - drm_mode_destroy(dev, mode); + drm_mode_unreference(mode); } } } @@ -1046,7 +1065,7 @@ void drm_mode_connector_list_update(struct drm_connector *connector, else mode->type = pmode->type; list_del(&pmode->head); - drm_mode_destroy(connector->dev, pmode); + drm_mode_unreference(pmode); break; } } diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index ba9b3d5..3f9d44a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c @@ -72,7 +72,7 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) if (display->ops->get_panel) panel = display->ops->get_panel(display); else { - drm_mode_destroy(connector->dev, mode); + drm_mode_unreference(mode); return 0; } diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 0be96fd..00eb0f63 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -1905,8 +1905,7 @@ static void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder) struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); if (psb_intel_sdvo->sdvo_lvds_fixed_mode != NULL) - drm_mode_destroy(encoder->dev, - psb_intel_sdvo->sdvo_lvds_fixed_mode); + drm_mode_unreference(psb_intel_sdvo->sdvo_lvds_fixed_mode); i2c_del_adapter(&psb_intel_sdvo->ddc); gma_encoder_destroy(encoder); diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 38a9857..cbf63e0 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1205,13 +1205,9 @@ int intel_panel_init(struct intel_panel *panel, void intel_panel_fini(struct intel_panel *panel) { - struct intel_connector *intel_connector = - container_of(panel, struct intel_connector, panel); - if (panel->fixed_mode) - drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode); + drm_mode_unreference(panel->fixed_mode); if (panel->downclock_mode) - drm_mode_destroy(intel_connector->base.dev, - panel->downclock_mode); + drm_mode_unreference(panel->downclock_mode); } diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 9350edd..7049ac7 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2248,8 +2248,7 @@ static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) struct intel_sdvo *intel_sdvo = to_sdvo(to_intel_encoder(encoder)); if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) - drm_mode_destroy(encoder->dev, - intel_sdvo->sdvo_lvds_fixed_mode); + drm_mode_unreference(intel_sdvo->sdvo_lvds_fixed_mode); i2c_del_adapter(&intel_sdvo->ddc); intel_encoder_destroy(encoder); diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index dbdc9ad..876ae75 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -739,7 +739,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) /* destroy the native mode, the attached monitor could have changed. */ if (nv_connector->native_mode) { - drm_mode_destroy(dev, nv_connector->native_mode); + drm_mode_unreference(nv_connector->native_mode); nv_connector->native_mode = NULL; } diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 36bc5cc..222d42a 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -224,7 +224,7 @@ static int omap_connector_mode_valid(struct drm_connector *connector, new_mode->vrefresh = 0; if (mode->vrefresh == drm_mode_vrefresh(new_mode)) ret = MODE_OK; - drm_mode_destroy(dev, new_mode); + drm_mode_unreference(new_mode); } DBG("connector: mode %s: " diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index d2bc2b0..d726a81 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1964,13 +1964,13 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, mode->vdisplay)) { drm_mode_probed_add(connector, mode); } else { - drm_mode_destroy(dev, mode); + drm_mode_unreference(mode); mode = NULL; } if (du->pref_mode) { list_del_init(&du->pref_mode->head); - drm_mode_destroy(dev, du->pref_mode); + drm_mode_unreference(du->pref_mode); } /* mode might be null here, this is intended */ diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 91d0582..ef552c9 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -97,6 +97,8 @@ struct drm_display_mode { /* Header */ struct list_head head; struct drm_mode_object base; + struct kref refcount; + struct drm_device *dev; char name[DRM_DISPLAY_MODE_LEN]; @@ -178,7 +180,8 @@ struct drm_connector; struct drm_cmdline_mode; struct drm_display_mode *drm_mode_create(struct drm_device *dev); -void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); +void drm_mode_reference(struct drm_display_mode *mode); +void drm_mode_unreference(struct drm_display_mode *mode); void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); void drm_mode_debug_printmodeline(const struct drm_display_mode *mode);