diff options
author | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2008-08-13 10:04:21 +0200 |
---|---|---|
committer | Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> | 2008-08-13 10:04:21 +0200 |
commit | af12ef4f6b4ca111d9a2ef45263ad89610498724 (patch) | |
tree | 9794799de029ef303f3145f12738c680d033d80e /linux-core/drm_lock.c | |
parent | b0e68829462aad00ce68be998da6313bca754e9a (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.c | 12 |
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]); |