aboutsummaryrefslogtreecommitdiff
path: root/linux-core/drm_lock.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-08-13 10:04:21 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-08-13 10:04:21 +0200
commitaf12ef4f6b4ca111d9a2ef45263ad89610498724 (patch)
tree9794799de029ef303f3145f12738c680d033d80e /linux-core/drm_lock.c
parentb0e68829462aad00ce68be998da6313bca754e9a (diff)
Don't call the vblank tasklet with irqs disabled.
If a specific tasklet shares data with irq context, it needs to take a private irq-blocking spinlock within the tasklet itself.
Diffstat (limited to 'linux-core/drm_lock.c')
-rw-r--r--linux-core/drm_lock.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/linux-core/drm_lock.c b/linux-core/drm_lock.c
index a2966efb..cad2e44d 100644
--- a/linux-core/drm_lock.c
+++ b/linux-core/drm_lock.c
@@ -155,6 +155,7 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
struct drm_lock *lock = data;
unsigned long irqflags;
+ void (*tasklet_func)(struct drm_device *);
if (lock->context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
@@ -163,14 +164,11 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
}
spin_lock_irqsave(&dev->tasklet_lock, irqflags);
-
- if (dev->locked_tasklet_func) {
- dev->locked_tasklet_func(dev);
-
- dev->locked_tasklet_func = NULL;
- }
-
+ tasklet_func = dev->locked_tasklet_func;
+ dev->locked_tasklet_func = NULL;
spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
+ if (tasklet_func != NULL)
+ tasklet_func(dev);
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);