drm/amdgpu: enable bo priority setting from user space

Submitted by Chunming Zhou on March 7, 2019, 9:15 a.m.

Details

Message ID 20190307091528.22788-1-david1.zhou@amd.com
State New
Headers show
Series "drm/amdgpu: enable bo priority setting from user space" ( rev: 1 ) in AMD X.Org drivers

Not browsing as part of any series.

Commit Message

Chunming Zhou March 7, 2019, 9:15 a.m.
Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c     |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c    | 13 +++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h    |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h |  1 +
 include/drm/ttm/ttm_bo_driver.h            |  9 ++++++++-
 include/uapi/drm/amdgpu_drm.h              |  3 +++
 7 files changed, 29 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index 5cbde74b97dd..70a6baf20c22 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -144,6 +144,7 @@  static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
 	size = mode_cmd->pitches[0] * height;
 	aligned_size = ALIGN(size, PAGE_SIZE);
 	ret = amdgpu_gem_object_create(adev, aligned_size, 0, domain,
+				       TTM_BO_PRIORITY_NORMAL,
 				       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
 				       AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS |
 				       AMDGPU_GEM_CREATE_VRAM_CLEARED,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index d21dd2f369da..7c1c2362c67e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -44,6 +44,7 @@  void amdgpu_gem_object_free(struct drm_gem_object *gobj)
 
 int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
 			     int alignment, u32 initial_domain,
+			     enum ttm_bo_priority priority,
 			     u64 flags, enum ttm_bo_type type,
 			     struct reservation_object *resv,
 			     struct drm_gem_object **obj)
@@ -60,6 +61,7 @@  int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
 	bp.type = type;
 	bp.resv = resv;
 	bp.preferred_domain = initial_domain;
+	bp.priority = priority;
 retry:
 	bp.flags = flags;
 	bp.domain = initial_domain;
@@ -229,6 +231,14 @@  int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
 	if (args->in.domains & ~AMDGPU_GEM_DOMAIN_MASK)
 		return -EINVAL;
 
+	/* check priority */
+	if (args->in.priority == 0) {
+		/* default is normal */
+		args->in.priority = TTM_BO_PRIORITY_NORMAL;
+	} else if (args->in.priority > TTM_MAX_BO_PRIORITY) {
+		args->in.priority = TTM_MAX_BO_PRIORITY;
+		DRM_ERROR("priority specified from user space is over MAX priority\n");
+	}
 	/* create a gem object to contain this object in */
 	if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
 	    AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
@@ -252,6 +262,7 @@  int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
 
 	r = amdgpu_gem_object_create(adev, size, args->in.alignment,
 				     (u32)(0xffffffff & args->in.domains),
+				     args->in.priority - 1,
 				     flags, ttm_bo_type_device, resv, &gobj);
 	if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
 		if (!r) {
@@ -304,6 +315,7 @@  int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
 
 	/* create a gem object to contain this object in */
 	r = amdgpu_gem_object_create(adev, args->size, 0, AMDGPU_GEM_DOMAIN_CPU,
+				     TTM_BO_PRIORITY_NORMAL,
 				     0, ttm_bo_type_device, NULL, &gobj);
 	if (r)
 		return r;
@@ -755,6 +767,7 @@  int amdgpu_mode_dumb_create(struct drm_file *file_priv,
 	domain = amdgpu_bo_get_preferred_pin_domain(adev,
 				amdgpu_display_supported_domains(adev));
 	r = amdgpu_gem_object_create(adev, args->size, 0, domain,
+				     TTM_BO_PRIORITY_NORMAL,
 				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
 				     ttm_bo_type_device, NULL, &gobj);
 	if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h
index f1ddfc50bcc7..47b0a8190948 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h
@@ -61,7 +61,7 @@  extern const struct dma_buf_ops amdgpu_dmabuf_ops;
  */
 void amdgpu_gem_force_release(struct amdgpu_device *adev);
 int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
-			     int alignment, u32 initial_domain,
+			     int alignment, u32 initial_domain, u32 priority,
 			     u64 flags, enum ttm_bo_type type,
 			     struct reservation_object *resv,
 			     struct drm_gem_object **obj);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index fd9c4beeaaa4..c85304e03021 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -494,8 +494,9 @@  static int amdgpu_bo_do_create(struct amdgpu_device *adev,
 
 	bo->tbo.bdev = &adev->mman.bdev;
 	amdgpu_bo_placement_from_domain(bo, bp->domain);
+	bo->tbo.priority = bp->priority;
 	if (bp->type == ttm_bo_type_kernel)
-		bo->tbo.priority = 1;
+		bo->tbo.priority = TTM_BO_PRIORITY_VERYHIGH;
 
 	r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, bp->type,
 				 &bo->placement, page_align, &ctx, acc_size,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index 9291c2f837e9..091a7884a821 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -39,6 +39,7 @@  struct amdgpu_bo_param {
 	int				byte_align;
 	u32				domain;
 	u32				preferred_domain;
+	u32				priority;
 	u64				flags;
 	enum ttm_bo_type		type;
 	struct reservation_object	*resv;
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index cbf3180cb612..53f39ed540d7 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -43,7 +43,14 @@ 
 #include "ttm_placement.h"
 #include "ttm_tt.h"
 
-#define TTM_MAX_BO_PRIORITY	4U
+enum ttm_bo_priority {
+	TTM_BO_PRIORITY_VERYLOW = 0,
+	TTM_BO_PRIORITY_LOW,
+	TTM_BO_PRIORITY_NORMAL,
+	TTM_BO_PRIORITY_HIGH,
+	TTM_BO_PRIORITY_VERYHIGH,
+	TTM_MAX_BO_PRIORITY
+};
 
 #define TTM_MEMTYPE_FLAG_FIXED         (1 << 0)	/* Fixed (on-card) PCI memory */
 #define TTM_MEMTYPE_FLAG_MAPPABLE      (1 << 1)	/* Memory mappable */
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index b7718bfdf8ad..b74a7583d7f3 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -138,6 +138,9 @@  struct drm_amdgpu_gem_create_in  {
 	__u64 domains;
 	/** allocation flags */
 	__u64 domain_flags;
+	/** priority */
+	__u32 priority;
+	__u32 pad;
 };
 
 struct drm_amdgpu_gem_create_out  {

Comments

On 2019-03-07 10:15 a.m., Chunming Zhou wrote:
> Signed-off-by: Chunming Zhou <david1.zhou@amd.com>

Please provide corresponding UMD patches showing how this is to be used.


> @@ -229,6 +231,14 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
>  	if (args->in.domains & ~AMDGPU_GEM_DOMAIN_MASK)
>  		return -EINVAL;
>  
> +	/* check priority */
> +	if (args->in.priority == 0) {

Did you verify that this is 0 with old userspace compiled against struct
drm_amdgpu_gem_create_in without the priority field?


> +		/* default is normal */
> +		args->in.priority = TTM_BO_PRIORITY_NORMAL;
> +	} else if (args->in.priority > TTM_MAX_BO_PRIORITY) {
> +		args->in.priority = TTM_MAX_BO_PRIORITY;
> +		DRM_ERROR("priority specified from user space is over MAX priority\n");

This must be DRM_DEBUG, or buggy/malicious userspace can spam dmesg.


> @@ -252,6 +262,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
>  
>  	r = amdgpu_gem_object_create(adev, size, args->in.alignment,
>  				     (u32)(0xffffffff & args->in.domains),
> +				     args->in.priority - 1,
>  				     flags, ttm_bo_type_device, resv, &gobj);

It might be less confusing to subtract 1 after checking against
TTM_MAX_BO_PRIORITY instead of here. Still kind of confusing though. How
about this instead:

Make the priority field of struct drm_amdgpu_gem_create_in signed. In
amdgpu_gem_create_ioctl, clamp the priority to the supported range:

	args->in.priority += TTM_BO_PRIORITY_NORMAL;
	args->in.priority = max(args->in.priority, 0);
	args->in.priority = min(args->in.priority,
				TTM_BO_PRIORITY_NORMAL - 1);

This way userspace doesn't need to do a weird mapping of the priority
values (where 0 and 2 have the same meaning), and the range of supported
priorities could at least theoretically be extended without breaking
userspace.


> @@ -304,6 +315,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
>  
>  	/* create a gem object to contain this object in */
>  	r = amdgpu_gem_object_create(adev, args->size, 0, AMDGPU_GEM_DOMAIN_CPU,
> +				     TTM_BO_PRIORITY_NORMAL,
>  				     0, ttm_bo_type_device, NULL, &gobj);

Should the userptr ioctl also allow setting the priority?


> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index fd9c4beeaaa4..c85304e03021 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -494,8 +494,9 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
>  
>  	bo->tbo.bdev = &adev->mman.bdev;
>  	amdgpu_bo_placement_from_domain(bo, bp->domain);
> +	bo->tbo.priority = bp->priority;
>  	if (bp->type == ttm_bo_type_kernel)
> -		bo->tbo.priority = 1;
> +		bo->tbo.priority = TTM_BO_PRIORITY_VERYHIGH;

	if (bp->type == ttm_bo_type_kernel)
		bo->tbo.priority = TTM_BO_PRIORITY_VERYHIGH;
	else
		bo->tbo.priority = bp->priority;

would be clearer I think.

On 2019-03-07 11:48 a.m., zhoucm1 wrote:
> On 2019年03月07日 17:55, Michel Dänzer wrote:
>> On 2019-03-07 10:15 a.m., Chunming Zhou wrote:
>>> Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
>> Please provide corresponding UMD patches showing how this is to be used.
> spec is here:
> https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html,
> please search "|VkMemoryPriorityAllocateInfoEXT|".
> 
> Fortunately, Windows guy already implemented it before, otherwise, I
> cannot find ready code on opensource, I hate this chicken first and egg
> first question :

Whether you like it or not, the rule documented in
Documentation/gpu/drm-uapi.rst is clear: New UAPI cannot go upstream
before corresponding userspace patches have been reviewed. This is
important to avoid adding broken/unmaintainable UAPI.


> https://github.com/GPUOpen-Drivers/pal/blob/dev/src/core/gpuMemory.cpp,
> please search "createInfo.priority".
> https://github.com/GPUOpen-Drivers/pal/blob/dev/inc/core/palGpuMemory.h,
> priority definition is here.

These don't show how the priority field of struct
drm_amdgpu_gem_create_in is used.


>>> @@ -229,6 +231,14 @@ int amdgpu_gem_create_ioctl(struct drm_device
>>> *dev, void *data,
>>>       if (args->in.domains & ~AMDGPU_GEM_DOMAIN_MASK)
>>>           return -EINVAL;
>>>   +    /* check priority */
>>> +    if (args->in.priority == 0) {
>> Did you verify that this is 0 with old userspace compiled against struct
>> drm_amdgpu_gem_create_in without the priority field?
> Without priority field, I don't think we can check here. Do you mean we
> need to add a new args struct?

I don't think so. Presumably this will be initialized to 0 if userspace
doesn't pass in a value, but this needs to be verified.


>>> @@ -252,6 +262,7 @@ int amdgpu_gem_create_ioctl(struct drm_device
>>> *dev, void *data,
>>>         r = amdgpu_gem_object_create(adev, size, args->in.alignment,
>>>                        (u32)(0xffffffff & args->in.domains),
>>> +                     args->in.priority - 1,
>>>                        flags, ttm_bo_type_device, resv, &gobj);
>> It might be less confusing to subtract 1 after checking against
>> TTM_MAX_BO_PRIORITY instead of here. Still kind of confusing though. How
>> about this instead:
>>
>> Make the priority field of struct drm_amdgpu_gem_create_in signed. In
>> amdgpu_gem_create_ioctl, clamp the priority to the supported range:
>>
>>     args->in.priority += TTM_BO_PRIORITY_NORMAL;
>>     args->in.priority = max(args->in.priority, 0);
>>     args->in.priority = min(args->in.priority,
>>                 TTM_BO_PRIORITY_NORMAL - 1);
>>
>> This way userspace doesn't need to do a weird mapping of the priority
>> values (where 0 and 2 have the same meaning), and the range of supported
>> priorities could at least theoretically be extended without breaking
>> userspace.
> First, I want to explain a bit the priority value from vulkan:
> "    From Vulkan Spec, 0.0 <= value <= 1.0, and the granularity of the
> priorities is implementation-dependent.
>      One thing Spec forced is that if VkMemoryPriority not specified as
> default behavior, it is as if the
>      priority value is 0.5. Our strategy is that map 0.5 to
> GpuMemPriority::Normal-GpuMemPriorityOffset::Offset0,
>      which is consistent to MemoryPriorityDefault. We adopts
> GpuMemPriority::VeryLow, GpuMemPriority::Low,
>      GpuMemPriority::Normal, GpuMemPriority::High, 4 priority grades,
> each of which contains 8 steps of offests.
>      This maps [0.0-1.0) to totally 32 steps. Finally, 1.0 maps to
> GpuMemPriority::VeryHigh.
> "

In that case, I'd suggest making the priority field signed, and mapping
the full integer range to the range of supported priorities:

* 0 maps to TTM_BO_PRIORITY_NORMAL
* INT_MIN maps to TTM_BO_PRIORITY_VERYLOW
* INT_MAX maps to TTM_BO_PRIORITY_VERYHIGH

Intermediate values are interpolated appropriately to the supported
range of priorities.


This way, the Vulkan float priority value can easily be converted to the
integer priority value, and the actual range of priorities used on the
kernel side can be changed arbitrarily without breaking userspace.


> So my original purpose is directly use Priority enum defined in PAL,
> [...]

I don't think it's a good idea to let PAL dictate UAPI.


>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>> index fd9c4beeaaa4..c85304e03021 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>> @@ -494,8 +494,9 @@ static int amdgpu_bo_do_create(struct
>>> amdgpu_device *adev,
>>>         bo->tbo.bdev = &adev->mman.bdev;
>>>       amdgpu_bo_placement_from_domain(bo, bp->domain);
>>> +    bo->tbo.priority = bp->priority;
>>>       if (bp->type == ttm_bo_type_kernel)
>>> -        bo->tbo.priority = 1;
>>> +        bo->tbo.priority = TTM_BO_PRIORITY_VERYHIGH;
>>     if (bp->type == ttm_bo_type_kernel)
>>         bo->tbo.priority = TTM_BO_PRIORITY_VERYHIGH;
>>     else
>>         bo->tbo.priority = bp->priority;
>>
>> would be clearer I think.
> Agree.

Another question is whether userspace should be allowed to set the same
priority as the kernel? I'm inclined to say no, there should be a
separate priority for the kernel.
Am 07.03.19 um 10:15 schrieb Chunming Zhou:
> Signed-off-by: Chunming Zhou <david1.zhou@amd.com>

Well NAK to the whole approach.

The TTM priority is a global priority, but processes are only allowed to 
specific the priority inside their own allocations. So this approach 
will never fly upstream.

What you can do is to add a priority for per vm BOs to affect their sort 
order on the LRU, but I doubt that this will have much of an effect.

Regards,
Christian.

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c     |  1 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c    | 13 +++++++++++++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h    |  2 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.c |  3 ++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.h |  1 +
>   include/drm/ttm/ttm_bo_driver.h            |  9 ++++++++-
>   include/uapi/drm/amdgpu_drm.h              |  3 +++
>   7 files changed, 29 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> index 5cbde74b97dd..70a6baf20c22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> @@ -144,6 +144,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
>   	size = mode_cmd->pitches[0] * height;
>   	aligned_size = ALIGN(size, PAGE_SIZE);
>   	ret = amdgpu_gem_object_create(adev, aligned_size, 0, domain,
> +				       TTM_BO_PRIORITY_NORMAL,
>   				       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
>   				       AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS |
>   				       AMDGPU_GEM_CREATE_VRAM_CLEARED,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> index d21dd2f369da..7c1c2362c67e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> @@ -44,6 +44,7 @@ void amdgpu_gem_object_free(struct drm_gem_object *gobj)
>   
>   int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
>   			     int alignment, u32 initial_domain,
> +			     enum ttm_bo_priority priority,
>   			     u64 flags, enum ttm_bo_type type,
>   			     struct reservation_object *resv,
>   			     struct drm_gem_object **obj)
> @@ -60,6 +61,7 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
>   	bp.type = type;
>   	bp.resv = resv;
>   	bp.preferred_domain = initial_domain;
> +	bp.priority = priority;
>   retry:
>   	bp.flags = flags;
>   	bp.domain = initial_domain;
> @@ -229,6 +231,14 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
>   	if (args->in.domains & ~AMDGPU_GEM_DOMAIN_MASK)
>   		return -EINVAL;
>   
> +	/* check priority */
> +	if (args->in.priority == 0) {
> +		/* default is normal */
> +		args->in.priority = TTM_BO_PRIORITY_NORMAL;
> +	} else if (args->in.priority > TTM_MAX_BO_PRIORITY) {
> +		args->in.priority = TTM_MAX_BO_PRIORITY;
> +		DRM_ERROR("priority specified from user space is over MAX priority\n");
> +	}
>   	/* create a gem object to contain this object in */
>   	if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
>   	    AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
> @@ -252,6 +262,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
>   
>   	r = amdgpu_gem_object_create(adev, size, args->in.alignment,
>   				     (u32)(0xffffffff & args->in.domains),
> +				     args->in.priority - 1,
>   				     flags, ttm_bo_type_device, resv, &gobj);
>   	if (flags & AMDGPU_GEM_CREATE_VM_ALWAYS_VALID) {
>   		if (!r) {
> @@ -304,6 +315,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
>   
>   	/* create a gem object to contain this object in */
>   	r = amdgpu_gem_object_create(adev, args->size, 0, AMDGPU_GEM_DOMAIN_CPU,
> +				     TTM_BO_PRIORITY_NORMAL,
>   				     0, ttm_bo_type_device, NULL, &gobj);
>   	if (r)
>   		return r;
> @@ -755,6 +767,7 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
>   	domain = amdgpu_bo_get_preferred_pin_domain(adev,
>   				amdgpu_display_supported_domains(adev));
>   	r = amdgpu_gem_object_create(adev, args->size, 0, domain,
> +				     TTM_BO_PRIORITY_NORMAL,
>   				     AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
>   				     ttm_bo_type_device, NULL, &gobj);
>   	if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h
> index f1ddfc50bcc7..47b0a8190948 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.h
> @@ -61,7 +61,7 @@ extern const struct dma_buf_ops amdgpu_dmabuf_ops;
>    */
>   void amdgpu_gem_force_release(struct amdgpu_device *adev);
>   int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
> -			     int alignment, u32 initial_domain,
> +			     int alignment, u32 initial_domain, u32 priority,
>   			     u64 flags, enum ttm_bo_type type,
>   			     struct reservation_object *resv,
>   			     struct drm_gem_object **obj);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index fd9c4beeaaa4..c85304e03021 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -494,8 +494,9 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
>   
>   	bo->tbo.bdev = &adev->mman.bdev;
>   	amdgpu_bo_placement_from_domain(bo, bp->domain);
> +	bo->tbo.priority = bp->priority;
>   	if (bp->type == ttm_bo_type_kernel)
> -		bo->tbo.priority = 1;
> +		bo->tbo.priority = TTM_BO_PRIORITY_VERYHIGH;
>   
>   	r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, bp->type,
>   				 &bo->placement, page_align, &ctx, acc_size,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> index 9291c2f837e9..091a7884a821 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
> @@ -39,6 +39,7 @@ struct amdgpu_bo_param {
>   	int				byte_align;
>   	u32				domain;
>   	u32				preferred_domain;
> +	u32				priority;
>   	u64				flags;
>   	enum ttm_bo_type		type;
>   	struct reservation_object	*resv;
> diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
> index cbf3180cb612..53f39ed540d7 100644
> --- a/include/drm/ttm/ttm_bo_driver.h
> +++ b/include/drm/ttm/ttm_bo_driver.h
> @@ -43,7 +43,14 @@
>   #include "ttm_placement.h"
>   #include "ttm_tt.h"
>   
> -#define TTM_MAX_BO_PRIORITY	4U
> +enum ttm_bo_priority {
> +	TTM_BO_PRIORITY_VERYLOW = 0,
> +	TTM_BO_PRIORITY_LOW,
> +	TTM_BO_PRIORITY_NORMAL,
> +	TTM_BO_PRIORITY_HIGH,
> +	TTM_BO_PRIORITY_VERYHIGH,
> +	TTM_MAX_BO_PRIORITY
> +};
>   
>   #define TTM_MEMTYPE_FLAG_FIXED         (1 << 0)	/* Fixed (on-card) PCI memory */
>   #define TTM_MEMTYPE_FLAG_MAPPABLE      (1 << 1)	/* Memory mappable */
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index b7718bfdf8ad..b74a7583d7f3 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -138,6 +138,9 @@ struct drm_amdgpu_gem_create_in  {
>   	__u64 domains;
>   	/** allocation flags */
>   	__u64 domain_flags;
> +	/** priority */
> +	__u32 priority;
> +	__u32 pad;
>   };
>   
>   struct drm_amdgpu_gem_create_out  {