mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-08 17:29:02 +02:00
Code to help in debugging of the mga drm modules locking policy
This commit is contained in:
parent
5f2cfc5bd8
commit
4f2c60bb65
11 changed files with 323 additions and 98 deletions
|
|
@ -27,6 +27,7 @@ export-objs := $(patsubst %.o,%_drv.o,$(module-list))
|
|||
#
|
||||
lib-objs := init.o memory.o proc.o auth.o context.o drawable.o bufs.o
|
||||
lib-objs += lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
|
||||
lib-objs += drm_heavy_kern_lock.o
|
||||
|
||||
ifeq ($(CONFIG_AGP),y)
|
||||
lib-objs += agpsupport.o
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ typedef struct drm_ioctl_desc {
|
|||
drm_ioctl_t *func;
|
||||
int auth_needed;
|
||||
int root_only;
|
||||
int needs_hvy_lock;
|
||||
} drm_ioctl_desc_t;
|
||||
|
||||
typedef struct drm_devstate {
|
||||
|
|
@ -430,9 +431,10 @@ typedef struct drm_file {
|
|||
struct drm_file *next;
|
||||
struct drm_file *prev;
|
||||
struct drm_device *dev;
|
||||
volatile int lock_depth;
|
||||
unsigned long irq_flags;
|
||||
} drm_file_t;
|
||||
|
||||
|
||||
typedef struct drm_queue {
|
||||
atomic_t use_count; /* Outstanding uses (+1) */
|
||||
atomic_t finalization; /* Finalization in progress */
|
||||
|
|
@ -615,6 +617,12 @@ typedef struct drm_device {
|
|||
void *dev_private;
|
||||
drm_sigdata_t sigdata; /* For block_all_signals */
|
||||
sigset_t sigmask;
|
||||
|
||||
spinlock_t big_fscking_lock;
|
||||
volatile int irq_lock_depth;
|
||||
unsigned long irq_flags;
|
||||
volatile int bh_lock_depth;
|
||||
unsigned long bh_flags;
|
||||
} drm_device_t;
|
||||
|
||||
|
||||
|
|
@ -817,6 +825,16 @@ extern void drm_ctxbitmap_cleanup(drm_device_t *dev);
|
|||
extern int drm_ctxbitmap_next(drm_device_t *dev);
|
||||
extern void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle);
|
||||
|
||||
/* BIG Fscking lock (drm_heavy_kern_lock.c) */
|
||||
extern void drm_schedule(drm_device_t *dev);
|
||||
extern void drm_schedule_timeout(drm_device_t *dev, unsigned long timeout);
|
||||
extern void drm_big_fscking_lock(drm_device_t *dev);
|
||||
extern void drm_big_fscking_unlock(drm_device_t *dev);
|
||||
extern void __inline drm_big_fscking_lock_filp(drm_device_t *dev,
|
||||
drm_file_t *filp);
|
||||
extern void __inline drm_big_fscking_unlock_filp(drm_device_t *dev,
|
||||
drm_file_t *filp);
|
||||
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
/* AGP/GART support (agpsupport.c) */
|
||||
extern drm_agp_head_t *drm_agp_init(void);
|
||||
|
|
|
|||
|
|
@ -66,54 +66,55 @@ static struct miscdevice mga_misc = {
|
|||
};
|
||||
|
||||
static drm_ioctl_desc_t mga_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { mga_version, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { mga_version, 0, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { mga_control, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { mga_addbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { mga_markbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { mga_infobufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { mga_mapbufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { mga_freebufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { mga_control, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { mga_addbufs, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { mga_markbufs, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { mga_infobufs, 1, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { mga_mapbufs, 1, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { mga_freebufs, 1, 0, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { mga_addctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { mga_rmctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { mga_modctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { mga_getctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { mga_switchctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { mga_newctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { mga_resctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { mga_addctx, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { mga_rmctx, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { mga_modctx, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { mga_getctx, 1, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { mga_switchctx, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { mga_newctx, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { mga_resctx, 1, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma, 1, 0, 1 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_flush_ioctl, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_flush_ioctl, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0, 1 },
|
||||
};
|
||||
|
||||
#define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls)
|
||||
|
|
@ -182,6 +183,9 @@ static int mga_setup(drm_device_t *dev)
|
|||
dev->last_context = 0;
|
||||
dev->last_switch = 0;
|
||||
dev->last_checked = 0;
|
||||
dev->irq_lock_depth = -1;
|
||||
dev->bh_lock_depth = -1;
|
||||
|
||||
init_timer(&dev->timer);
|
||||
init_waitqueue_head(&dev->context_wait);
|
||||
|
||||
|
|
@ -192,6 +196,7 @@ static int mga_setup(drm_device_t *dev)
|
|||
dev->buf_wp = dev->buf;
|
||||
dev->buf_end = dev->buf + DRM_BSZ;
|
||||
dev->buf_async = NULL;
|
||||
|
||||
init_waitqueue_head(&dev->buf_readers);
|
||||
init_waitqueue_head(&dev->buf_writers);
|
||||
|
||||
|
|
@ -539,7 +544,7 @@ int mga_release(struct inode *inode, struct file *filp)
|
|||
/* Contention */
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
drm_schedule(dev);
|
||||
if (signal_pending(current)) {
|
||||
retcode = -ERESTARTSYS;
|
||||
break;
|
||||
|
|
@ -619,7 +624,11 @@ int mga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
|| (ioctl->auth_needed && !priv->authenticated)) {
|
||||
retcode = -EACCES;
|
||||
} else {
|
||||
if(ioctl->needs_hvy_lock == 1)
|
||||
drm_big_fscking_lock_filp(dev, priv);
|
||||
retcode = (func)(inode, filp, cmd, arg);
|
||||
if(ioctl->needs_hvy_lock == 1)
|
||||
drm_big_fscking_unlock_filp(dev, priv);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ export-objs := $(patsubst %.o,%_drv.o,$(module-list))
|
|||
#
|
||||
lib-objs := init.o memory.o proc.o auth.o context.o drawable.o bufs.o
|
||||
lib-objs += lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
|
||||
lib-objs += drm_heavy_kern_lock.o
|
||||
|
||||
ifeq ($(CONFIG_AGP),y)
|
||||
lib-objs += agpsupport.o
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ LIBS= libdrm.a
|
|||
PROGS= drmstat
|
||||
|
||||
DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
|
||||
lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
|
||||
lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o \
|
||||
drm_heavy_kern_lock.o
|
||||
DRMHEADERS= drm.h drmP.h compat-pre24.h
|
||||
|
||||
GAMMAOBJS= gamma_drv.o gamma_dma.o
|
||||
|
|
|
|||
20
linux/drmP.h
20
linux/drmP.h
|
|
@ -300,6 +300,7 @@ typedef struct drm_ioctl_desc {
|
|||
drm_ioctl_t *func;
|
||||
int auth_needed;
|
||||
int root_only;
|
||||
int needs_hvy_lock;
|
||||
} drm_ioctl_desc_t;
|
||||
|
||||
typedef struct drm_devstate {
|
||||
|
|
@ -430,9 +431,10 @@ typedef struct drm_file {
|
|||
struct drm_file *next;
|
||||
struct drm_file *prev;
|
||||
struct drm_device *dev;
|
||||
volatile int lock_depth;
|
||||
unsigned long irq_flags;
|
||||
} drm_file_t;
|
||||
|
||||
|
||||
typedef struct drm_queue {
|
||||
atomic_t use_count; /* Outstanding uses (+1) */
|
||||
atomic_t finalization; /* Finalization in progress */
|
||||
|
|
@ -615,6 +617,12 @@ typedef struct drm_device {
|
|||
void *dev_private;
|
||||
drm_sigdata_t sigdata; /* For block_all_signals */
|
||||
sigset_t sigmask;
|
||||
|
||||
spinlock_t big_fscking_lock;
|
||||
volatile int irq_lock_depth;
|
||||
unsigned long irq_flags;
|
||||
volatile int bh_lock_depth;
|
||||
unsigned long bh_flags;
|
||||
} drm_device_t;
|
||||
|
||||
|
||||
|
|
@ -817,6 +825,16 @@ extern void drm_ctxbitmap_cleanup(drm_device_t *dev);
|
|||
extern int drm_ctxbitmap_next(drm_device_t *dev);
|
||||
extern void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle);
|
||||
|
||||
/* BIG Fscking lock (drm_heavy_kern_lock.c) */
|
||||
extern void drm_schedule(drm_device_t *dev);
|
||||
extern void drm_schedule_timeout(drm_device_t *dev, unsigned long timeout);
|
||||
extern void drm_big_fscking_lock(drm_device_t *dev);
|
||||
extern void drm_big_fscking_unlock(drm_device_t *dev);
|
||||
extern void __inline drm_big_fscking_lock_filp(drm_device_t *dev,
|
||||
drm_file_t *filp);
|
||||
extern void __inline drm_big_fscking_unlock_filp(drm_device_t *dev,
|
||||
drm_file_t *filp);
|
||||
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
/* AGP/GART support (agpsupport.c) */
|
||||
extern drm_agp_head_t *drm_agp_init(void);
|
||||
|
|
|
|||
150
linux/drm_heavy_kern_lock.c
Normal file
150
linux/drm_heavy_kern_lock.c
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/* This has to be used VERY carefully, since you never want to sleep with the
|
||||
* lock. It would be very bad if you slept w/ irq's disabled.
|
||||
*/
|
||||
|
||||
/* Big fscking lock implementation */
|
||||
#define __NO_VERSION__
|
||||
#include "drmP.h"
|
||||
#include <asm/softirq.h>
|
||||
|
||||
/* This is not smp safe! */
|
||||
static __inline__ drm_file_t *drm_find_filp_by_current_pid(drm_device_t *dev)
|
||||
{
|
||||
drm_file_t *first;
|
||||
|
||||
/* down(&dev->struct_sem); */
|
||||
first = dev->file_first;
|
||||
while(first != NULL) {
|
||||
if(first->pid == current->pid) {
|
||||
break;
|
||||
}
|
||||
first = first->next;
|
||||
}
|
||||
|
||||
/* up(&dev->struct_sem); */
|
||||
return first;
|
||||
}
|
||||
|
||||
static __inline__ void drm_release_big_fscking_lock(drm_device_t *dev, drm_file_t *filp)
|
||||
{
|
||||
if(filp->lock_depth >= 0)
|
||||
spin_unlock_irqrestore(&dev->big_fscking_lock,
|
||||
filp->irq_flags);
|
||||
}
|
||||
|
||||
static __inline__ void drm_reacquire_big_fscking_lock(drm_device_t *dev, drm_file_t *filp)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if(filp->lock_depth >= 0) {
|
||||
barrier();
|
||||
spin_lock_irqsave(&dev->big_fscking_lock, flags);
|
||||
filp->irq_flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
/* This can NEVER be called from an interrupt */
|
||||
void drm_schedule(drm_device_t *dev)
|
||||
{
|
||||
drm_file_t *filp;
|
||||
|
||||
if(in_interrupt()) {
|
||||
BUG();
|
||||
}
|
||||
|
||||
filp = drm_find_filp_by_current_pid(dev);
|
||||
if(filp == NULL) BUG();
|
||||
drm_release_big_fscking_lock(dev, filp);
|
||||
schedule();
|
||||
drm_reacquire_big_fscking_lock(dev, filp);
|
||||
}
|
||||
|
||||
void drm_schedule_timeout(drm_device_t *dev, unsigned long timeout)
|
||||
{
|
||||
drm_file_t *filp;
|
||||
|
||||
if(in_interrupt()) {
|
||||
BUG();
|
||||
}
|
||||
|
||||
filp = drm_find_filp_by_current_pid(dev);
|
||||
if(filp == NULL) BUG();
|
||||
drm_release_big_fscking_lock(dev, filp);
|
||||
schedule_timeout(timeout);
|
||||
drm_reacquire_big_fscking_lock(dev, filp);
|
||||
}
|
||||
|
||||
void drm_big_fscking_lock(drm_device_t *dev)
|
||||
{
|
||||
drm_file_t *filp;
|
||||
unsigned long flags;
|
||||
|
||||
if(in_irq()) {
|
||||
barrier();
|
||||
if(!++dev->irq_lock_depth) {
|
||||
spin_lock_irqsave(&dev->big_fscking_lock,
|
||||
flags);
|
||||
dev->irq_flags = flags;
|
||||
}
|
||||
} else if (in_softirq()) {
|
||||
barrier();
|
||||
if(!++dev->bh_lock_depth) {
|
||||
spin_lock_irqsave(&dev->big_fscking_lock,
|
||||
flags);
|
||||
dev->bh_flags = flags;
|
||||
}
|
||||
} else {
|
||||
filp = drm_find_filp_by_current_pid(dev);
|
||||
if(filp == NULL) BUG();
|
||||
barrier();
|
||||
if(!++filp->lock_depth) {
|
||||
spin_lock_irqsave(&dev->big_fscking_lock,
|
||||
flags);
|
||||
dev->irq_flags = flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drm_big_fscking_unlock(drm_device_t *dev)
|
||||
{
|
||||
drm_file_t *filp;
|
||||
|
||||
if(in_irq()) {
|
||||
barrier();
|
||||
if(--dev->irq_lock_depth < 0)
|
||||
spin_unlock_irqrestore(&dev->big_fscking_lock,
|
||||
dev->irq_flags);
|
||||
} else if (in_softirq()) {
|
||||
barrier();
|
||||
if(--dev->bh_lock_depth < 0)
|
||||
spin_unlock_irqrestore(&dev->big_fscking_lock,
|
||||
dev->bh_flags);
|
||||
} else {
|
||||
filp = drm_find_filp_by_current_pid(dev);
|
||||
if(filp == NULL) BUG();
|
||||
barrier();
|
||||
if(--filp->lock_depth < 0)
|
||||
spin_unlock_irqrestore(&dev->big_fscking_lock,
|
||||
filp->irq_flags);
|
||||
}
|
||||
}
|
||||
|
||||
void __inline drm_big_fscking_lock_filp(drm_device_t *dev, drm_file_t *filp)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
barrier();
|
||||
if(!++filp->lock_depth) {
|
||||
spin_lock_irqsave(&dev->big_fscking_lock,
|
||||
flags);
|
||||
dev->irq_flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
void __inline drm_big_fscking_unlock_filp(drm_device_t *dev, drm_file_t *filp)
|
||||
{
|
||||
barrier();
|
||||
if(--filp->lock_depth < 0)
|
||||
spin_unlock_irqrestore(&dev->big_fscking_lock,
|
||||
filp->irq_flags);
|
||||
}
|
||||
|
|
@ -55,6 +55,7 @@ int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
|
|||
priv->dev = dev;
|
||||
priv->ioctl_count = 0;
|
||||
priv->authenticated = capable(CAP_SYS_ADMIN);
|
||||
priv->lock_depth = -1;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if (!dev->file_last) {
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ drm_buf_t *mga_freelist_get(drm_device_t *dev)
|
|||
&dev_priv->dispatch_status))
|
||||
break;
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
schedule();
|
||||
drm_schedule(dev);
|
||||
if (signal_pending(current)) {
|
||||
clear_bit(MGA_IN_GETBUF,
|
||||
&dev_priv->dispatch_status);
|
||||
|
|
@ -417,6 +417,7 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
|
|||
}
|
||||
|
||||
mga_flush_write_combine();
|
||||
|
||||
atomic_inc(&dev_priv->pending_bufs);
|
||||
MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
|
||||
MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
|
||||
|
|
@ -472,7 +473,7 @@ int mga_advance_primary(drm_device_t *dev)
|
|||
break;
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
atomic_inc(&dma->total_missed_sched);
|
||||
schedule();
|
||||
drm_schedule(dev);
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
|
|
@ -563,6 +564,8 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
drm_device_dma_t *dma = dev->dma;
|
||||
int retval = 0;
|
||||
|
||||
drm_big_fscking_lock(dev);
|
||||
|
||||
if (test_and_set_bit(0, &dev->dma_flag)) {
|
||||
atomic_inc(&dma->total_missed_dma);
|
||||
retval = -EBUSY;
|
||||
|
|
@ -633,6 +636,7 @@ sch_out_wakeup:
|
|||
}
|
||||
|
||||
clear_bit(0, &dev->dma_flag);
|
||||
drm_big_fscking_unlock(dev);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -645,6 +649,7 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
|
|||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
atomic_inc(&dev->total_irq);
|
||||
if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return;
|
||||
drm_big_fscking_lock(dev);
|
||||
MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
|
||||
last_prim_buffer = dev_priv->last_prim;
|
||||
last_prim_buffer->num_dwords = 0;
|
||||
|
|
@ -658,6 +663,7 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
|
|||
atomic_dec(&dev_priv->pending_bufs);
|
||||
queue_task(&dev->tq, &tq_immediate);
|
||||
mark_bh(IMMEDIATE_BH);
|
||||
drm_big_fscking_unlock(dev);
|
||||
}
|
||||
|
||||
static void mga_dma_task_queue(void *device)
|
||||
|
|
@ -813,8 +819,9 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
|||
/* Poll for the first buffer to insure that
|
||||
* the status register will be correct
|
||||
*/
|
||||
|
||||
|
||||
mga_flush_write_combine();
|
||||
|
||||
MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
|
||||
|
||||
MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
|
||||
|
|
@ -960,7 +967,7 @@ static int mga_flush_queue(drm_device_t *dev)
|
|||
&dev_priv->dispatch_status))
|
||||
break;
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
schedule();
|
||||
drm_schedule(dev);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR; /* Can't restart */
|
||||
clear_bit(MGA_IN_FLUSH,
|
||||
|
|
@ -1050,7 +1057,7 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
/* Contention */
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
drm_schedule(dev);
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -66,54 +66,55 @@ static struct miscdevice mga_misc = {
|
|||
};
|
||||
|
||||
static drm_ioctl_desc_t mga_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { mga_version, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { mga_version, 0, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { mga_control, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { mga_addbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { mga_markbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { mga_infobufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { mga_mapbufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { mga_freebufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { mga_control, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { mga_addbufs, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { mga_markbufs, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { mga_infobufs, 1, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { mga_mapbufs, 1, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { mga_freebufs, 1, 0, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { mga_addctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { mga_rmctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { mga_modctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { mga_getctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { mga_switchctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { mga_newctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { mga_resctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { mga_addctx, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { mga_rmctx, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { mga_modctx, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { mga_getctx, 1, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { mga_switchctx, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { mga_newctx, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { mga_resctx, 1, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma, 1, 0, 1 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_flush_ioctl, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1, 0 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_flush_ioctl, 1, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0, 1 },
|
||||
};
|
||||
|
||||
#define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls)
|
||||
|
|
@ -182,6 +183,9 @@ static int mga_setup(drm_device_t *dev)
|
|||
dev->last_context = 0;
|
||||
dev->last_switch = 0;
|
||||
dev->last_checked = 0;
|
||||
dev->irq_lock_depth = -1;
|
||||
dev->bh_lock_depth = -1;
|
||||
|
||||
init_timer(&dev->timer);
|
||||
init_waitqueue_head(&dev->context_wait);
|
||||
|
||||
|
|
@ -192,6 +196,7 @@ static int mga_setup(drm_device_t *dev)
|
|||
dev->buf_wp = dev->buf;
|
||||
dev->buf_end = dev->buf + DRM_BSZ;
|
||||
dev->buf_async = NULL;
|
||||
|
||||
init_waitqueue_head(&dev->buf_readers);
|
||||
init_waitqueue_head(&dev->buf_writers);
|
||||
|
||||
|
|
@ -539,7 +544,7 @@ int mga_release(struct inode *inode, struct file *filp)
|
|||
/* Contention */
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
drm_schedule(dev);
|
||||
if (signal_pending(current)) {
|
||||
retcode = -ERESTARTSYS;
|
||||
break;
|
||||
|
|
@ -619,7 +624,11 @@ int mga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
|| (ioctl->auth_needed && !priv->authenticated)) {
|
||||
retcode = -EACCES;
|
||||
} else {
|
||||
if(ioctl->needs_hvy_lock == 1)
|
||||
drm_big_fscking_lock_filp(dev, priv);
|
||||
retcode = (func)(inode, filp, cmd, arg);
|
||||
if(ioctl->needs_hvy_lock == 1)
|
||||
drm_big_fscking_unlock_filp(dev, priv);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -218,8 +218,8 @@ static void mgaG400EmitTex1(drm_mga_private_t * dev_priv, int source )
|
|||
|
||||
/* This takes 25 dwords */
|
||||
|
||||
PRIMOUTREG(MGAREG_TEXCTL2,
|
||||
regs[MGA_TEXREG_CTL2] | TMC_map1_enable | 0x00008000);
|
||||
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | TMC_map1_enable |
|
||||
0x00008000);
|
||||
PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]);
|
||||
PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER]);
|
||||
PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL]);
|
||||
|
|
@ -873,7 +873,9 @@ int mga_clear_bufs(struct inode *inode, struct file *filp,
|
|||
clear.clear_color_mask,
|
||||
clear.clear_depth_mask);
|
||||
PRIMUPDATE(dev_priv);
|
||||
|
||||
mga_flush_write_combine();
|
||||
|
||||
mga_dma_schedule(dev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -903,7 +905,9 @@ int mga_swap_bufs(struct inode *inode, struct file *filp,
|
|||
PRIMUPDATE(dev_priv);
|
||||
set_bit(MGA_BUF_SWAP_PENDING,
|
||||
&dev_priv->current_prim->buffer_status);
|
||||
|
||||
mga_flush_write_combine();
|
||||
|
||||
mga_dma_schedule(dev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -951,7 +955,9 @@ int mga_iload(struct inode *inode, struct file *filp,
|
|||
AGEBUF(dev_priv, buf_priv);
|
||||
buf_priv->discard = 1;
|
||||
mga_freelist_put(dev, buf);
|
||||
|
||||
mga_flush_write_combine();
|
||||
|
||||
mga_dma_schedule(dev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -999,7 +1005,9 @@ int mga_vertex(struct inode *inode, struct file *filp,
|
|||
mga_dma_dispatch_vertex(dev, buf);
|
||||
|
||||
PRIMUPDATE(dev_priv);
|
||||
|
||||
mga_flush_write_combine();
|
||||
|
||||
mga_dma_schedule(dev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1046,7 +1054,9 @@ int mga_indices(struct inode *inode, struct file *filp,
|
|||
mga_dma_dispatch_indices(dev, buf, indices.start, indices.end);
|
||||
|
||||
PRIMUPDATE(dev_priv);
|
||||
|
||||
mga_flush_write_combine();
|
||||
|
||||
mga_dma_schedule(dev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue