Beispiel #1
0
static struct i915_vma *
vma_create(struct drm_i915_gem_object *obj,
	   struct i915_address_space *vm,
	   const struct i915_ggtt_view *view)
{
	struct i915_vma *vma;
	struct rb_node *rb, **p;
	int i;

	/* The aliasing_ppgtt should never be used directly! */
	GEM_BUG_ON(vm == &vm->i915->mm.aliasing_ppgtt->base);

	vma = kmem_cache_zalloc(vm->i915->vmas, GFP_KERNEL);
	if (vma == NULL)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
		init_request_active(&vma->last_read[i], i915_vma_retire);
	init_request_active(&vma->last_fence, NULL);
	vma->vm = vm;
	vma->obj = obj;
	vma->resv = obj->resv;
	vma->size = obj->base.size;
	vma->display_alignment = I915_GTT_MIN_ALIGNMENT;

	if (view && view->type != I915_GGTT_VIEW_NORMAL) {
		vma->ggtt_view = *view;
		if (view->type == I915_GGTT_VIEW_PARTIAL) {
			GEM_BUG_ON(range_overflows_t(u64,
						     view->partial.offset,
						     view->partial.size,
						     obj->base.size >> PAGE_SHIFT));
			vma->size = view->partial.size;
			vma->size <<= PAGE_SHIFT;
			GEM_BUG_ON(vma->size > obj->base.size);
		} else if (view->type == I915_GGTT_VIEW_ROTATED) {
static int __i915_gem_timeline_init(struct drm_i915_private *i915,
				    struct i915_gem_timeline *timeline,
				    const char *name,
				    struct lock_class_key *lockclass,
				    const char *lockname)
{
	unsigned int i;
	u64 fences;

	lockdep_assert_held(&i915->drm.struct_mutex);

	timeline->i915 = i915;
	timeline->name = kstrdup(name ?: "[kernel]", GFP_KERNEL);
	if (!timeline->name)
		return -ENOMEM;

	list_add(&timeline->link, &i915->gt.timelines);

	/* Called during early_init before we know how many engines there are */
	fences = dma_fence_context_alloc(ARRAY_SIZE(timeline->engine));
	for (i = 0; i < ARRAY_SIZE(timeline->engine); i++) {
		struct intel_timeline *tl = &timeline->engine[i];

		tl->fence_context = fences++;
		tl->common = timeline;
#ifdef CONFIG_DEBUG_SPINLOCK
		__raw_spin_lock_init(&tl->lock.rlock, lockname, lockclass);
#else
		spin_lock_init(&tl->lock);
#endif
		init_request_active(&tl->last_request, NULL);
		INIT_LIST_HEAD(&tl->requests);
	}

	return 0;
}
Beispiel #3
0
static struct i915_vma *
__i915_vma_create(struct drm_i915_gem_object *obj,
		  struct i915_address_space *vm,
		  const struct i915_ggtt_view *view)
{
	struct i915_vma *vma;
	struct rb_node *rb, **p;
	int i;

	GEM_BUG_ON(vm->closed);

	vma = kmem_cache_zalloc(to_i915(obj->base.dev)->vmas, GFP_KERNEL);
	if (vma == NULL)
		return ERR_PTR(-ENOMEM);

	INIT_LIST_HEAD(&vma->exec_list);
	for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
		init_request_active(&vma->last_read[i], i915_vma_retire);
	init_request_active(&vma->last_fence, NULL);
	list_add(&vma->vm_link, &vm->unbound_list);
	vma->vm = vm;
	vma->obj = obj;
	vma->size = obj->base.size;

	if (view) {
		vma->ggtt_view = *view;
		if (view->type == I915_GGTT_VIEW_PARTIAL) {
			vma->size = view->params.partial.size;
			vma->size <<= PAGE_SHIFT;
		} else if (view->type == I915_GGTT_VIEW_ROTATED) {
			vma->size =
				intel_rotation_info_size(&view->params.rotated);
			vma->size <<= PAGE_SHIFT;
		}
	}

	if (i915_is_ggtt(vm)) {
		vma->flags |= I915_VMA_GGTT;
		list_add(&vma->obj_link, &obj->vma_list);
	} else {
		i915_ppgtt_get(i915_vm_to_ppgtt(vm));
		list_add_tail(&vma->obj_link, &obj->vma_list);
	}

	rb = NULL;
	p = &obj->vma_tree.rb_node;
	while (*p) {
		struct i915_vma *pos;

		rb = *p;
		pos = rb_entry(rb, struct i915_vma, obj_node);
		if (i915_vma_compare(pos, vm, view) < 0)
			p = &rb->rb_right;
		else
			p = &rb->rb_left;
	}
	rb_link_node(&vma->obj_node, rb, p);
	rb_insert_color(&vma->obj_node, &obj->vma_tree);

	return vma;
}