Ejemplo n.º 1
0
void drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf)
{
	cycles_t queued_to_dispatched;
	cycles_t dispatched_to_completed;
	cycles_t completed_to_freed;
	int	 q2d, d2c, c2f, q2c, q2f;
	
	if (buf->time_queued) {
		queued_to_dispatched	= (buf->time_dispatched
					   - buf->time_queued);
		dispatched_to_completed = (buf->time_completed
					   - buf->time_dispatched);
		completed_to_freed	= (buf->time_freed
					   - buf->time_completed);

		q2d = drm_histogram_slot(queued_to_dispatched);
		d2c = drm_histogram_slot(dispatched_to_completed);
		c2f = drm_histogram_slot(completed_to_freed);

		q2c = drm_histogram_slot(queued_to_dispatched
					 + dispatched_to_completed);
		q2f = drm_histogram_slot(queued_to_dispatched
					 + dispatched_to_completed
					 + completed_to_freed);
		
		atomic_inc(&dev->histo.total);
		atomic_inc(&dev->histo.queued_to_dispatched[q2d]);
		atomic_inc(&dev->histo.dispatched_to_completed[d2c]);
		atomic_inc(&dev->histo.completed_to_freed[c2f]);
		
		atomic_inc(&dev->histo.queued_to_completed[q2c]);
		atomic_inc(&dev->histo.queued_to_freed[q2f]);

	}
	buf->time_queued     = 0;
	buf->time_dispatched = 0;
	buf->time_completed  = 0;
	buf->time_freed	     = 0;
}
Ejemplo n.º 2
0
int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
		 unsigned long arg)
{
	drm_file_t	  *priv	  = filp->private_data;
	drm_device_t	  *dev	  = priv->dev;
	drm_lock_t	  lock;

	if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
		return -EFAULT;

	if (lock.context == DRM_KERNEL_CONTEXT) {
		DRM_ERROR("Process %d using kernel context %d\n",
			  current->pid, lock.context);
		return -EINVAL;
	}

	DRM_DEBUG("%d frees lock (%d holds)\n",
		  lock.context,
		  _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
	atomic_inc(&dev->total_unlocks);
	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);
	if (!dev->context_flag) {
		if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
				  DRM_KERNEL_CONTEXT)) {
			DRM_ERROR("\n");
		}
	}
#if DRM_DMA_HISTOGRAM
	atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles()
						       - dev->lck_start)]);
#endif

	unblock_all_signals();
	return 0;
}
Ejemplo n.º 3
0
int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd,
	      unsigned long arg)
{
        drm_file_t        *priv   = filp->private_data;
        drm_device_t      *dev    = priv->dev;
        DECLARE_WAITQUEUE(entry, current);
        int               ret   = 0;
        drm_lock_t        lock;
#if DRM_DMA_HISTOGRAM
        cycles_t          start;

        dev->lck_start = start = get_cycles();
#endif

        if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
		return -EFAULT;

        if (lock.context == DRM_KERNEL_CONTEXT) {
                DRM_ERROR("Process %d using kernel context %d\n",
                          current->pid, lock.context);
                return -EINVAL;
        }

        DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
                  lock.context, current->pid, dev->lock.hw_lock->lock,
                  lock.flags);

#if 0
				/* dev->queue_count == 0 right now for
                                   tdfx.  FIXME? */
        if (lock.context < 0 || lock.context >= dev->queue_count)
                return -EINVAL;
#endif

        if (!ret) {
#if 0
                if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
                    != lock.context) {
                        long j = jiffies - dev->lock.lock_time;

                        if (lock.context == tdfx_res_ctx.handle &&
				j >= 0 && j < DRM_LOCK_SLICE) {
                                /* Can't take lock if we just had it and
                                   there is contention. */
                                DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n",
					lock.context, current->pid, j,
					dev->lock.lock_time, jiffies);
                                current->state = TASK_INTERRUPTIBLE;
                                schedule_timeout(DRM_LOCK_SLICE-j);
				DRM_DEBUG("jiffies=%d\n", jiffies);
                        }
                }
#endif
                add_wait_queue(&dev->lock.lock_queue, &entry);
                for (;;) {
                        current->state = TASK_INTERRUPTIBLE;
                        if (!dev->lock.hw_lock) {
                                /* Device has been unregistered */
                                ret = -EINTR;
                                break;
                        }
                        if (drm_lock_take(&dev->lock.hw_lock->lock,
                                          lock.context)) {
                                dev->lock.pid       = current->pid;
                                dev->lock.lock_time = jiffies;
                                atomic_inc(&dev->total_locks);
                                break;  /* Got lock */
                        }

                                /* Contention */
                        atomic_inc(&dev->total_sleeps);
			yield();
                        if (signal_pending(current)) {
                                ret = -ERESTARTSYS;
                                break;
                        }
                }
                current->state = TASK_RUNNING;
                remove_wait_queue(&dev->lock.lock_queue, &entry);
        }

#if 0
	if (!ret && dev->last_context != lock.context &&
		lock.context != tdfx_res_ctx.handle &&
		dev->last_context != tdfx_res_ctx.handle) {
		add_wait_queue(&dev->context_wait, &entry);
	        current->state = TASK_INTERRUPTIBLE;
                /* PRE: dev->last_context != lock.context */
	        tdfx_context_switch(dev, dev->last_context, lock.context);
		/* POST: we will wait for the context
                   switch and will dispatch on a later call
                   when dev->last_context == lock.context
                   NOTE WE HOLD THE LOCK THROUGHOUT THIS
                   TIME! */
		yield();
	        current->state = TASK_RUNNING;
	        remove_wait_queue(&dev->context_wait, &entry);
	        if (signal_pending(current)) {
	                ret = -EINTR;
	        } else if (dev->last_context != lock.context) {
			DRM_ERROR("Context mismatch: %d %d\n",
                        	dev->last_context, lock.context);
	        }
	}
#endif

        if (!ret) {
		sigemptyset(&dev->sigmask);
		sigaddset(&dev->sigmask, SIGSTOP);
		sigaddset(&dev->sigmask, SIGTSTP);
		sigaddset(&dev->sigmask, SIGTTIN);
		sigaddset(&dev->sigmask, SIGTTOU);
		dev->sigdata.context = lock.context;
		dev->sigdata.lock    = dev->lock.hw_lock;
		block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);

                if (lock.flags & _DRM_LOCK_READY) {
				/* Wait for space in DMA/FIFO */
		}
                if (lock.flags & _DRM_LOCK_QUIESCENT) {
				/* Make hardware quiescent */
#if 0
                        tdfx_quiescent(dev);
#endif
		}
        }

#if LINUX_VERSION_CODE < 0x020400
	if (lock.context != tdfx_res_ctx.handle) {
		current->counter = 5;
		current->priority = DEF_PRIORITY/4;
	}
#endif
        DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");

#if DRM_DMA_HISTOGRAM
        atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
#endif

        return ret;
}