diff mbox

drm: Hold idr_mutex for _drm_lease_revoke

Message ID 20171019105344.1886-1-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson Oct. 19, 2017, 10:53 a.m. UTC
_drm_lease_revoke() requires it callers to hold the idr_mutex, but its
only caller did not. Every device release would then trigger:

 WARNING: CPU: 7 PID: 4169 at drivers/gpu/drm/drm_lease.c:313 _drm_lease_revoke+0x12c/0x140
 Modules linked in: vgem snd_hda_codec_hdmi snd_hda_codec_generic i915 x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul crc32_pclmul snd_hda_intel ghash_clmulni_intel snd_hda_codec r8169 snd_hwdep mii snd_hda_core snd_pcm mei_me mei prime_numbers i2c_hid pinctrl_sunrisepoint pinctrl_intel
 CPU: 7 PID: 4169 Comm: pm_backlight Tainted: G     U  W       4.14.0-rc5-CI-CI_DRM_3262+ #1
 Hardware name: TOSHIBA SATELLITE P50-C/06F4                            , BIOS 1.40 03/29/2016
 task: ffff8801f5a2a880 task.stack: ffffc900007e4000
 RIP: 0010:_drm_lease_revoke+0x12c/0x140
 RSP: 0018:ffffc900007e7da8 EFLAGS: 00010246
 RAX: 0000000000000000 RBX: ffff8801decdafd8 RCX: 0000000000000001
 RDX: 0000000000000000 RSI: 00000000ffffffff RDI: ffff88026afc05d0
 RBP: ffffc900007e7dd0 R08: ffff8801f5a2b168 R09: 0000000000000000
 R10: ffffc900007e7dd0 R11: 0000000000000001 R12: ffff88026afc0000
 R13: ffff8802730609f8 R14: ffff8802730609f8 R15: dead000000000100
 FS:  00007f9848442a40(0000) GS:ffff880281dc0000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 00007f9459c9ff80 CR3: 00000001df36e003 CR4: 00000000003606e0
 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
 Call Trace:
  drm_master_release+0xa5/0x120
  drm_release+0x345/0x3c0
  __fput+0xb9/0x200
  ____fput+0xe/0x10
  task_work_run+0x89/0xc0
  exit_to_usermode_loop+0x83/0x90
  syscall_return_slowpath+0xd0/0x110
  entry_SYSCALL_64_fastpath+0xaf/0xb1
 RIP: 0033:0x7f984691b730
 RSP: 002b:00007fffdf0092e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000003
 RAX: 0000000000000000 RBX: 00007fffdf0093a0 RCX: 00007f984691b730
 RDX: 00007fffdf0092d0 RSI: 0000000040086409 RDI: 0000000000000003
 RBP: 0000000000000000 R08: 0000557b2a88c7c0 R09: 0000000000000001
 R10: 0000000000000069 R11: 0000000000000246 R12: 0000000000000000
 R13: 0000000000000002 R14: 0000000000000001 R15: 0000557b2a88c4e0
 Code: 00 00 49 81 ec f8 00 00 00 e9 20 ff ff ff 48 8b 47 08 be ff ff ff ff 48 8d b8 d0 05 00 00 e8 cc 07 ad ff 85 c0 0f 85 f9 fe ff ff <0f> ff e9 f2 fe ff ff 90 90 90 90 90 90 90 90 90 90 90 90 90 0f

Fixes: 801d74c2fe00 ("drm: Add drm_object lease infrastructure [v5]")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Keith Packard <keithp@keithp.com>
Cc: Sean Paul <seanpaul@chromium.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Dave Airlie <airlied@redhat.com>
---
 drivers/gpu/drm/drm_auth.c  |  2 +-
 drivers/gpu/drm/drm_lease.c | 19 +++++++++++++------
 include/drm/drm_lease.h     |  2 +-
 3 files changed, 15 insertions(+), 8 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index bab26b477738..4c14b2cbc733 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -289,7 +289,7 @@  void drm_master_release(struct drm_file *file_priv)
 		/* Revoke any leases held by this or lessees, but only if
 		 * this is the "real" master
 		 */
-		_drm_lease_revoke(master);
+		drm_lease_revoke(master);
 	}
 
 	/* drop the master reference held by the file priv */
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 52c8fa29e6cc..387a6cb4bbe0 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -299,12 +299,7 @@  void drm_lease_destroy(struct drm_master *master)
 	DRM_DEBUG_LEASE("drm_lease_destroy done %d\n", master->lessee_id);
 }
 
-/**
- * _drm_lease_revoke - revoke access to all leased objects (idr_mutex held)
- * @top: the master losing its lease
- */
-
-void _drm_lease_revoke(struct drm_master *top)
+static void __drm_lease_revoke(struct drm_master *top)
 {
 	int object;
 	void *entry;
@@ -340,3 +335,15 @@  void _drm_lease_revoke(struct drm_master *top)
 		}
 	}
 }
+
+/**
+ * drm_lease_revoke - revoke access to all leased objects (idr_mutex held)
+ * @top: the master losing its lease
+ */
+
+void drm_lease_revoke(struct drm_master *top)
+{
+	mutex_lock(&top->dev->mode_config.idr_mutex);
+	__drm_lease_revoke(top);
+	mutex_unlock(&top->dev->mode_config.idr_mutex);
+}
diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h
index 0981631b9aed..6149e56ddbf3 100644
--- a/include/drm/drm_lease.h
+++ b/include/drm/drm_lease.h
@@ -27,7 +27,7 @@  bool drm_lease_held(struct drm_file *file_priv, int id);
 
 bool _drm_lease_held(struct drm_file *file_priv, int id);
 
-void _drm_lease_revoke(struct drm_master *master);
+void drm_lease_revoke(struct drm_master *master);
 
 uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs);