From patchwork Wed Dec 12 13:07:07 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 1866991 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 2DE95DF2EE for ; Wed, 12 Dec 2012 14:24:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 15B4DE659F for ; Wed, 12 Dec 2012 06:24:12 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-ee0-f49.google.com (mail-ee0-f49.google.com [74.125.83.49]) by gabe.freedesktop.org (Postfix) with ESMTP id E746DE6533 for ; Wed, 12 Dec 2012 05:14:43 -0800 (PST) Received: by mail-ee0-f49.google.com with SMTP id c4so430034eek.36 for ; Wed, 12 Dec 2012 05:14:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=ZpxMls5OFQGuIE7JbsKfJbvMW8k5JMjVxKE2kA8IWAE=; b=DFidm+SsX8ZqMScdcR7EM/tnQLWFTTVvYR1rCuWf0ZShXnTEw/7fz3doejgoqbmzxa fUHc8tBEGL6Uo2sfULKHrKg7d7OwciFPjZFIgFjCLnCeSIaW3vMzgFqsnndznt20kRQ+ jJXt9MLT5529FQ5RKcv4Kq4e2Npi7bGbLy3BE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=ZpxMls5OFQGuIE7JbsKfJbvMW8k5JMjVxKE2kA8IWAE=; b=fhG8OOnOrj/ANnjziK7eRZgnFw0K07plJ+wU/9Hy7NT5r/xzaUFXqeeOxHdN0iQV9I UinqwoitIfDMFsFuQumXVV1aFt+oTF2Q+iPaOBi6P6AUHRRsYUzqFS9lvh1mnnQhoZGh T9bHVmIlOC7Z17upPIDpYSdWNjQSnvESIgWgx3UuxSTaKcJDh0BhIq9Y27yubiYGXXhk 31uElld7h0EqjIKfY6HUmyGu7x8VuSMYl6IsnRNcz6dssChNvfN4fyfJLIP6IbQAv7z7 hiL92m4VK0z6k0CGs+UP7mxIzn6FkyD8acNeEXy7gG+WJ8JrTD2xO7UTCE7BGUT7diyg oG4g== Received: by 10.14.213.134 with SMTP id a6mr2718274eep.45.1355317670275; Wed, 12 Dec 2012 05:07:50 -0800 (PST) Received: from biers.ffwll.local (178-83-130-250.dynamic.hispeed.ch. [178.83.130.250]) by mx.google.com with ESMTPS id r1sm55868541eeo.2.2012.12.12.05.07.49 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 12 Dec 2012 05:07:49 -0800 (PST) From: Daniel Vetter To: DRI Development Subject: [PATCH 27/37] drm: refcounting for sprite framebuffers Date: Wed, 12 Dec 2012 14:07:07 +0100 Message-Id: <1355317637-16742-28-git-send-email-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1355317637-16742-1-git-send-email-daniel.vetter@ffwll.ch> References: <1355317637-16742-1-git-send-email-daniel.vetter@ffwll.ch> X-Gm-Message-State: ALoCoQmD0EdC89XEnfd+Be6ObesfPPLbAxoWYqQ3+iKm0B/i3+LTCw9SU693itorQejmRtFLWpUu Cc: Nouveau Dev , Intel Graphics Development , Radeon Dev , Daniel Vetter X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Now plane->fb holds a reference onto it's framebuffer. Nothing too fancy going on here: - Extract __drm_framebuffer_unreference to be called when we know we're not dropping the last reference, e.g. useful in the fb cleanup code. - Reduce the locked sections in the set_plane ioctl to only protect plane->fb/plane->crtc and the driver callback (i.e. hw state). Everything either doesn't disappear (crtc, plane) or is refcounted (fb), and all the data we check is invariant over the respective object's lifetimes. Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8132e13..ccf15ad 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -444,6 +444,12 @@ static void drm_framebuffer_free_bug(struct kref *kref) BUG(); } +static void __drm_framebuffer_unreference(struct drm_framebuffer *fb) +{ + DRM_DEBUG("FB ID: %d\n", fb->base.id); + kref_put(&fb->refcount, drm_framebuffer_free_bug); +} + /* dev->mode_config.fb_lock must be held! */ static void __drm_framebuffer_unregister(struct drm_device *dev, struct drm_framebuffer *fb) @@ -454,7 +460,7 @@ static void __drm_framebuffer_unregister(struct drm_device *dev, fb->base.id = 0; - kref_put(&fb->refcount, drm_framebuffer_free_bug); + __drm_framebuffer_unreference(fb); } /** @@ -543,6 +549,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) if (ret) DRM_ERROR("failed to disable plane with busy fb\n"); /* disconnect the plane from the fb and crtc: */ + __drm_framebuffer_unreference(plane->fb); plane->fb = NULL; plane->crtc = NULL; } @@ -1849,7 +1856,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data, struct drm_mode_object *obj; struct drm_plane *plane; struct drm_crtc *crtc; - struct drm_framebuffer *fb; + struct drm_framebuffer *fb = NULL, *old_fb = NULL; int ret = 0; unsigned int fb_width, fb_height; int i; @@ -1857,8 +1864,6 @@ int drm_mode_setplane(struct drm_device *dev, void *data, if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; - drm_modeset_lock_all(dev); - /* * First, find the plane, crtc, and fb objects. If not available, * we don't bother to call the driver. @@ -1868,16 +1873,18 @@ int drm_mode_setplane(struct drm_device *dev, void *data, if (!obj) { DRM_DEBUG_KMS("Unknown plane ID %d\n", plane_req->plane_id); - ret = -ENOENT; - goto out; + return -ENOENT; } plane = obj_to_plane(obj); /* No fb means shut it down */ if (!plane_req->fb_id) { + drm_modeset_lock_all(dev); + old_fb = plane->fb; plane->funcs->disable_plane(plane); plane->crtc = NULL; plane->fb = NULL; + drm_modeset_unlock_all(dev); goto out; } @@ -1898,8 +1905,6 @@ int drm_mode_setplane(struct drm_device *dev, void *data, ret = -ENOENT; goto out; } - /* fb is protect by the mode_config lock, so drop the ref immediately */ - drm_framebuffer_unreference(fb); /* Check whether this plane supports the fb pixel format. */ for (i = 0; i < plane->format_count; i++) @@ -1945,18 +1950,25 @@ int drm_mode_setplane(struct drm_device *dev, void *data, goto out; } + drm_modeset_lock_all(dev); ret = plane->funcs->update_plane(plane, crtc, fb, plane_req->crtc_x, plane_req->crtc_y, plane_req->crtc_w, plane_req->crtc_h, plane_req->src_x, plane_req->src_y, plane_req->src_w, plane_req->src_h); if (!ret) { + old_fb = plane->fb; + fb = NULL; plane->crtc = crtc; plane->fb = fb; } + drm_modeset_unlock_all(dev); out: - drm_modeset_unlock_all(dev); + if (fb) + drm_framebuffer_unreference(fb); + if (old_fb) + drm_framebuffer_unreference(old_fb); return ret; }