diff options
Diffstat (limited to 'linux-core')
-rw-r--r-- | linux-core/drmP.h | 21 | ||||
-rw-r--r-- | linux-core/drm_bufs.c | 12 | ||||
-rw-r--r-- | linux-core/drm_dma.c | 36 | ||||
-rw-r--r-- | linux-core/drm_drv.c | 24 | ||||
-rw-r--r-- | linux-core/drm_lock.c | 10 | ||||
-rw-r--r-- | linux-core/drm_os_linux.h | 15 | ||||
-rw-r--r-- | linux-core/i810_dma.c | 9 | ||||
-rw-r--r-- | linux-core/i810_drv.h | 2 | ||||
-rw-r--r-- | linux-core/i830_dma.c | 9 | ||||
-rw-r--r-- | linux-core/i830_drv.h | 2 |
10 files changed, 79 insertions, 61 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 5c1474df..a6b32285 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -276,6 +276,17 @@ do { \ (_map) = (_dev)->context_sareas[_ctx]; \ } while(0) +#define LOCK_TEST_WITH_RETURN( dev, filp ) \ +do { \ + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ + dev->lock.filp != filp ) { \ + DRM_ERROR( "%s called without lock held\n", \ + __FUNCTION__ ); \ + return -EINVAL; \ + } \ +} while (0) + + typedef int drm_ioctl_t( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -324,7 +335,7 @@ typedef struct drm_buf { __volatile__ int waiting; /* On kernel DMA queue */ __volatile__ int pending; /* On hardware DMA queue */ wait_queue_head_t dma_wait; /* Processes waiting */ - pid_t pid; /* PID of holding process */ + struct file *filp; /* Pointer to holding file descr */ int context; /* Kernel queue for this buffer */ int while_locked;/* Dispatch this buffer while locked */ enum { @@ -442,7 +453,7 @@ typedef struct drm_queue { typedef struct drm_lock_data { drm_hw_lock_t *hw_lock; /* Hardware lock */ - pid_t pid; /* PID of lock holder (0=kernel) */ + struct file *filp; /* File descr of lock holder (0=kernel) */ wait_queue_head_t lock_queue; /* Queue of blocked processes */ unsigned long lock_time; /* Time of last lock in jiffies */ } drm_lock_data_t; @@ -818,15 +829,15 @@ extern int DRM(mapbufs)( struct inode *inode, struct file *filp, extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); -extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid); +extern void DRM(reclaim_buffers)( struct file *filp ); #if __HAVE_OLD_DMA /* GH: This is a dirty hack for now... */ extern void DRM(clear_next_buffer)(drm_device_t *dev); extern int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long)); -extern int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *dma); -extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma); +extern int DRM(dma_enqueue)(struct file *filp, drm_dma_t *dma); +extern int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma); #endif #if __HAVE_DMA_IRQ extern int DRM(control)( struct inode *inode, struct file *filp, diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 9ce7cfff..b4e73699 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -404,7 +404,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, buf->waiting = 0; buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); - buf->pid = 0; + buf->filp = 0; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -617,7 +617,7 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp, buf->waiting = 0; buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); - buf->pid = 0; + buf->filp = 0; #if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; @@ -774,7 +774,7 @@ int DRM(addbufs_sg)( struct inode *inode, struct file *filp, buf->waiting = 0; buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); - buf->pid = 0; + buf->filp = 0; buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T); buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T), @@ -1012,9 +1012,9 @@ int DRM(freebufs)( struct inode *inode, struct file *filp, return -EINVAL; } buf = dma->buflist[idx]; - if ( buf->pid != current->pid ) { - DRM_ERROR( "Process %d freeing buffer owned by %d\n", - current->pid, buf->pid ); + if ( buf->filp != filp ) { + DRM_ERROR( "Process %d freeing buffer not owned\n", + current->pid ); return -EINVAL; } DRM(free_buffer)( dev, buf ); diff --git a/linux-core/drm_dma.c b/linux-core/drm_dma.c index 1b0b639e..d21c8b9d 100644 --- a/linux-core/drm_dma.c +++ b/linux-core/drm_dma.c @@ -189,7 +189,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->waiting = 0; buf->pending = 0; - buf->pid = 0; + buf->filp = 0; buf->used = 0; #if __HAVE_DMA_HISTOGRAM buf->time_completed = get_cycles(); @@ -211,14 +211,16 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) } #if !__HAVE_DMA_RECLAIM -void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) +void DRM(reclaim_buffers)( struct file *filp ) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; int i; if (!dma) return; for (i = 0; i < dma->buf_count; i++) { - if (dma->buflist[i]->pid == pid) { + if (dma->buflist[i]->filp == filp) { switch (dma->buflist[i]->list) { case DRM_LIST_NONE: DRM(free_buffer)(dev, dma->buflist[i]); @@ -319,8 +321,10 @@ int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long)) } -int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) +int DRM(dma_enqueue)(struct file *filp, drm_dma_t *d) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; int i; drm_queue_t *q; drm_buf_t *buf; @@ -382,10 +386,10 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) return -EINVAL; } buf = dma->buflist[ idx ]; - if (buf->pid != current->pid) { + if (buf->filp != filp) { atomic_dec(&q->use_count); - DRM_ERROR("Process %d using buffer owned by %d\n", - current->pid, buf->pid); + DRM_ERROR("Process %d using buffer not owned\n", + current->pid); return -EINVAL; } if (buf->list != DRM_LIST_NONE) { @@ -427,9 +431,11 @@ int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d) return 0; } -static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, +static int DRM(dma_get_buffers_of_order)(struct file *filp, drm_dma_t *d, int order) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; int i; drm_buf_t *buf; drm_device_dma_t *dma = dev->dma; @@ -439,13 +445,13 @@ static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, d->flags & _DRM_DMA_WAIT); if (!buf) break; if (buf->pending || buf->waiting) { - DRM_ERROR("Free buffer %d in use by %d (w%d, p%d)\n", + DRM_ERROR("Free buffer %d in use by %x (w%d, p%d)\n", buf->idx, - buf->pid, + buf->filp, buf->waiting, buf->pending); } - buf->pid = current->pid; + buf->filp = filp; if (copy_to_user(&d->request_indices[i], &buf->idx, sizeof(buf->idx))) @@ -462,7 +468,7 @@ static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d, } -int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) +int DRM(dma_get_buffers)(struct file *filp, drm_dma_t *dma) { int order; int retcode = 0; @@ -471,7 +477,7 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) order = DRM(order)(dma->request_size); dma->granted_count = 0; - retcode = DRM(dma_get_buffers_of_order)(dev, dma, order); + retcode = DRM(dma_get_buffers_of_order)(filp, dma, order); if (dma->granted_count < dma->request_count && (dma->flags & _DRM_DMA_SMALLER_OK)) { @@ -481,7 +487,7 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) && tmp_order >= DRM_MIN_ORDER; --tmp_order) { - retcode = DRM(dma_get_buffers_of_order)(dev, dma, + retcode = DRM(dma_get_buffers_of_order)(filp, dma, tmp_order); } } @@ -494,7 +500,7 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) && tmp_order <= DRM_MAX_ORDER; ++tmp_order) { - retcode = DRM(dma_get_buffers_of_order)(dev, dma, + retcode = DRM(dma_get_buffers_of_order)(filp, dma, tmp_order); } } diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 41349e8c..0a4f3aeb 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -496,7 +496,7 @@ static int DRM(takedown)( drm_device_t *dev ) #endif if ( dev->lock.hw_lock ) { dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ - dev->lock.pid = 0; + dev->lock.filp = 0; wake_up_interruptible( &dev->lock.lock_queue ); } up( &dev->struct_sem ); @@ -732,8 +732,6 @@ int DRM(open)( struct inode *inode, struct file *filp ) return -ENODEV; } - DRM_DEBUG( "open_count = %d\n", dev->open_count ); - retcode = DRM(open_helper)( inode, filp, dev ); if ( !retcode ) { atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); @@ -770,10 +768,10 @@ int DRM(release)( struct inode *inode, struct file *filp ) if ( dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && - dev->lock.pid == current->pid ) { - DRM_DEBUG( "Process %d dead, freeing lock for context %d\n", - current->pid, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); + dev->lock.filp == filp ) { + DRM_DEBUG( "File %p released, freeing lock for context %d\n", + filp, + _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); #if __HAVE_RELEASE DRIVER_RELEASE(); #endif @@ -789,6 +787,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) else if ( dev->lock.hw_lock ) { /* The lock is required to reclaim buffers */ DECLARE_WAITQUEUE( entry, current ); + add_wait_queue( &dev->lock.lock_queue, &entry ); for (;;) { current->state = TASK_INTERRUPTIBLE; @@ -799,7 +798,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT ) ) { - dev->lock.pid = priv->pid; + dev->lock.filp = filp; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ @@ -823,7 +822,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) } } #elif __HAVE_DMA - DRM(reclaim_buffers)( dev, priv->pid ); + DRM(reclaim_buffers)( filp ); #endif DRM(fasync)( -1, filp, 0 ); @@ -847,7 +846,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) dev->file_last = priv->prev; } up( &dev->struct_sem ); - + DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES ); /* ======================================================== @@ -872,6 +871,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) spin_unlock( &dev->count_lock ); unlock_kernel(); + return retcode; } @@ -969,7 +969,7 @@ int DRM(lock)( struct inode *inode, struct file *filp, } if ( DRM(lock_take)( &dev->lock.hw_lock->lock, lock.context ) ) { - dev->lock.pid = current->pid; + dev->lock.filp = filp; dev->lock.lock_time = jiffies; atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); break; /* Got lock */ @@ -1051,7 +1051,7 @@ int DRM(unlock)( struct inode *inode, struct file *filp, * agent to request it then we should just be able to * take it immediately and not eat the ioctl. */ - dev->lock.pid = 0; + dev->lock.filp = 0; { __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock; unsigned int old, new, prev, ctx; diff --git a/linux-core/drm_lock.c b/linux-core/drm_lock.c index c887d1f6..e9b17cc4 100644 --- a/linux-core/drm_lock.c +++ b/linux-core/drm_lock.c @@ -79,7 +79,7 @@ int DRM(lock_transfer)(drm_device_t *dev, { unsigned int old, new, prev; - dev->lock.pid = 0; + dev->lock.filp = 0; do { old = *lock; new = context | _DRM_LOCK_HELD; @@ -92,19 +92,17 @@ int DRM(lock_free)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new, prev; - pid_t pid = dev->lock.pid; - dev->lock.pid = 0; + dev->lock.filp = 0; do { old = *lock; new = 0; prev = cmpxchg(lock, old, new); } while (prev != old); if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { - DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n", + DRM_ERROR("%d freed heavyweight lock held by %d\n", context, - _DRM_LOCKING_CONTEXT(old), - pid); + _DRM_LOCKING_CONTEXT(old)); return 1; } wake_up_interruptible(&dev->lock.lock_queue); diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h index e9b24356..b57efd34 100644 --- a/linux-core/drm_os_linux.h +++ b/linux-core/drm_os_linux.h @@ -3,16 +3,17 @@ #include <linux/interrupt.h> /* For task queue support */ #include <linux/delay.h> +#define DRMFILE struct file * #define DRM_IOCTL_ARGS struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data #define DRM_ERR(d) -(d) #define DRM_CURRENTPID current->pid #define DRM_UDELAY(d) udelay(d) -#define DRM_READ8(addr) readb(addr) -#define DRM_READ32(addr) readl(addr) -#define DRM_WRITE8(addr, val) writeb(val, addr) -#define DRM_WRITE32(addr, val) writel(val, addr) -#define DRM_READMEMORYBARRIER() mb() -#define DRM_WRITEMEMORYBARRIER() wmb() +#define DRM_READ8(map, offset) readb(((unsigned long)(map)->handle) + (offset)) +#define DRM_READ32(map, offset) readl(((unsigned long)(map)->handle) + (offset)) +#define DRM_WRITE8(map, offset, val) writeb(val, ((unsigned long)(map)->handle) + (offset)) +#define DRM_WRITE32(map, offset, val) writel(val, ((unsigned long)(map)->handle) + (offset)) +#define DRM_READMEMORYBARRIER(map) mb() +#define DRM_WRITEMEMORYBARRIER(map) wmb() #define DRM_DEVICE drm_file_t *priv = filp->private_data; \ drm_device_t *dev = priv->dev @@ -42,7 +43,7 @@ /* malloc/free without the overhead of DRM(alloc) */ #define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL) -#define DRM_FREE(x) kfree(x) +#define DRM_FREE(x,size) kfree(x) #define DRM_GETSAREA() \ do { \ diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index 91c204c5..de9345e3 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -209,7 +209,6 @@ static int i810_unmap_buffer(drm_buf_t *buf) static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, struct file *filp) { - drm_file_t *priv = filp->private_data; drm_buf_t *buf; drm_i810_buf_priv_t *buf_priv; int retcode = 0; @@ -227,7 +226,7 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, DRM_ERROR("mapbuf failed, retcode %d\n", retcode); return retcode; } - buf->pid = priv->pid; + buf->filp = filp; buf_priv = buf->dev_private; d->granted = 1; d->request_idx = buf->idx; @@ -856,8 +855,10 @@ static int i810_flush_queue(drm_device_t *dev) } /* Must be called with the lock held */ -void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) +void i810_reclaim_buffers(struct file *filp) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; int i; @@ -871,7 +872,7 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - if (buf->pid == pid && buf_priv) { + if (buf->filp == filp && buf_priv) { int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h index 24bcc55f..bbb570bc 100644 --- a/linux-core/i810_drv.h +++ b/linux-core/i810_drv.h @@ -88,7 +88,7 @@ extern int i810_dma_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_flush_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern void i810_reclaim_buffers(drm_device_t *dev, pid_t pid); +extern void i810_reclaim_buffers(struct file *filp); extern int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma); diff --git a/linux-core/i830_dma.c b/linux-core/i830_dma.c index 419cea12..d2555c92 100644 --- a/linux-core/i830_dma.c +++ b/linux-core/i830_dma.c @@ -217,7 +217,6 @@ static int i830_unmap_buffer(drm_buf_t *buf) static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, struct file *filp) { - drm_file_t *priv = filp->private_data; drm_buf_t *buf; drm_i830_buf_priv_t *buf_priv; int retcode = 0; @@ -235,7 +234,7 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, DRM_ERROR("mapbuf failed, retcode %d\n", retcode); return retcode; } - buf->pid = priv->pid; + buf->filp = filp; buf_priv = buf->dev_private; d->granted = 1; d->request_idx = buf->idx; @@ -1301,8 +1300,10 @@ static int i830_flush_queue(drm_device_t *dev) } /* Must be called with the lock held */ -void i830_reclaim_buffers(drm_device_t *dev, pid_t pid) +void i830_reclaim_buffers( struct file *filp ) { + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; drm_device_dma_t *dma = dev->dma; int i; @@ -1316,7 +1317,7 @@ void i830_reclaim_buffers(drm_device_t *dev, pid_t pid) drm_buf_t *buf = dma->buflist[ i ]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - if (buf->pid == pid && buf_priv) { + if (buf->filp == filp && buf_priv) { int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE); diff --git a/linux-core/i830_drv.h b/linux-core/i830_drv.h index daad4760..37313afd 100644 --- a/linux-core/i830_drv.h +++ b/linux-core/i830_drv.h @@ -101,7 +101,7 @@ extern int i830_dma_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i830_flush_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern void i830_reclaim_buffers(drm_device_t *dev, pid_t pid); +extern void i830_reclaim_buffers(struct file *filp); extern int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma); |