aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_fops.c')
-rw-r--r--drivers/gpu/drm/drm_fops.c33
1 files changed, 11 insertions, 22 deletions
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index e7aace20981f..3a652a65546f 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -39,6 +39,9 @@
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/smp_lock.h> 40#include <linux/smp_lock.h>
41 41
42/* from BKL pushdown: note that nothing else serializes idr_find() */
43DEFINE_MUTEX(drm_global_mutex);
44
42static int drm_open_helper(struct inode *inode, struct file *filp, 45static int drm_open_helper(struct inode *inode, struct file *filp,
43 struct drm_device * dev); 46 struct drm_device * dev);
44 47
@@ -132,15 +135,9 @@ int drm_open(struct inode *inode, struct file *filp)
132 retcode = drm_open_helper(inode, filp, dev); 135 retcode = drm_open_helper(inode, filp, dev);
133 if (!retcode) { 136 if (!retcode) {
134 atomic_inc(&dev->counts[_DRM_STAT_OPENS]); 137 atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
135 spin_lock(&dev->count_lock); 138 if (!dev->open_count++)
136 if (!dev->open_count++) {
137 spin_unlock(&dev->count_lock);
138 retcode = drm_setup(dev); 139 retcode = drm_setup(dev);
139 goto out;
140 }
141 spin_unlock(&dev->count_lock);
142 } 140 }
143out:
144 if (!retcode) { 141 if (!retcode) {
145 mutex_lock(&dev->struct_mutex); 142 mutex_lock(&dev->struct_mutex);
146 if (minor->type == DRM_MINOR_LEGACY) { 143 if (minor->type == DRM_MINOR_LEGACY) {
@@ -175,8 +172,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
175 172
176 DRM_DEBUG("\n"); 173 DRM_DEBUG("\n");
177 174
178 /* BKL pushdown: note that nothing else serializes idr_find() */ 175 mutex_lock(&drm_global_mutex);
179 lock_kernel();
180 minor = idr_find(&drm_minors_idr, minor_id); 176 minor = idr_find(&drm_minors_idr, minor_id);
181 if (!minor) 177 if (!minor)
182 goto out; 178 goto out;
@@ -197,7 +193,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
197 fops_put(old_fops); 193 fops_put(old_fops);
198 194
199out: 195out:
200 unlock_kernel(); 196 mutex_unlock(&drm_global_mutex);
201 return err; 197 return err;
202} 198}
203 199
@@ -472,7 +468,7 @@ int drm_release(struct inode *inode, struct file *filp)
472 struct drm_device *dev = file_priv->minor->dev; 468 struct drm_device *dev = file_priv->minor->dev;
473 int retcode = 0; 469 int retcode = 0;
474 470
475 lock_kernel(); 471 mutex_lock(&drm_global_mutex);
476 472
477 DRM_DEBUG("open_count = %d\n", dev->open_count); 473 DRM_DEBUG("open_count = %d\n", dev->open_count);
478 474
@@ -568,22 +564,15 @@ int drm_release(struct inode *inode, struct file *filp)
568 */ 564 */
569 565
570 atomic_inc(&dev->counts[_DRM_STAT_CLOSES]); 566 atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
571 spin_lock(&dev->count_lock);
572 if (!--dev->open_count) { 567 if (!--dev->open_count) {
573 if (atomic_read(&dev->ioctl_count)) { 568 if (atomic_read(&dev->ioctl_count)) {
574 DRM_ERROR("Device busy: %d\n", 569 DRM_ERROR("Device busy: %d\n",
575 atomic_read(&dev->ioctl_count)); 570 atomic_read(&dev->ioctl_count));
576 spin_unlock(&dev->count_lock); 571 retcode = -EBUSY;
577 unlock_kernel(); 572 } else
578 return -EBUSY; 573 retcode = drm_lastclose(dev);
579 }
580 spin_unlock(&dev->count_lock);
581 unlock_kernel();
582 return drm_lastclose(dev);
583 } 574 }
584 spin_unlock(&dev->count_lock); 575 mutex_unlock(&drm_global_mutex);
585
586 unlock_kernel();
587 576
588 return retcode; 577 return retcode;
589} 578}