From patchwork Fri Apr 15 05:10:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Airlie X-Patchwork-Id: 8844931 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E32A29FBEA for ; Fri, 15 Apr 2016 05:11:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C90132037C for ; Fri, 15 Apr 2016 05:11:13 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 6BD8C20377 for ; Fri, 15 Apr 2016 05:11:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 584C36EB7B; Fri, 15 Apr 2016 05:11:05 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTPS id EE9376E114 for ; Fri, 15 Apr 2016 05:10:53 +0000 (UTC) Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9467F552D2 for ; Fri, 15 Apr 2016 05:10:53 +0000 (UTC) Received: from dreadlord-bne-redhat-com.bne.redhat.com (dhcp-40-179.bne.redhat.com [10.64.40.179]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u3F5AlYi005176 for ; Fri, 15 Apr 2016 01:10:52 -0400 From: Dave Airlie To: dri-devel@lists.freedesktop.org Subject: [PATCH 05/15] drm/mode: move framebuffer reference into object. Date: Fri, 15 Apr 2016 15:10:36 +1000 Message-Id: <1460697046-23781-6-git-send-email-airlied@gmail.com> In-Reply-To: <1460697046-23781-1-git-send-email-airlied@gmail.com> References: <1460697046-23781-1-git-send-email-airlied@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 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=-5.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,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 From: Dave Airlie This is the initial code to add references to some mode objects. In the future we need to start reference counting connectors so firstly I want to reorganise the code so the framebuffer ref counting uses the same paths. This patch shouldn't change any functionality, just moves the kref. Signed-off-by: Dave Airlie Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 72 ++++++++++++++++++++++++---------------------- include/drm/drm_crtc.h | 20 ++++++++++--- 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8616737..75a45e9 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -275,7 +275,8 @@ EXPORT_SYMBOL(drm_get_format_name); static int drm_mode_object_get_reg(struct drm_device *dev, struct drm_mode_object *obj, uint32_t obj_type, - bool register_obj) + bool register_obj, + void (*obj_free_cb)(struct kref *kref)) { int ret; @@ -288,6 +289,10 @@ static int drm_mode_object_get_reg(struct drm_device *dev, */ obj->id = ret; obj->type = obj_type; + if (obj_free_cb) { + obj->free_cb = obj_free_cb; + kref_init(&obj->refcount); + } } mutex_unlock(&dev->mode_config.idr_mutex); @@ -311,7 +316,7 @@ static int drm_mode_object_get_reg(struct drm_device *dev, int drm_mode_object_get(struct drm_device *dev, struct drm_mode_object *obj, uint32_t obj_type) { - return drm_mode_object_get_reg(dev, obj, obj_type, true); + return drm_mode_object_get_reg(dev, obj, obj_type, true, NULL); } static void drm_mode_object_register(struct drm_device *dev, @@ -389,10 +394,35 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, } EXPORT_SYMBOL(drm_mode_object_find); +void drm_mode_object_unreference(struct drm_mode_object *obj) +{ + if (obj->free_cb) { + DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount)); + kref_put(&obj->refcount, obj->free_cb); + } +} +EXPORT_SYMBOL(drm_mode_object_unreference); + +/** + * drm_mode_object_reference - incr the fb refcnt + * @obj: mode_object + * + * This function operates only on refcounted objects. + * This functions increments the object's refcount. + */ +void drm_mode_object_reference(struct drm_mode_object *obj) +{ + if (obj->free_cb) { + DRM_DEBUG("OBJ ID: %d (%d)\n", obj->id, atomic_read(&obj->refcount.refcount)); + kref_get(&obj->refcount); + } +} +EXPORT_SYMBOL(drm_mode_object_reference); + static void drm_framebuffer_free(struct kref *kref) { struct drm_framebuffer *fb = - container_of(kref, struct drm_framebuffer, refcount); + container_of(kref, struct drm_framebuffer, base.refcount); struct drm_device *dev = fb->dev; /* @@ -430,12 +460,12 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, int ret; mutex_lock(&dev->mode_config.fb_lock); - kref_init(&fb->refcount); INIT_LIST_HEAD(&fb->filp_head); fb->dev = dev; fb->funcs = funcs; - ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB); + ret = drm_mode_object_get_reg(dev, &fb->base, DRM_MODE_OBJECT_FB, + true, drm_framebuffer_free); if (ret) goto out; @@ -482,7 +512,7 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, mutex_lock(&dev->mode_config.fb_lock); fb = __drm_framebuffer_lookup(dev, id); if (fb) { - if (!kref_get_unless_zero(&fb->refcount)) + if (!kref_get_unless_zero(&fb->base.refcount)) fb = NULL; } mutex_unlock(&dev->mode_config.fb_lock); @@ -492,32 +522,6 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, EXPORT_SYMBOL(drm_framebuffer_lookup); /** - * drm_framebuffer_unreference - unref a framebuffer - * @fb: framebuffer to unref - * - * This functions decrements the fb's refcount and frees it if it drops to zero. - */ -void drm_framebuffer_unreference(struct drm_framebuffer *fb) -{ - DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount)); - kref_put(&fb->refcount, drm_framebuffer_free); -} -EXPORT_SYMBOL(drm_framebuffer_unreference); - -/** - * drm_framebuffer_reference - incr the fb refcnt - * @fb: framebuffer - * - * This functions increments the fb's refcount. - */ -void drm_framebuffer_reference(struct drm_framebuffer *fb) -{ - DRM_DEBUG("%p: FB ID: %d (%d)\n", fb, fb->base.id, atomic_read(&fb->refcount.refcount)); - kref_get(&fb->refcount); -} -EXPORT_SYMBOL(drm_framebuffer_reference); - -/** * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr * @fb: fb to unregister * @@ -902,7 +906,7 @@ int drm_connector_init(struct drm_device *dev, drm_modeset_lock_all(dev); - ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false); + ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false, NULL); if (ret) goto out_unlock; @@ -5922,7 +5926,7 @@ void drm_mode_config_cleanup(struct drm_device *dev) */ WARN_ON(!list_empty(&dev->mode_config.fb_list)); list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { - drm_framebuffer_free(&fb->refcount); + drm_framebuffer_free(&fb->base.refcount); } list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list, diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 99a12f0..576faf4 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -59,6 +59,8 @@ struct drm_mode_object { uint32_t id; uint32_t type; struct drm_object_properties *properties; + struct kref refcount; + void (*free_cb)(struct kref *kref); }; #define DRM_OBJECT_MAX_PROPERTY 24 @@ -233,8 +235,8 @@ struct drm_framebuffer { * should be deferred. In cases like this, the driver would like to * hold a ref to the fb even though it has already been removed from * userspace perspective. + * The refcount is stored inside the mode object. */ - struct kref refcount; /* * Place on the dev->mode_config.fb_list, access protected by * dev->mode_config.fb_lock. @@ -2386,8 +2388,6 @@ extern int drm_framebuffer_init(struct drm_device *dev, const struct drm_framebuffer_funcs *funcs); extern struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, uint32_t id); -extern void drm_framebuffer_unreference(struct drm_framebuffer *fb); -extern void drm_framebuffer_reference(struct drm_framebuffer *fb); extern void drm_framebuffer_remove(struct drm_framebuffer *fb); extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb); extern void drm_framebuffer_unregister_private(struct drm_framebuffer *fb); @@ -2445,6 +2445,8 @@ extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size); extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type); +void drm_mode_object_reference(struct drm_mode_object *obj); +void drm_mode_object_unreference(struct drm_mode_object *obj); /* IOCTLs */ extern int drm_mode_getresources(struct drm_device *dev, @@ -2608,9 +2610,19 @@ static inline uint32_t drm_color_lut_extract(uint32_t user_input, return clamp_val(val, 0, max); } +static inline void drm_framebuffer_reference(struct drm_framebuffer *fb) +{ + drm_mode_object_reference(&fb->base); +} + +static inline void drm_framebuffer_unreference(struct drm_framebuffer *fb) +{ + drm_mode_object_unreference(&fb->base); +} + static inline uint32_t drm_framebuffer_read_refcount(struct drm_framebuffer *fb) { - return atomic_read(&fb->refcount.refcount); + return atomic_read(&fb->base.refcount.refcount); } /* Plane list iterator for legacy (overlay only) planes. */