From patchwork Mon Dec 17 15:58:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Vetter X-Patchwork-Id: 1887841 Return-Path: X-Original-To: patchwork-dri-devel@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 F3EAC3FCA5 for ; Mon, 17 Dec 2012 16:02:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A59C5E614C for ; Mon, 17 Dec 2012 08:02:46 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wg0-f45.google.com (mail-wg0-f45.google.com [74.125.82.45]) by gabe.freedesktop.org (Postfix) with ESMTP id 84481E5C64 for ; Mon, 17 Dec 2012 07:59:10 -0800 (PST) Received: by mail-wg0-f45.google.com with SMTP id dq12so2641306wgb.12 for ; Mon, 17 Dec 2012 07:59:10 -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=4p8B4jFze7zyIjd/qRff2NX/u1j248QQ9dMxP8OI6CQ=; b=fh0s/lL2OK2ubchGUsq/w6o431Q+7HsG/jFW2vn60lwFMWJuXyC22lETVc7SGjUL6n bk8y6XRnOyFR0a5vsd4qgNjuBGGgGeLjq0bTzb6V6Y3YUvAc4DEVt9nx11ZbCUvu3zgz qbZXFN01xrMcpuH8obFmqxTVnxhzYFiQ7yxXM= 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=4p8B4jFze7zyIjd/qRff2NX/u1j248QQ9dMxP8OI6CQ=; b=XItETOwj/41EtwJxLkmbg8UyJglS/IdJh3lp453ksoMOimboM45DYzC0bVgqzzoSub YuY5KvwgKTtk/Puh8pUJK6gvwe9kbhMoWWsGYT7CJluRgwCH05w8Toi4Zj82vwu4cqj/ 1mavh9NKuT5D7o997QhTqGtTHdrz6jgYXAgtyV1oMLwqqMJa1mCJjmkcC9praU9pJ0lY KU62Fe81nwvREAbiAe074NI18mgu3zIKNrpNmOFJZA1BIvLelBHtBBLmiN+bEgFOXzcW I9+d6YpkKc/KeY/Dn72CaUnb5LuJ2NPO8WPkDCcBse7o0jKApkc4i2o07/XCyhy95rG/ wT9A== Received: by 10.194.86.72 with SMTP id n8mr18012980wjz.19.1355759949976; Mon, 17 Dec 2012 07:59:09 -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 l5sm13116389wia.10.2012.12.17.07.59.08 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 17 Dec 2012 07:59:09 -0800 (PST) From: Daniel Vetter To: DRI Development Subject: [PATCH 1/2] drm/fb_helper: check whether fbcon is bound Date: Mon, 17 Dec 2012 16:58:59 +0100 Message-Id: <1355759940-7464-2-git-send-email-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1355759940-7464-1-git-send-email-daniel.vetter@ffwll.ch> References: <1355759940-7464-1-git-send-email-daniel.vetter@ffwll.ch> X-Gm-Message-State: ALoCoQlWx6EfISHynBfJg3P+SZ0YrOMNahwXb5hNDyj7TlLjEybo0ufhZ/nB7AXXs34Ztgpp3OQX Cc: Daniel Vetter , Intel Graphics Development 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 We need to make sure that the fbcon is still bound when touching the hw, since otherwise we might corrupt the modeset state of kms clients. X mostly works around that with VT switching and setting the VT into raw mode, which disables most fbcon events. Raw kms test programs though don't do that dance, and in the future we might want to aim to abolish CONFIG_VT anyway. So improve preventive measures a bit. To do so, extract the existing logic for handling hotplug events (which X can't block with the current set of tricks) and reuse it for the fbdev blanking helper. Long-term we really need to either scrap this all and only have a OOPS console, or come up with a saner model for device ownership sharing between fbdev/fbcon and kms userspace. And for those wondering whether this check can't be added to fb_set_par e.g. to prevent undue panning - drm initialization locking is too screwed up for that to work out, I'm sorry :( Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_fb_helper.c | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index be0f2d6..0c6e25e 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -305,6 +305,24 @@ void drm_fb_helper_restore(void) } EXPORT_SYMBOL(drm_fb_helper_restore); +static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper) +{ + struct drm_device *dev = fb_helper->dev; + struct drm_crtc *crtc; + int bound = 0, crtcs_bound = 0; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (crtc->fb) + crtcs_bound++; + if (crtc->fb == fb_helper->fb) + bound++; + } + + if (bound < crtcs_bound) + return false; + return true; +} + #ifdef CONFIG_MAGIC_SYSRQ static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) { @@ -338,6 +356,11 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) * For each CRTC in this fb, turn the connectors on/off. */ drm_modeset_lock_all(dev); + if (!drm_fb_helper_is_bound(fb_helper)) { + drm_modeset_unlock_all(dev); + return; + } + for (i = 0; i < fb_helper->crtc_count; i++) { crtc = fb_helper->crtc_info[i].mode_set.crtc; @@ -702,6 +725,11 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, int i; drm_modeset_lock_all(dev); + if (!drm_fb_helper_is_bound(fb_helper)) { + drm_modeset_unlock_all(dev); + return -EBUSY; + } + for (i = 0; i < fb_helper->crtc_count; i++) { crtc = fb_helper->crtc_info[i].mode_set.crtc; @@ -1369,21 +1397,12 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) struct drm_device *dev = fb_helper->dev; int count = 0; u32 max_width, max_height, bpp_sel; - int bound = 0, crtcs_bound = 0; - struct drm_crtc *crtc; if (!fb_helper->fb) return 0; drm_modeset_lock_all(dev); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (crtc->fb) - crtcs_bound++; - if (crtc->fb == fb_helper->fb) - bound++; - } - - if (bound < crtcs_bound) { + if (!drm_fb_helper_is_bound(fb_helper)) { fb_helper->delayed_hotplug = true; drm_modeset_unlock_all(dev); return 0;