Sync with Linux 2.4.0-test7 Add signal blocking support to all drivers
authorRik Faith <faith@alephnull.com>
Sat, 26 Aug 2000 10:36:44 +0000 (10:36 +0000)
committerRik Faith <faith@alephnull.com>
Sat, 26 Aug 2000 10:36:44 +0000 (10:36 +0000)
    (using control-z on a running direct-rendering client should work now)

18 files changed:
linux-core/drmP.h
linux-core/i810_dma.c
linux-core/i810_drv.c
linux-core/mga_drv.c
linux-core/r128_drv.c
linux-core/sis_drv.c
linux-core/tdfx_drv.c
linux/drmP.h
linux/gamma_dma.c
linux/gamma_drv.c
linux/i810_dma.c
linux/i810_drv.c
linux/lock.c
linux/mga_dma.c
linux/mga_drv.c
linux/r128_drv.c
linux/sis_drv.c
linux/tdfx_drv.c

index aa9bc01..b9a4dab 100644 (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);
index 19b7bd9..5792bf3 100644 (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");
index 275663a..1816860 100644 (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;
 }
index acc42b8..a4a8fe5 100644 (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;
 }
index fac8824..c4eb634 100644 (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;
 }
index 5dda149..434a1cc 100644 (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;
 }
 
index 59f1019..07febea 100644 (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;
 }
index aa9bc01..b9a4dab 100644 (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);
index a99f24c..4a2acfb 100644 (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) {
index 13d37c2..1fcd193 100644 (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;
 }
index 19b7bd9..5792bf3 100644 (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");
index 275663a..1816860 100644 (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;
 }
index 5508272..33b2cc0 100644 (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;
+}
index 9ca7229..d315954 100644 (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);
index acc42b8..a4a8fe5 100644 (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;
 }
index fac8824..c4eb634 100644 (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;
 }
index 5dda149..434a1cc 100644 (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;
 }
 
index 59f1019..07febea 100644 (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;
 }