Sync with Linux 2.4.0-test7 Add signal blocking support to all drivers
(using control-z on a running direct-rendering client should work now)main
parent
37643234af
commit
6f07e1ff6b
|
@ -57,7 +57,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/agp_backend.h>
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
|
||||
#if LINUX_VERSION_CODE >= 0x020100 /* KERNEL_VERSION(2,1,0) */
|
||||
#include <linux/tqueue.h>
|
||||
#include <linux/poll.h>
|
||||
#endif
|
||||
|
@ -451,6 +451,11 @@ typedef struct {
|
|||
extern drm_agp_func_t drm_agp;
|
||||
#endif
|
||||
|
||||
typedef struct drm_sigdata {
|
||||
int context;
|
||||
drm_hw_lock_t *lock;
|
||||
} drm_sigdata_t;
|
||||
|
||||
typedef struct drm_device {
|
||||
const char *name; /* Simple driver name */
|
||||
char *unique; /* Unique identifier: e.g., busid */
|
||||
|
@ -535,6 +540,8 @@ typedef struct drm_device {
|
|||
#endif
|
||||
unsigned long *ctx_bitmap;
|
||||
void *dev_private;
|
||||
drm_sigdata_t sigdata; /* For block_all_signals */
|
||||
sigset_t sigmask;
|
||||
} drm_device_t;
|
||||
|
||||
|
||||
|
@ -729,6 +736,7 @@ extern int drm_flush_unblock(drm_device_t *dev, int context,
|
|||
drm_lock_flags_t flags);
|
||||
extern int drm_flush_block_and_flush(drm_device_t *dev, int context,
|
||||
drm_lock_flags_t flags);
|
||||
extern int drm_notifier(void *priv);
|
||||
|
||||
/* Context Bitmap support (ctxbitmap.c) */
|
||||
extern int drm_ctxbitmap_init(drm_device_t *dev);
|
||||
|
|
|
@ -1227,6 +1227,16 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
|
||||
if (!ret) {
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
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);
|
||||
#endif
|
||||
if (lock.flags & _DRM_LOCK_QUIESCENT) {
|
||||
DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");
|
||||
DRM_DEBUG("fred\n");
|
||||
|
|
|
@ -642,5 +642,8 @@ int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
- dev->lck_start)]);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -655,5 +655,8 @@ int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
DRM_ERROR("\n");
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -656,6 +656,16 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
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);
|
||||
#endif
|
||||
if (lock.flags & _DRM_LOCK_READY) {
|
||||
/* Wait for space in DMA/FIFO */
|
||||
}
|
||||
|
@ -720,5 +730,8 @@ int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -626,6 +626,16 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
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);
|
||||
#endif
|
||||
if (lock.flags & _DRM_LOCK_READY) {
|
||||
/* Wait for space in DMA/FIFO */
|
||||
}
|
||||
|
@ -676,7 +686,10 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
DRM_ERROR("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -615,6 +615,16 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
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);
|
||||
#endif
|
||||
if (lock.flags & _DRM_LOCK_READY) {
|
||||
/* Wait for space in DMA/FIFO */
|
||||
}
|
||||
|
@ -679,5 +689,8 @@ int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
10
linux/drmP.h
10
linux/drmP.h
|
@ -57,7 +57,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/agp_backend.h>
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
|
||||
#if LINUX_VERSION_CODE >= 0x020100 /* KERNEL_VERSION(2,1,0) */
|
||||
#include <linux/tqueue.h>
|
||||
#include <linux/poll.h>
|
||||
#endif
|
||||
|
@ -451,6 +451,11 @@ typedef struct {
|
|||
extern drm_agp_func_t drm_agp;
|
||||
#endif
|
||||
|
||||
typedef struct drm_sigdata {
|
||||
int context;
|
||||
drm_hw_lock_t *lock;
|
||||
} drm_sigdata_t;
|
||||
|
||||
typedef struct drm_device {
|
||||
const char *name; /* Simple driver name */
|
||||
char *unique; /* Unique identifier: e.g., busid */
|
||||
|
@ -535,6 +540,8 @@ typedef struct drm_device {
|
|||
#endif
|
||||
unsigned long *ctx_bitmap;
|
||||
void *dev_private;
|
||||
drm_sigdata_t sigdata; /* For block_all_signals */
|
||||
sigset_t sigmask;
|
||||
} drm_device_t;
|
||||
|
||||
|
||||
|
@ -729,6 +736,7 @@ extern int drm_flush_unblock(drm_device_t *dev, int context,
|
|||
drm_lock_flags_t flags);
|
||||
extern int drm_flush_block_and_flush(drm_device_t *dev, int context,
|
||||
drm_lock_flags_t flags);
|
||||
extern int drm_notifier(void *priv);
|
||||
|
||||
/* Context Bitmap support (ctxbitmap.c) */
|
||||
extern int drm_ctxbitmap_init(drm_device_t *dev);
|
||||
|
|
|
@ -804,6 +804,16 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_flush_unblock(dev, lock.context, lock.flags); /* cleanup phase */
|
||||
|
||||
if (!ret) {
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
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);
|
||||
#endif
|
||||
if (lock.flags & _DRM_LOCK_READY)
|
||||
gamma_dma_ready(dev);
|
||||
if (lock.flags & _DRM_LOCK_QUIESCENT) {
|
||||
|
|
|
@ -564,5 +564,8 @@ int gamma_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
- dev->lck_start)]);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1227,6 +1227,16 @@ int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
|
||||
if (!ret) {
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
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);
|
||||
#endif
|
||||
if (lock.flags & _DRM_LOCK_QUIESCENT) {
|
||||
DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");
|
||||
DRM_DEBUG("fred\n");
|
||||
|
|
|
@ -642,5 +642,8 @@ int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
- dev->lck_start)]);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
32
linux/lock.c
32
linux/lock.c
|
@ -223,3 +223,35 @@ int drm_finish(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_flush_unblock(dev, lock.context, lock.flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If we get here, it means that the process has called DRM_IOCTL_LOCK
|
||||
without calling DRM_IOCTL_UNLOCK.
|
||||
|
||||
If the lock is not held, then let the signal proceed as usual.
|
||||
|
||||
If the lock is held, then set the contended flag and keep the signal
|
||||
blocked.
|
||||
|
||||
|
||||
Return 1 if the signal should be delivered normally.
|
||||
Return 0 if the signal should be blocked. */
|
||||
|
||||
int drm_notifier(void *priv)
|
||||
{
|
||||
drm_sigdata_t *s = (drm_sigdata_t *)priv;
|
||||
unsigned int old, new, prev;
|
||||
|
||||
|
||||
/* Allow signal delivery if lock isn't held */
|
||||
if (!_DRM_LOCK_IS_HELD(s->lock->lock)
|
||||
|| _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
|
||||
|
||||
/* Otherwise, set flag to force call to
|
||||
drmUnlock */
|
||||
do {
|
||||
old = s->lock->lock;
|
||||
new = old | _DRM_LOCK_CONT;
|
||||
prev = cmpxchg(&s->lock->lock, old, new);
|
||||
} while (prev != old);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1074,6 +1074,16 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
|
||||
if (!ret) {
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
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);
|
||||
#endif
|
||||
if (lock.flags & _DRM_LOCK_QUIESCENT) {
|
||||
DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");
|
||||
mga_flush_queue(dev);
|
||||
|
|
|
@ -655,5 +655,8 @@ int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
DRM_ERROR("\n");
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -656,6 +656,16 @@ int r128_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
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);
|
||||
#endif
|
||||
if (lock.flags & _DRM_LOCK_READY) {
|
||||
/* Wait for space in DMA/FIFO */
|
||||
}
|
||||
|
@ -720,5 +730,8 @@ int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -626,6 +626,16 @@ int sis_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
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);
|
||||
#endif
|
||||
if (lock.flags & _DRM_LOCK_READY) {
|
||||
/* Wait for space in DMA/FIFO */
|
||||
}
|
||||
|
@ -676,7 +686,10 @@ int sis_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
DRM_ERROR("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -615,6 +615,16 @@ int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
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);
|
||||
#endif
|
||||
if (lock.flags & _DRM_LOCK_READY) {
|
||||
/* Wait for space in DMA/FIFO */
|
||||
}
|
||||
|
@ -679,5 +689,8 @@ int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= 0x020400 /* KERNEL_VERSION(2,4,0) */
|
||||
unblock_all_signals();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue