drm/i915: Add soft-pinning API for execbuffer
Subsystems (3)
PATCH 1/1 drm/i915: Add soft-pinning API for execbuffer
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
--- drivers/gpu/drm/i915/i915_drv.h | 5 +++ drivers/gpu/drm/i915/i915_gem.c | 53 ++++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_gem_evict.c | 52 +++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 9 ++++- include/uapi/drm/i915_drm.h | 3 +- 5 files changed, 106 insertions(+), 16 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +5 -0
@@ -2590,7 +2590,9 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_NONBLOCK 0x2#define PIN_GLOBAL 0x4#define PIN_OFFSET_BIAS 0x8 +#define PIN_OFFSET_FIXED 0x10#define PIN_OFFSET_MASK (~4095) + int __must_check i915_gem_object_pin_view(struct drm_i915_gem_object *obj, struct i915_address_space *vm, uint32_t size,
@@ -2942,6 +2944,9 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,unsigned long start, unsigned long end, unsigned flags); +int __must_check +i915_gem_evict_range (struct drm_device *dev,struct i915_address_space *vm, +unsigned long start,unsigned long end);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);int i915_gem_evict_everything (struct drm_device *dev);
drivers/gpu/drm/i915/i915_gem.c +39 -14
67 lines not on this page · raw message
drivers/gpu/drm/i915/i915_gem_evict.c +52 -0
58 lines not on this page · raw message
drivers/gpu/drm/i915/i915_gem_execbuffer.c +8 -1
@@ -590,6 +590,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ; } ret = i915_gem_object_pin(obj, vma->vm,
@@ -666,6 +668,10 @@ eb_vma_misplaced(struct i915_vma *vma)if (vma->node.size < entry->pad_to_size)return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;
@@ -1392,7 +1398,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }
include/uapi/drm/i915_drm.h +2 -1
@@ -679,7 +679,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_PAD_TO_SIZE (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PAD_TO_SIZE<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;__u64 pad_to_size;
Signature · 6 lines
2.1.4 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 6 lines · Chris Wilson
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Chris, would you add libdrm support for this? e.g beignet doesn't handle exec object itself but use libdrm.
Signature · 3 lines
Open Source Technology Center, Intel ltd. $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
_______________________________________________
Beignet mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/beignet
Quoted 36 lines
-----Original Message-----
From: Intel-gfx [mailto:[email protected]] On Behalf Of Chris Wilson
Sent: Friday, March 6, 2015 9:44 AM
To: [email protected]
Subject: [Intel-gfx] [PATCH] drm/i915: Add soft-pinning API for execbufferUserspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>--- drivers/gpu/drm/i915/i915_drv.h | 5 +++ drivers/gpu/drm/i915/i915_gem.c | 53 ++++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_gem_evict.c | 52 +++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 9 ++++- include/uapi/drm/i915_drm.h | 3 +- 5 files changed, 106 insertions(+), 16 deletions(-)drivers/gpu/drm/i915/i915_gem.c +2
-0@@ -3592,22 +3592,43 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, if (IS_ERR(vma)) goto err_unpin; +if (flags &PIN_OFFSET_FIXED ) { +uint64_t offset = flags &PIN_OFFSET_MASK ;
drivers/gpu/drm/i915/i915_gem.c i915_gem_object_bind_to_vm(struct · line 3607
Quoted 10 lines
drivers/gpu/drm/i915/i915_gem.c +10
-0+if (offset & (alignment -1 )) { + vma =ERR_PTR (-EINVAL ); + goto err_free_vma; + } + vma->node.start = offset; + vma->node.size = size; + vma->node.color = obj->cache_level; + ret =drm_mm_reserve_node (&vm->mm, &vma->node); +if (ret) { + ret =i915_gem_evict_range (dev, vm, start, end);
Did you mean i915_gem_evict_range(dev, vm, offset, offset+size) ?
Quoted 75 lines
drivers/gpu/drm/i915/i915_gem.c +13
-13+if (ret ==0 ) + ret =drm_mm_reserve_node (&vm->mm, &vma->node); + } +if (ret) { + vma =ERR_PTR (ret); + goto err_free_vma; + } + }else { search_free: - ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, - size, alignment, - obj->cache_level, - start, end, -DRM_MM_SEARCH_DEFAULT , - DRM_MM_CREATE_DEFAULT); -if (ret) { - ret =i915_gem_evict_something (dev, vm, size, alignment, - obj->cache_level, - start, end, - flags); -if (ret ==0 ) - goto search_free; + ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node, + size, alignment, + obj->cache_level, + start, end, +
DRM_MM_SEARCH_DEFAULT,
+DRM_MM_CREATE_DEFAULT);drivers/gpu/drm/i915/i915_gem.c +2
-0+if (ret) { + ret = i915_gem_evict_something(dev, vm, size,alignment,
drivers/gpu/drm/i915/i915_gem.c +7
-1+ obj->cache_level, + start, end, + flags); +if (ret ==0 ) + goto search_free; - goto err_free_vma; + goto err_free_vma; + } }if (WARN_ON (!i915_gem_valid_gtt_space (vma, obj->cache_level))) { ret = -EINVAL ;drivers/gpu/drm/i915/i915_gem_evict.c +14
-0@@ -195,6 +195,58 @@ found:return ret; } +int +i915_gem_evict_range (struct drm_device *dev,struct i915_address_space *vm, +unsigned long start,unsigned long end) +{ +struct drm_mm_node *node; +struct list_head eviction_list; +int ret =0 ; + +INIT_LIST_HEAD (&eviction_list); +drm_mm_for_each_node (node, &vm->mm) { +struct i915_vma *vma; + +if (node->start + node->size <= start) +continue ;
drivers/gpu/drm/i915/i915_gem_evict.c found: · line 222
Quoted 10 lines
drivers/gpu/drm/i915/i915_gem_evict.c +10
-0+if (node->start >= end) +break ; + + vma =container_of (node,typeof (*vma), node); +if (vma->pin_count) { + ret = -EBUSY ; +break ; + } + +if (WARN_ON (!list_empty (&vma->exec_list))) {
So if an execbuffer uses both EXEC_OBJECT_PINNED and ordinary buffers in its exec_list then the ordinary buffers cannot be relocated if they are in the range of the pinned buffer. Was this your intention?
drivers/gpu/drm/i915/i915_gem_evict.c found: · line 227
Quoted 6 lines
drivers/gpu/drm/i915/i915_gem_evict.c +6
-0+ ret = -EINVAL ; +break ; + } + +drm_gem_object_reference (&vma->obj->base); +list_add (&vma->exec_list, &eviction_list);
I guess we need another list_head if we want to support both types of object in the same execbuffer call and allow relocation.
Quoted 11 lines
drivers/gpu/drm/i915/i915_gem_evict.c +11
-0+ } + +while (!list_empty (&eviction_list)) { +struct i915_vma *vma; +struct drm_gem_object *obj; + + vma =list_first_entry (&eviction_list, + struct i915_vma, + exec_list); + + obj = &vma->obj->base;
drivers/gpu/drm/i915/i915_gem_evict.c found: · line 248
Quoted 10 lines
drivers/gpu/drm/i915/i915_gem_evict.c +10
-0+ +list_del_init (&vma->exec_list); +if (ret ==0 ) + ret =i915_vma_unbind (vma); + +drm_gem_object_unreference (obj); + } + +return ret; +}
Useful and worthwhile patch though. Cheers.
Thomas.
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 34 lines · Thomas
Quoted 34 lines
-----Original Message-----
From: Intel-gfx [mailto:[email protected]] On Behalf Of Chris Wilson
Sent: Friday, March 6, 2015 9:44 AM
To: [email protected]
Subject: [Intel-gfx] [PATCH] drm/i915: Add soft-pinning API for execbufferUserspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>--- drivers/gpu/drm/i915/i915_drv.h | 5 +++ drivers/gpu/drm/i915/i915_gem.c | 53 ++++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_gem_evict.c | 52 +++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 9 ++++- include/uapi/drm/i915_drm.h | 3 +- 5 files changed, 106 insertions(+), 16 deletions(-)drivers/gpu/drm/i915/i915_gem.c +0
-0@@ -3592,22 +3592,43 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, if (IS_ERR(vma)) goto err_unpin;
Quoted 13 lines
drivers/gpu/drm/i915/i915_gem.c i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, · line 3606
Quoted 12 lines
drivers/gpu/drm/i915/i915_gem.c +12
-0+if (flags &PIN_OFFSET_FIXED ) { +uint64_t offset = flags &PIN_OFFSET_MASK ; +if (offset & (alignment -1 )) { + vma =ERR_PTR (-EINVAL ); + goto err_free_vma; + } + vma->node.start = offset; + vma->node.size = size; + vma->node.color = obj->cache_level; + ret =drm_mm_reserve_node (&vm->mm, &vma->node); +if (ret) { + ret =i915_gem_evict_range (dev, vm, start, end);Did you mean
i915_gem_evict_range(dev, vm, offset, offset+size)?
Whoops. I guess i915_gem_evict_vma() would be a better interface.
Quoted 18 lines
Quoted 18 lines
drivers/gpu/drm/i915/i915_gem.c +17
-0+int +i915_gem_evict_range (struct drm_device *dev,struct i915_address_space *vm, +unsigned long start,unsigned long end) +{ +struct drm_mm_node *node; +struct list_head eviction_list; +int ret =0 ; + +INIT_LIST_HEAD (&eviction_list); +drm_mm_for_each_node (node, &vm->mm) { +struct i915_vma *vma; + +if (node->start + node->size <= start) +continue ; +if (node->start >= end) +break ; +
Quoted 8 lines
drivers/gpu/drm/i915/i915_gem.c i915_gem_object_bind_to_vm(struct · line 3632
Quoted 7 lines
drivers/gpu/drm/i915/i915_gem.c +7
-0+ vma =container_of (node,typeof (*vma), node); +if (vma->pin_count) { + ret = -EBUSY ; +break ; + } + +if (WARN_ON (!list_empty (&vma->exec_list))) {So if an execbuffer uses both
EXEC_OBJECT_PINNEDand ordinary buffers in itsexec_listthen the ordinary buffers cannot be relocated if they are in the range of the pinned buffer. Was this your intention?
The desired behaviour should be to restart the reservation process with bind the fixed objects first, then bind the rest.
The reservation logic is design around not moving objects, with the expectation that we can reuse the layout from the last batch and optimised for that. We should return ENOSPC here which causes the reservation logic to unpin everything, evict and try again. It will be easy enough to place the fixed objects at the head of the second pass.
I choose EINVAL initially thinking it should catch the condition of two overlapping fixed objects without consider evicting ordinary bo (I was caught thinking of userspace doing an all or nothing approach).
Quoted 8 lines
drivers/gpu/drm/i915/i915_gem.c i915_gem_object_bind_to_vm(struct
Quoted 7 lines
drivers/gpu/drm/i915/i915_gem.c +6
-0+ ret = -EINVAL ; +break ; + } + +drm_gem_object_reference (&vma->obj->base); +list_add (&vma->exec_list, &eviction_list);I guess we need another
list_headif we want to support both types of object in the same execbuffer call and allow relocation.
Actually, here since we are walking the drm_mm rather than using the scanner, we can switch over to list_for_each_entry_safe() and do the unbinding inline.
Reduces to
inti915_gem_evict_for_vma(struct i915_vma *target)
{
struct drm_mm_node *node, *next;
int ret;
list_for_each_entry_safe(node, next,
&target->vm->mm.head_node.node_list,
node_list) {
struct i915_vma *vma;
if (node->start + node->size <= target->node.start)
continue;
if (node->start >= target->node.start + target->node.size)
break;
vma = container_of(node, typeof(*vma), node);
if (vma->exec_entry &&
vma->exec_entry->flags & EXEC_OBJECT_PINNED)
/* Overlapping fixed objects in the same batch */
return -EINVAL;
if (vma->pin_count)
/* We may need to evict an buffer in the same batch */
return vma->exec_entry ? -ENOSPC : -EBUSY;
ret = i915_vma_unbind(vma);
if (ret)
return ret;
}
return 0;
}-Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH v4 1/1 drm/i915: Add soft-pinning API for execbuffer
In reply to Chris WilsonFrom: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)
v4: Moved soft-pinned objects to the front of ordered_vmas so that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.
--- drivers/gpu/drm/i915/i915_drv.h | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 51 ++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_gem_evict.c | 38 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++-- include/uapi/drm/i915_drm.h | 9 +++-- 5 files changed, 99 insertions(+), 19 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +4 -0
@@ -2747,7 +2747,9 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_USER (1<<4)#define PIN_UPDATE (1<<5)#define PIN_FULL_RANGE (1<<6) +#define PIN_OFFSET_FIXED (1<<7)#define PIN_OFFSET_MASK (~4095) + int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, struct i915_address_space *vm,
@@ -3085,6 +3087,8 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,unsigned long start, unsigned long end, unsigned flags); +int __must_check +i915_gem_evict_for_vma (struct i915_vma *target);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);int i915_gem_evict_everything (struct drm_device *dev);
drivers/gpu/drm/i915/i915_gem.c +37 -14
65 lines not on this page · raw message
drivers/gpu/drm/i915/i915_gem_evict.c +38 -0
@@ -199,6 +199,44 @@ found:return ret; } +int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +/* We may need to evict a buffer in the same batch */ +if (!vma->exec_entry) +return -EBUSY ; + +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */ +return -EINVAL ; + +return -ENOSPC ; + } + + ret =i915_vma_unbind (vma); +if (ret) +return ret; + } + +return 0 ; +} +/** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse
drivers/gpu/drm/i915/i915_gem_execbuffer.c +14 -2
@@ -596,6 +596,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL |PIN_MAPPABLE ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ; } ret =i915_gem_object_pin (obj, vma->vm, entry->alignment, flags);
@@ -665,6 +667,10 @@ eb_vma_misplaced(struct i915_vma *vma) vma->node.start & (entry->alignment - 1))return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;
@@ -690,6 +696,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring,struct i915_vma *vma;struct i915_address_space *vm;struct list_head ordered_vmas; +struct list_head pinned_vmas;bool has_fenced_gpu_access =INTEL_INFO (ring->dev)->gen <4 ;int retry;
@@ -698,6 +705,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;INIT_LIST_HEAD (&ordered_vmas); +INIT_LIST_HEAD (&pinned_vmas);while (!list_empty (vmas)) {struct drm_i915_gem_exec_object2 *entry;bool need_fence, need_mappable;
@@ -716,7 +724,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode !=I915_TILING_NONE ; need_mappable = need_fence ||need_reloc_mappable (vma); -if (need_mappable) { +if (entry->flags &EXEC_OBJECT_PINNED ) +list_move_tail (&vma->exec_list, &pinned_vmas); +else if (need_mappable) { entry->flags |= __EXEC_OBJECT_NEEDS_MAP;list_move (&vma->exec_list, &ordered_vmas); }else
@@ -726,6 +736,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_write_domain =0 ; }list_splice (&ordered_vmas, vmas); +list_splice (&pinned_vmas, vmas);/* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases:
@@ -1404,7 +1415,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }
include/uapi/drm/i915_drm.h +6 -3
@@ -677,8 +677,10 @@ struct drm_i915_gem_exec_object2 {__u64 alignment;/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* Otherwise the kernel populates it with the value of the updated +* offset of the object, for future presumed_offset writes. */ __u64 offset;
@@ -686,7 +688,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_SUPPORTS_48BBADDRESS (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48BBADDRESS<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;__u64 rsvd1;
Signature · 6 lines
1.7.9.5 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Many apologies to Michal for incorrectly spelling his name in the CC list.
Thomas.
Quoted 300 lines
-----Original Message-----
From: Daniel, Thomas
Sent: Tuesday, June 30, 2015 3:13 PM
To: [email protected]
Cc: Chris Wilson; Goel, Akash; Belgaumkar, Vinay; Michal Winiarsky; Zou, Nanhai; Daniel, Thomas
Subject: [PATCH v4] drm/i915: Add soft-pinning API for execbufferFrom: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarsky <[email protected]>Cc Zou Nanhai <[email protected]>Signed-off-by Thomas Daniel <[email protected]>--- drivers/gpu/drm/i915/i915_drv.h | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 51 ++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_gem_evict.c | 38 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++-- include/uapi/drm/i915_drm.h | 9 +++-- 5 files changed, 99 insertions(+), 19 deletions(-)drivers/gpu/drm/i915/i915_drv.h +4
-0@@ -2747,7 +2747,9 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_USER (1<<4)#define PIN_UPDATE (1<<5)#define PIN_FULL_RANGE (1<<6) +#define PIN_OFFSET_FIXED (1<<7)#define PIN_OFFSET_MASK (~4095) + int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, struct i915_address_space *vm,@@ -3085,6 +3087,8 @@ int __must_check i915_gem_evict_something(structdrm_device *dev, unsigned long start, unsigned long end, unsigned flags); +int __must_check +i915_gem_evict_for_vma (struct i915_vma *target);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);int i915_gem_evict_everything (struct drm_device *dev);drivers/gpu/drm/i915/i915_gem.c +37
-14@@ -3806,22 +3806,41 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, if (IS_ERR(vma)) goto err_unpin; +if (flags &PIN_OFFSET_FIXED ) { +uint64_t offset = flags &PIN_OFFSET_MASK ; +if (offset & (alignment -1 )) { + ret = -EINVAL ; + goto err_free_vma; + } + vma->node.start = offset; + vma->node.size = size; + vma->node.color = obj->cache_level; + ret =drm_mm_reserve_node (&vm->mm, &vma->node); +if (ret) { + ret =i915_gem_evict_for_vma (vma); +if (ret ==0 ) + ret =drm_mm_reserve_node (&vm->mm, &vma->node); + } +if (ret) + goto err_free_vma; + }else { search_free: - ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, - size, alignment, - obj->cache_level, - start, end, - search_flag, - alloc_flag); -if (ret) { - ret =i915_gem_evict_something (dev, vm, size, alignment, - obj->cache_level, - start, end, - flags); -if (ret ==0 ) - goto search_free; + ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, + size, alignment, + obj->cache_level, + start, end, + search_flag, + alloc_flag); +if (ret) { + ret =i915_gem_evict_something (dev, vm, size, alignment, + obj->cache_level, + start, end, + flags); +if (ret ==0 ) + goto search_free; - goto err_free_vma; + goto err_free_vma; + } }if (WARN_ON (!i915_gem_valid_gtt_space (vma, obj->cache_level))) { ret = -EINVAL ;@@ -4357,6 +4376,10 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags) vma->node.start < (flags & PIN_OFFSET_MASK)) return true; +if (flags &PIN_OFFSET_FIXED && + vma->node.start != (flags &PIN_OFFSET_MASK )) +return true; +return false; }drivers/gpu/drm/i915/i915_gem_evict.c +38
-0@@ -199,6 +199,44 @@ found:return ret; } +int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +/* We may need to evict a buffer in the same batch */ +if (!vma->exec_entry) +return -EBUSY ; + +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */ +return -EINVAL ; + +return -ENOSPC ; + } + + ret =i915_vma_unbind (vma); +if (ret) +return ret; + } + +return 0 ; +} +/** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse
drivers/gpu/drm/i915/i915_gem_execbuffer.c +2
-0@@ -596,6 +596,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL |PIN_MAPPABLE ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ; }drivers/gpu/drm/i915/i915_gem_execbuffer.c +6
-0ret =i915_gem_object_pin (obj, vma->vm, entry->alignment, flags);@@ -665,6 +667,10 @@ eb_vma_misplaced(struct i915_vma *vma) vma->node.start & (entry->alignment - 1))return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;@@ -690,6 +696,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, struct i915_vma *vma;struct i915_address_space *vm;struct list_head ordered_vmas; +struct list_head pinned_vmas;bool has_fenced_gpu_access =INTEL_INFO (ring->dev)->gen <4 ;int retry;@@ -698,6 +705,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;INIT_LIST_HEAD (&ordered_vmas); +INIT_LIST_HEAD (&pinned_vmas);while (!list_empty (vmas)) {struct drm_i915_gem_exec_object2 *entry;drivers/gpu/drm/i915/i915_gem_execbuffer.c +3
-1bool need_fence, need_mappable;@@ -716,7 +724,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode !=I915_TILING_NONE ; need_mappable = need_fence ||need_reloc_mappable (vma); -if (need_mappable) { +if (entry->flags &EXEC_OBJECT_PINNED ) +list_move_tail (&vma->exec_list, &pinned_vmas); +else if (need_mappable) { entry->flags |= __EXEC_OBJECT_NEEDS_MAP;list_move (&vma->exec_list, &ordered_vmas);drivers/gpu/drm/i915/i915_gem_execbuffer.c +1
-0}else @@ -726,6 +736,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_write_domain =0 ; }list_splice (&ordered_vmas, vmas); +list_splice (&pinned_vmas, vmas);/* Attempt to pin all of the buffers into the GTT. drivers/gpu/drm/i915/i915_gem_execbuffer.c +2
-1* This is done in 3 phases: @@ -1404,7 +1415,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }include/uapi/drm/i915_drm.h +6
-3@@ -677,8 +677,10 @@ struct drm_i915_gem_exec_object2 {__u64 alignment;/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* Otherwise the kernel populates it with the value of the updated +* offset of the object, for future presumed_offset writes. */ __u64 offset;@@ -686,7 +688,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_SUPPORTS_48BBADDRESS (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS - (EXEC_OBJECT_SUPPORTS_48BBADDRESS<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;
Quoted 3 lines
__u64rsvd1;
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 181 lines · Thomas
Many apologies to Michal for incorrectly spelling his name in the CC list.
Thomas.
Quoted 177 lines
-----Original Message-----
From: Daniel, Thomas
Sent: Tuesday, June 30, 2015 3:13 PM
To: [email protected]
Cc: Chris Wilson; Goel, Akash; Belgaumkar, Vinay; Michal Winiarsky; Zou, Nanhai; Daniel, Thomas
Subject: [PATCH v4] drm/i915: Add soft-pinning API for execbufferFrom: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarsky <[email protected]>Cc Zou Nanhai <[email protected]>Signed-off-by Thomas Daniel <[email protected]>--- drivers/gpu/drm/i915/i915_drv.h | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 51 ++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_gem_evict.c | 38 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++-- include/uapi/drm/i915_drm.h | 9 +++-- 5 files changed, 99 insertions(+), 19 deletions(-)drivers/gpu/drm/i915/i915_drv.h +4
-0@@ -2747,7 +2747,9 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_USER (1<<4)#define PIN_UPDATE (1<<5)#define PIN_FULL_RANGE (1<<6) +#define PIN_OFFSET_FIXED (1<<7)#define PIN_OFFSET_MASK (~4095) + int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, struct i915_address_space *vm,@@ -3085,6 +3087,8 @@ int __must_check i915_gem_evict_something(structdrm_device *dev, unsigned long start, unsigned long end, unsigned flags); +int __must_check +i915_gem_evict_for_vma (struct i915_vma *target);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);int i915_gem_evict_everything (struct drm_device *dev);drivers/gpu/drm/i915/i915_gem.c +37
-14@@ -3806,22 +3806,41 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, if (IS_ERR(vma)) goto err_unpin; +if (flags &PIN_OFFSET_FIXED ) { +uint64_t offset = flags &PIN_OFFSET_MASK ; +if (offset & (alignment -1 )) { + ret = -EINVAL ; + goto err_free_vma; + } + vma->node.start = offset; + vma->node.size = size; + vma->node.color = obj->cache_level; + ret =drm_mm_reserve_node (&vm->mm, &vma->node); +if (ret) { + ret =i915_gem_evict_for_vma (vma); +if (ret ==0 ) + ret =drm_mm_reserve_node (&vm->mm, &vma->node); + } +if (ret) + goto err_free_vma; + }else { search_free: - ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, - size, alignment, - obj->cache_level, - start, end, - search_flag, - alloc_flag); -if (ret) { - ret =i915_gem_evict_something (dev, vm, size, alignment, - obj->cache_level, - start, end, - flags); -if (ret ==0 ) - goto search_free; + ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, + size, alignment, + obj->cache_level, + start, end, + search_flag, + alloc_flag); +if (ret) { + ret =i915_gem_evict_something (dev, vm, size, alignment, + obj->cache_level, + start, end, + flags); +if (ret ==0 ) + goto search_free; - goto err_free_vma; + goto err_free_vma; + } }if (WARN_ON (!i915_gem_valid_gtt_space (vma, obj->cache_level))) { ret = -EINVAL ;@@ -4357,6 +4376,10 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags) vma->node.start < (flags & PIN_OFFSET_MASK)) return true; +if (flags &PIN_OFFSET_FIXED && + vma->node.start != (flags &PIN_OFFSET_MASK )) +return true; +return false; }drivers/gpu/drm/i915/i915_gem_evict.c +21
-0@@ -199,6 +199,44 @@ found:return ret; } +int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +/* We may need to evict a buffer in the same batch */ +if (!vma->exec_entry)
Quoted 8 lines
drivers/gpu/drm/i915/i915_gem_evict.c found: · line 229
Quoted 8 lines
drivers/gpu/drm/i915/i915_gem_evict.c +7
-0+return -EBUSY ; + +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */ +return -EINVAL ; + +return -ENOSPC ;
Can we actually hit this condition, considering the soft pinned objects are now on the front side of 'eb->vmas' list ? If we do encounter such a case, it probably means that the overlapping object is already pinned from some other path.
Is there a scope of an additional check here ?
i.e. if (vma->pin_count) is > 1, this indicates that the object is not only pinned due to execbuffer, hence cannot be evicted, so -EBUSY can be straight away returned to User.
Best regards
Akash
Quoted 115 lines
Quoted 115 lines
drivers/gpu/drm/i915/i915_gem_evict.c +10
-0+ } + + ret =i915_vma_unbind (vma); +if (ret) +return ret; + } + +return 0 ; +} +/** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse
drivers/gpu/drm/i915/i915_gem_execbuffer.c +2
-0@@ -596,6 +596,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL |PIN_MAPPABLE ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ; }ret = i915_gem_object_pin(obj, vma->vm, entry->alignment, flags);drivers/gpu/drm/i915/i915_gem_execbuffer.c +6
-0@@ -665,6 +667,10 @@ eb_vma_misplaced(struct i915_vma *vma) vma->node.start & (entry->alignment - 1))return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;@@ -690,6 +696,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, struct i915_vma *vma;struct i915_address_space *vm;struct list_head ordered_vmas; +struct list_head pinned_vmas;bool has_fenced_gpu_access =INTEL_INFO (ring->dev)->gen <4 ;int retry;@@ -698,6 +705,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;INIT_LIST_HEAD (&ordered_vmas); +INIT_LIST_HEAD (&pinned_vmas);while (!list_empty (vmas)) {struct drm_i915_gem_exec_object2 *entry;bool
need_fence,need_mappable;drivers/gpu/drm/i915/i915_gem_execbuffer.c +3
-1@@ -716,7 +724,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode !=I915_TILING_NONE ; need_mappable = need_fence ||need_reloc_mappable (vma); -if (need_mappable) { +if (entry->flags &EXEC_OBJECT_PINNED ) +list_move_tail (&vma->exec_list, &pinned_vmas); +else if (need_mappable) { entry->flags |= __EXEC_OBJECT_NEEDS_MAP;list_move (&vma->exec_list, &ordered_vmas);} elsedrivers/gpu/drm/i915/i915_gem_execbuffer.c +1
-0@@ -726,6 +736,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_write_domain =0 ; }list_splice (&ordered_vmas, vmas); +list_splice (&pinned_vmas, vmas);/* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases:
drivers/gpu/drm/i915/i915_gem_execbuffer.c +2
-1@@ -1404,7 +1415,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }include/uapi/drm/i915_drm.h +6
-3@@ -677,8 +677,10 @@ struct drm_i915_gem_exec_object2 {__u64 alignment;/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* Otherwise the kernel populates it with the value of the updated +* offset of the object, for future presumed_offset writes. */ __u64 offset;@@ -686,7 +688,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_SUPPORTS_48BBADDRESS (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS - (EXEC_OBJECT_SUPPORTS_48BBADDRESS<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;
Quoted 4 lines
Quoted 3 lines
__u64rsvd1;
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 26 lines · Akash
Quoted 26 lines
Quoted 26 lines
drivers/gpu/drm/i915/i915_gem_evict.c +25
-0+int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +/* We may need to evict a buffer in the same batch */ +if (!vma->exec_entry) +return -EBUSY ; + +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */
Quoted 8 lines
Quoted 3 lines
drivers/gpu/drm/i915/i915_gem_evict.c found: · line 229
Quoted 3 lines
drivers/gpu/drm/i915/i915_gem_evict.c +3
-0+return -EINVAL ; + +return -ENOSPC ;Can we actually hit this condition, considering the soft pinned objects are now on the front side of '
eb->vmas' list ? If we do encounter such a case, it probably means that the overlapping object is already pinned from some other path.
Note that softpinned objects are only first on the second pass through the reservation.
Quoted 4 lines
Is there a scope of an additional check here ?
i.e. if (vma->pin_count) is > 1, this indicates that the object is not only pinned due to execbuffer, hence cannot be evicted, so-EBUSYcan be straight away returned to User.
Consider this instead:
inti915_gem_evict_for_vma(struct i915_vma *target, unsigned flags)
{
struct list_head eviction_list;
struct interval_tree_node *it;
u64 end = target->node.start + target->node.size;
struct drm_mm_node *node;
struct i915_vma *vma, *next;
int ret;
it = interval_tree_iter_first(&target->vm->mm.interval_tree,
target->node.start, end -1);
if (it == NULL)
return 0;
INIT_LIST_HEAD(&eviction_list);
node = container_of(it, typeof(*node), it);
list_for_each_entry_from(node,
&target->vm->mm.head_node.node_list,
node_list) {
if (node->start >= end)
break;
vma = container_of(node, typeof(*vma), node);
if (flags & PIN_NONBLOCK &&
(vma->pin_count || vma->active.request)) {
ret = -ENOSPC;
break;
}
if (vma->exec_entry &&
vma->exec_entry->flags & EXEC_OBJECT_PINNED) {
/* Overlapping pinned objects in the same batch */
ret = -EINVAL;
break;
}
if (vma->pin_count) {
/* We may need to evict an buffer in the same batch */
ret = vma->exec_entry ? -ENOSPC : -EBUSY;
break;
}
list_add(&vma->exec_list, &eviction_list);
drm_gem_object_reference(&vma->obj->base);
}
ret = 0;
list_for_each_entry_safe(vma, next, &eviction_list, exec_list) {
struct drm_i915_gem_object *obj = vma->obj;
if (ret == 0)
ret = i915_vma_unbind(vma);
drm_gem_object_unreference(&obj->base);
}
return ret;
}-Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 44 lines
-----Original Message-----
From: Chris Wilson [mailto:[email protected]]
Sent: Wednesday, July 15, 2015 4:06 PM
To: Goel, Akash
Cc: Daniel, Thomas; [email protected]; Belgaumkar, Vinay; Winiarski, Michal; Zou, Nanhai
Subject: Re: [PATCH v4] drm/i915: Add soft-pinning API for execbufferQuoted 26 lines · Akash
Quoted 26 lines
Quoted 26 lines
drivers/gpu/drm/i915/i915_gem_evict.c +25
-0+int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +/* We may need to evict a buffer in the same batch */ +if (!vma->exec_entry) +return -EBUSY ; + +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */
Quoted 8 lines
Quoted 3 lines
drivers/gpu/drm/i915/i915_gem_evict.c found: · line 229
Quoted 3 lines
drivers/gpu/drm/i915/i915_gem_evict.c +3
-0+return -EINVAL ; + +return -ENOSPC ;Can we actually hit this condition, considering the soft pinned objects are now on the front side of '
eb->vmas' list ? If we do encounter such a case, it probably means that the overlapping object is already pinned from some other path.
Quoted 2 lines
Note that softpinned objects are only first on the second pass through the reservation.
Eh? I modified i915_gem_execbuffer_reserve() to always put the softpinned vmas first so they should never collide with objects in the same execbuff.
Quoted 65 lines
Quoted 5 lines
Is there a scope of an additional check here ?
i.e. if (vma->pin_count) is > 1, this indicates that the object is not only pinned due to execbuffer, hence cannot be evicted, so-EBUSYcan be straight away returned to User.Consider this instead:
int
i915_gem_evict_for_vma(struct i915_vma *target, unsigned flags){ struct list_head eviction_list; struct interval_tree_node *it; u64 end = target->node.start + target->node.size; struct drm_mm_node *node; struct i915_vma *vma, *next; int ret; it = interval_tree_iter_first(&target->vm->mm.interval_tree, target->node.start, end -1); if (it == NULL) return 0; INIT_LIST_HEAD(&eviction_list); node = container_of(it, typeof(*node), it); list_for_each_entry_from(node, &target->vm->mm.head_node.node_list, node_list) { if (node->start >= end) break; vma = container_of(node, typeof(*vma), node); if (flags & PIN_NONBLOCK && (vma->pin_count || vma->active.request)) { ret = -ENOSPC; break; } if (vma->exec_entry && vma->exec_entry->flags & EXEC_OBJECT_PINNED) { /* Overlapping pinned objects in the same batch */ ret = -EINVAL; break; } if (vma->pin_count) { /* We may need to evict an buffer in the same batch */ ret = vma->exec_entry ? -ENOSPC : -EBUSY; break; } list_add(&vma->exec_list, &eviction_list); drm_gem_object_reference(&vma->obj->base); } ret = 0; list_for_each_entry_safe(vma, next, &eviction_list, exec_list) { struct drm_i915_gem_object *obj = vma->obj; if (ret == 0) ret = i915_vma_unbind(vma); drm_gem_object_unreference(&obj->base); } return ret; }
Quoted 1 line
-Chris
This contains special stuff which I don't have visibility of (mm.interval_tree, vma.active).
Thomas.
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 44 lines · Thomas
Quoted 44 lines
-----Original Message-----
From: Chris Wilson [mailto:[email protected]]
Sent: Wednesday, July 15, 2015 4:06 PM
To: Goel, Akash
Cc: Daniel, Thomas; [email protected]; Belgaumkar, Vinay; Winiarski, Michal; Zou, Nanhai
Subject: Re: [PATCH v4] drm/i915: Add soft-pinning API for execbufferQuoted 34 lines · Akash
Quoted 21 lines
Quoted 21 lines
drivers/gpu/drm/i915/i915_gem_evict.c +21
-0+int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +/* We may need to evict a buffer in the same batch */ +if (!vma->exec_entry)Quoted 8 lines
drivers/gpu/drm/i915/i915_gem_evict.c found: · line 229
Quoted 8 lines
drivers/gpu/drm/i915/i915_gem_evict.c +4
-0+return -EBUSY ; + +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */
drivers/gpu/drm/i915/i915_gem_evict.c +3
-0+return -EINVAL ; + +return -ENOSPC ;Can we actually hit this condition, considering the soft pinned objects are now on the front side of '
eb->vmas' list ? If we do encounter such a case, it probably means that the overlapping object is already pinned from some other path.
Quoted 3 lines
Quoted 2 lines
Note that softpinned objects are only first on the second pass through the reservation.
Eh? I modified
i915_gem_execbuffer_reserve()to always put the softpinned vmas first so they should never collide with objects in the same execbuff.
That would be a severe performance penalty for the usual case where we only have to run once through the list.
Quoted 1 line
This contains special stuff which I don't have visibility of (mm.interval_tree, vma.active).
Yes. I mentioned that using softpin introduced some perf regressions. -Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 57 lines
-----Original Message-----
From: Chris Wilson [mailto:[email protected]]
Sent: Wednesday, July 15, 2015 4:47 PM
To: Daniel, Thomas
Cc: Goel, Akash; [email protected]; Belgaumkar, Vinay; Winiarski, Michal; Zou, Nanhai
Subject: Re: [PATCH v4] drm/i915: Add soft-pinning API for execbufferQuoted 24 lines · Thomas
Quoted 9 lines
-----Original Message-----
From: Chris Wilson [mailto:[email protected]]
Sent: Wednesday, July 15, 2015 4:06 PM
To: Goel, Akash
Cc: Daniel, Thomas; [email protected]; Belgaumkar, Vinay; Winiarski, Michal; Zou, Nanhai
Subject: Re: [PATCH v4] drm/i915: Add soft-pinning API for execbufferOn Wed, Jul 15, 2015 at 08:25:23PM +0530, Goel, Akash wrote:
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/i915/i915_gem_evict.c +6
-0+int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + + list_for_each_entry_safe(node, next,Quoted 8 lines
Quoted 8 lines
drivers/gpu/drm/i915/i915_gem_evict.c found:
Quoted 8 lines
drivers/gpu/drm/i915/i915_gem_evict.c +8
-0+ &target->vm->mm.head_node.node_list, + node_list) { + struct i915_vma *vma; + int ret; + + if (node->start + node->size <= target->node.start) + continue; + if (node->start >= target->node.start + target-node.size)
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/gpu/drm/i915/i915_gem_evict.c found:
Quoted 6 lines
drivers/gpu/drm/i915/i915_gem_evict.c +6
-0+break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +/* We may need to evict a buffer in the same batch */
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
drivers/gpu/drm/i915/i915_gem_evict.c found:
Quoted 4 lines
drivers/gpu/drm/i915/i915_gem_evict.c +4
-0+if (!vma->exec_entry) +return -EBUSY ; + + if (vma->exec_entry->flags &
EXEC_OBJECT_PINNED)Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review
Quoted 1 line
(quoted diff) +1
-0+ /* Overlapping fixed objects in thesame batch
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
Quoted 4 lines
drivers/gpu/drm/i915/i915_gem_evict.c found: · line 229
Quoted 4 lines
*/
drivers/gpu/drm/i915/i915_gem_evict.c +3
-0+return -EINVAL ; + +return -ENOSPC ;Can we actually hit this condition, considering the soft pinned objects are now on the front side of '
eb->vmas' list ? If we do encounter such a case, it probably means that the overlapping object is already pinned from some other path.
Quoted 7 lines
Quoted 3 lines
Quoted 2 lines
Note that softpinned objects are only first on the second pass through the reservation.
Eh? I modified
i915_gem_execbuffer_reserve()to always put the softpinnedvmas first so they should never collide with objects in the same execbuff.
That would be a severe performance penalty for the usual case where we only have to run once through the list.
How so? execbuffer_reserve() already traverses the entire vma list and does a list_move or list_move_tail onto ordered_vmas for each entry. I've simply created a new list for the softpinned vmas and spliced the two together at the end.
Quoted 6 lines
Quoted 2 lines
This contains special stuff which I don't have visibility of (mm.interval_tree,
vma.active).
Yes. I mentioned that using softpin introduced some perf regressions. -Chris
Can we get your improvements as follow-up patches?
Cheers,
Thomas.
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 57 lines · Thomas
Quoted 57 lines
-----Original Message-----
From: Chris Wilson [mailto:[email protected]]
Sent: Wednesday, July 15, 2015 4:47 PM
To: Daniel, Thomas
Cc: Goel, Akash; [email protected]; Belgaumkar, Vinay; Winiarski, Michal; Zou, Nanhai
Subject: Re: [PATCH v4] drm/i915: Add soft-pinning API for execbufferQuoted 24 lines · Thomas
Quoted 9 lines
-----Original Message-----
From: Chris Wilson [mailto:[email protected]]
Sent: Wednesday, July 15, 2015 4:06 PM
To: Goel, Akash
Cc: Daniel, Thomas; [email protected]; Belgaumkar, Vinay; Winiarski, Michal; Zou, Nanhai
Subject: Re: [PATCH v4] drm/i915: Add soft-pinning API for execbufferOn Wed, Jul 15, 2015 at 08:25:23PM +0530, Goel, Akash wrote:
Quoted 14 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
(quoted diff) +6
-0+int +i915_gem_evict_for_vma(struct i915_vma *target) +{ + struct drm_mm_node *node, *next; + + list_for_each_entry_safe(node, next,Quoted 8 lines
Quoted 8 lines
Review
Quoted 8 lines
(quoted diff) +8
-0+ &target->vm->mm.head_node.node_list, + node_list) { + struct i915_vma *vma; + int ret; + + if (node->start + node->size <= target->node.start) + continue; + if (node->start >= target->node.start + target-node.size)
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+ break; + + vma = container_of(node, typeof(*vma), node); + + if (vma->pin_count) { + /* We may need to evict a buffer in the samebatch */
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Review
Quoted 4 lines
(quoted diff) +4
-0+ if (!vma->exec_entry) + return -EBUSY; + + if (vma->exec_entry->flags &
EXEC_OBJECT_PINNED)Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Review
Quoted 1 line
(quoted diff) +1
-0+ /* Overlapping fixed objects in thesame batch
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
Quoted 4 lines
Review
Quoted 4 lines
*/
(quoted diff) +3
-0+ return -EINVAL; + + return -ENOSPC;Can we actually hit this condition, considering the soft pinned objects are now on the front side of '
eb->vmas' list ? If we do encounter such a case, it probably means that the overlapping object is already pinned from some other path.
Quoted 8 lines
Quoted 7 lines
Quoted 3 lines
Quoted 2 lines
Note that softpinned objects are only first on the second pass through the reservation.
Eh? I modified
i915_gem_execbuffer_reserve()to always put the softpinnedvmas first so they should never collide with objects in the same execbuff.
That would be a severe performance penalty for the usual case where we only have to run once through the list.
How so?
execbuffer_reserve()already traverses the entire vma list and does alist_moveorlist_move_tailontoordered_vmasfor each entry. I've simply created a new list for the softpinned vmas and spliced the two together at the end.
I posted the fix for that a few months ago.
Quoted 6 lines
Quoted 5 lines
Quoted 1 line
This contains special stuff which I don't have visibility of (mm.interval_tree,
vma.active).
Yes. I mentioned that using softpin introduced some perf regressions. -Chris
Can we get your improvements as follow-up patches?
No. Softpin has requirements that are not met by the current kernel. -Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 19 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)
Quoted 4 lines
v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.
Can we add an I915_PARAM_HAS_EXEC_PINNED param for this feature?
Kristian
Quoted 256 lines
Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarsky <[email protected]>Cc Zou Nanhai <[email protected]>Signed-off-by Thomas Daniel <[email protected]>--- drivers/gpu/drm/i915/i915_drv.h | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 51 ++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_gem_evict.c | 38 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++-- include/uapi/drm/i915_drm.h | 9 +++-- 5 files changed, 99 insertions(+), 19 deletions(-)drivers/gpu/drm/i915/i915_drv.h +4
-0@@ -2747,7 +2747,9 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_USER (1<<4)#define PIN_UPDATE (1<<5)#define PIN_FULL_RANGE (1<<6) +#define PIN_OFFSET_FIXED (1<<7)#define PIN_OFFSET_MASK (~4095) + int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, struct i915_address_space *vm,@@ -3085,6 +3087,8 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,unsigned long start, unsigned long end, unsigned flags); +int __must_check +i915_gem_evict_for_vma (struct i915_vma *target);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);int i915_gem_evict_everything (struct drm_device *dev);drivers/gpu/drm/i915/i915_gem.c +37
-14@@ -3806,22 +3806,41 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,if (IS_ERR (vma)) goto err_unpin; +if (flags &PIN_OFFSET_FIXED ) { +uint64_t offset = flags &PIN_OFFSET_MASK ; +if (offset & (alignment -1 )) { + ret = -EINVAL ; + goto err_free_vma; + } + vma->node.start = offset; + vma->node.size = size; + vma->node.color = obj->cache_level; + ret =drm_mm_reserve_node (&vm->mm, &vma->node); +if (ret) { + ret =i915_gem_evict_for_vma (vma); +if (ret ==0 ) + ret =drm_mm_reserve_node (&vm->mm, &vma->node); + } +if (ret) + goto err_free_vma; + }else { search_free: - ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, - size, alignment, - obj->cache_level, - start, end, - search_flag, - alloc_flag); -if (ret) { - ret =i915_gem_evict_something (dev, vm, size, alignment, - obj->cache_level, - start, end, - flags); -if (ret ==0 ) - goto search_free; + ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, + size, alignment, + obj->cache_level, + start, end, + search_flag, + alloc_flag); +if (ret) { + ret =i915_gem_evict_something (dev, vm, size, alignment, + obj->cache_level, + start, end, + flags); +if (ret ==0 ) + goto search_free; - goto err_free_vma; + goto err_free_vma; + } }if (WARN_ON (!i915_gem_valid_gtt_space (vma, obj->cache_level))) { ret = -EINVAL ;@@ -4357,6 +4376,10 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags) vma->node.start < (flags & PIN_OFFSET_MASK))return true; +if (flags &PIN_OFFSET_FIXED && + vma->node.start != (flags &PIN_OFFSET_MASK )) +return true; +return false; }drivers/gpu/drm/i915/i915_gem_evict.c +38
-0@@ -199,6 +199,44 @@ found:return ret; } +int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +/* We may need to evict a buffer in the same batch */ +if (!vma->exec_entry) +return -EBUSY ; + +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */ +return -EINVAL ; + +return -ENOSPC ; + } + + ret =i915_vma_unbind (vma); +if (ret) +return ret; + } + +return 0 ; +} +/** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse drivers/gpu/drm/i915/i915_gem_execbuffer.c +14
-2@@ -596,6 +596,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL |PIN_MAPPABLE ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ; } ret =i915_gem_object_pin (obj, vma->vm, entry->alignment, flags);@@ -665,6 +667,10 @@ eb_vma_misplaced(struct i915_vma *vma) vma->node.start & (entry->alignment - 1))return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;@@ -690,6 +696,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring,struct i915_vma *vma;struct i915_address_space *vm;struct list_head ordered_vmas; +struct list_head pinned_vmas;bool has_fenced_gpu_access =INTEL_INFO (ring->dev)->gen <4 ;int retry;@@ -698,6 +705,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;INIT_LIST_HEAD (&ordered_vmas); +INIT_LIST_HEAD (&pinned_vmas);while (!list_empty (vmas)) {struct drm_i915_gem_exec_object2 *entry;bool need_fence, need_mappable;@@ -716,7 +724,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode !=I915_TILING_NONE ; need_mappable = need_fence ||need_reloc_mappable (vma); -if (need_mappable) { +if (entry->flags &EXEC_OBJECT_PINNED ) +list_move_tail (&vma->exec_list, &pinned_vmas); +else if (need_mappable) { entry->flags |= __EXEC_OBJECT_NEEDS_MAP;list_move (&vma->exec_list, &ordered_vmas); }else @@ -726,6 +736,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_write_domain =0 ; }list_splice (&ordered_vmas, vmas); +list_splice (&pinned_vmas, vmas);/* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases: @@ -1404,7 +1415,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }include/uapi/drm/i915_drm.h +6
-4@@ -677,8 +677,10 @@ struct drm_i915_gem_exec_object2 {__u64 alignment;/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* Otherwise the kernel populates it with the value of the updated +* offset of the object, for future presumed_offset writes. */ __u64 offset;@@ -686,7 +688,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_SUPPORTS_48BBADDRESS (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48BBADDRESS<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;__u64 rsvd1; --1.7.9.5
Quoted 4 lines
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 20 lines · Kristian Høgsberg
Quoted 19 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)
Quoted 4 lines
Quoted 4 lines
v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.
Note this patch is outdated compared to the one I have in my tree. There are also requirements to improve drm_mm_reserve_node().
Quoted 1 line
Can we add an
I915_PARAM_HAS_EXEC_PINNEDparam for this feature?
Yeah, it's not that difficult to test,
static bool test_has_softpin(int fd)
{
struct drm_i915_gem_create create;
struct drm_i915_gem_exec_object2 object;
struct drm_i915_gem_pwrite pwrite;
struct drm_i915_gem_execbuffer2 execbuf;
uint32_t batch[2] = { 0xa << 23 };
bool ret = false;
if (DBG_NO_SOFTPIN)
return DBG_NO_SOFTPIN < 0;
if (gem_param(fd, I915_PARAM_HAS_ALIASING_PPGTT) < 2)
return false;
memset(&create, 0, sizeof(create));
create.size = 4096;
drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
memset(&pwrite, 0, sizeof(pwrite));
pwrite.handle = create.handle;
pwrite.offset = 0;
pwrite.size = sizeof(batch);
pwrite.data_ptr = (uintptr_t)batch;
if (drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite))
goto fail;
object.handle = create.handle;
memset(&execbuf, 0, sizeof(execbuf));
execbuf.buffers_ptr = (uintptr_t)&object;
execbuf.buffer_count = 1;
if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf))
goto fail; object.flags = EXEC_OBJECT_PINNED;
ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) == 0;
fail:
drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &create);
return ret;
}
but compares to
static bool test_has_softpin(int fd)
{
if (DBG_NO_SOFTPIN)
return DBG_NO_SOFTPIN < 0;
if (gem_param(fd, I915_PARAM_HAS_ALIASING_PPGTT) < 2)
return false;
return gem_param(fd, I915_PARAM_HAS_EXEC_SOFTPIN) > 0;
}
with a parameter. At some point, we probably want to add a GETPARAMV! -Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 31 lines
-----Original Message-----
From: Chris Wilson [mailto:[email protected]]
Sent: Saturday, July 4, 2015 1:24 PM
To: Kristian Høgsberg
Cc: Daniel, Thomas; Belgaumkar, Vinay; [email protected]; Michal Winiarsky; Goel, Akash
Subject: Re: [Intel-gfx] [PATCH v4] drm/i915: Add soft-pinning API for execbufferQuoted 1 line · Kristian Høgsberg
On Tue, Jun 30, 2015 at 7:13 AM, Thomas Daniel <[email protected]>
Quoted 8 lines · wrote:
Quoted 8 lines
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Quoted 8 lines
Quoted 8 lines
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned objectused
Quoted 3 lines
Quoted 3 lines
by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)
Quoted 7 lines
Quoted 4 lines
Quoted 4 lines
v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.Note this patch is outdated compared to the one I have in my tree. There are also requirements to improve
drm_mm_reserve_node().
What requirements are these?
Quoted 60 lines
Quoted 1 line
Can we add an
I915_PARAM_HAS_EXEC_PINNEDparam for this feature?Yeah, it's not that difficult to test,
static bool
test_has_softpin(int fd){ struct drm_i915_gem_create create; struct drm_i915_gem_exec_object2 object; struct drm_i915_gem_pwrite pwrite; struct drm_i915_gem_execbuffer2 execbuf; uint32_t batch[2] = { 0xa << 23 }; bool ret = false; if (DBG_NO_SOFTPIN) return DBG_NO_SOFTPIN < 0; if (gem_param(fd, I915_PARAM_HAS_ALIASING_PPGTT) < 2) return false; memset(&create, 0, sizeof(create)); create.size = 4096; drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); memset(&pwrite, 0, sizeof(pwrite)); pwrite.handle = create.handle; pwrite.offset = 0; pwrite.size = sizeof(batch); pwrite.data_ptr = (uintptr_t)batch; if (drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite)) goto fail; object.handle = create.handle; memset(&execbuf, 0, sizeof(execbuf)); execbuf.buffers_ptr = (uintptr_t)&object; execbuf.buffer_count = 1; if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)) goto fail; object.flags = EXEC_OBJECT_PINNED; ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) == 0; fail: drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &create); return ret; }but compares to
static bool
test_has_softpin(int fd){ if (DBG_NO_SOFTPIN) return DBG_NO_SOFTPIN < 0; if (gem_param(fd, I915_PARAM_HAS_ALIASING_PPGTT) < 2) return false; return gem_param(fd, I915_PARAM_HAS_EXEC_SOFTPIN) > 0; }
Quoted 1 line
with a parameter. At some point, we probably want to add a GETPARAMV!
Yes, a parameter would be cleaner.
Thomas.
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 31 lines · Thomas
Quoted 31 lines
-----Original Message-----
From: Chris Wilson [mailto:[email protected]]
Sent: Saturday, July 4, 2015 1:24 PM
To: Kristian Høgsberg
Cc: Daniel, Thomas; Belgaumkar, Vinay; [email protected]; Michal Winiarsky; Goel, Akash
Subject: Re: [Intel-gfx] [PATCH v4] drm/i915: Add soft-pinning API for execbufferQuoted 1 line · Kristian Høgsberg
On Tue, Jun 30, 2015 at 7:13 AM, Thomas Daniel <[email protected]>
Quoted 8 lines · wrote:
Quoted 8 lines
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Quoted 8 lines
Quoted 8 lines
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned objectused
Quoted 3 lines
Quoted 3 lines
by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)
Quoted 8 lines
Quoted 7 lines
Quoted 4 lines
Quoted 4 lines
v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.Note this patch is outdated compared to the one I have in my tree. There are also requirements to improve
drm_mm_reserve_node().What requirements are these?
I switched execbuffer to try reusing the last address by default (i.e. softpin everything) and the linear walk in reserve_node and evict_for_vma were major bottlenecks. Adding an interval-tree to drm_mm fixes the issue but also requires rewriting evict_for_vma. Plus using it by default highlighted a few errors in the failure handling.
Also don't forget that softpinning requires us to be able to reuse the vm for all rings, i.e. we need the API fix to allow user contexts for rings other than RCS.
-Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
include/uapi/drm/i915_drm.h struct drm_i915_gem_exec_object2 { · line 684
Quoted 8 lines · Thomas Daniel
include/uapi/drm/i915_drm.h +4
-2/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* Otherwise the kernel populates it with the value of the updated +* offset of the object, for future presumed_offset writes. */
This isn't strictly true, even without PINNED but NO_RELOC this field must be accurately populated with the presumed_offset. No matter what, the kernel returns the value of the current address after execbuffer. -Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH v5 1/1 drm/i915: Add soft-pinning API for execbuffer
In reply to Thomas DanielFrom: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)
v4: Moved soft-pinned objects to the front of ordered_vmas so that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.
v5: Added I915_PARAM_HAS_EXEC_SOFTPIN parameter for detecting this capability (Kristian). Added check for multiple pinnings on eviction (Akash). Made sure buffers are not considered misplaced without the user specifying EXEC_OBJECT_SUPPORTS_48BBADDRESS. User must assume responsibility for any addressing workarounds. Updated object2.offset field comment again to clarify NO_RELOC case (Chris). checkpatch cleanup.
--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 4 +++ drivers/gpu/drm/i915/i915_gem.c | 52 ++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 19 ++++++++-- include/uapi/drm/i915_drm.h | 12 +++++-- 6 files changed, 109 insertions(+), 20 deletions(-)
drivers/gpu/drm/i915/i915_dma.c +3 -0
@@ -167,6 +167,9 @@ static int i915_getparam(struct drm_device *dev, void *data, value = i915.enable_hangcheck &&intel_has_gpu_reset (dev);break ; +case I915_PARAM_HAS_EXEC_SOFTPIN : + value =1 ; +break ;default :DRM_DEBUG ("Unknown parameter %d\n" , param->param);return -EINVAL ;
drivers/gpu/drm/i915/i915_drv.h +4 -0
@@ -2747,7 +2747,9 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_USER (1<<4)#define PIN_UPDATE (1<<5)#define PIN_FULL_RANGE (1<<6) +#define PIN_OFFSET_FIXED (1<<7)#define PIN_OFFSET_MASK (~4095) + int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, struct i915_address_space *vm,
@@ -3085,6 +3087,8 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,unsigned long start, unsigned long end, unsigned flags); +int __must_check +i915_gem_evict_for_vma (struct i915_vma *target);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);int i915_gem_evict_everything (struct drm_device *dev);
drivers/gpu/drm/i915/i915_gem.c +38 -14
66 lines not on this page · raw message
drivers/gpu/drm/i915/i915_gem_evict.c +39 -0
@@ -199,6 +199,45 @@ found:return ret; } +int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +if (!vma->exec_entry || (vma->pin_count >1 )) +/* Object is pinned for some other use */ +return -EBUSY ; + +/* We need to evict a buffer in the same batch */ +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */ +return -EINVAL ; + +return -ENOSPC ; + } + + ret =i915_vma_unbind (vma); +if (ret) +return ret; + } + +return 0 ; +} +/** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse
drivers/gpu/drm/i915/i915_gem_execbuffer.c +16 -3
@@ -596,6 +596,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL |PIN_MAPPABLE ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ; } ret =i915_gem_object_pin (obj, vma->vm, entry->alignment, flags);
@@ -665,6 +667,10 @@ eb_vma_misplaced(struct i915_vma *vma) vma->node.start & (entry->alignment - 1))return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;
@@ -673,7 +679,8 @@ eb_vma_misplaced(struct i915_vma *vma)if (entry->flags & __EXEC_OBJECT_NEEDS_MAP && !obj->map_and_fenceable)return !only_mappable_for_reloc (entry->flags); -if (!(entry->flags &EXEC_OBJECT_SUPPORTS_48BBADDRESS ) && +if (!(entry->flags & + (EXEC_OBJECT_SUPPORTS_48BBADDRESS |EXEC_OBJECT_PINNED )) && vma->node.start >= (1ULL <<32 ))return true;
@@ -690,6 +697,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring,struct i915_vma *vma;struct i915_address_space *vm;struct list_head ordered_vmas; +struct list_head pinned_vmas;bool has_fenced_gpu_access =INTEL_INFO (ring->dev)->gen <4 ;int retry;
@@ -698,6 +706,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;INIT_LIST_HEAD (&ordered_vmas); +INIT_LIST_HEAD (&pinned_vmas);while (!list_empty (vmas)) {struct drm_i915_gem_exec_object2 *entry;bool need_fence, need_mappable;
@@ -716,7 +725,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode !=I915_TILING_NONE ; need_mappable = need_fence ||need_reloc_mappable (vma); -if (need_mappable) { +if (entry->flags &EXEC_OBJECT_PINNED ) +list_move_tail (&vma->exec_list, &pinned_vmas); +else if (need_mappable) { entry->flags |= __EXEC_OBJECT_NEEDS_MAP;list_move (&vma->exec_list, &ordered_vmas); }else
@@ -726,6 +737,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_write_domain =0 ; }list_splice (&ordered_vmas, vmas); +list_splice (&pinned_vmas, vmas);/* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases:
@@ -1404,7 +1416,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }
include/uapi/drm/i915_drm.h +9 -3
@@ -355,6 +355,7 @@ typedef struct drm_i915_irq_wait {#define I915_PARAM_SUBSLICE_TOTAL 33#define I915_PARAM_EU_TOTAL 34#define I915_PARAM_HAS_GPU_RESET 35 +#define I915_PARAM_HAS_EXEC_SOFTPIN 36 typedef struct drm_i915_getparam { int param;
@@ -677,8 +678,12 @@ struct drm_i915_gem_exec_object2 {__u64 alignment;/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* When the I915_EXEC_NO_RELOC flag is specified this must contain the +* presumed_offset of the object. +* During execbuffer2 the kernel populates it with the value of the +* current GTT offset of the object, for future presumed_offset writes. */ __u64 offset;
@@ -686,7 +691,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_SUPPORTS_48BBADDRESS (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48BBADDRESS<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;__u64 rsvd1;
Signature · 6 lines
1.7.9.5 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 24 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.
Quoted 6 lines
v5: Added
I915_PARAM_HAS_EXEC_SOFTPINparameter for detecting this capability (Kristian). Added check for multiple pinnings on eviction (Akash). Made sure buffers are not considered misplaced without the user specifyingEXEC_OBJECT_SUPPORTS_48BBADDRESS. User must assume responsibility for any addressing workarounds. Updated object2.offset field comment again to clarifyNO_RELOCcase (Chris). checkpatch cleanup.
There are a couple of requirements we need first. One we have to be able to use our vm on any engine, and the second is that without fixing the list iterator in drm_mm using softpining ends up as a performance regression.
It would be nice if people reviewed patches so that I can get those fixes in.
-Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH v6 1/1 drm/i915: Add soft-pinning API for execbuffer
In reply to Thomas DanielFrom: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)
v4: Moved soft-pinned objects to the front of ordered_vmas so that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.
v5: Added I915_PARAM_HAS_EXEC_SOFTPIN parameter for detecting this capability (Kristian). Added check for multiple pinnings on eviction (Akash). Made sure buffers are not considered misplaced without the user specifying EXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for any addressing workarounds. Updated object2.offset field comment again to clarify NO_RELOC case (Chris). checkpatch cleanup.
v6: Trivial rebase on latest drm-intel-nightly
--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 19 +++++++-- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 113 insertions(+), 26 deletions(-)
drivers/gpu/drm/i915/i915_dma.c +3 -0
@@ -170,6 +170,9 @@ static int i915_getparam(struct drm_device *dev, void *data,case I915_PARAM_HAS_RESOURCE_STREAMER : value =HAS_RESOURCE_STREAMER (dev);break ; +case I915_PARAM_HAS_EXEC_SOFTPIN : + value =1 ; +break ;default :DRM_DEBUG ("Unknown parameter %d\n" , param->param);return -EINVAL ;
drivers/gpu/drm/i915/i915_drv.h +2 -0
@@ -2816,6 +2816,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_UPDATE (1<<5)#define PIN_ZONE_4G (1<<6)#define PIN_HIGH (1<<7) +#define PIN_OFFSET_FIXED (1<<8)#define PIN_OFFSET_MASK (~4095) int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
@@ -3163,6 +3164,7 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,unsigned long start, unsigned long end, unsigned flags); +int __must_check i915_gem_evict_for_vma (struct i915_vma *target);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);/* belongs in i915_gem_gtt.h */
drivers/gpu/drm/i915/i915_gem.c +44 -20
80 lines not on this page · raw message
drivers/gpu/drm/i915/i915_gem_evict.c +39 -0
@@ -199,6 +199,45 @@ found:return ret; } +int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +if (!vma->exec_entry || (vma->pin_count >1 )) +/* Object is pinned for some other use */ +return -EBUSY ; + +/* We need to evict a buffer in the same batch */ +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */ +return -EINVAL ; + +return -ENOSPC ; + } + + ret =i915_vma_unbind (vma); +if (ret) +return ret; + } + +return 0 ; +} +/** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse
drivers/gpu/drm/i915/i915_gem_execbuffer.c +16 -3
@@ -599,6 +599,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL |PIN_MAPPABLE ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ;if ((flags &PIN_MAPPABLE ) ==0 ) flags |=PIN_HIGH ; }
@@ -670,6 +672,10 @@ eb_vma_misplaced(struct i915_vma *vma) vma->node.start & (entry->alignment - 1))return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;
@@ -678,7 +684,8 @@ eb_vma_misplaced(struct i915_vma *vma)if (entry->flags & __EXEC_OBJECT_NEEDS_MAP && !obj->map_and_fenceable)return !only_mappable_for_reloc (entry->flags); -if ((entry->flags &EXEC_OBJECT_SUPPORTS_48B_ADDRESS ) ==0 && +if (!(entry->flags & + (EXEC_OBJECT_SUPPORTS_48B_ADDRESS |EXEC_OBJECT_PINNED )) && (vma->node.start + vma->node.size -1 ) >>32 )return true;
@@ -695,6 +702,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring,struct i915_vma *vma;struct i915_address_space *vm;struct list_head ordered_vmas; +struct list_head pinned_vmas;bool has_fenced_gpu_access =INTEL_INFO (ring->dev)->gen <4 ;int retry;
@@ -703,6 +711,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;INIT_LIST_HEAD (&ordered_vmas); +INIT_LIST_HEAD (&pinned_vmas);while (!list_empty (vmas)) {struct drm_i915_gem_exec_object2 *entry;bool need_fence, need_mappable;
@@ -721,7 +730,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode !=I915_TILING_NONE ; need_mappable = need_fence ||need_reloc_mappable (vma); -if (need_mappable) { +if (entry->flags &EXEC_OBJECT_PINNED ) +list_move_tail (&vma->exec_list, &pinned_vmas); +else if (need_mappable) { entry->flags |= __EXEC_OBJECT_NEEDS_MAP;list_move (&vma->exec_list, &ordered_vmas); }else
@@ -731,6 +742,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_write_domain =0 ; }list_splice (&ordered_vmas, vmas); +list_splice (&pinned_vmas, vmas);/* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases:
@@ -1317,7 +1329,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }
include/uapi/drm/i915_drm.h +9 -3
@@ -356,6 +356,7 @@ typedef struct drm_i915_irq_wait {#define I915_PARAM_EU_TOTAL 34#define I915_PARAM_HAS_GPU_RESET 35#define I915_PARAM_HAS_RESOURCE_STREAMER 36 +#define I915_PARAM_HAS_EXEC_SOFTPIN 37 typedef struct drm_i915_getparam { __s32 param;
@@ -682,8 +683,12 @@ struct drm_i915_gem_exec_object2 {__u64 alignment;/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* When the I915_EXEC_NO_RELOC flag is specified this must contain the +* presumed_offset of the object. +* During execbuffer2 the kernel populates it with the value of the +* current GTT offset of the object, for future presumed_offset writes. */ __u64 offset;
@@ -691,7 +696,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;__u64 rsvd1;
Signature · 6 lines
1.9.1 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Discussed sometime back about this patch with Chris. He mainly has 2 concerns with it.
1. The linear walk used by the patch to detect the overlapping objects would be expensive.
2. Restriction to disallow !RCS submissions for non-default contexts, which could lead to lot of conflicts for the placements, once multiple engines like media/blit/vebox are used
Both of them can be addressed by the subsequent patches.
Chris already has the patch ready to reduce the validation overhead with the use of rbtree and there should be no implications of allowing the non-default contexts for !RCS submissions in execbuffer.
In the standalone form, the patch looks good, so
Quoted 327 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.v5: Added
I915_PARAM_HAS_EXEC_SOFTPINparameter for detecting this capability (Kristian). Added check for multiple pinnings on eviction (Akash). Made sure buffers are not considered misplaced without the user specifyingEXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for any addressing workarounds. Updated object2.offset field comment again to clarifyNO_RELOCcase (Chris). checkpatch cleanup.v6: Trivial rebase on latest drm-intel-nightly
Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarski <[email protected]>Cc Zou Nanhai <[email protected]>Cc Kristian Høgsberg <[email protected]>Signed-off-by Thomas Daniel <[email protected]>--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 19 +++++++-- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 113 insertions(+), 26 deletions(-)drivers/gpu/drm/i915/i915_dma.c +3
-0@@ -170,6 +170,9 @@ static int i915_getparam(struct drm_device *dev, void *data,case I915_PARAM_HAS_RESOURCE_STREAMER : value =HAS_RESOURCE_STREAMER (dev);break ; +case I915_PARAM_HAS_EXEC_SOFTPIN : + value =1 ; +break ;default :DRM_DEBUG ("Unknown parameter %d\n" , param->param);return -EINVAL ;drivers/gpu/drm/i915/i915_drv.h +2
-0@@ -2816,6 +2816,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_UPDATE (1<<5)#define PIN_ZONE_4G (1<<6)#define PIN_HIGH (1<<7) +#define PIN_OFFSET_FIXED (1<<8)#define PIN_OFFSET_MASK (~4095) int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,@@ -3163,6 +3164,7 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,unsigned long start, unsigned long end, unsigned flags); +int __must_check i915_gem_evict_for_vma (struct i915_vma *target);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);/* belongs in i915_gem_gtt.h */ drivers/gpu/drm/i915/i915_gem.c +44
-20@@ -3450,30 +3450,50 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,if (IS_ERR (vma)) goto err_unpin; -if (flags &PIN_HIGH ) { - search_flag =DRM_MM_SEARCH_BELOW ; - alloc_flag =DRM_MM_CREATE_TOP ; +if (flags &PIN_OFFSET_FIXED ) { +uint64_t offset = flags &PIN_OFFSET_MASK ; + +if (offset & (alignment -1 )) { + ret = -EINVAL ; + goto err_free_vma; + } + vma->node.start = offset; + vma->node.size = size; + vma->node.color = obj->cache_level; + ret =drm_mm_reserve_node (&vm->mm, &vma->node); +if (ret) { + ret =i915_gem_evict_for_vma (vma); +if (ret ==0 ) + ret =drm_mm_reserve_node (&vm->mm, &vma->node); + } +if (ret) + goto err_free_vma; }else { - search_flag =DRM_MM_SEARCH_DEFAULT ; - alloc_flag =DRM_MM_CREATE_DEFAULT ; - } +if (flags &PIN_HIGH ) { + search_flag =DRM_MM_SEARCH_BELOW ; + alloc_flag =DRM_MM_CREATE_TOP ; + }else { + search_flag =DRM_MM_SEARCH_DEFAULT ; + alloc_flag =DRM_MM_CREATE_DEFAULT ; + } search_free: - ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, - size, alignment, - obj->cache_level, - start, end, - search_flag, - alloc_flag); -if (ret) { - ret =i915_gem_evict_something (dev, vm, size, alignment, - obj->cache_level, - start, end, - flags); -if (ret ==0 ) - goto search_free; + ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, + size, alignment, + obj->cache_level, + start, end, + search_flag, + alloc_flag); +if (ret) { + ret =i915_gem_evict_something (dev, vm, size, alignment, + obj->cache_level, + start, end, + flags); +if (ret ==0 ) + goto search_free; - goto err_free_vma; + goto err_free_vma; + } }if (WARN_ON (!i915_gem_valid_gtt_space (vma, obj->cache_level))) { ret = -EINVAL ;@@ -4007,6 +4027,10 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags) vma->node.start < (flags & PIN_OFFSET_MASK))return true; +if (flags &PIN_OFFSET_FIXED && + vma->node.start != (flags &PIN_OFFSET_MASK )) +return true; +return false; }drivers/gpu/drm/i915/i915_gem_evict.c +39
-0@@ -199,6 +199,45 @@ found:return ret; } +int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +if (!vma->exec_entry || (vma->pin_count >1 )) +/* Object is pinned for some other use */ +return -EBUSY ; + +/* We need to evict a buffer in the same batch */ +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */ +return -EINVAL ; + +return -ENOSPC ; + } + + ret =i915_vma_unbind (vma); +if (ret) +return ret; + } + +return 0 ; +} +/** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse drivers/gpu/drm/i915/i915_gem_execbuffer.c +16
-3@@ -599,6 +599,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL |PIN_MAPPABLE ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ;if ((flags &PIN_MAPPABLE ) ==0 ) flags |=PIN_HIGH ; }@@ -670,6 +672,10 @@ eb_vma_misplaced(struct i915_vma *vma) vma->node.start & (entry->alignment - 1))return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;@@ -678,7 +684,8 @@ eb_vma_misplaced(struct i915_vma *vma)if (entry->flags & __EXEC_OBJECT_NEEDS_MAP && !obj->map_and_fenceable)return !only_mappable_for_reloc (entry->flags); -if ((entry->flags &EXEC_OBJECT_SUPPORTS_48B_ADDRESS ) ==0 && +if (!(entry->flags & + (EXEC_OBJECT_SUPPORTS_48B_ADDRESS |EXEC_OBJECT_PINNED )) && (vma->node.start + vma->node.size -1 ) >>32 )return true;@@ -695,6 +702,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring,struct i915_vma *vma;struct i915_address_space *vm;struct list_head ordered_vmas; +struct list_head pinned_vmas;bool has_fenced_gpu_access =INTEL_INFO (ring->dev)->gen <4 ;int retry;@@ -703,6 +711,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;INIT_LIST_HEAD (&ordered_vmas); +INIT_LIST_HEAD (&pinned_vmas);while (!list_empty (vmas)) {struct drm_i915_gem_exec_object2 *entry;bool need_fence, need_mappable;@@ -721,7 +730,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode !=I915_TILING_NONE ; need_mappable = need_fence ||need_reloc_mappable (vma); -if (need_mappable) { +if (entry->flags &EXEC_OBJECT_PINNED ) +list_move_tail (&vma->exec_list, &pinned_vmas); +else if (need_mappable) { entry->flags |= __EXEC_OBJECT_NEEDS_MAP;list_move (&vma->exec_list, &ordered_vmas); }else @@ -731,6 +742,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_write_domain =0 ; }list_splice (&ordered_vmas, vmas); +list_splice (&pinned_vmas, vmas);/* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases: @@ -1317,7 +1329,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }include/uapi/drm/i915_drm.h +7
-2@@ -356,6 +356,7 @@ typedef struct drm_i915_irq_wait {#define I915_PARAM_EU_TOTAL 34#define I915_PARAM_HAS_GPU_RESET 35#define I915_PARAM_HAS_RESOURCE_STREAMER 36 +#define I915_PARAM_HAS_EXEC_SOFTPIN 37 typedef struct drm_i915_getparam { __s32 param;@@ -682,8 +683,12 @@ struct drm_i915_gem_exec_object2 {__u64 alignment;/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* When the I915_EXEC_NO_RELOC flag is specified this must contain the +* presumed_offset of the object. +* During execbuffer2 the kernel populates it with the value of the +* current GTT offset of the object, for future presumed_offset writes. */ __u64 offset;
include/uapi/drm/i915_drm.h struct drm_i915_gem_exec_object2 { · line 703
Quoted 9 lines
include/uapi/drm/i915_drm.h +2
-1@@ -691,7 +696,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;__u64 rsvd1;
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 9 lines · Akash
Discussed sometime back about this patch with Chris. He mainly has 2 concerns with it.
1. The linear walk used by the patch to detect the overlapping objects would be expensive.
2. Restriction to disallow !RCS submissions for non-default contexts, which could lead to lot of conflicts for the placements, once multiple engines like media/blit/vebox are used
Quoted 8 lines
Both of them can be addressed by the subsequent patches. Chris already has the patch ready to reduce the validation overhead with the use of rbtree and there should be no implications of allowing the non-default contexts for !RCS submissions in execbuffer.
In the standalone form, the patch looks good, so
Reviewed-by "Akash Goel <[email protected]>"
I am sorry, but this patch does not reflect the final version that I wrote, in particular does not provide the support I actually use inside the kernel.
-Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 95 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.v5: Added
I915_PARAM_HAS_EXEC_SOFTPINparameter for detecting this capability (Kristian). Added check for multiple pinnings on eviction (Akash). Made sure buffers are not considered misplaced without the user specifyingEXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for any addressing workarounds. Updated object2.offset field comment again to clarifyNO_RELOCcase (Chris). checkpatch cleanup.v6: Trivial rebase on latest drm-intel-nightly
Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarski <[email protected]>Cc Zou Nanhai <[email protected]>Cc Kristian Høgsberg <[email protected]>Signed-off-by Thomas Daniel <[email protected]>--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 19 +++++++-- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 113 insertions(+), 26 deletions(-)drivers/gpu/drm/i915/i915_dma.c +3
-0@@ -170,6 +170,9 @@ static int i915_getparam(struct drm_device *dev, void *data,case I915_PARAM_HAS_RESOURCE_STREAMER : value =HAS_RESOURCE_STREAMER (dev);break ; +case I915_PARAM_HAS_EXEC_SOFTPIN : + value =1 ; +break ;default :DRM_DEBUG ("Unknown parameter %d\n" , param->param);return -EINVAL ;drivers/gpu/drm/i915/i915_drv.h +2
-0@@ -2816,6 +2816,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_UPDATE (1<<5)#define PIN_ZONE_4G (1<<6)#define PIN_HIGH (1<<7) +#define PIN_OFFSET_FIXED (1<<8)#define PIN_OFFSET_MASK (~4095) int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,@@ -3163,6 +3164,7 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,unsigned long start, unsigned long end, unsigned flags); +int __must_check i915_gem_evict_for_vma (struct i915_vma *target);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);/* belongs in i915_gem_gtt.h */ drivers/gpu/drm/i915/i915_gem.c +1
-3@@ -3450,30 +3450,50 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,if (IS_ERR (vma)) goto err_unpin; -if (flags &PIN_HIGH ) { - search_flag =DRM_MM_SEARCH_BELOW ; - alloc_flag =DRM_MM_CREATE_TOP ; +if (flags &PIN_OFFSET_FIXED ) {
drivers/gpu/drm/i915/i915_gem.c i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj, · line 3463
Quoted 10 lines
drivers/gpu/drm/i915/i915_gem.c +10
-0+uint64_t offset = flags &PIN_OFFSET_MASK ; + +if (offset & (alignment -1 )) { + ret = -EINVAL ; + goto err_free_vma; + } + vma->node.start = offset; + vma->node.size = size; + vma->node.color = obj->cache_level; + ret =drm_mm_reserve_node (&vm->mm, &vma->node);
This will return ENOSPC to userspace when they have passed in an address outside the (PP)GTT range which is misleading.
I would suggest explicit checking against the 'end' (available a bit further up in the same function) and returning something more appropriate. At least EINVAL, although execbuf overloads that one so much I would even rather steal some other semi-appropriate one like ENXIO (No such device or _address_) or something.
Regards,
Tvrtko
Quoted 222 lines
drivers/gpu/drm/i915/i915_gem.c +33
-17+if (ret) { + ret =i915_gem_evict_for_vma (vma); +if (ret ==0 ) + ret =drm_mm_reserve_node (&vm->mm, &vma->node); + } +if (ret) + goto err_free_vma; }else { - search_flag =DRM_MM_SEARCH_DEFAULT ; - alloc_flag =DRM_MM_CREATE_DEFAULT ; - } +if (flags &PIN_HIGH ) { + search_flag =DRM_MM_SEARCH_BELOW ; + alloc_flag =DRM_MM_CREATE_TOP ; + }else { + search_flag =DRM_MM_SEARCH_DEFAULT ; + alloc_flag =DRM_MM_CREATE_DEFAULT ; + } search_free: - ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, - size, alignment, - obj->cache_level, - start, end, - search_flag, - alloc_flag); -if (ret) { - ret =i915_gem_evict_something (dev, vm, size, alignment, - obj->cache_level, - start, end, - flags); -if (ret ==0 ) - goto search_free; + ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, + size, alignment, + obj->cache_level, + start, end, + search_flag, + alloc_flag); +if (ret) { + ret =i915_gem_evict_something (dev, vm, size, alignment, + obj->cache_level, + start, end, + flags); +if (ret ==0 ) + goto search_free; - goto err_free_vma; + goto err_free_vma; + } }if (WARN_ON (!i915_gem_valid_gtt_space (vma, obj->cache_level))) { ret = -EINVAL ;@@ -4007,6 +4027,10 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags) vma->node.start < (flags & PIN_OFFSET_MASK))return true; +if (flags &PIN_OFFSET_FIXED && + vma->node.start != (flags &PIN_OFFSET_MASK )) +return true; +return false; }drivers/gpu/drm/i915/i915_gem_evict.c +39
-0@@ -199,6 +199,45 @@ found:return ret; } +int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +if (!vma->exec_entry || (vma->pin_count >1 )) +/* Object is pinned for some other use */ +return -EBUSY ; + +/* We need to evict a buffer in the same batch */ +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */ +return -EINVAL ; + +return -ENOSPC ; + } + + ret =i915_vma_unbind (vma); +if (ret) +return ret; + } + +return 0 ; +} +/** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse drivers/gpu/drm/i915/i915_gem_execbuffer.c +16
-3@@ -599,6 +599,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL |PIN_MAPPABLE ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ;if ((flags &PIN_MAPPABLE ) ==0 ) flags |=PIN_HIGH ; }@@ -670,6 +672,10 @@ eb_vma_misplaced(struct i915_vma *vma) vma->node.start & (entry->alignment - 1))return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;@@ -678,7 +684,8 @@ eb_vma_misplaced(struct i915_vma *vma)if (entry->flags & __EXEC_OBJECT_NEEDS_MAP && !obj->map_and_fenceable)return !only_mappable_for_reloc (entry->flags); -if ((entry->flags &EXEC_OBJECT_SUPPORTS_48B_ADDRESS ) ==0 && +if (!(entry->flags & + (EXEC_OBJECT_SUPPORTS_48B_ADDRESS |EXEC_OBJECT_PINNED )) && (vma->node.start + vma->node.size -1 ) >>32 )return true;@@ -695,6 +702,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring,struct i915_vma *vma;struct i915_address_space *vm;struct list_head ordered_vmas; +struct list_head pinned_vmas;bool has_fenced_gpu_access =INTEL_INFO (ring->dev)->gen <4 ;int retry;@@ -703,6 +711,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;INIT_LIST_HEAD (&ordered_vmas); +INIT_LIST_HEAD (&pinned_vmas);while (!list_empty (vmas)) {struct drm_i915_gem_exec_object2 *entry;bool need_fence, need_mappable;@@ -721,7 +730,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode !=I915_TILING_NONE ; need_mappable = need_fence ||need_reloc_mappable (vma); -if (need_mappable) { +if (entry->flags &EXEC_OBJECT_PINNED ) +list_move_tail (&vma->exec_list, &pinned_vmas); +else if (need_mappable) { entry->flags |= __EXEC_OBJECT_NEEDS_MAP;list_move (&vma->exec_list, &ordered_vmas); }else @@ -731,6 +742,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_write_domain =0 ; }list_splice (&ordered_vmas, vmas); +list_splice (&pinned_vmas, vmas);/* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases: @@ -1317,7 +1329,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }include/uapi/drm/i915_drm.h +7
-2@@ -356,6 +356,7 @@ typedef struct drm_i915_irq_wait {#define I915_PARAM_EU_TOTAL 34#define I915_PARAM_HAS_GPU_RESET 35#define I915_PARAM_HAS_RESOURCE_STREAMER 36 +#define I915_PARAM_HAS_EXEC_SOFTPIN 37 typedef struct drm_i915_getparam { __s32 param;@@ -682,8 +683,12 @@ struct drm_i915_gem_exec_object2 {__u64 alignment;/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* When the I915_EXEC_NO_RELOC flag is specified this must contain the +* presumed_offset of the object. +* During execbuffer2 the kernel populates it with the value of the +* current GTT offset of the object, for future presumed_offset writes. */ __u64 offset;
include/uapi/drm/i915_drm.h struct drm_i915_gem_exec_object2 { · line 703
Quoted 9 lines
include/uapi/drm/i915_drm.h +2
-1@@ -691,7 +696,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;__u64 rsvd1;
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 2 lines · Tvrtko Ursulin
This will return ENOSPC to userspace when they have passed in an address outside the (PP)GTT range which is misleading.
Reviewing the wrong patch.
-Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH v7 1/1 drm/i915: Add soft-pinning API for execbuffer
In reply to Thomas DanielFrom: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)
v4: Moved soft-pinned objects to the front of ordered_vmas so that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.
v5: Added I915_PARAM_HAS_EXEC_SOFTPIN parameter for detecting this capability (Kristian). Added check for multiple pinnings on eviction (Akash). Made sure buffers are not considered misplaced without the user specifying EXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for any addressing workarounds. Updated object2.offset field comment again to clarify NO_RELOC case (Chris). checkpatch cleanup.
v6: Trivial rebase on latest drm-intel-nightly
v7: Catch attempts to pin above the max virtual address size and return EINVAL (Tvrtko). Decouple EXEC_OBJECT_SUPPORTS_48B_ADDRESS and EXEC_OBJECT_PINNED flags, user must pass both flags in any attempt to pin something at an offset above 4GB (Chris, Daniel Vetter).
--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 111 insertions(+), 25 deletions(-)
drivers/gpu/drm/i915/i915_dma.c +3 -0
@@ -169,6 +169,9 @@ static int i915_getparam(struct drm_device *dev, void *data,case I915_PARAM_HAS_RESOURCE_STREAMER : value =HAS_RESOURCE_STREAMER (dev);break ; +case I915_PARAM_HAS_EXEC_SOFTPIN : + value =1 ; +break ;default :DRM_DEBUG ("Unknown parameter %d\n" , param->param);return -EINVAL ;
drivers/gpu/drm/i915/i915_drv.h +2 -0
@@ -2860,6 +2860,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_UPDATE (1<<5)#define PIN_ZONE_4G (1<<6)#define PIN_HIGH (1<<7) +#define PIN_OFFSET_FIXED (1<<8)#define PIN_OFFSET_MASK (~4095) int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
@@ -3205,6 +3206,7 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,unsigned long start, unsigned long end, unsigned flags); +int __must_check i915_gem_evict_for_vma (struct i915_vma *target);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);/* belongs in i915_gem_gtt.h */
drivers/gpu/drm/i915/i915_gem.c +44 -20
80 lines not on this page · raw message
drivers/gpu/drm/i915/i915_gem_evict.c +39 -0
@@ -199,6 +199,45 @@ found:return ret; } +int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +if (!vma->exec_entry || (vma->pin_count >1 )) +/* Object is pinned for some other use */ +return -EBUSY ; + +/* We need to evict a buffer in the same batch */ +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */ +return -EINVAL ; + +return -ENOSPC ; + } + + ret =i915_vma_unbind (vma); +if (ret) +return ret; + } + +return 0 ; +} +/** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse
drivers/gpu/drm/i915/i915_gem_execbuffer.c +14 -2
@@ -599,6 +599,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL |PIN_MAPPABLE ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ;if ((flags &PIN_MAPPABLE ) ==0 ) flags |=PIN_HIGH ; }
@@ -670,6 +672,10 @@ eb_vma_misplaced(struct i915_vma *vma) vma->node.start & (entry->alignment - 1))return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;
@@ -695,6 +701,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring,struct i915_vma *vma;struct i915_address_space *vm;struct list_head ordered_vmas; +struct list_head pinned_vmas;bool has_fenced_gpu_access =INTEL_INFO (ring->dev)->gen <4 ;int retry;
@@ -703,6 +710,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;INIT_LIST_HEAD (&ordered_vmas); +INIT_LIST_HEAD (&pinned_vmas);while (!list_empty (vmas)) {struct drm_i915_gem_exec_object2 *entry;bool need_fence, need_mappable;
@@ -721,7 +729,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode !=I915_TILING_NONE ; need_mappable = need_fence ||need_reloc_mappable (vma); -if (need_mappable) { +if (entry->flags &EXEC_OBJECT_PINNED ) +list_move_tail (&vma->exec_list, &pinned_vmas); +else if (need_mappable) { entry->flags |= __EXEC_OBJECT_NEEDS_MAP;list_move (&vma->exec_list, &ordered_vmas); }else
@@ -731,6 +741,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_write_domain =0 ; }list_splice (&ordered_vmas, vmas); +list_splice (&pinned_vmas, vmas);/* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases:
@@ -1317,7 +1328,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }
include/uapi/drm/i915_drm.h +9 -3
@@ -356,6 +356,7 @@ typedef struct drm_i915_irq_wait {#define I915_PARAM_EU_TOTAL 34#define I915_PARAM_HAS_GPU_RESET 35#define I915_PARAM_HAS_RESOURCE_STREAMER 36 +#define I915_PARAM_HAS_EXEC_SOFTPIN 37 typedef struct drm_i915_getparam { __s32 param;
@@ -682,8 +683,12 @@ struct drm_i915_gem_exec_object2 {__u64 alignment;/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* When the I915_EXEC_NO_RELOC flag is specified this must contain the +* presumed_offset of the object. +* During execbuffer2 the kernel populates it with the value of the +* current GTT offset of the object, for future presumed_offset writes. */ __u64 offset;
@@ -691,7 +696,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;__u64 rsvd1;
Signature · 6 lines
1.9.1 _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 46 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski. (Not published externally)
v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.v5: Added
I915_PARAM_HAS_EXEC_SOFTPINparameter for detecting this capability (Kristian). Added check for multiple pinnings on eviction (Akash). Made sure buffers are not considered misplaced without the user specifyingEXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for any addressing workarounds. Updated object2.offset field comment again to clarifyNO_RELOCcase (Chris). checkpatch cleanup.v6: Trivial rebase on latest drm-intel-nightly
v7: Catch attempts to pin above the max virtual address size and return EINVAL (Tvrtko). Decouple
EXEC_OBJECT_SUPPORTS_48B_ADDRESSandEXEC_OBJECT_PINNEDflags, user must pass both flags in any attempt to pin something at an offset above 4GB (Chris, Daniel Vetter).Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarski <[email protected]>Cc Zou Nanhai <[email protected]>Cc Kristian Høgsberg <[email protected]>Cc Tvrtko Ursulin <[email protected]>Signed-off-by Thomas Daniel <[email protected]>
Quoted 9 lines
--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 111 insertions(+), 25 deletions(-)
Extra support from the other patch aside, v6 already had rb from Akash and this one,
Quoted 279 lines
drivers/gpu/drm/i915/i915_dma.c +3
-0@@ -169,6 +169,9 @@ static int i915_getparam(struct drm_device *dev, void *data,case I915_PARAM_HAS_RESOURCE_STREAMER : value =HAS_RESOURCE_STREAMER (dev);break ; +case I915_PARAM_HAS_EXEC_SOFTPIN : + value =1 ; +break ;default :DRM_DEBUG ("Unknown parameter %d\n" , param->param);return -EINVAL ;drivers/gpu/drm/i915/i915_drv.h +2
-0@@ -2860,6 +2860,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma);#define PIN_UPDATE (1<<5)#define PIN_ZONE_4G (1<<6)#define PIN_HIGH (1<<7) +#define PIN_OFFSET_FIXED (1<<8)#define PIN_OFFSET_MASK (~4095) int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,@@ -3205,6 +3206,7 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,unsigned long start, unsigned long end, unsigned flags); +int __must_check i915_gem_evict_for_vma (struct i915_vma *target);int i915_gem_evict_vm (struct i915_address_space *vm,bool do_idle);/* belongs in i915_gem_gtt.h */ drivers/gpu/drm/i915/i915_gem.c +44
-20@@ -3476,30 +3476,50 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,if (IS_ERR (vma)) goto err_unpin; -if (flags &PIN_HIGH ) { - search_flag =DRM_MM_SEARCH_BELOW ; - alloc_flag =DRM_MM_CREATE_TOP ; +if (flags &PIN_OFFSET_FIXED ) { +uint64_t offset = flags &PIN_OFFSET_MASK ; + +if (offset & (alignment -1 ) || offset + size > end) { + ret = -EINVAL ; + goto err_free_vma; + } + vma->node.start = offset; + vma->node.size = size; + vma->node.color = obj->cache_level; + ret =drm_mm_reserve_node (&vm->mm, &vma->node); +if (ret) { + ret =i915_gem_evict_for_vma (vma); +if (ret ==0 ) + ret =drm_mm_reserve_node (&vm->mm, &vma->node); + } +if (ret) + goto err_free_vma; }else { - search_flag =DRM_MM_SEARCH_DEFAULT ; - alloc_flag =DRM_MM_CREATE_DEFAULT ; - } +if (flags &PIN_HIGH ) { + search_flag =DRM_MM_SEARCH_BELOW ; + alloc_flag =DRM_MM_CREATE_TOP ; + }else { + search_flag =DRM_MM_SEARCH_DEFAULT ; + alloc_flag =DRM_MM_CREATE_DEFAULT ; + } search_free: - ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, - size, alignment, - obj->cache_level, - start, end, - search_flag, - alloc_flag); -if (ret) { - ret =i915_gem_evict_something (dev, vm, size, alignment, - obj->cache_level, - start, end, - flags); -if (ret ==0 ) - goto search_free; + ret =drm_mm_insert_node_in_range_generic (&vm->mm, &vma->node, + size, alignment, + obj->cache_level, + start, end, + search_flag, + alloc_flag); +if (ret) { + ret =i915_gem_evict_something (dev, vm, size, alignment, + obj->cache_level, + start, end, + flags); +if (ret ==0 ) + goto search_free; - goto err_free_vma; + goto err_free_vma; + } }if (WARN_ON (!i915_gem_valid_gtt_space (vma, obj->cache_level))) { ret = -EINVAL ;@@ -4090,6 +4110,10 @@ i915_vma_misplaced(struct i915_vma *vma, uint32_t alignment, uint64_t flags) vma->node.start < (flags & PIN_OFFSET_MASK))return true; +if (flags &PIN_OFFSET_FIXED && + vma->node.start != (flags &PIN_OFFSET_MASK )) +return true; +return false; }drivers/gpu/drm/i915/i915_gem_evict.c +39
-0@@ -199,6 +199,45 @@ found:return ret; } +int +i915_gem_evict_for_vma (struct i915_vma *target) +{ +struct drm_mm_node *node, *next; + +list_for_each_entry_safe (node, next, + &target->vm->mm.head_node.node_list, + node_list) { +struct i915_vma *vma; +int ret; + +if (node->start + node->size <= target->node.start) +continue ; +if (node->start >= target->node.start + target->node.size) +break ; + + vma =container_of (node,typeof (*vma), node); + +if (vma->pin_count) { +if (!vma->exec_entry || (vma->pin_count >1 )) +/* Object is pinned for some other use */ +return -EBUSY ; + +/* We need to evict a buffer in the same batch */ +if (vma->exec_entry->flags &EXEC_OBJECT_PINNED ) +/* Overlapping fixed objects in the same batch */ +return -EINVAL ; + +return -ENOSPC ; + } + + ret =i915_vma_unbind (vma); +if (ret) +return ret; + } + +return 0 ; +} +/** * i915_gem_evict_vm - Evict all idle vmas from a vm * @vm: Address space to cleanse drivers/gpu/drm/i915/i915_gem_execbuffer.c +14
-2@@ -599,6 +599,8 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, flags |=PIN_GLOBAL |PIN_MAPPABLE ;if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) flags |=BATCH_OFFSET_BIAS |PIN_OFFSET_BIAS ; +if (entry->flags &EXEC_OBJECT_PINNED ) + flags |= entry->offset |PIN_OFFSET_FIXED ;if ((flags &PIN_MAPPABLE ) ==0 ) flags |=PIN_HIGH ; }@@ -670,6 +672,10 @@ eb_vma_misplaced(struct i915_vma *vma) vma->node.start & (entry->alignment - 1))return true; +if (entry->flags &EXEC_OBJECT_PINNED && + vma->node.start != entry->offset) +return true; +if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && vma->node.start <BATCH_OFFSET_BIAS )return true;@@ -695,6 +701,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring,struct i915_vma *vma;struct i915_address_space *vm;struct list_head ordered_vmas; +struct list_head pinned_vmas;bool has_fenced_gpu_access =INTEL_INFO (ring->dev)->gen <4 ;int retry;@@ -703,6 +710,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;INIT_LIST_HEAD (&ordered_vmas); +INIT_LIST_HEAD (&pinned_vmas);while (!list_empty (vmas)) {struct drm_i915_gem_exec_object2 *entry;bool need_fence, need_mappable;@@ -721,7 +729,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode !=I915_TILING_NONE ; need_mappable = need_fence ||need_reloc_mappable (vma); -if (need_mappable) { +if (entry->flags &EXEC_OBJECT_PINNED ) +list_move_tail (&vma->exec_list, &pinned_vmas); +else if (need_mappable) { entry->flags |= __EXEC_OBJECT_NEEDS_MAP;list_move (&vma->exec_list, &ordered_vmas); }else @@ -731,6 +741,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_write_domain =0 ; }list_splice (&ordered_vmas, vmas); +list_splice (&pinned_vmas, vmas);/* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases: @@ -1317,7 +1328,8 @@ eb_get_batch(struct eb_vmas *eb)* Note that actual hangs have only been observed on gen7, but for * paranoia do it everywhere. */ - vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS; +if ((vma->exec_entry->flags &EXEC_OBJECT_PINNED ) ==0 ) + vma->exec_entry->flags |= __EXEC_OBJECT_NEEDS_BIAS;return vma->obj; }include/uapi/drm/i915_drm.h +9
-4@@ -356,6 +356,7 @@ typedef struct drm_i915_irq_wait {#define I915_PARAM_EU_TOTAL 34#define I915_PARAM_HAS_GPU_RESET 35#define I915_PARAM_HAS_RESOURCE_STREAMER 36 +#define I915_PARAM_HAS_EXEC_SOFTPIN 37 typedef struct drm_i915_getparam { __s32 param;@@ -682,8 +683,12 @@ struct drm_i915_gem_exec_object2 {__u64 alignment;/** -* Returned value of the updated offset of the object, for future -* presumed_offset writes. +* When the EXEC_OBJECT_PINNED flag is specified this is populated by +* the user with the GTT offset at which this object will be pinned. +* When the I915_EXEC_NO_RELOC flag is specified this must contain the +* presumed_offset of the object. +* During execbuffer2 the kernel populates it with the value of the +* current GTT offset of the object, for future presumed_offset writes. */ __u64 offset;@@ -691,7 +696,8 @@ struct drm_i915_gem_exec_object2 {#define EXEC_OBJECT_NEEDS_GTT (1<<1)#define EXEC_OBJECT_WRITE (1<<2)#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3) -#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1) +#define EXEC_OBJECT_PINNED (1<<4) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_PINNED<<1)__u64 flags;__u64 rsvd1; --1.9.1
Quoted 5 lines
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 68 lines · Michel Thierry
Quoted 56 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris
Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski.
(Not published externally)v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction
to allow eviction of soft-pinned objects when another soft-pinned object used
by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are
pinned first after an address conflict happens to avoid repeated conflicts in
rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.v5: Added
I915_PARAM_HAS_EXEC_SOFTPINparameter for detecting this capability
(Kristian). Added check for multiple pinnings on eviction (Akash). Made sure
buffers are not considered misplaced without the user specifyingEXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for any
addressing workarounds. Updated object2.offset field comment again to clarifyNO_RELOCcase (Chris). checkpatch cleanup.v6: Trivial rebase on latest drm-intel-nightly
v7: Catch attempts to pin above the max virtual address size and return EINVAL (Tvrtko). Decouple
EXEC_OBJECT_SUPPORTS_48B_ADDRESSandEXEC_OBJECT_PINNEDflags, user must pass both flags in any attempt to pin something at an offset above 4GB (Chris, Daniel Vetter).Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarski <[email protected]>Cc Zou Nanhai <[email protected]>Cc Kristian Høgsberg <[email protected]>Cc Tvrtko Ursulin <[email protected]>Signed-off-by Thomas Daniel <[email protected]>Quoted 10 lines
--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 111 insertions(+), 25 deletions(-)
Quoted 3 lines
Extra support from the other patch aside, v6 already had rb from Akash and this one,
Reviewed-by Michel Thierry <[email protected]>
This patch was acked by the PDT so I merged it to drm-intel-next-queued.
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 70 lines · Tvrtko Ursulin
Quoted 68 lines · Michel Thierry
Quoted 66 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris
Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski.
(Not published externally)v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction
to allow eviction of soft-pinned objects when another soft-pinned object used
by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are
pinned first after an address conflict happens to avoid repeated conflicts in
rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.v5: Added
I915_PARAM_HAS_EXEC_SOFTPINparameter for detecting this capability
(Kristian). Added check for multiple pinnings on eviction (Akash). Made sure
buffers are not considered misplaced without the user specifyingEXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for any
addressing workarounds. Updated object2.offset field comment again to clarifyNO_RELOCcase (Chris). checkpatch cleanup.v6: Trivial rebase on latest drm-intel-nightly
v7: Catch attempts to pin above the max virtual address size and return EINVAL (Tvrtko). Decouple
EXEC_OBJECT_SUPPORTS_48B_ADDRESSandEXEC_OBJECT_PINNEDflags, user must pass both flags in any attempt to pin something at an offset above 4GB (Chris, Daniel Vetter).Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarski <[email protected]>Cc Zou Nanhai <[email protected]>Cc Kristian Høgsberg <[email protected]>Cc Tvrtko Ursulin <[email protected]>Signed-off-by Thomas Daniel <[email protected]>--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 111 insertions(+), 25 deletions(-)
Quoted 5 lines
Quoted 3 lines
Extra support from the other patch aside, v6 already had rb from Akash and this one,
Reviewed-by Michel Thierry <[email protected]>This patch was acked by the PDT so I merged it to drm-intel-next-queued.
Please revert immediately. We need to fix the ABI for canonical addressing before proceeding. Then please work on the better patch. -Chris
Signature · 5 lines
Chris Wilson, Intel Open Source Technology Centre _______________________________________________ Intel-gfx mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 71 lines · Chris Wilson
Quoted 70 lines · Tvrtko Ursulin
Quoted 68 lines · Michel Thierry
Quoted 66 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris
Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski.
(Not published externally)v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction
to allow eviction of soft-pinned objects when another soft-pinned object used
by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are
pinned first after an address conflict happens to avoid repeated conflicts in
rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.v5: Added
I915_PARAM_HAS_EXEC_SOFTPINparameter for detecting this capability
(Kristian). Added check for multiple pinnings on eviction (Akash). Made sure
buffers are not considered misplaced without the user specifyingEXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for any
addressing workarounds. Updated object2.offset field comment again to clarifyNO_RELOCcase (Chris). checkpatch cleanup.v6: Trivial rebase on latest drm-intel-nightly
v7: Catch attempts to pin above the max virtual address size and return EINVAL (Tvrtko). Decouple
EXEC_OBJECT_SUPPORTS_48B_ADDRESSandEXEC_OBJECT_PINNEDflags, user must pass both flags in any attempt to pin something at an offset above 4GB (Chris, Daniel Vetter).Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarski <[email protected]>Cc Zou Nanhai <[email protected]>Cc Kristian Høgsberg <[email protected]>Cc Tvrtko Ursulin <[email protected]>Signed-off-by Thomas Daniel <[email protected]>--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 111 insertions(+), 25 deletions(-)
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Extra support from the other patch aside, v6 already had rb from Akash and this one,
Reviewed-by Michel Thierry <[email protected]>This patch was acked by the PDT so I merged it to drm-intel-next-queued.
Please revert immediately. We need to fix the ABI for canonical addressing before proceeding. Then please work on the better patch.
Sounds like this is a valid comment, guys please check the thread with subject "[PATCH v2] drm/i915: Avoid writing relocs with addresses in non-canonical form".
amd64 ABI mandates rules on virtual addresess - https://en.wikipedia.org/wiki/X86-64#Canonical_form_addresses.
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 88 lines · Tvrtko Ursulin
Quoted 73 lines · Chris Wilson
Quoted 72 lines · Tvrtko Ursulin
Quoted 70 lines · Michel Thierry
Quoted 68 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris
Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski.
(Not published externally)v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction
to allow eviction of soft-pinned objects when another soft-pinned object used
by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are
pinned first after an address conflict happens to avoid repeated conflicts in
rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.v5: Added
I915_PARAM_HAS_EXEC_SOFTPINparameter for detecting this capability
(Kristian). Added check for multiple pinnings on eviction (Akash). Made sure
buffers are not considered misplaced without the user specifyingEXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for any
addressing workarounds. Updated object2.offset field comment again to clarifyNO_RELOCcase (Chris). checkpatch cleanup.v6: Trivial rebase on latest drm-intel-nightly
v7: Catch attempts to pin above the max virtual address size and return
EINVAL (Tvrtko). DecoupleEXEC_OBJECT_SUPPORTS_48B_ADDRESSandEXEC_OBJECT_PINNEDflags, user must pass both flags in any attempt to pin
something at an offset above 4GB (Chris, Daniel Vetter).Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarski <[email protected]>Cc Zou Nanhai <[email protected]>Cc Kristian Høgsberg <[email protected]>Cc Tvrtko Ursulin <[email protected]>Signed-off-by Thomas Daniel <[email protected]>--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 111 insertions(+), 25 deletions(-)Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Extra support from the other patch aside, v6 already had rb from Akash and this one,
Reviewed-by Michel Thierry <[email protected]>This patch was acked by the PDT so I merged it to drm-intel-next-queued.
Please revert immediately. We need to fix the ABI for canonical addressing before proceeding. Then please work on the better patch.
Sounds like this is a valid comment, guys please check the thread with subject "[PATCH v2] drm/i915: Avoid writing relocs with addresses in non-canonical form".
Quoted 6 lines
amd64 ABI mandates rules on virtual addresess -
https://en.wikipedia.org/wiki/X86-64#Canonical_form_addresses.Regards,
Tvrtko
And if the someone tries to use softpin with a virtual address in non-canonical form, reject with EINVAL?
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoted 98 lines · Michel Thierry
Quoted 97 lines · Tvrtko Ursulin
Quoted 82 lines · Chris Wilson
Quoted 81 lines · Tvrtko Ursulin
Quoted 78 lines · Michel Thierry
Quoted 63 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located
at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will
rarely have to make space for the user's requests.Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested
by Chris
Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski.
(Not published externally)v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction
to allow eviction of soft-pinned objects when another soft-pinned object used
by a subsequent execbuffer overlaps reported by Michal Winiarski. (Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are
pinned first after an address conflict happens to avoid repeated conflicts in
rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.v5: Added
I915_PARAM_HAS_EXEC_SOFTPINparameter for detecting this capability
(Kristian). Added check for multiple pinnings on eviction (Akash). Made sure
buffers are not considered misplaced without the user specifyingEXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for
any
addressing workarounds. Updated object2.offset field comment again to
clarifyNO_RELOCcase (Chris). checkpatch cleanup.v6: Trivial rebase on latest drm-intel-nightly
v7: Catch attempts to pin above the max virtual address size and return
EINVAL (Tvrtko). DecoupleEXEC_OBJECT_SUPPORTS_48B_ADDRESSandEXEC_OBJECT_PINNEDflags, user must pass both flags in any attempt to pin
something at an offset above 4GB (Chris, Daniel Vetter).Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarski <[email protected]>Cc Zou Nanhai <[email protected]>Cc Kristian Høgsberg <[email protected]>Cc Tvrtko Ursulin <[email protected]>Signed-off-by Thomas Daniel <[email protected]>Quoted 10 lines
--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 111 insertions(+), 25 deletions(-)Extra support from the other patch aside, v6 already had rb from Akash and this one,
Reviewed-by Michel Thierry <[email protected]>Quoted 5 lines
Quoted 2 lines
This patch was acked by the PDT so I merged it to
drm-intel-next-queued.Please revert immediately. We need to fix the ABI for canonical addressing before proceeding. Then please work on the better patch.
Sounds like this is a valid comment, guys please check the thread with subject "[PATCH v2] drm/i915: Avoid writing relocs with addresses in non-canonical form".
amd64 ABI mandates rules on virtual addresess -
https://en.wikipedia.org/wiki/X86-64#Canonical_form_addresses.
Quoted 6 lines
Quoted 3 lines
Regards,
Tvrtko
And if the someone tries to use softpin with a virtual address in non-canonical form, reject with EINVAL?
I think so, since they are not valid userspace virtual addresses.
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
The stress test will need to be modified to ensure a canonical address(currently uses starting address of 0x8000000000000). The invalid_vma test takes care of the non-canonical scenario in an indirect way. Do we still need a separate test for this change then?
Thanks,
Vinay.
-----Original Message-----
From: Tvrtko Ursulin [mailto:[email protected]]
Sent: Wednesday, December 9, 2015 5:36 AM
To: Thierry, Michel; Chris Wilson; Daniel, Thomas; [email protected]; Belgaumkar, Vinay; Goel, Akash; Kristian Høgsberg
Subject: Re: [Intel-gfx] [PATCH v7] drm/i915: Add soft-pinning API for execbuffer
Quoted 89 lines · Michel Thierry
Quoted 88 lines · Tvrtko Ursulin
Quoted 73 lines · Chris Wilson
Quoted 72 lines · Tvrtko Ursulin
Quoted 69 lines · Michel Thierry
Quoted 54 lines · Thomas Daniel
From: Chris Wilson <[email protected]>
Userspace can pass in an offset that it presumes the object is located at. The kernel will then do its utmost to fit the object into that location. The assumption is that userspace is handling its own object locations (for example along with full-ppgtt) and that the kernel will rarely have to make space for the user's requests.
Signed-off-by Chris Wilson <[email protected]>v2: Fixed incorrect eviction found by Michal Winiarski - fix suggested by Chris Wilson. Fixed incorrect error paths causing crash found by Michal Winiarski.
(Not published externally)v3: Rebased because of trivial conflict in
object_bind_to_vm. Fixed eviction to allow eviction of soft-pinned objects when another soft-pinned object used by a subsequent execbuffer overlaps reported by Michal Winiarski.
(Not published externally)v4: Moved soft-pinned objects to the front of
ordered_vmasso that they are pinned first after an address conflict happens to avoid repeated conflicts in rare cases (Suggested by Chris Wilson). Expanded comment on drm_i915_gem_exec_object2.offset to cover this new API.v5: Added
I915_PARAM_HAS_EXEC_SOFTPINparameter for detecting this capability (Kristian). Added check for multiple pinnings on eviction (Akash).
Made sure
buffers are not considered misplaced without the user specifyingEXEC_OBJECT_SUPPORTS_48B_ADDRESS. User must assume responsibility for any addressing workarounds. Updated object2.offset field comment again to clarifyNO_RELOCcase (Chris). checkpatch cleanup.v6: Trivial rebase on latest drm-intel-nightly
v7: Catch attempts to pin above the max virtual address size and return EINVAL (Tvrtko). Decouple
EXEC_OBJECT_SUPPORTS_48B_ADDRESSandEXEC_OBJECT_PINNEDflags, user must pass both flags in any attempt to pin something at an offset above 4GB (Chris, Daniel Vetter).Cc Chris Wilson <[email protected]>Cc Akash Goel <[email protected]>Cc Vinay Belgaumkar <[email protected]>Cc Michal Winiarski <[email protected]>Cc Zou Nanhai <[email protected]>Cc Kristian Høgsberg <[email protected]>Cc Tvrtko Ursulin <[email protected]>Signed-off-by Thomas Daniel <[email protected]>Quoted 10 lines
--- drivers/gpu/drm/i915/i915_dma.c | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 64 ++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 39 ++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 16 +++++++- include/uapi/drm/i915_drm.h | 12 ++++-- 6 files changed, 111 insertions(+), 25 deletions(-)Extra support from the other patch aside, v6 already had rb from Akash and this one,
Reviewed-by Michel Thierry <[email protected]>Quoted 5 lines
Quoted 2 lines
This patch was acked by the PDT so I merged it to
drm-intel-next-queued.Please revert immediately. We need to fix the ABI for canonical addressing before proceeding. Then please work on the better patch.
Sounds like this is a valid comment, guys please check the thread with subject "[PATCH v2] drm/i915: Avoid writing relocs with addresses in non-canonical form".
amd64 ABI mandates rules on virtual addresess -
https://en.wikipedia.org/wiki/X86-64#Canonical_form_addresses.
Quoted 6 lines
Quoted 3 lines
Regards,
Tvrtko
And if the someone tries to use softpin with a virtual address in non-canonical form, reject with EINVAL?
I think so, since they are not valid userspace virtual addresses.
Regards,
Tvrtko
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx