Beispiel #1
0
/* Frees older cached buffers.  Called under table_lock */
drm_private void
drm_tegra_bo_cache_cleanup(struct drm_tegra *drm,
			   time_t time)
{
	struct drm_tegra_bo_cache *cache = &drm->bo_cache;
	time_t delta;
	int i;

	if (cache->time == time)
		return;

	for (i = 0; i < cache->num_buckets; i++) {
		struct drm_tegra_bo_bucket *bucket = &cache->cache_bucket[i];
		struct drm_tegra_bo *bo;

		if (time && !bucket_free_up(drm, bucket, false))
			continue;

		while (!DRMLISTEMPTY(&bucket->list)) {
			bo = DRMLISTENTRY(struct drm_tegra_bo,
					bucket->list.next, bo_list);

			delta = time - bo->free_time;

			/* keep things in cache for at least 1 second: */
			if (time && delta <= 1)
				break;

			/* keep things in cache longer if not much */
			if (time && delta < 60 && bucket->num_entries < 5)
				break;

			VG_BO_OBTAIN(bo);
			DRMLISTDEL(&bo->bo_list);
			drm_tegra_bo_free(bo);
#ifndef NDEBUG
			if (drm->debug_bo)
				drm->debug_bos_cached--;
#endif
			bucket->num_entries--;
		}
	}

	cache->time = time;
}
Beispiel #2
0
drm_public int drm_tegra_bo_unref(struct drm_tegra_bo *bo)
{
	int err = 0;

	if (!bo)
		return -EINVAL;

	DBG_BO(bo, "\n");

	if (!atomic_dec_and_test(&bo->ref))
		return 0;

	drm_tegra_bo_check_guards(bo);

	pthread_mutex_lock(&table_lock);

	if (!bo->reuse || drm_tegra_bo_cache_free(bo))
		err = drm_tegra_bo_free(bo);

	pthread_mutex_unlock(&table_lock);

	return err;
}
Beispiel #3
0
drm_public
int drm_tegra_bo_from_dmabuf(struct drm_tegra_bo **bop, struct drm_tegra *drm,
			     int fd, uint32_t flags)
{
	struct drm_tegra_bo *dup;
	struct drm_tegra_bo *bo;
	uint32_t handle;
	uint32_t size;
	int err;

	if (!drm || !bop)
		return -EINVAL;

	pthread_mutex_lock(&table_lock);

	bo = calloc(1, sizeof(*bo));
	if (!bo) {
		err = -ENOMEM;
		goto unlock;
	}

	err = drmPrimeFDToHandle(drm->fd, fd, &handle);
	if (err) {
		free(bo);
		bo = NULL;
		goto unlock;
	}

	/* check handle table to see if BO is already open */
	dup = lookup_bo(drm->handle_table, handle);
	if (dup) {
		DBG_BO(dup, "success reused\n");
		free(bo);
		bo = dup;
		goto unlock;
	}

	errno = 0;
	/* lseek() to get bo size */
	size = lseek(fd, 0, SEEK_END);
	lseek(fd, 0, SEEK_CUR);
	/* store lseek() error number */
	err = -errno;

	atomic_set(&bo->ref, 1);
	bo->handle = handle;
	bo->flags = flags;
	bo->size = size;
	bo->drm = drm;

	VG_BO_ALLOC(bo);

	/* add ourself into the handle table: */
	drmHashInsert(drm->handle_table, handle, bo);

	/* handle lseek() error */
	if (err) {
		VDBG_BO(bo, "lseek failed %d (%s)\n", err, strerror(-err));
		drm_tegra_bo_free(bo);
		bo = NULL;
	} else {
		DBG_BO(bo, "success\n");
	}

unlock:
	pthread_mutex_unlock(&table_lock);

	*bop = bo;

	return err;
}
Beispiel #4
0
void drm_tegra_bo_unref(struct drm_tegra_bo *bo)
{
	if (bo && atomic_dec_and_test(&bo->ref))
		drm_tegra_bo_free(bo);
}