mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-08 12:48:05 +02:00
Performance tuning
This commit is contained in:
parent
122f75065c
commit
2753541c30
4 changed files with 52 additions and 13 deletions
|
|
@ -328,6 +328,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);
|
||||
}
|
||||
|
|
@ -337,6 +338,7 @@ int mga_advance_primary(drm_device_t *dev)
|
|||
DECLARE_WAITQUEUE(entry, current);
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_prim_buf_t *prim_buffer;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int next_prim_idx;
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -350,18 +352,13 @@ int mga_advance_primary(drm_device_t *dev)
|
|||
/* In use is cleared in interrupt handler */
|
||||
atomic_set(&dev_priv->in_wait, 1);
|
||||
if(test_and_set_bit(0, &prim_buffer->in_use)) {
|
||||
/* We need to wait, we should probably use
|
||||
* a wait queue for this.
|
||||
*/
|
||||
add_wait_queue(&dev_priv->wait_queue, &entry);
|
||||
for (;;) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
mga_dma_schedule(dev, 0);
|
||||
if(!test_and_set_bit(0, &prim_buffer->in_use)) break;
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
#if 0
|
||||
schedule_timeout(HZ/60);
|
||||
#endif
|
||||
atomic_inc(&dma->total_missed_sched);
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
|
|
@ -382,6 +379,41 @@ int mga_advance_primary(drm_device_t *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* More dynamic performance decisions */
|
||||
static inline int mga_decide_to_fire(drm_device_t *dev)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
||||
if(atomic_read(&dev_priv->next_prim->force_fire) ||
|
||||
(atomic_read(&dev_priv->in_flush) && dev_priv->next_prim->num_dwords)) {
|
||||
atomic_inc(&dma->total_prio);
|
||||
return 1;
|
||||
}
|
||||
if(atomic_read(&dev_priv->pending_bufs) <= (MGA_NUM_PRIM_BUFS - 3)) {
|
||||
|
||||
if(test_bit(0, &dev_priv->next_prim->swap_pending)) {
|
||||
atomic_inc(&dma->total_dmas);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if(atomic_read(&dev_priv->pending_bufs) <= (MGA_NUM_PRIM_BUFS / 2)) {
|
||||
if(dev_priv->next_prim->sec_used >= (MGA_DMA_BUF_NR / 8)) {
|
||||
atomic_inc(&dma->total_hit);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if(atomic_read(&dev_priv->pending_bufs) >= (MGA_NUM_PRIM_BUFS / 2)) {
|
||||
if(dev_priv->next_prim->sec_used >= (MGA_DMA_BUF_NR / 4)) {
|
||||
atomic_inc(&dma->total_missed_free);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
atomic_inc(&dma->total_tried);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_dma_schedule(drm_device_t *dev, int locked)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
|
|
@ -407,9 +439,7 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
|
||||
if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) {
|
||||
/* Fire dma buffer */
|
||||
if(dev_priv->next_prim->sec_used >= (MGA_DMA_BUF_NR / 2) ||
|
||||
(dev_priv->next_prim->num_dwords && atomic_read(&dev_priv->in_flush)) ||
|
||||
atomic_read(&dev_priv->next_prim->force_fire)) {
|
||||
if(mga_decide_to_fire(dev)) {
|
||||
DRM_DEBUG("mga_fire_primary\n");
|
||||
atomic_set(&dev_priv->next_prim->force_fire, 0);
|
||||
if(dev_priv->current_prim == dev_priv->next_prim) {
|
||||
|
|
@ -455,16 +485,17 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
|
|||
last_prim_buffer = dev_priv->prim_bufs[softrap_idx];
|
||||
dev_priv->last_prim = last_prim_buffer;
|
||||
last_prim_buffer->num_dwords = 0;
|
||||
last_prim_buffer->sec_used = 0;
|
||||
clear_bit(0, &last_prim_buffer->in_use);
|
||||
clear_bit(0, &last_prim_buffer->swap_pending);
|
||||
clear_bit(0, &dev_priv->dispatch_lock);
|
||||
atomic_dec(&dev_priv->pending_bufs);
|
||||
queue_task(&dev->tq, &tq_immediate);
|
||||
mark_bh(IMMEDIATE_BH);
|
||||
}
|
||||
|
||||
static void mga_dma_task_queue(void *device)
|
||||
{
|
||||
/* This needs to do primary buffer ping-ponging as well
|
||||
* as flushing */
|
||||
drm_device_t *dev = (drm_device_t *) device;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
|
||||
|
|
@ -853,6 +884,7 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
*/
|
||||
|
||||
if (!ret) {
|
||||
#if 0
|
||||
if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
|
||||
== lock.context && _DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock)) {
|
||||
long j = jiffies - dev->lock.lock_time;
|
||||
|
|
@ -864,6 +896,7 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
schedule_timeout(j);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
add_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
for (;;) {
|
||||
if (!dev->lock.hw_lock) {
|
||||
|
|
@ -911,8 +944,11 @@ int mga_flush_ioctl(struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
||||
|
||||
DRM_DEBUG("mga_flush_ioctl\n");
|
||||
atomic_inc(&dma->total_lost);
|
||||
mga_flush_queue(dev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ typedef struct {
|
|||
|
||||
#define MGA_VERBOSE 0
|
||||
|
||||
#define MGA_NUM_PRIM_BUFS 16
|
||||
#define MGA_NUM_PRIM_BUFS 8
|
||||
/* Primary buffer versions of above -- pretty similar really.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ typedef struct {
|
|||
u32 phys_head;
|
||||
int sec_used;
|
||||
int idx;
|
||||
int swap_pending;
|
||||
u32 in_use;
|
||||
atomic_t force_fire;
|
||||
} drm_mga_prim_buf_t;
|
||||
|
|
@ -67,6 +68,7 @@ typedef struct _drm_mga_private {
|
|||
u32 dispatch_lock;
|
||||
atomic_t in_flush;
|
||||
atomic_t in_wait;
|
||||
atomic_t pending_bufs;
|
||||
unsigned int last_sync_tag;
|
||||
unsigned int sync_tag;
|
||||
void *status_page;
|
||||
|
|
|
|||
|
|
@ -779,7 +779,8 @@ int mga_swap_bufs(struct inode *inode, struct file *filp,
|
|||
dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
|
||||
mga_dma_dispatch_swap( dev );
|
||||
PRIMUPDATE(dev_priv);
|
||||
atomic_set(&dev_priv->current_prim->force_fire, 1);
|
||||
set_bit(0, &dev_priv->current_prim->swap_pending);
|
||||
dev_priv->current_prim->swap_pending = 1;
|
||||
mga_dma_schedule(dev, 1);
|
||||
sarea_priv->last_dispatch = status[1];
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue