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
Rik Faith 2000-08-26 10:36:44 +00:00
parent 37643234af
commit 6f07e1ff6b
18 changed files with 185 additions and 4 deletions

View File

@ -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);

View File

@ -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");

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}

View File

@ -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");

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}