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: 1866741 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 4F5E24006E for ; Wed, 12 Dec 2012 14:04:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2F538E5EF6 for ; Wed, 12 Dec 2012 06:04:11 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-ea0-f177.google.com (mail-ea0-f177.google.com [209.85.215.177]) by gabe.freedesktop.org (Postfix) with ESMTP id 78E14E63B7 for ; Wed, 12 Dec 2012 05:13:26 -0800 (PST) Received: by mail-ea0-f177.google.com with SMTP id c10so221537eaa.36 for ; Wed, 12 Dec 2012 05:13:25 -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=GOIZkCearsbbJ5v/gLcWc2hpGjETdo9eaaPI5cqeF2b0p2X0MNG1c+QeyDmR1SeZrT KOYVQnQYwgmWbiiUTY3vqo5Jud70qpw72ZOK0aKLS5SJ5w4CZKMswILlERFGoDw10vEb M3V5guFQmaFb58jPvT/2yFfGnJ2CzmkloE+jvnVjcXA0idAUUxPb2SSUOPD9LJu9hxWb Fw6eRNuUKZzcxF9b//tZrU2YyHLi6Jwl+rJJ2PVrGVP57PS6+Tg/JUpWrgLMxrdy0PFW pKx1IOm3s8wS00QIjfuHDSZiCld1x3x2s5mC1k8PG3lU7UbKJ5Ay3Hu/n4iIoW/rPSp4 twNw== 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 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: ALoCoQkXNMcosknQvm9TUOKCIMso4ygeGo9656pDcV9jd66+CZwizh2Pw4/XjHtEFDAqJIF2R0MG Cc: Nouveau Dev , Intel Graphics Development , Radeon Dev , Daniel Vetter Subject: [Intel-gfx] [PATCH 27/37] drm: refcounting for sprite framebuffers X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=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; }