Fix some interrupt races.

This commit is contained in:
Doug Rabson 2000-06-11 14:47:31 +00:00
parent dee6c46251
commit 4e5b40a9bd
5 changed files with 24 additions and 6 deletions

View file

@ -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<<b;
u_int32_t r = *p & m;
*p |= m;
splx(s);
return r;
}

View file

@ -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<<b;
u_int32_t r = *p & m;
*p |= m;
splx(s);
return r;
}

View file

@ -40,8 +40,6 @@
#include <vm/vm.h>
#include <vm/pmap.h>
#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);

View file

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

View file

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