aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2016-04-26 13:29:41 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-04-27 04:16:17 -0400
commit1d2ac403ae3bfde7c50328ee0d39d3fb3d8d9823 (patch)
treeebdb7a84d3399feeb2e06b855f5ee04550101ea4
parentf47dbdd75bf3388ce8107c2e7e5a1eebd3700dd5 (diff)
drm: Protect dev->filelist with its own mutex
amdgpu gained dev->struct_mutex usage, and that's because it's walking the dev->filelist list. Protect that list with it's own lock to take one more step towards getting rid of struct_mutex usage in drivers once and for all. While doing the conversion I noticed that 2 debugfs files in i915 completely lacked appropriate locking. Fix that up too. v2: don't forget to switch to drm_gem_object_unreference_unlocked. Cc: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1461691808-12414-9-git-send-email-daniel.vetter@ffwll.ch
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c10
-rw-r--r--drivers/gpu/drm/drm_drv.c1
-rw-r--r--drivers/gpu/drm/drm_fops.c9
-rw-r--r--drivers/gpu/drm/drm_info.c4
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c12
-rw-r--r--include/drm/drmP.h1
6 files changed, 25 insertions, 12 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index fa6a27bff298..a087b9638cde 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -93,7 +93,7 @@ void amdgpu_gem_force_release(struct amdgpu_device *adev)
93 struct drm_device *ddev = adev->ddev; 93 struct drm_device *ddev = adev->ddev;
94 struct drm_file *file; 94 struct drm_file *file;
95 95
96 mutex_lock(&ddev->struct_mutex); 96 mutex_lock(&ddev->filelist_mutex);
97 97
98 list_for_each_entry(file, &ddev->filelist, lhead) { 98 list_for_each_entry(file, &ddev->filelist, lhead) {
99 struct drm_gem_object *gobj; 99 struct drm_gem_object *gobj;
@@ -103,13 +103,13 @@ void amdgpu_gem_force_release(struct amdgpu_device *adev)
103 spin_lock(&file->table_lock); 103 spin_lock(&file->table_lock);
104 idr_for_each_entry(&file->object_idr, gobj, handle) { 104 idr_for_each_entry(&file->object_idr, gobj, handle) {
105 WARN_ONCE(1, "And also active allocations!\n"); 105 WARN_ONCE(1, "And also active allocations!\n");
106 drm_gem_object_unreference(gobj); 106 drm_gem_object_unreference_unlocked(gobj);
107 } 107 }
108 idr_destroy(&file->object_idr); 108 idr_destroy(&file->object_idr);
109 spin_unlock(&file->table_lock); 109 spin_unlock(&file->table_lock);
110 } 110 }
111 111
112 mutex_unlock(&ddev->struct_mutex); 112 mutex_unlock(&ddev->filelist_mutex);
113} 113}
114 114
115/* 115/*
@@ -769,7 +769,7 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
769 struct drm_file *file; 769 struct drm_file *file;
770 int r; 770 int r;
771 771
772 r = mutex_lock_interruptible(&dev->struct_mutex); 772 r = mutex_lock_interruptible(&dev->filelist_mutex);
773 if (r) 773 if (r)
774 return r; 774 return r;
775 775
@@ -793,7 +793,7 @@ static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data)
793 spin_unlock(&file->table_lock); 793 spin_unlock(&file->table_lock);
794 } 794 }
795 795
796 mutex_unlock(&dev->struct_mutex); 796 mutex_unlock(&dev->filelist_mutex);
797 return 0; 797 return 0;
798} 798}
799 799
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index e1fb52d4f72c..bff89226a344 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -590,6 +590,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
590 spin_lock_init(&dev->buf_lock); 590 spin_lock_init(&dev->buf_lock);
591 spin_lock_init(&dev->event_lock); 591 spin_lock_init(&dev->event_lock);
592 mutex_init(&dev->struct_mutex); 592 mutex_init(&dev->struct_mutex);
593 mutex_init(&dev->filelist_mutex);
593 mutex_init(&dev->ctxlist_mutex); 594 mutex_init(&dev->ctxlist_mutex);
594 mutex_init(&dev->master_mutex); 595 mutex_init(&dev->master_mutex);
595 596
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index c3d0aaac0669..7af7f8bcb355 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -297,9 +297,9 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor)
297 } 297 }
298 mutex_unlock(&dev->master_mutex); 298 mutex_unlock(&dev->master_mutex);
299 299
300 mutex_lock(&dev->struct_mutex); 300 mutex_lock(&dev->filelist_mutex);
301 list_add(&priv->lhead, &dev->filelist); 301 list_add(&priv->lhead, &dev->filelist);
302 mutex_unlock(&dev->struct_mutex); 302 mutex_unlock(&dev->filelist_mutex);
303 303
304#ifdef __alpha__ 304#ifdef __alpha__
305 /* 305 /*
@@ -447,8 +447,11 @@ int drm_release(struct inode *inode, struct file *filp)
447 447
448 DRM_DEBUG("open_count = %d\n", dev->open_count); 448 DRM_DEBUG("open_count = %d\n", dev->open_count);
449 449
450 mutex_lock(&dev->struct_mutex); 450 mutex_lock(&dev->filelist_mutex);
451 list_del(&file_priv->lhead); 451 list_del(&file_priv->lhead);
452 mutex_unlock(&dev->filelist_mutex);
453
454 mutex_lock(&dev->struct_mutex);
452 if (file_priv->magic) 455 if (file_priv->magic)
453 idr_remove(&file_priv->master->magic_map, file_priv->magic); 456 idr_remove(&file_priv->master->magic_map, file_priv->magic);
454 mutex_unlock(&dev->struct_mutex); 457 mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index cbb4fc0fc969..5d469b2f26f4 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -174,7 +174,7 @@ int drm_clients_info(struct seq_file *m, void *data)
174 /* dev->filelist is sorted youngest first, but we want to present 174 /* dev->filelist is sorted youngest first, but we want to present
175 * oldest first (i.e. kernel, servers, clients), so walk backwardss. 175 * oldest first (i.e. kernel, servers, clients), so walk backwardss.
176 */ 176 */
177 mutex_lock(&dev->struct_mutex); 177 mutex_lock(&dev->filelist_mutex);
178 list_for_each_entry_reverse(priv, &dev->filelist, lhead) { 178 list_for_each_entry_reverse(priv, &dev->filelist, lhead) {
179 struct task_struct *task; 179 struct task_struct *task;
180 180
@@ -190,7 +190,7 @@ int drm_clients_info(struct seq_file *m, void *data)
190 priv->magic); 190 priv->magic);
191 rcu_read_unlock(); 191 rcu_read_unlock();
192 } 192 }
193 mutex_unlock(&dev->struct_mutex); 193 mutex_unlock(&dev->filelist_mutex);
194 return 0; 194 return 0;
195} 195}
196 196
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 85933940fe9c..c298312f83f6 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -498,6 +498,10 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
498 498
499 seq_putc(m, '\n'); 499 seq_putc(m, '\n');
500 print_batch_pool_stats(m, dev_priv); 500 print_batch_pool_stats(m, dev_priv);
501
502 mutex_unlock(&dev->struct_mutex);
503
504 mutex_lock(&dev->filelist_mutex);
501 list_for_each_entry_reverse(file, &dev->filelist, lhead) { 505 list_for_each_entry_reverse(file, &dev->filelist, lhead) {
502 struct file_stats stats; 506 struct file_stats stats;
503 struct task_struct *task; 507 struct task_struct *task;
@@ -518,8 +522,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
518 print_file_stats(m, task ? task->comm : "<unknown>", stats); 522 print_file_stats(m, task ? task->comm : "<unknown>", stats);
519 rcu_read_unlock(); 523 rcu_read_unlock();
520 } 524 }
521 525 mutex_unlock(&dev->filelist_mutex);
522 mutex_unlock(&dev->struct_mutex);
523 526
524 return 0; 527 return 0;
525} 528}
@@ -2325,6 +2328,7 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
2325 else if (INTEL_INFO(dev)->gen >= 6) 2328 else if (INTEL_INFO(dev)->gen >= 6)
2326 gen6_ppgtt_info(m, dev); 2329 gen6_ppgtt_info(m, dev);
2327 2330
2331 mutex_lock(&dev->filelist_mutex);
2328 list_for_each_entry_reverse(file, &dev->filelist, lhead) { 2332 list_for_each_entry_reverse(file, &dev->filelist, lhead) {
2329 struct drm_i915_file_private *file_priv = file->driver_priv; 2333 struct drm_i915_file_private *file_priv = file->driver_priv;
2330 struct task_struct *task; 2334 struct task_struct *task;
@@ -2339,6 +2343,7 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
2339 idr_for_each(&file_priv->context_idr, per_file_ctx, 2343 idr_for_each(&file_priv->context_idr, per_file_ctx,
2340 (void *)(unsigned long)m); 2344 (void *)(unsigned long)m);
2341 } 2345 }
2346 mutex_unlock(&dev->filelist_mutex);
2342 2347
2343out_put: 2348out_put:
2344 intel_runtime_pm_put(dev_priv); 2349 intel_runtime_pm_put(dev_priv);
@@ -2374,6 +2379,8 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
2374 intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit), 2379 intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit),
2375 intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit), 2380 intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit),
2376 intel_gpu_freq(dev_priv, dev_priv->rps.max_freq)); 2381 intel_gpu_freq(dev_priv, dev_priv->rps.max_freq));
2382
2383 mutex_lock(&dev->filelist_mutex);
2377 spin_lock(&dev_priv->rps.client_lock); 2384 spin_lock(&dev_priv->rps.client_lock);
2378 list_for_each_entry_reverse(file, &dev->filelist, lhead) { 2385 list_for_each_entry_reverse(file, &dev->filelist, lhead) {
2379 struct drm_i915_file_private *file_priv = file->driver_priv; 2386 struct drm_i915_file_private *file_priv = file->driver_priv;
@@ -2396,6 +2403,7 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
2396 list_empty(&dev_priv->rps.mmioflips.link) ? "" : ", active"); 2403 list_empty(&dev_priv->rps.mmioflips.link) ? "" : ", active");
2397 seq_printf(m, "Kernel boosts: %d\n", dev_priv->rps.boosts); 2404 seq_printf(m, "Kernel boosts: %d\n", dev_priv->rps.boosts);
2398 spin_unlock(&dev_priv->rps.client_lock); 2405 spin_unlock(&dev_priv->rps.client_lock);
2406 mutex_unlock(&dev->filelist_mutex);
2399 2407
2400 return 0; 2408 return 0;
2401} 2409}
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 5de4cff05ac9..7901768bb47c 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -769,6 +769,7 @@ struct drm_device {
769 atomic_t buf_alloc; /**< Buffer allocation in progress */ 769 atomic_t buf_alloc; /**< Buffer allocation in progress */
770 /*@} */ 770 /*@} */
771 771
772 struct mutex filelist_mutex;
772 struct list_head filelist; 773 struct list_head filelist;
773 774
774 /** \name Memory management */ 775 /** \name Memory management */