aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_lock.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2008-08-24 03:00:00 -0400
committerDave Airlie <airlied@linux.ie>2008-08-24 16:35:21 -0400
commite5b4f19417b75a2d7c1e36934f60a3e836c4337e (patch)
tree1daed2d024ce8f1b0ce586ceb29159d908a9bb4b /drivers/gpu/drm/drm_lock.c
parent649ffc06a62bf487b78440669bdfeb637f1d675b (diff)
drm: 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. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_lock.c')
-rw-r--r--drivers/gpu/drm/drm_lock.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index 0998723cde79..d78e0dc18245 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -150,6 +150,7 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
150{ 150{
151 struct drm_lock *lock = data; 151 struct drm_lock *lock = data;
152 unsigned long irqflags; 152 unsigned long irqflags;
153 void (*tasklet_func)(struct drm_device *);
153 154
154 if (lock->context == DRM_KERNEL_CONTEXT) { 155 if (lock->context == DRM_KERNEL_CONTEXT) {
155 DRM_ERROR("Process %d using kernel context %d\n", 156 DRM_ERROR("Process %d using kernel context %d\n",
@@ -158,14 +159,11 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
158 } 159 }
159 160
160 spin_lock_irqsave(&dev->tasklet_lock, irqflags); 161 spin_lock_irqsave(&dev->tasklet_lock, irqflags);
161 162 tasklet_func = dev->locked_tasklet_func;
162 if (dev->locked_tasklet_func) { 163 dev->locked_tasklet_func = NULL;
163 dev->locked_tasklet_func(dev);
164
165 dev->locked_tasklet_func = NULL;
166 }
167
168 spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); 164 spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
165 if (tasklet_func != NULL)
166 tasklet_func(dev);
169 167
170 atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); 168 atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
171 169