From 4e5b40a9bd8b7dd30a7053a8508b33b6713f45a7 Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Sun, 11 Jun 2000 14:47:31 +0000 Subject: [PATCH] Fix some interrupt races. --- bsd-core/drmP.h | 2 ++ bsd/drmP.h | 2 ++ bsd/mga/mga_dma.c | 10 ++++------ bsd/mga/mga_drv.c | 4 ++++ bsd/mga/mga_state.c | 12 ++++++++++++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 11f5aeea..cda46875 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -77,9 +77,11 @@ typedef u_int32_t spinlock_t; static __inline u_int32_t test_and_set_bit(int b, volatile u_int32_t *p) { + int s = splhigh(); u_int32_t m = 1< #include -#define splmga spltty /* XXX bogus */ - #define MGA_REG(reg) 2 #define MGA_BASE(reg) ((unsigned long) \ ((drm_device_t *)dev)->maplist[MGA_REG(reg)]->handle) @@ -234,7 +232,7 @@ drm_buf_t *mga_freelist_get(drm_device_t *dev) if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) { DRM_DEBUG("I'm waiting on the freelist!!! %d\n", dev_priv->last_prim_age); - s = splmga(); + s = splsofttq(); set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status); for (;;) { mga_dma_schedule(dev, 0); @@ -474,7 +472,7 @@ int mga_advance_primary(drm_device_t *dev) /* In use is cleared in interrupt handler */ - s = splmga(); + s = splsofttq(); if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) { for (;;) { mga_dma_schedule(dev, 0); @@ -958,7 +956,7 @@ static int mga_flush_queue(drm_device_t *dev) } if(dev_priv->next_prim->num_dwords != 0) { - s = splmga(); + s = splsofttq(); set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status); for (;;) { mga_dma_schedule(dev, 0); @@ -1092,7 +1090,7 @@ int mga_flush_ioctl(dev_t kdev, u_long cmd, caddr_t data, dev_priv->prim_bufs[dev_priv->current_prim_idx]; if(temp_buf && temp_buf->num_dwords) { - s = splmga(); + s = splsofttq(); set_bit(MGA_BUF_FORCE_FIRE, &temp_buf->buffer_status); mga_advance_primary(dev); mga_dma_schedule(dev, 1); diff --git a/bsd/mga/mga_drv.c b/bsd/mga/mga_drv.c index fb130b24..09937201 100644 --- a/bsd/mga/mga_drv.c +++ b/bsd/mga/mga_drv.c @@ -683,6 +683,7 @@ mga_unlock(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p) { drm_device_t *dev = kdev->si_drv1; drm_lock_t lock; + int s; lock = *(drm_lock_t *) data; @@ -699,7 +700,10 @@ mga_unlock(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p) if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock)) atomic_inc(&dev->total_contends); drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT); + + s = splsofttq(); mga_dma_schedule(dev, 1); + splx(s); if (drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { diff --git a/bsd/mga/mga_state.c b/bsd/mga/mga_state.c index 763864a6..73029bbe 100644 --- a/bsd/mga/mga_state.c +++ b/bsd/mga/mga_state.c @@ -797,6 +797,7 @@ int mga_clear_bufs(dev_t kdev, u_long cmd, caddr_t data, (drm_mga_private_t *) dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_clear_t clear; + int s; clear = *(drm_mga_clear_t *) data; DRM_DEBUG("%s\n", __FUNCTION__); @@ -816,7 +817,9 @@ int mga_clear_bufs(dev_t kdev, u_long cmd, caddr_t data, clear.clear_color, clear.clear_depth); PRIMUPDATE(dev_priv); mga_flush_write_combine(); + s = splsofttq(); mga_dma_schedule(dev, 1); + splx(s); return 0; } @@ -827,6 +830,8 @@ int mga_swap_bufs(dev_t kdev, u_long cmd, caddr_t data, drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + int s; + DRM_DEBUG("%s\n", __FUNCTION__); if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { @@ -845,7 +850,9 @@ int mga_swap_bufs(dev_t kdev, u_long cmd, caddr_t data, set_bit(MGA_BUF_SWAP_PENDING, &dev_priv->current_prim->buffer_status); mga_flush_write_combine(); + s = splsofttq(); mga_dma_schedule(dev, 1); + splx(s); return 0; } @@ -861,6 +868,8 @@ int mga_iload(dev_t kdev, u_long cmd, caddr_t data, drm_mga_buf_priv_t *buf_priv; drm_mga_iload_t iload; unsigned long bus_address; + int s; + DRM_DEBUG("%s\n", __FUNCTION__); DRM_DEBUG("Starting Iload\n"); @@ -891,7 +900,9 @@ int mga_iload(dev_t kdev, u_long cmd, caddr_t data, buf_priv->discard = 1; mga_freelist_put(dev, buf); mga_flush_write_combine(); + s = splsofttq(); mga_dma_schedule(dev, 1); + splx(s); return 0; } @@ -905,6 +916,7 @@ int mga_vertex(dev_t kdev, u_long cmd, caddr_t data, drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; drm_mga_vertex_t vertex; + DRM_DEBUG("%s\n", __FUNCTION__); vertex = *(drm_mga_vertex_t *) data;