Blob Blame History Raw
From bdac4a052a47920eeae22441ab608612dc0ef4e5 Mon Sep 17 00:00:00 2001
From: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Tue, 4 Jul 2017 17:18:24 +0200
Subject: [PATCH] drm/fb-helper: Push locking in fb_is_bound
Git-commit: bdac4a052a47920eeae22441ab608612dc0ef4e5
Patch-mainline: v4.14-rc1
References: FATE#322643 bsc#1055900

That function only needs to take the individual crtc locks, not all
the kms locks. Push down the locking and then minimize it.

Cc: John Stultz <john.stultz@linaro.org>
Cc: Thierry Reding <treding@nvidia.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170704151833.17304-5-daniel.vetter@ffwll.ch
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/gpu/drm/drm_fb_helper.c |   24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -543,10 +543,12 @@ static bool drm_fb_helper_is_bound(struc
 		return false;
 
 	drm_for_each_crtc(crtc, dev) {
+		drm_modeset_lock(&crtc->mutex, NULL);
 		if (crtc->primary->fb)
 			crtcs_bound++;
 		if (crtc->primary->fb == fb_helper->fb)
 			bound++;
+		drm_modeset_unlock(&crtc->mutex);
 	}
 
 	if (bound < crtcs_bound)
@@ -621,13 +623,12 @@ static void drm_fb_helper_dpms(struct fb
 	 * For each CRTC in this fb, turn the connectors on/off.
 	 */
 	mutex_lock(&fb_helper->lock);
-	drm_modeset_lock_all(dev);
 	if (!drm_fb_helper_is_bound(fb_helper)) {
-		drm_modeset_unlock_all(dev);
 		mutex_unlock(&fb_helper->lock);
 		return;
 	}
 
+	drm_modeset_lock_all(dev);
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		crtc = fb_helper->crtc_info[i].mode_set.crtc;
 
@@ -1263,13 +1264,12 @@ int drm_fb_helper_setcmap(struct fb_cmap
 		return -EBUSY;
 
 	mutex_lock(&fb_helper->lock);
-	drm_modeset_lock_all(dev);
 	if (!drm_fb_helper_is_bound(fb_helper)) {
-		drm_modeset_unlock_all(dev);
 		mutex_unlock(&fb_helper->lock);
 		return -EBUSY;
 	}
 
+	drm_modeset_lock_all(dev);
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		crtc = fb_helper->crtc_info[i].mode_set.crtc;
 		crtc_funcs = crtc->helper_private;
@@ -1323,12 +1323,12 @@ int drm_fb_helper_ioctl(struct fb_info *
 	int ret = 0;
 
 	mutex_lock(&fb_helper->lock);
-	mutex_lock(&dev->mode_config.mutex);
 	if (!drm_fb_helper_is_bound(fb_helper)) {
 		ret = -EBUSY;
 		goto unlock;
 	}
 
+	mutex_lock(&dev->mode_config.mutex);
 	switch (cmd) {
 	case FBIO_WAITFORVSYNC:
 		/*
@@ -1600,13 +1600,12 @@ int drm_fb_helper_pan_display(struct fb_
 		return -EBUSY;
 
 	mutex_lock(&fb_helper->lock);
-	drm_modeset_lock_all(dev);
 	if (!drm_fb_helper_is_bound(fb_helper)) {
-		drm_modeset_unlock_all(dev);
 		mutex_unlock(&fb_helper->lock);
 		return -EBUSY;
 	}
 
+	drm_modeset_lock_all(dev);
 	if (drm_drv_uses_atomic_modeset(dev))
 		ret = pan_display_atomic(var, info);
 	else
@@ -2467,16 +2466,15 @@ int drm_fb_helper_hotplug_event(struct d
 		return 0;
 
 	mutex_lock(&fb_helper->lock);
-	mutex_lock(&dev->mode_config.mutex);
-
 	if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) {
 		fb_helper->delayed_hotplug = true;
-		mutex_unlock(&dev->mode_config.mutex);
-		goto unlock;
+		mutex_unlock(&fb_helper->lock);
+		return err;
 	}
 
 	DRM_DEBUG_KMS("\n");
 
+	mutex_lock(&dev->mode_config.mutex);
 	drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height);
 
 	mutex_unlock(&dev->mode_config.mutex);
@@ -2485,10 +2483,6 @@ int drm_fb_helper_hotplug_event(struct d
 	drm_fb_helper_set_par(fb_helper->fbdev);
 
 	return 0;
-
-unlock:
-	mutex_unlock(&fb_helper->lock);
-	return err;
 }
 EXPORT_SYMBOL(drm_fb_helper_hotplug_event);