From e5b4f19417b75a2d7c1e36934f60a3e836c4337e Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Sun, 24 Aug 2008 17:00:00 +1000 Subject: 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 --- drivers/gpu/drm/drm_lock.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/drm_lock.c') 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) { 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", @@ -158,14 +159,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]); -- cgit v1.2.2 From 3e5fc80a404a24c858468030b63555cccfb3e79c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 24 Aug 2008 17:02:26 +1000 Subject: drm: don't set the signal blocker on the master process. There is a problem with debugging the X server and gdb crashes in the xkb startup code. This avoids the problem by allowing the master process to get signals. It should be safe as the signal blocker is mainly so that you can Ctrl-Z a 3D application without locking up the whole box. Ctrl-Z the X server isn't something many people do. Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_lock.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/drm_lock.c') diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index d78e0dc18245..a4caf95485d7 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c @@ -105,14 +105,19 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) ret ? "interrupted" : "has lock"); if (ret) return ret; - sigemptyset(&dev->sigmask); - sigaddset(&dev->sigmask, SIGSTOP); - sigaddset(&dev->sigmask, SIGTSTP); - sigaddset(&dev->sigmask, SIGTTIN); - sigaddset(&dev->sigmask, SIGTTOU); - dev->sigdata.context = lock->context; - dev->sigdata.lock = dev->lock.hw_lock; - block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); + /* don't set the block all signals on the master process for now + * really probably not the correct answer but lets us debug xkb + * xserver for now */ + if (!file_priv->master) { + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock->context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); + } if (dev->driver->dma_ready && (lock->flags & _DRM_LOCK_READY)) dev->driver->dma_ready(dev); -- cgit v1.2.2