[PATCH] MAINTAINERS: Remove me from amdgpu maintainers

2020-05-06 Thread Chunming Zhou
Glad to spend time on kernel driver in past years.
I've moved to new focus in umd and couldn't commit
enough time to discussions.

Signed-off-by: Chunming Zhou 
---
 MAINTAINERS | 1 -
 1 file changed, 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 938316092634..4ca508bd4c9e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14066,7 +14066,6 @@ F:  drivers/net/wireless/quantenna
 RADEON and AMDGPU DRM DRIVERS
 M: Alex Deucher 
 M: Christian König 
-M: David (ChunMing) Zhou 
 L: amd-...@lists.freedesktop.org
 S: Supported
 T: git git://people.freedesktop.org/~agd5f/linux
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/ttm: Schedule out if possibe in bo delayed delete worker

2020-04-09 Thread Chunming Zhou

We can have both of yours, I think.

Even switch to use spin_trylock, I think we are ok to have 
cond_resched() Xinhui added in this patch. That can give more chance to 
urgent task to use cpu.



-David

在 2020/4/9 22:59, Christian König 写道:

Why we break out the loops when there are pending bos to be released?


We do this anyway if we can't acquire the necessary locks. Freeing 
already deleted BOs is just a very lazy background work.



So it did not break anything with this patch I think.


Oh, the patch will certainly work. I'm just not sure if it's the ideal 
behavior.



https://elixir.bootlin.com/linux/latest/source/mm/slab.c#L4026

This is another example of the usage of  cond_sched.


Yes, and that is also a good example of what I mean here:

	if  (!mutex_trylock 
(_mutex 
))

/* Give up. Setup the next iteration. */
goto  out;


If the function can't acquire the lock immediately it gives up and 
waits for the next iteration.


I think it would be better if we do this in TTM as well if we spend to 
much time cleaning up old BOs.


On the other hand you are right that cond_resched() has the advantage 
that we could spend more time on cleaning up old BOs if there is 
nothing else for the CPU TODO.


Regards,
Christian.

Am 09.04.20 um 16:24 schrieb Pan, Xinhui:

https://elixir.bootlin.com/linux/latest/source/mm/slab.c#L4026

This is another example of the usage of  cond_sched.

*From:* Pan, Xinhui 
*Sent:* Thursday, April 9, 2020 10:11:08 PM
*To:* Lucas Stach ; 
amd-...@lists.freedesktop.org ; 
Koenig, Christian 

*Cc:* dri-devel@lists.freedesktop.org 
*Subject:* Re: [PATCH] drm/ttm: Schedule out if possibe in bo delayed 
delete worker
I think it doesn't matter if workitem schedule out. Even we did not 
schedule out, the workqueue itself will schedule out later.

So it did not break anything with this patch I think.

*From:* Pan, Xinhui 
*Sent:* Thursday, April 9, 2020 10:07:09 PM
*To:* Lucas Stach ; 
amd-...@lists.freedesktop.org ; 
Koenig, Christian 

*Cc:* dri-devel@lists.freedesktop.org 
*Subject:* Re: [PATCH] drm/ttm: Schedule out if possibe in bo delayed 
delete worker

Why we break out the loops when there are pending bos to be released?

And I just checked the process_one_work. Right after the work item 
callback is called,  the workqueue itself will call cond_resched. So 
I think


*From:* Koenig, Christian 
*Sent:* Thursday, April 9, 2020 9:38:24 PM
*To:* Lucas Stach ; Pan, Xinhui 
; amd-...@lists.freedesktop.org 


*Cc:* dri-devel@lists.freedesktop.org 
*Subject:* Re: [PATCH] drm/ttm: Schedule out if possibe in bo delayed 
delete worker

Am 09.04.20 um 15:25 schrieb Lucas Stach:
> Am Donnerstag, den 09.04.2020, 14:35 +0200 schrieb Christian König:
>> Am 09.04.20 um 03:31 schrieb xinhui pan:
>>> The delayed delete list is per device which might be very huge. 
And in

>>> a heavy workload test, the list might always not be empty. That will
>>> trigger any RCU stall warnings or softlockups in non-preemptible 
kernels

>>> Lets do schedule out if possible in that case.
>> Mhm, I'm not sure if that is actually allowed. This is called from a
>> work item and those are not really supposed to be scheduled away.
> Huh? Workitems can schedule out just fine, otherwise they would be
> horribly broken when it comes to sleeping locks.

Let me refine the sentence: Work items are not really supposed to be
scheduled purposely. E.g. you shouldn't call schedule() or
cond_resched() like in the case here.

Getting scheduled away because we wait for a lock is of course perfectly
fine.

>   The workqueue code
> even has measures to keep the workqueues at the expected concurrency
> level by starting other workitems when one of them goes to sleep.

Yeah, and exactly that's what I would say we should avoid here :)

In other words work items can be scheduled away, but they should not if
not really necessary (e.g. waiting for a lock).

Otherwise as you said new threads for work item processing are started
up and I don't think we want that.

Just returning from the work item and waiting for the next cycle is most
likely the better option.

Regards,
Christian.

>
> 

Re: [PATCH] drm/syncobj: extend syncobj query ability v3

2019-10-24 Thread Chunming Zhou

在 2019/10/24 4:21, Sean Paul 写道:
> On Tue, Jul 30, 2019 at 9:22 AM Chunming Zhou  wrote:
>>
>> 在 2019/7/30 21:17, Koenig, Christian 写道:
>>> Am 30.07.19 um 15:02 schrieb Chunming Zhou:
>>>> user space needs a flexiable query ability.
>>>> So that umd can get last signaled or submitted point.
>>>> v2:
>>>> add sanitizer checking.
>>>> v3:
>>>> rebase
>>>>
>>>> Change-Id: I6512b430524ebabe715e602a2bf5abb0a7e780ea
>>>> Signed-off-by: Chunming Zhou 
>>>> Cc: Lionel Landwerlin 
>>>> Cc: Christian König 
>>>> Reviewed-by: Lionel Landwerlin 
>>> Reviewed-by: Christian König 
>>>
>>> Lionel is the Intel code using this already public? Or David any chance
>>> that we can get a public amdvlk release using this?
>> In latest public amdvlk, We should be able to see how timeline syncobj
>> is used in it.
>>
> I couldn't find this anywhere, could you please provide a link?

https://github.com/GPUOpen-Drivers/xgl/blob/dev/icd/api/vk_semaphore.cpp

You can check the source here.


Cheers,

-David

>
> Sean
>
>> -David
>>
>>> Christian.
>>>
>>>> ---
>>>> drivers/gpu/drm/drm_syncobj.c | 37 +--
>>>> include/uapi/drm/drm.h|  3 ++-
>>>> 2 files changed, 24 insertions(+), 16 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
>>>> index cecff2e447b1..d4432f1513ac 100644
>>>> --- a/drivers/gpu/drm/drm_syncobj.c
>>>> +++ b/drivers/gpu/drm/drm_syncobj.c
>>>> @@ -1197,7 +1197,7 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device 
>>>> *dev, void *data,
>>>>   if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
>>>>   return -EOPNOTSUPP;
>>>>
>>>> -if (args->pad != 0)
>>>> +if (args->flags != 0)
>>>>   return -EINVAL;
>>>>
>>>>   if (args->count_handles == 0)
>>>> @@ -1268,7 +1268,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, 
>>>> void *data,
>>>>   if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
>>>>   return -EOPNOTSUPP;
>>>>
>>>> -if (args->pad != 0)
>>>> +if (args->flags & ~DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED)
>>>>   return -EINVAL;
>>>>
>>>>   if (args->count_handles == 0)
>>>> @@ -1289,25 +1289,32 @@ int drm_syncobj_query_ioctl(struct drm_device 
>>>> *dev, void *data,
>>>>   fence = drm_syncobj_fence_get(syncobjs[i]);
>>>>   chain = to_dma_fence_chain(fence);
>>>>   if (chain) {
>>>> -struct dma_fence *iter, *last_signaled = NULL;
>>>> -
>>>> -dma_fence_chain_for_each(iter, fence) {
>>>> -if (iter->context != fence->context) {
>>>> -dma_fence_put(iter);
>>>> -/* It is most likely that timeline has
>>>> - * unorder points. */
>>>> -break;
>>>> +struct dma_fence *iter, *last_signaled =
>>>> +dma_fence_get(fence);
>>>> +
>>>> +if (args->flags &
>>>> +DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED) {
>>>> +point = fence->seqno;
>>>> +} else {
>>>> +dma_fence_chain_for_each(iter, fence) {
>>>> +if (iter->context != fence->context) {
>>>> +dma_fence_put(iter);
>>>> +/* It is most likely that 
>>>> timeline has
>>>> +* unorder points. */
>>>> +break;
>>>> +}
>>>> +dma_fence_put(last_signaled);
>>>> +last_signaled = dma_fence_get(iter);
>>>>   }
>>>> -

Re: [PATCH v3 1/1] drm/syncobj: add sideband payload

2019-08-08 Thread Chunming Zhou

在 2019/8/8 22:34, Lionel Landwerlin 写道:
> On 08/08/2019 17:16, Chunming Zhou wrote:
>> 在 2019/8/8 22:01, Lionel Landwerlin 写道:
>>> On 08/08/2019 16:42, Chunming Zhou wrote:
>>>> No, I just see your comment "The next vkQueueSubmit()
>>>> waiting on a the syncobj will read the sideband payload and wait for a
>>>> fence chain element with a seqno superior or equal to the sideband
>>>> payload value to be added into the fence chain and use that fence to
>>>> trigger the submission on the kernel driver. ".
>>>
>>> That was meant to say wait on the chain fence to reach the sideband
>>> payload value.
>>>
>>> It a bit confusing but I can't see any other way to word it.
>>>
>>>
>>>> In that, you mentioned wait for sideband.
>>>> So I want to know we how to use that, maybe I miss something in 
>>>> previous
>>>> discussing thread.
>>>
>>> In QueueSubmit(), we start by reading the sideband payloads :
>>> https://gitlab.freedesktop.org/llandwerlin/mesa/blob/review/anv-timeline_semaphore_prep/src/intel/vulkan/anv_queue.c#L655
>>>  
>>>
>>>
>>> Then build everything for the submission and hand it over to the
>>> submission thread.
>>>
>>> Instead of the just waiting on the timeline semaphore values, we also
>>> wait on the binary semaphore sideband payload values.
>> Waiting on timeline values is when finding fence in kernel.
>
>
> Hmm aren't you waiting in a thread in userspace?

Yes, For timeline case, we can use waitForSyncobj()..., At begin of 
QueueThread, I let it wait in cs_ioctl when drm_syncobj_find_fence.

But I still didn't get how to wait on sideband for binary Syncobj.

Ah, I see, you will compare it in your QueueThread, if sideband value is 
 >= expected, then do submission, otherwise, loop QueueThread, right?

That sounds the QueueThread will be always busy.

-David


>
>
>>
>> But I don't see how to wait/block in kernel when finding fence for
>> binary sideband payload  values.
>
>
> Essentially our driver now handles timelines & binary semaphore using 
> dma-fence-chain in both cases.



>
> Only with timelines we take the values submitted by the vulkan 
> application.


>
> The binary semaphore auto increment on vkQueueSubmit() and that is 
> managed by the userspace driver.
>
>
> -Lionel
>
>
>>
>>
>> -David
>>
>>> Finally before exiting the QueueSubmit() call, we bump the sideband
>>> payloads of all the binary semaphores have have been signaled :
>>> https://gitlab.freedesktop.org/llandwerlin/mesa/blob/review/anv-timeline_semaphore_prep/src/intel/vulkan/anv_queue.c#L806
>>>  
>>>
>>>
>>>
>>> Whoever calls QueueSubmit() after that will pickup the new sideband
>>> payload values to wait on.
>>>
>>>
>>> -Lionel
>>>
>>>
>>>
>>>> -DAvid
>>>>
>>>>
>>>> 在 2019/8/8 21:38, Lionel Landwerlin 写道:
>>>>> Interesting question :)
>>>>>
>>>>> I didn't see any usecase for that.
>>>>> This sideband payload value is used for a wait so waiting on the wait
>>>>> value for another wait is bit meta :)
>>>>>
>>>>> Do you have a use case for that?
>>>>>
>>>>> -Lionel
>>>>>
>>>>> On 08/08/2019 16:23, Chunming Zhou wrote:
>>>>>> The propursal is fine with me.
>>>>>>
>>>>>> one question:
>>>>>>
>>>>>> how to wait sideband payload? Following patch will show that?
>>>>>>
>>>>>> -David
>>>>>>
>>>>>> 在 2019/8/8 21:14, Lionel Landwerlin 写道:
>>>>>>> The Vulkan timeline semaphores allow signaling to happen on the 
>>>>>>> point
>>>>>>> of the timeline without all of the its dependencies to be created.
>>>>>>>
>>>>>>> The current 2 implementations (AMD/Intel) of the Vulkan spec on
>>>>>>> top of
>>>>>>> the Linux kernel are using a thread to wait on the dependencies 
>>>>>>> of a
>>>>>>> given point to materialize and delay actual submission to the 
>>>>>>> kernel
>>>>>>> driver until the wait completes.
>>>>>>>
>>>>>>> If a binary semaphore is 

Re: [PATCH v3 1/1] drm/syncobj: add sideband payload

2019-08-08 Thread Chunming Zhou

在 2019/8/8 22:01, Lionel Landwerlin 写道:
> On 08/08/2019 16:42, Chunming Zhou wrote:
>> No, I just see your comment "The next vkQueueSubmit()
>> waiting on a the syncobj will read the sideband payload and wait for a
>> fence chain element with a seqno superior or equal to the sideband
>> payload value to be added into the fence chain and use that fence to
>> trigger the submission on the kernel driver. ".
>
>
> That was meant to say wait on the chain fence to reach the sideband 
> payload value.
>
> It a bit confusing but I can't see any other way to word it.
>
>
>> In that, you mentioned wait for sideband.
>> So I want to know we how to use that, maybe I miss something in previous
>> discussing thread.
>
>
> In QueueSubmit(), we start by reading the sideband payloads : 
> https://gitlab.freedesktop.org/llandwerlin/mesa/blob/review/anv-timeline_semaphore_prep/src/intel/vulkan/anv_queue.c#L655
>
> Then build everything for the submission and hand it over to the 
> submission thread.
>
> Instead of the just waiting on the timeline semaphore values, we also 
> wait on the binary semaphore sideband payload values.

Waiting on timeline values is when finding fence in kernel.

But I don't see how to wait/block in kernel when finding fence for 
binary sideband payload  values.


-David

>
> Finally before exiting the QueueSubmit() call, we bump the sideband 
> payloads of all the binary semaphores have have been signaled : 
> https://gitlab.freedesktop.org/llandwerlin/mesa/blob/review/anv-timeline_semaphore_prep/src/intel/vulkan/anv_queue.c#L806
>
>
> Whoever calls QueueSubmit() after that will pickup the new sideband 
> payload values to wait on.
>
>
> -Lionel
>
>
>
>>
>> -DAvid
>>
>>
>> 在 2019/8/8 21:38, Lionel Landwerlin 写道:
>>> Interesting question :)
>>>
>>> I didn't see any usecase for that.
>>> This sideband payload value is used for a wait so waiting on the wait
>>> value for another wait is bit meta :)
>>>
>>> Do you have a use case for that?
>>>
>>> -Lionel
>>>
>>> On 08/08/2019 16:23, Chunming Zhou wrote:
>>>> The propursal is fine with me.
>>>>
>>>> one question:
>>>>
>>>> how to wait sideband payload? Following patch will show that?
>>>>
>>>> -David
>>>>
>>>> 在 2019/8/8 21:14, Lionel Landwerlin 写道:
>>>>> The Vulkan timeline semaphores allow signaling to happen on the point
>>>>> of the timeline without all of the its dependencies to be created.
>>>>>
>>>>> The current 2 implementations (AMD/Intel) of the Vulkan spec on 
>>>>> top of
>>>>> the Linux kernel are using a thread to wait on the dependencies of a
>>>>> given point to materialize and delay actual submission to the kernel
>>>>> driver until the wait completes.
>>>>>
>>>>> If a binary semaphore is submitted for signaling along the side of a
>>>>> timeline semaphore waiting for completion that means that the drm
>>>>> syncobj associated with that binary semaphore will not have a DMA
>>>>> fence associated with it by the time vkQueueSubmit() returns. This 
>>>>> and
>>>>> the fact that a binary semaphore can be signaled and unsignaled as
>>>>> before its DMA fences materialize mean that we cannot just rely on 
>>>>> the
>>>>> fence within the syncobj but we also need a sideband payload 
>>>>> verifying
>>>>> that the fence in the syncobj matches the last submission from the
>>>>> Vulkan API point of view.
>>>>>
>>>>> This change adds a sideband payload that is incremented with signaled
>>>>> syncobj when vkQueueSubmit() is called. The next vkQueueSubmit()
>>>>> waiting on a the syncobj will read the sideband payload and wait 
>>>>> for a
>>>>> fence chain element with a seqno superior or equal to the sideband
>>>>> payload value to be added into the fence chain and use that fence to
>>>>> trigger the submission on the kernel driver.
>>>>>
>>>>> v2: Use a separate ioctl to get/set the sideband value (Christian)
>>>>>
>>>>> v3: Use 2 ioctls for get/set (Christian)
>>>>>
>>>>> Signed-off-by: Lionel Landwerlin 
>>>>> Cc: Christian Koenig 
>>>>> Cc: Jason Ekstrand 
>>>>> Cc: David(ChunMing) Zhou 
>

Re: [PATCH v3 1/1] drm/syncobj: add sideband payload

2019-08-08 Thread Chunming Zhou
No, I just see your comment "The next vkQueueSubmit()
waiting on a the syncobj will read the sideband payload and wait for a
fence chain element with a seqno superior or equal to the sideband
payload value to be added into the fence chain and use that fence to
trigger the submission on the kernel driver. ".

In that, you mentioned wait for sideband.
So I want to know we how to use that, maybe I miss something in previous 
discussing thread.

-DAvid


在 2019/8/8 21:38, Lionel Landwerlin 写道:
> Interesting question :)
>
> I didn't see any usecase for that.
> This sideband payload value is used for a wait so waiting on the wait 
> value for another wait is bit meta :)
>
> Do you have a use case for that?
>
> -Lionel
>
> On 08/08/2019 16:23, Chunming Zhou wrote:
>> The propursal is fine with me.
>>
>> one question:
>>
>> how to wait sideband payload? Following patch will show that?
>>
>> -David
>>
>> 在 2019/8/8 21:14, Lionel Landwerlin 写道:
>>> The Vulkan timeline semaphores allow signaling to happen on the point
>>> of the timeline without all of the its dependencies to be created.
>>>
>>> The current 2 implementations (AMD/Intel) of the Vulkan spec on top of
>>> the Linux kernel are using a thread to wait on the dependencies of a
>>> given point to materialize and delay actual submission to the kernel
>>> driver until the wait completes.
>>>
>>> If a binary semaphore is submitted for signaling along the side of a
>>> timeline semaphore waiting for completion that means that the drm
>>> syncobj associated with that binary semaphore will not have a DMA
>>> fence associated with it by the time vkQueueSubmit() returns. This and
>>> the fact that a binary semaphore can be signaled and unsignaled as
>>> before its DMA fences materialize mean that we cannot just rely on the
>>> fence within the syncobj but we also need a sideband payload verifying
>>> that the fence in the syncobj matches the last submission from the
>>> Vulkan API point of view.
>>>
>>> This change adds a sideband payload that is incremented with signaled
>>> syncobj when vkQueueSubmit() is called. The next vkQueueSubmit()
>>> waiting on a the syncobj will read the sideband payload and wait for a
>>> fence chain element with a seqno superior or equal to the sideband
>>> payload value to be added into the fence chain and use that fence to
>>> trigger the submission on the kernel driver.
>>>
>>> v2: Use a separate ioctl to get/set the sideband value (Christian)
>>>
>>> v3: Use 2 ioctls for get/set (Christian)
>>>
>>> Signed-off-by: Lionel Landwerlin 
>>> Cc: Christian Koenig 
>>> Cc: Jason Ekstrand 
>>> Cc: David(ChunMing) Zhou 
>>> ---
>>>    drivers/gpu/drm/drm_internal.h |  4 ++
>>>    drivers/gpu/drm/drm_ioctl.c    |  5 +++
>>>    drivers/gpu/drm/drm_syncobj.c  | 79 
>>> +-
>>>    include/drm/drm_syncobj.h  |  9 
>>>    include/uapi/drm/drm.h |  2 +
>>>    5 files changed, 98 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_internal.h 
>>> b/drivers/gpu/drm/drm_internal.h
>>> index 51a2055c8f18..0c9736199df0 100644
>>> --- a/drivers/gpu/drm/drm_internal.h
>>> +++ b/drivers/gpu/drm/drm_internal.h
>>> @@ -208,6 +208,10 @@ int drm_syncobj_timeline_signal_ioctl(struct 
>>> drm_device *dev, void *data,
>>>  struct drm_file *file_private);
>>>    int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
>>>    struct drm_file *file_private);
>>> +int drm_syncobj_get_sideband_ioctl(struct drm_device *dev, void *data,
>>> +   struct drm_file *file_private);
>>> +int drm_syncobj_set_sideband_ioctl(struct drm_device *dev, void *data,
>>> +   struct drm_file *file_private);
>>>       /* drm_framebuffer.c */
>>>    void drm_framebuffer_print_info(struct drm_printer *p, unsigned 
>>> int indent,
>>> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
>>> index f675a3bb2c88..48500bf62801 100644
>>> --- a/drivers/gpu/drm/drm_ioctl.c
>>> +++ b/drivers/gpu/drm/drm_ioctl.c
>>> @@ -703,6 +703,11 @@ static const struct drm_ioctl_desc drm_ioctls[] 
>>> = {
>>>  DRM_RENDER_ALLOW),
>>>    DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
>>>  DRM_RENDER_ALLOW),

Re: [PATCH v3 1/1] drm/syncobj: add sideband payload

2019-08-08 Thread Chunming Zhou
The propursal is fine with me.

one question:

how to wait sideband payload? Following patch will show that?

-David

在 2019/8/8 21:14, Lionel Landwerlin 写道:
> The Vulkan timeline semaphores allow signaling to happen on the point
> of the timeline without all of the its dependencies to be created.
>
> The current 2 implementations (AMD/Intel) of the Vulkan spec on top of
> the Linux kernel are using a thread to wait on the dependencies of a
> given point to materialize and delay actual submission to the kernel
> driver until the wait completes.
>
> If a binary semaphore is submitted for signaling along the side of a
> timeline semaphore waiting for completion that means that the drm
> syncobj associated with that binary semaphore will not have a DMA
> fence associated with it by the time vkQueueSubmit() returns. This and
> the fact that a binary semaphore can be signaled and unsignaled as
> before its DMA fences materialize mean that we cannot just rely on the
> fence within the syncobj but we also need a sideband payload verifying
> that the fence in the syncobj matches the last submission from the
> Vulkan API point of view.
>
> This change adds a sideband payload that is incremented with signaled
> syncobj when vkQueueSubmit() is called. The next vkQueueSubmit()
> waiting on a the syncobj will read the sideband payload and wait for a
> fence chain element with a seqno superior or equal to the sideband
> payload value to be added into the fence chain and use that fence to
> trigger the submission on the kernel driver.
>
> v2: Use a separate ioctl to get/set the sideband value (Christian)
>
> v3: Use 2 ioctls for get/set (Christian)
>
> Signed-off-by: Lionel Landwerlin 
> Cc: Christian Koenig 
> Cc: Jason Ekstrand 
> Cc: David(ChunMing) Zhou 
> ---
>   drivers/gpu/drm/drm_internal.h |  4 ++
>   drivers/gpu/drm/drm_ioctl.c|  5 +++
>   drivers/gpu/drm/drm_syncobj.c  | 79 +-
>   include/drm/drm_syncobj.h  |  9 
>   include/uapi/drm/drm.h |  2 +
>   5 files changed, 98 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index 51a2055c8f18..0c9736199df0 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -208,6 +208,10 @@ int drm_syncobj_timeline_signal_ioctl(struct drm_device 
> *dev, void *data,
> struct drm_file *file_private);
>   int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
>   struct drm_file *file_private);
> +int drm_syncobj_get_sideband_ioctl(struct drm_device *dev, void *data,
> +struct drm_file *file_private);
> +int drm_syncobj_set_sideband_ioctl(struct drm_device *dev, void *data,
> +struct drm_file *file_private);
>   
>   /* drm_framebuffer.c */
>   void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index f675a3bb2c88..48500bf62801 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -703,6 +703,11 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
> DRM_RENDER_ALLOW),
>   DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
> DRM_RENDER_ALLOW),
> + DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_GET_SIDEBAND, 
> drm_syncobj_get_sideband_ioctl,
> +   DRM_RENDER_ALLOW),
> + DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SET_SIDEBAND, 
> drm_syncobj_set_sideband_ioctl,
> +   DRM_RENDER_ALLOW),
> +
>   DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, 
> 0),
>   DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, 
> drm_crtc_queue_sequence_ioctl, 0),
>   DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, 
> DRM_MASTER),
> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
> index b927e482e554..c90ef20b9242 100644
> --- a/drivers/gpu/drm/drm_syncobj.c
> +++ b/drivers/gpu/drm/drm_syncobj.c
> @@ -1150,8 +1150,10 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void 
> *data,
>   if (ret < 0)
>   return ret;
>   
> - for (i = 0; i < args->count_handles; i++)
> + for (i = 0; i < args->count_handles; i++) {
>   drm_syncobj_replace_fence(syncobjs[i], NULL);
> + syncobjs[i]->sideband_payload = 0;
> + }
>   
>   drm_syncobj_array_free(syncobjs, args->count_handles);
>   
> @@ -1321,6 +1323,81 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, 
> void *data,
> 

Re: [PATCH] drm/syncobj: extend syncobj query ability v3

2019-07-30 Thread Chunming Zhou

在 2019/7/30 21:17, Koenig, Christian 写道:
> Am 30.07.19 um 15:02 schrieb Chunming Zhou:
>> user space needs a flexiable query ability.
>> So that umd can get last signaled or submitted point.
>> v2:
>> add sanitizer checking.
>> v3:
>> rebase
>>
>> Change-Id: I6512b430524ebabe715e602a2bf5abb0a7e780ea
>> Signed-off-by: Chunming Zhou 
>> Cc: Lionel Landwerlin 
>> Cc: Christian König 
>> Reviewed-by: Lionel Landwerlin 
> Reviewed-by: Christian König 
>
> Lionel is the Intel code using this already public? Or David any chance
> that we can get a public amdvlk release using this?

In latest public amdvlk, We should be able to see how timeline syncobj 
is used in it.


-David

>
> Christian.
>
>> ---
>>drivers/gpu/drm/drm_syncobj.c | 37 +--
>>include/uapi/drm/drm.h|  3 ++-
>>2 files changed, 24 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
>> index cecff2e447b1..d4432f1513ac 100644
>> --- a/drivers/gpu/drm/drm_syncobj.c
>> +++ b/drivers/gpu/drm/drm_syncobj.c
>> @@ -1197,7 +1197,7 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device 
>> *dev, void *data,
>>  if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
>>  return -EOPNOTSUPP;
>>
>> -if (args->pad != 0)
>> +if (args->flags != 0)
>>  return -EINVAL;
>>
>>  if (args->count_handles == 0)
>> @@ -1268,7 +1268,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, 
>> void *data,
>>  if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
>>  return -EOPNOTSUPP;
>>
>> -if (args->pad != 0)
>> +if (args->flags & ~DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED)
>>  return -EINVAL;
>>
>>  if (args->count_handles == 0)
>> @@ -1289,25 +1289,32 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, 
>> void *data,
>>  fence = drm_syncobj_fence_get(syncobjs[i]);
>>  chain = to_dma_fence_chain(fence);
>>  if (chain) {
>> -struct dma_fence *iter, *last_signaled = NULL;
>> -
>> -dma_fence_chain_for_each(iter, fence) {
>> -if (iter->context != fence->context) {
>> -dma_fence_put(iter);
>> -/* It is most likely that timeline has
>> - * unorder points. */
>> -break;
>> +struct dma_fence *iter, *last_signaled =
>> +dma_fence_get(fence);
>> +
>> +if (args->flags &
>> +DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED) {
>> +point = fence->seqno;
>> +} else {
>> +dma_fence_chain_for_each(iter, fence) {
>> +if (iter->context != fence->context) {
>> +dma_fence_put(iter);
>> +/* It is most likely that 
>> timeline has
>> +* unorder points. */
>> +break;
>> +}
>> +dma_fence_put(last_signaled);
>> +last_signaled = dma_fence_get(iter);
>>  }
>> -dma_fence_put(last_signaled);
>> -last_signaled = dma_fence_get(iter);
>> +point = dma_fence_is_signaled(last_signaled) ?
>> +last_signaled->seqno :
>> +
>> to_dma_fence_chain(last_signaled)->prev_seqno;
>>  }
>> -point = dma_fence_is_signaled(last_signaled) ?
>> -last_signaled->seqno :
>> -to_dma_fence_chain(last_signaled)->prev_seqno;
>>  dma_fence_put(last_signaled);
>>  } else {
>>  point = 0;
>>  }
>> +dma_fence_put(fence);
>>  ret = copy_to_user([i], , sizeof(uint64_t));
>>  ret = ret ? -EFAULT : 0;
>>  if (ret)
&g

[PATCH] drm/syncobj: extend syncobj query ability v3

2019-07-30 Thread Chunming Zhou
user space needs a flexiable query ability.
So that umd can get last signaled or submitted point.
v2:
add sanitizer checking.
v3:
rebase

Change-Id: I6512b430524ebabe715e602a2bf5abb0a7e780ea
Signed-off-by: Chunming Zhou 
Cc: Lionel Landwerlin 
Cc: Christian König 
Reviewed-by: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_syncobj.c | 37 +--
 include/uapi/drm/drm.h|  3 ++-
 2 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index cecff2e447b1..d4432f1513ac 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1197,7 +1197,7 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, 
void *data,
if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
return -EOPNOTSUPP;
 
-   if (args->pad != 0)
+   if (args->flags != 0)
return -EINVAL;
 
if (args->count_handles == 0)
@@ -1268,7 +1268,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void 
*data,
if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
return -EOPNOTSUPP;
 
-   if (args->pad != 0)
+   if (args->flags & ~DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED)
return -EINVAL;
 
if (args->count_handles == 0)
@@ -1289,25 +1289,32 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, 
void *data,
fence = drm_syncobj_fence_get(syncobjs[i]);
chain = to_dma_fence_chain(fence);
if (chain) {
-   struct dma_fence *iter, *last_signaled = NULL;
-
-   dma_fence_chain_for_each(iter, fence) {
-   if (iter->context != fence->context) {
-   dma_fence_put(iter);
-   /* It is most likely that timeline has
-* unorder points. */
-   break;
+   struct dma_fence *iter, *last_signaled =
+   dma_fence_get(fence);
+
+   if (args->flags &
+   DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED) {
+   point = fence->seqno;
+   } else {
+   dma_fence_chain_for_each(iter, fence) {
+   if (iter->context != fence->context) {
+   dma_fence_put(iter);
+   /* It is most likely that 
timeline has
+   * unorder points. */
+   break;
+   }
+   dma_fence_put(last_signaled);
+   last_signaled = dma_fence_get(iter);
}
-   dma_fence_put(last_signaled);
-   last_signaled = dma_fence_get(iter);
+   point = dma_fence_is_signaled(last_signaled) ?
+   last_signaled->seqno :
+   
to_dma_fence_chain(last_signaled)->prev_seqno;
}
-   point = dma_fence_is_signaled(last_signaled) ?
-   last_signaled->seqno :
-   to_dma_fence_chain(last_signaled)->prev_seqno;
dma_fence_put(last_signaled);
} else {
point = 0;
}
+   dma_fence_put(fence);
ret = copy_to_user([i], , sizeof(uint64_t));
ret = ret ? -EFAULT : 0;
if (ret)
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 661d73f9a919..fd987ce24d9f 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -777,11 +777,12 @@ struct drm_syncobj_array {
__u32 pad;
 };
 
+#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available 
point on timeline syncobj */
 struct drm_syncobj_timeline_array {
__u64 handles;
__u64 points;
__u32 count_handles;
-   __u32 pad;
+   __u32 flags;
 };
 
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH] drm/syncobj: remove boring message

2019-07-29 Thread Chunming Zhou
It is normal that binary syncobj replaces the underlying fence.

Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/drm_syncobj.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 929f7c64f9a2..bc7ec1679e4d 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -151,9 +151,6 @@ void drm_syncobj_add_point(struct drm_syncobj *syncobj,
spin_lock(>lock);
 
prev = drm_syncobj_fence_get(syncobj);
-   /* You are adding an unorder point to timeline, which could cause 
payload returned from query_ioctl is 0! */
-   if (prev && prev->seqno >= point)
-   DRM_ERROR("You are adding an unorder point to timeline!\n");
dma_fence_chain_init(chain, prev, fence, point);
rcu_assign_pointer(syncobj->fence, >base);
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/syncobj: extend syncobj query ability v2

2019-07-25 Thread Chunming Zhou

在 2019/7/25 20:21, Daniel Vetter 写道:
> On Wed, Jul 24, 2019 at 07:48:23AM +, Koenig, Christian wrote:
>> Am 24.07.19 um 08:32 schrieb zhoucm1:
>>>
>>> On 2019年07月24日 03:20, Lionel Landwerlin wrote:
>>>> On 23/07/2019 17:21, Chunming Zhou wrote:
>>>>> user space needs a flexiable query ability.
>>>>> So that umd can get last signaled or submitted point.
>>>>> v2:
>>>>> add sanitizer checking.
>>>>>
>>>>> Change-Id: I6512b430524ebabe715e602a2bf5abb0a7e780ea
>>>>> Signed-off-by: Chunming Zhou 
>>>>> Cc: Lionel Landwerlin 
>>>>> Cc: Christian König 
>>>> Reviewed-by: Lionel Landwerlin 
>>> Thanks.
>>> Which branch should this patch go to?
>>> Is it OK to push to amd-staging-drm-next?
>>> Or should it go to drm-misc?
>>> If drm-misc, I need your help to push it since I have no permission to
>>> write.
>> drm-misc-next is probably more appropriated.
>>
>> I'm going to take of that, but first let me push my fix now.
> btw we once discussed to hide the syncobj stuff until the userspace side
> is public too. Not seeing that merged anywhere. Can you pls take care of
> this?
>
> I'm not against developing new uapi in upstream, that's occasionally just
> the most reasonable thing to do here. But we are quite badly flaunting the
> entire "needs open source consumer in userspace" rule here ...

Hi Daniel,

I got your means. The enablement feature flag is already removed from 
drm-misc, so it shouldn't have other effect.

If only amd driver stuff and only amd uses that, we can flexiblely deal 
with that.

Since syncobj is moved to drm level, we are working here. I think you 
should already see that timeline syncobj is also used by Intel ANV, and 
Lionel is co-working with us. If we hide these stuff, how do we know who 
is working on that? How do we share one same implementation? Where 
should we discuss? everyone implements own's desgin behind?

-David

> -Daniel
>
>> Christian.
>>
>>> -David
>>>>> ---
>>>>>    drivers/gpu/drm/drm_syncobj.c | 34 --
>>>>>    include/uapi/drm/drm.h    |  3 ++-
>>>>>    2 files changed, 22 insertions(+), 15 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/drm_syncobj.c
>>>>> b/drivers/gpu/drm/drm_syncobj.c
>>>>> index 3d400905100b..3fc8f66ada68 100644
>>>>> --- a/drivers/gpu/drm/drm_syncobj.c
>>>>> +++ b/drivers/gpu/drm/drm_syncobj.c
>>>>> @@ -1197,7 +1197,7 @@ drm_syncobj_timeline_signal_ioctl(struct
>>>>> drm_device *dev, void *data,
>>>>>    if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
>>>>>    return -EOPNOTSUPP;
>>>>>    -    if (args->pad != 0)
>>>>> +    if (args->flags != 0)
>>>>>    return -EINVAL;
>>>>>      if (args->count_handles == 0)
>>>>> @@ -1268,7 +1268,7 @@ int drm_syncobj_query_ioctl(struct drm_device
>>>>> *dev, void *data,
>>>>>    if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
>>>>>    return -EOPNOTSUPP;
>>>>>    -    if (args->pad != 0)
>>>>> +    if (args->flags & ~DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED)
>>>>>    return -EINVAL;
>>>>>      if (args->count_handles == 0)
>>>>> @@ -1291,23 +1291,29 @@ int drm_syncobj_query_ioctl(struct
>>>>> drm_device *dev, void *data,
>>>>>    if (chain) {
>>>>>    struct dma_fence *iter, *last_signaled = NULL;
>>>>>    -    dma_fence_chain_for_each(iter, fence) {
>>>>> -    if (!iter)
>>>>> -    break;
>>>>> -    dma_fence_put(last_signaled);
>>>>> -    last_signaled = dma_fence_get(iter);
>>>>> -    if (!to_dma_fence_chain(last_signaled)->prev_seqno)
>>>>> -    /* It is most likely that timeline has
>>>>> - * unorder points. */
>>>>> -    break;
>>>>> +    if (args->flags &
>>>>> +    DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED) {
>>>>> +    point = fence->seqno;
>>>>> +    } else {
>>>>> +    dma_fence_chain_for_eac

[PATCH libdrm] libdrm: wrap new flexible syncobj query interface v2

2019-07-25 Thread Chunming Zhou
v2: nit-picks fix

Signed-off-by: Chunming Zhou 
Cc: Lionel Landwerlin 
Cc: Christian König 
Reviewed-by: Christian König 
For the xf86drm.[ch] part : Reviewed-by: Lionel Landwerlin 

---
 amdgpu/amdgpu-symbol-check |  1 +
 amdgpu/amdgpu.h| 18 ++
 amdgpu/amdgpu_cs.c | 10 ++
 include/drm/drm.h  |  3 ++-
 xf86drm.c  | 15 +++
 xf86drm.h  |  2 ++
 6 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 274b4c6d..597a99b2 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -56,6 +56,7 @@ amdgpu_cs_syncobj_export_sync_file2
 amdgpu_cs_syncobj_import_sync_file
 amdgpu_cs_syncobj_import_sync_file2
 amdgpu_cs_syncobj_query
+amdgpu_cs_syncobj_query2
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
 amdgpu_cs_syncobj_timeline_signal
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 9d9b0832..19f74bd6 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1591,6 +1591,24 @@ int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle 
dev,
 int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
uint32_t *handles, uint64_t *points,
unsigned num_handles);
+/**
+ *  Query sync objects last signaled or submitted point.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [out] array of sync points returned, which presents
+ * syncobj payload.
+ * \param   num_handles - \c [in] self-explanatory
+ * \param   flags   - \c [in] a bitmask of DRM_SYNCOBJ_QUERY_FLAGS_*
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_query2(amdgpu_device_handle dev,
+uint32_t *handles, uint64_t *points,
+unsigned num_handles, uint32_t flags);
 
 /**
  *  Export kernel sync object to shareable fd.
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 977fa3cf..01e2b2c8 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -721,6 +721,16 @@ drm_public int 
amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
return drmSyncobjQuery(dev->fd, handles, points, num_handles);
 }
 
+drm_public int amdgpu_cs_syncobj_query2(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles, uint32_t flags)
+{
+   if (!dev)
+   return -EINVAL;
+
+   return drmSyncobjQuery2(dev->fd, handles, points, num_handles, flags);
+}
+
 drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
uint32_t handle,
int *shared_fd)
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 532787bf..af37a80b 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -771,11 +771,12 @@ struct drm_syncobj_array {
__u32 pad;
 };
 
+#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available 
point on timeline syncobj */
 struct drm_syncobj_timeline_array {
__u64 handles;
__u64 points;
__u32 count_handles;
-   __u32 pad;
+   __u32 flags;
 };
 
 
diff --git a/xf86drm.c b/xf86drm.c
index 953fc762..28a61264 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4314,6 +4314,21 @@ drm_public int drmSyncobjQuery(int fd, uint32_t 
*handles, uint64_t *points,
 return 0;
 }
 
+drm_public int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points,
+   uint32_t handle_count, uint32_t flags)
+{
+struct drm_syncobj_timeline_array args;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uintptr_t)points;
+args.count_handles = handle_count;
+args.flags = flags;
+
+return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, );
+}
+
+
 drm_public int drmSyncobjTransfer(int fd,
  uint32_t dst_handle, uint64_t dst_point,
  uint32_t src_handle, uint64_t src_point,
diff --git a/xf86drm.h b/xf86drm.h
index 3fb1d1ca..55ceaed9 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -884,6 +884,8 @@ extern int drmSyncobjTimelineWait(int fd, uint32_t 
*handles, uint64_t *points,
  uint32_t *first_signaled);
 extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
   uint32_t handle_count);
+extern int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points,
+   uint32_t handle_count, uint32_t flags);
 extern int drmSyncobjTransfer(int fd,
  uint32_t dst_handle, uint64_t dst_point,
  uint32_t src_handle, uint64_t src_point,
-- 
2.17.1

___
dr

[PATCH libdrm] libdrm: wrap new flexible syncobj query interface v2

2019-07-25 Thread Chunming Zhou
v2: nit-picks fix

Signed-off-by: Chunming Zhou 
Cc: Lionel Landwerlin 
Cc: Christian König 
---
 amdgpu/amdgpu-symbol-check |  1 +
 amdgpu/amdgpu.h| 18 ++
 amdgpu/amdgpu_cs.c | 10 ++
 include/drm/drm.h  |  3 ++-
 xf86drm.c  | 15 +++
 xf86drm.h  |  2 ++
 6 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 274b4c6d..597a99b2 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -56,6 +56,7 @@ amdgpu_cs_syncobj_export_sync_file2
 amdgpu_cs_syncobj_import_sync_file
 amdgpu_cs_syncobj_import_sync_file2
 amdgpu_cs_syncobj_query
+amdgpu_cs_syncobj_query2
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
 amdgpu_cs_syncobj_timeline_signal
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 9d9b0832..19f74bd6 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1591,6 +1591,24 @@ int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle 
dev,
 int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
uint32_t *handles, uint64_t *points,
unsigned num_handles);
+/**
+ *  Query sync objects last signaled or submitted point.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [out] array of sync points returned, which presents
+ * syncobj payload.
+ * \param   num_handles - \c [in] self-explanatory
+ * \param   flags   - \c [in] a bitmask of DRM_SYNCOBJ_QUERY_FLAGS_*
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_query2(amdgpu_device_handle dev,
+uint32_t *handles, uint64_t *points,
+unsigned num_handles, uint32_t flags);
 
 /**
  *  Export kernel sync object to shareable fd.
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 977fa3cf..feb2aec8 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -721,6 +721,16 @@ drm_public int 
amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
return drmSyncobjQuery(dev->fd, handles, points, num_handles);
 }
 
+drm_public int amdgpu_cs_syncobj_query2(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles, uint32_t flags)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjQuery2(dev->fd, handles, points, num_handles, flags);
+}
+
 drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
uint32_t handle,
int *shared_fd)
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 532787bf..af37a80b 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -771,11 +771,12 @@ struct drm_syncobj_array {
__u32 pad;
 };
 
+#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available 
point on timeline syncobj */
 struct drm_syncobj_timeline_array {
__u64 handles;
__u64 points;
__u32 count_handles;
-   __u32 pad;
+   __u32 flags;
 };
 
 
diff --git a/xf86drm.c b/xf86drm.c
index 953fc762..28a61264 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4314,6 +4314,21 @@ drm_public int drmSyncobjQuery(int fd, uint32_t 
*handles, uint64_t *points,
 return 0;
 }
 
+drm_public int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points,
+   uint32_t handle_count, uint32_t flags)
+{
+struct drm_syncobj_timeline_array args;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uintptr_t)points;
+args.count_handles = handle_count;
+args.flags = flags;
+
+return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, );
+}
+
+
 drm_public int drmSyncobjTransfer(int fd,
  uint32_t dst_handle, uint64_t dst_point,
  uint32_t src_handle, uint64_t src_point,
diff --git a/xf86drm.h b/xf86drm.h
index 3fb1d1ca..55ceaed9 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -884,6 +884,8 @@ extern int drmSyncobjTimelineWait(int fd, uint32_t 
*handles, uint64_t *points,
  uint32_t *first_signaled);
 extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
   uint32_t handle_count);
+extern int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points,
+   uint32_t handle_count, uint32_t flags);
 extern int drmSyncobjTransfer(int fd,
  uint32_t dst_handle, uint64_t dst_point,
  uint32_t src_handle, uint64_t src_point,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/m

[PATCH libdrm] libdrm: wrap new flexible syncobj query interface

2019-07-24 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
Cc: Lionel Landwerlin 
Cc: Christian König 
---
 amdgpu/amdgpu-symbol-check |  1 +
 amdgpu/amdgpu.h| 18 ++
 amdgpu/amdgpu_cs.c | 10 ++
 include/drm/drm.h  |  3 ++-
 xf86drm.c  | 19 +++
 xf86drm.h  |  2 ++
 6 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 274b4c6d..3bc1a9f1 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -56,6 +56,7 @@ amdgpu_cs_syncobj_export_sync_file2
 amdgpu_cs_syncobj_import_sync_file
 amdgpu_cs_syncobj_import_sync_file2
 amdgpu_cs_syncobj_query
+amdgpu_cs_syncobj_query1
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
 amdgpu_cs_syncobj_timeline_signal
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 9d9b0832..ce7e2bbb 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1591,6 +1591,24 @@ int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle 
dev,
 int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
uint32_t *handles, uint64_t *points,
unsigned num_handles);
+/**
+ *  Query sync objects payloads.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [out] array of sync points returned, which presents
+ * syncobj payload.
+ * \param   num_handles - \c [in] self-explanatory
+ * \param   flags   - \c [in] a bitmask of DRM_SYNCOBJ_QUERY_FLAGS_*
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_query1(amdgpu_device_handle dev,
+uint32_t *handles, uint64_t *points,
+unsigned num_handles, uint32_t flags);
 
 /**
  *  Export kernel sync object to shareable fd.
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 977fa3cf..e2287fa0 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -721,6 +721,16 @@ drm_public int 
amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
return drmSyncobjQuery(dev->fd, handles, points, num_handles);
 }
 
+drm_public int amdgpu_cs_syncobj_query1(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles, uint32_t flags)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjQuery1(dev->fd, handles, points, num_handles, flags);
+}
+
 drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
uint32_t handle,
int *shared_fd)
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 532787bf..af37a80b 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -771,11 +771,12 @@ struct drm_syncobj_array {
__u32 pad;
 };
 
+#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available 
point on timeline syncobj */
 struct drm_syncobj_timeline_array {
__u64 handles;
__u64 points;
__u32 count_handles;
-   __u32 pad;
+   __u32 flags;
 };
 
 
diff --git a/xf86drm.c b/xf86drm.c
index 953fc762..fb7d5cc5 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4314,6 +4314,25 @@ drm_public int drmSyncobjQuery(int fd, uint32_t 
*handles, uint64_t *points,
 return 0;
 }
 
+drm_public int drmSyncobjQuery1(int fd, uint32_t *handles, uint64_t *points,
+   uint32_t handle_count, uint32_t flags)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uintptr_t)points;
+args.count_handles = handle_count;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, );
+if (ret)
+return ret;
+return 0;
+}
+
+
 drm_public int drmSyncobjTransfer(int fd,
  uint32_t dst_handle, uint64_t dst_point,
  uint32_t src_handle, uint64_t src_point,
diff --git a/xf86drm.h b/xf86drm.h
index 3fb1d1ca..29c1df6d 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -884,6 +884,8 @@ extern int drmSyncobjTimelineWait(int fd, uint32_t 
*handles, uint64_t *points,
  uint32_t *first_signaled);
 extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
   uint32_t handle_count);
+extern int drmSyncobjQuery1(int fd, uint32_t *handles, uint64_t *points,
+   uint32_t handle_count, uint32_t flags);
 extern int drmSyncobjTransfer(int fd,
  uint32_t dst_handle, uint64_t dst_point,
  uint32_t src_handle, uint64_t src_point,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freede

[PATCH] drm/syncobj: extend syncobj query ability v2

2019-07-23 Thread Chunming Zhou
user space needs a flexiable query ability.
So that umd can get last signaled or submitted point.
v2:
add sanitizer checking.

Change-Id: I6512b430524ebabe715e602a2bf5abb0a7e780ea
Signed-off-by: Chunming Zhou 
Cc: Lionel Landwerlin 
Cc: Christian König 
---
 drivers/gpu/drm/drm_syncobj.c | 34 --
 include/uapi/drm/drm.h|  3 ++-
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 3d400905100b..3fc8f66ada68 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1197,7 +1197,7 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, 
void *data,
if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
return -EOPNOTSUPP;
 
-   if (args->pad != 0)
+   if (args->flags != 0)
return -EINVAL;
 
if (args->count_handles == 0)
@@ -1268,7 +1268,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void 
*data,
if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
return -EOPNOTSUPP;
 
-   if (args->pad != 0)
+   if (args->flags & ~DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED)
return -EINVAL;
 
if (args->count_handles == 0)
@@ -1291,23 +1291,29 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, 
void *data,
if (chain) {
struct dma_fence *iter, *last_signaled = NULL;
 
-   dma_fence_chain_for_each(iter, fence) {
-   if (!iter)
-   break;
-   dma_fence_put(last_signaled);
-   last_signaled = dma_fence_get(iter);
-   if 
(!to_dma_fence_chain(last_signaled)->prev_seqno)
-   /* It is most likely that timeline has
-* unorder points. */
-   break;
+   if (args->flags &
+   DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED) {
+   point = fence->seqno;
+   } else {
+   dma_fence_chain_for_each(iter, fence) {
+   if (!iter)
+   break;
+   dma_fence_put(last_signaled);
+   last_signaled = dma_fence_get(iter);
+   if 
(!to_dma_fence_chain(last_signaled)->prev_seqno)
+   /* It is most likely that 
timeline has
+   * unorder points. */
+   break;
+   }
+   point = dma_fence_is_signaled(last_signaled) ?
+   last_signaled->seqno :
+   
to_dma_fence_chain(last_signaled)->prev_seqno;
}
-   point = dma_fence_is_signaled(last_signaled) ?
-   last_signaled->seqno :
-   to_dma_fence_chain(last_signaled)->prev_seqno;
dma_fence_put(last_signaled);
} else {
point = 0;
}
+   dma_fence_put(fence);
ret = copy_to_user([i], , sizeof(uint64_t));
ret = ret ? -EFAULT : 0;
if (ret)
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 661d73f9a919..fd987ce24d9f 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -777,11 +777,12 @@ struct drm_syncobj_array {
__u32 pad;
 };
 
+#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available 
point on timeline syncobj */
 struct drm_syncobj_timeline_array {
__u64 handles;
__u64 points;
__u32 count_handles;
-   __u32 pad;
+   __u32 flags;
 };
 
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/syncobj: extend syncobj query ability

2019-07-23 Thread Chunming Zhou

在 2019/7/23 21:58, Koenig, Christian 写道:
> Am 23.07.19 um 07:22 schrieb Chunming Zhou:
>> user space needs a flexiable query ability.
>> So that umd can get last signaled or submitted point.
>>
>> Change-Id: I6512b430524ebabe715e602a2bf5abb0a7e780ea
>> Signed-off-by: Chunming Zhou 
>> Cc: Lionel Landwerlin 
>> Cc: Christian König 
> I've recently found a bug in drm_syncobj_query_ioctl() which I'm going
> to commit tomorrow.

Yes, I've realized. Loinel has put RB on it.


>
> Apart from that it looks good to me,

Thanks,


>   but I think we should cleanup a bit
> and move the dma_fence_chain_for_each()... into a helper function in
> dma-fence-chain.c

Do you mind a saperate cleanup patch for that? I don't want to touch 
kernel directory in this patch, so that we can cherry-pick it easily.


-David

>
> Christian.
>
>> ---
>>drivers/gpu/drm/drm_syncobj.c | 36 +--
>>include/uapi/drm/drm.h|  3 ++-
>>2 files changed, 20 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
>> index 3d400905100b..f70dedf3ef4f 100644
>> --- a/drivers/gpu/drm/drm_syncobj.c
>> +++ b/drivers/gpu/drm/drm_syncobj.c
>> @@ -1197,9 +1197,6 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device 
>> *dev, void *data,
>>  if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
>>  return -EOPNOTSUPP;
>>
>> -if (args->pad != 0)
>> -return -EINVAL;
>> -
>>  if (args->count_handles == 0)
>>  return -EINVAL;
>>
>> @@ -1268,9 +1265,6 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, 
>> void *data,
>>  if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
>>  return -EOPNOTSUPP;
>>
>> -if (args->pad != 0)
>> -return -EINVAL;
>> -
>>  if (args->count_handles == 0)
>>  return -EINVAL;
>>
>> @@ -1291,23 +1285,29 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, 
>> void *data,
>>  if (chain) {
>>  struct dma_fence *iter, *last_signaled = NULL;
>>
>> -dma_fence_chain_for_each(iter, fence) {
>> -if (!iter)
>> -break;
>> -dma_fence_put(last_signaled);
>> -last_signaled = dma_fence_get(iter);
>> -if 
>> (!to_dma_fence_chain(last_signaled)->prev_seqno)
>> -/* It is most likely that timeline has
>> - * unorder points. */
>> -break;
>> +if (args->flags &
>> +DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED) {
>> +point = fence->seqno;
>> +} else {
>> +dma_fence_chain_for_each(iter, fence) {
>> +if (!iter)
>> +break;
>> +dma_fence_put(last_signaled);
>> +last_signaled = dma_fence_get(iter);
>> +if 
>> (!to_dma_fence_chain(last_signaled)->prev_seqno)
>> +/* It is most likely that 
>> timeline has
>> +* unorder points. */
>> +break;
>> +}
>> +point = dma_fence_is_signaled(last_signaled) ?
>> +last_signaled->seqno :
>> +
>> to_dma_fence_chain(last_signaled)->prev_seqno;
>>  }
>> -point = dma_fence_is_signaled(last_signaled) ?
>> -last_signaled->seqno :
>> -to_dma_fence_chain(last_signaled)->prev_seqno;
>>  dma_fence_put(last_signaled);
>>  } else {
>>  point = 0;
>>  }
>> +dma_fence_put(fence);
>>  ret = copy_to_user([i], , sizeof(uint64_t));
>>  ret = ret ? -EFAULT : 0;
>>  if (ret)
>> diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
>> index 661d73f9a919..fd987c

[PATCH] drm/syncobj: extend syncobj query ability

2019-07-22 Thread Chunming Zhou
user space needs a flexiable query ability.
So that umd can get last signaled or submitted point.

Change-Id: I6512b430524ebabe715e602a2bf5abb0a7e780ea
Signed-off-by: Chunming Zhou 
Cc: Lionel Landwerlin 
Cc: Christian König 
---
 drivers/gpu/drm/drm_syncobj.c | 36 +--
 include/uapi/drm/drm.h|  3 ++-
 2 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 3d400905100b..f70dedf3ef4f 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1197,9 +1197,6 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, 
void *data,
if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
return -EOPNOTSUPP;
 
-   if (args->pad != 0)
-   return -EINVAL;
-
if (args->count_handles == 0)
return -EINVAL;
 
@@ -1268,9 +1265,6 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void 
*data,
if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
return -EOPNOTSUPP;
 
-   if (args->pad != 0)
-   return -EINVAL;
-
if (args->count_handles == 0)
return -EINVAL;
 
@@ -1291,23 +1285,29 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, 
void *data,
if (chain) {
struct dma_fence *iter, *last_signaled = NULL;
 
-   dma_fence_chain_for_each(iter, fence) {
-   if (!iter)
-   break;
-   dma_fence_put(last_signaled);
-   last_signaled = dma_fence_get(iter);
-   if 
(!to_dma_fence_chain(last_signaled)->prev_seqno)
-   /* It is most likely that timeline has
-* unorder points. */
-   break;
+   if (args->flags &
+   DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED) {
+   point = fence->seqno;
+   } else {
+   dma_fence_chain_for_each(iter, fence) {
+   if (!iter)
+   break;
+   dma_fence_put(last_signaled);
+   last_signaled = dma_fence_get(iter);
+   if 
(!to_dma_fence_chain(last_signaled)->prev_seqno)
+   /* It is most likely that 
timeline has
+   * unorder points. */
+   break;
+   }
+   point = dma_fence_is_signaled(last_signaled) ?
+   last_signaled->seqno :
+   
to_dma_fence_chain(last_signaled)->prev_seqno;
}
-   point = dma_fence_is_signaled(last_signaled) ?
-   last_signaled->seqno :
-   to_dma_fence_chain(last_signaled)->prev_seqno;
dma_fence_put(last_signaled);
} else {
point = 0;
}
+   dma_fence_put(fence);
ret = copy_to_user([i], , sizeof(uint64_t));
ret = ret ? -EFAULT : 0;
if (ret)
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 661d73f9a919..fd987ce24d9f 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -777,11 +777,12 @@ struct drm_syncobj_array {
__u32 pad;
 };
 
+#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available 
point on timeline syncobj */
 struct drm_syncobj_timeline_array {
__u64 handles;
__u64 points;
__u32 count_handles;
-   __u32 pad;
+   __u32 flags;
 };
 
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/syncobj: return meaningful value to user space

2019-07-18 Thread Chunming Zhou

在 2019/7/18 22:08, Lionel Landwerlin 写道:
> On 18/07/2019 16:02, Chunming Zhou wrote:
>> 在 2019/7/18 19:31, Lionel Landwerlin 写道:
>>> On 18/07/2019 14:13, Chunming Zhou wrote:
>>>> if WAIT_FOR_SUBMIT isn't set and in the meanwhile no underlying fence
>>>> on syncobj,
>>>> then return non-block error code to user sapce.
>>>>
>>>> Signed-off-by: Chunming Zhou 
>>>> ---
>>>>    drivers/gpu/drm/drm_syncobj.c | 4 ++--
>>>>    1 file changed, 2 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_syncobj.c
>>>> b/drivers/gpu/drm/drm_syncobj.c
>>>> index 361a01a08c18..929f7c64f9a2 100644
>>>> --- a/drivers/gpu/drm/drm_syncobj.c
>>>> +++ b/drivers/gpu/drm/drm_syncobj.c
>>>> @@ -252,7 +252,7 @@ int drm_syncobj_find_fence(struct drm_file
>>>> *file_private,
>>>>    return 0;
>>>>    dma_fence_put(*fence);
>>>>    } else {
>>>> -    ret = -EINVAL;
>>>> +    ret = -ENOTBLK;
>>>>    }
>>>>      if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
>>>> @@ -832,7 +832,7 @@ static signed long
>>>> drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>>>>    if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
>>>>    continue;
>>>>    } else {
>>>> -    timeout = -EINVAL;
>>>> +    timeout = -ENOTBLK;
>>>>    goto cleanup_entries;
>>>>    }
>>>>    }
>>>
>>> This would break existing tests for binary syncobjs.
>> How does this breaks binary syncobj?
>
>
> This is used in the submission path of several drivers.
>
> Changing the error code will change what the drivers are reporting to 
> userspace and could break tests.
>
>
> i915 doesn't use that function so it's not affected but 
> lima/panfrost/vc4 seem to be.


anyone from vc4 can confirm this? There are many place in wait_ioctl 
being able to return previous EINVAL, not sure what they use to.


>
>
>>
>>
>>> Is this really what we want?
>> I want to use this meaningful return value to judge if WaitBeforeSignal
>> happens.
>>
>> I think this is the cheapest change for that.
>
>
> I thought the plan was to add a new ioctl to query the last submitted 
> value.

Yes, that is optional way too.  I just thought changing return value is 
very cheap, isn't it?


-David

>
> Did I misunderstand?
>
>
> Thanks,
>
>
> -Lionel
>
>
>>
>> -David
>>
>>
>>>
>>> -Lionel
>>>
>>>
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/syncobj: return meaningful value to user space

2019-07-18 Thread Chunming Zhou

在 2019/7/18 21:15, Zhou, David(ChunMing) 写道:
> 在 2019/7/18 21:10, Chris Wilson 写道:
>> Quoting Chunming Zhou (2019-07-18 14:04:09)
>>> 在 2019/7/18 19:18, Chris Wilson 写道:
>>>> Quoting Chunming Zhou (2019-07-18 12:13:39)
>>>>> if WAIT_FOR_SUBMIT isn't set and in the meanwhile no underlying fence on 
>>>>> syncobj,
>>>>> then return non-block error code to user sapce.
>>>> Block device required?
>>> Yes, if WAIT_FOR_SUBMIT is set, then that will block device.
>> No, the error message is that it requires a "block device", not that it
>> will block the device, which is EWOULDBLOCK.

Ah, I think I don't want EWOULDBLOCK, which will try again and again 
ioctl, that is not my movitation.

I just need a meaningful value to identify the underlying fence isn't 
ready on syncobj.

Because it is in 'else' case, ENOTBLK is correct to say here need block 
but WAIT_FOR_SUBMIT isn't set.


-David

> OK, I got your mean.
>
> Any other possile value suggestted?
>
> -David
>
>> -Chris
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/syncobj: return meaningful value to user space

2019-07-18 Thread Chunming Zhou

在 2019/7/18 21:10, Chris Wilson 写道:
> Quoting Chunming Zhou (2019-07-18 14:04:09)
>> 在 2019/7/18 19:18, Chris Wilson 写道:
>>> Quoting Chunming Zhou (2019-07-18 12:13:39)
>>>> if WAIT_FOR_SUBMIT isn't set and in the meanwhile no underlying fence on 
>>>> syncobj,
>>>> then return non-block error code to user sapce.
>>> Block device required?
>> Yes, if WAIT_FOR_SUBMIT is set, then that will block device.
> No, the error message is that it requires a "block device", not that it
> will block the device, which is EWOULDBLOCK.

OK, I got your mean.

Any other possile value suggestted?

-David

> -Chris
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/syncobj: return meaningful value to user space

2019-07-18 Thread Chunming Zhou

在 2019/7/18 19:18, Chris Wilson 写道:
> Quoting Chunming Zhou (2019-07-18 12:13:39)
>> if WAIT_FOR_SUBMIT isn't set and in the meanwhile no underlying fence on 
>> syncobj,
>> then return non-block error code to user sapce.
> Block device required?

Yes, if WAIT_FOR_SUBMIT is set, then that will block device.


-David

>
> I presume you tried the EWOULDBLOCK which would be implied by your
> sentence and found that would be an interesting experience.
> -Chris
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/syncobj: return meaningful value to user space

2019-07-18 Thread Chunming Zhou

在 2019/7/18 19:31, Lionel Landwerlin 写道:
> On 18/07/2019 14:13, Chunming Zhou wrote:
>> if WAIT_FOR_SUBMIT isn't set and in the meanwhile no underlying fence 
>> on syncobj,
>> then return non-block error code to user sapce.
>>
>> Signed-off-by: Chunming Zhou 
>> ---
>>   drivers/gpu/drm/drm_syncobj.c | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_syncobj.c 
>> b/drivers/gpu/drm/drm_syncobj.c
>> index 361a01a08c18..929f7c64f9a2 100644
>> --- a/drivers/gpu/drm/drm_syncobj.c
>> +++ b/drivers/gpu/drm/drm_syncobj.c
>> @@ -252,7 +252,7 @@ int drm_syncobj_find_fence(struct drm_file 
>> *file_private,
>>   return 0;
>>   dma_fence_put(*fence);
>>   } else {
>> -    ret = -EINVAL;
>> +    ret = -ENOTBLK;
>>   }
>>     if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
>> @@ -832,7 +832,7 @@ static signed long 
>> drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>>   if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
>>   continue;
>>   } else {
>> -    timeout = -EINVAL;
>> +    timeout = -ENOTBLK;
>>   goto cleanup_entries;
>>   }
>>   }
>
>
> This would break existing tests for binary syncobjs.

How does this breaks binary syncobj?


>
> Is this really what we want?

I want to use this meaningful return value to judge if WaitBeforeSignal 
happens.

I think this is the cheapest change for that.

-David


>
>
> -Lionel
>
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH] drm/syncobj: return meaningful value to user space

2019-07-18 Thread Chunming Zhou
if WAIT_FOR_SUBMIT isn't set and in the meanwhile no underlying fence on 
syncobj,
then return non-block error code to user sapce.

Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/drm_syncobj.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 361a01a08c18..929f7c64f9a2 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -252,7 +252,7 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
return 0;
dma_fence_put(*fence);
} else {
-   ret = -EINVAL;
+   ret = -ENOTBLK;
}
 
if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
@@ -832,7 +832,7 @@ static signed long drm_syncobj_array_wait_timeout(struct 
drm_syncobj **syncobjs,
if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
continue;
} else {
-   timeout = -EINVAL;
+   timeout = -ENOTBLK;
goto cleanup_entries;
}
}
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 06/10] drm/ttm: fix busy memory to fail other user v10

2019-05-23 Thread Chunming Zhou

在 2019/5/23 19:03, Christian König 写道:
> [CAUTION: External Email]
>
> Am 23.05.19 um 12:24 schrieb zhoucm1:
>>
>>
>> On 2019年05月22日 20:59, Christian König wrote:
>>> [CAUTION: External Email]
>>>
>>> BOs on the LRU might be blocked during command submission
>>> and cause OOM situations.
>>>
>>> Avoid this by blocking for the first busy BO not locked by
>>> the same ticket as the BO we are searching space for.
>>>
>>> v10: completely start over with the patch since we didn't
>>>   handled a whole bunch of corner cases.
>>>
>>> Signed-off-by: Christian König 
>>> ---
>>>   drivers/gpu/drm/ttm/ttm_bo.c | 77 
>>> ++--
>>>   1 file changed, 66 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c 
>>> b/drivers/gpu/drm/ttm/ttm_bo.c
>>> index 4c6389d849ed..861facac33d4 100644
>>> --- a/drivers/gpu/drm/ttm/ttm_bo.c
>>> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
>>> @@ -771,32 +771,72 @@ EXPORT_SYMBOL(ttm_bo_eviction_valuable);
>>>    * b. Otherwise, trylock it.
>>>    */
>>>   static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object
>>> *bo,
>>> -   struct ttm_operation_ctx *ctx, bool *locked)
>>> +   struct ttm_operation_ctx *ctx, bool *locked,
>>> bool *busy)
>>>   {
>>>  bool ret = false;
>>>
>>> -   *locked = false;
>>>  if (bo->resv == ctx->resv) {
>>>  reservation_object_assert_held(bo->resv);
>>>  if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT
>>>  || !list_empty(>ddestroy))
>>>  ret = true;
>>> +   *locked = false;
>>> +   if (busy)
>>> +   *busy = false;
>>>  } else {
>>> -   *locked = reservation_object_trylock(bo->resv);
>>> -   ret = *locked;
>>> +   ret = reservation_object_trylock(bo->resv);
>>> +   *locked = ret;
>>> +   if (busy)
>>> +   *busy = !ret;
>>>  }
>>>
>>>  return ret;
>>>   }
>>>
>>> +/**
>>> + * ttm_mem_evict_wait_busy - wait for a busy BO to become available
>>> + *
>>> + * @busy_bo: BO which couldn't be locked with trylock
>>> + * @ctx: operation context
>>> + * @ticket: acquire ticket
>>> + *
>>> + * Try to lock a busy buffer object to avoid failing eviction.
>>> + */
>>> +static int ttm_mem_evict_wait_busy(struct ttm_buffer_object *busy_bo,
>>> +  struct ttm_operation_ctx *ctx,
>>> +  struct ww_acquire_ctx *ticket)
>>> +{
>>> +   int r;
>>> +
>>> +   if (!busy_bo || !ticket)
>>> +   return -EBUSY;
>>> +
>>> +   if (ctx->interruptible)
>>> +   r = 
>>> reservation_object_lock_interruptible(busy_bo->resv,
>>> + ticket);
>>> +   else
>>> +   r = reservation_object_lock(busy_bo->resv, ticket);
>>> +
>>> +   /*
>>> +    * TODO: It would be better to keep the BO locked until
>>> allocation is at
>>> +    * least tried one more time, but that would mean a much
>>> larger rework
>>> +    * of TTM.
>>> +    */
>>> +   if (!r)
>>> +   reservation_object_unlock(busy_bo->resv);
>>> +
>>> +   return r == -EDEADLK ? -EAGAIN : r;
>>> +}
>>> +
>>>   static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
>>>     uint32_t mem_type,
>>>     const struct ttm_place *place,
>>> -  struct ttm_operation_ctx *ctx)
>>> +  struct ttm_operation_ctx *ctx,
>>> +  struct ww_acquire_ctx *ticket)
>>>   {
>>> +   struct ttm_buffer_object *bo = NULL, *busy_bo = NULL;
>>>  struct ttm_bo_global *glob = bdev->glob;
>>>  struct ttm_mem_type_manager *man = >man[mem_type];
>>> -   struct ttm_buffer_object *bo = NULL;
>>>  bool locked = false;
>>>  unsigned i;
>>>  int ret;
>>> @@ -804,8 +844,15 @@ static int ttm_mem_evict_first(struct
>>> ttm_bo_device *bdev,
>>>  spin_lock(>lru_lock);
>>>  for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
>>>  list_for_each_entry(bo, >lru[i], lru) {
>>> -   if (!ttm_bo_evict_swapout_allowable(bo, ctx,
>>> ))
>>> +   bool busy;
>>> +
>>> +   if (!ttm_bo_evict_swapout_allowable(bo, ctx,
>>> ,
>>> + )) {
>>> +   if (busy && !busy_bo &&
>>> +   bo->resv->lock.ctx != ticket)
>>> +   busy_bo = bo;
>>>  continue;
>>> +   }
>>>
>>>  if (place &&
>>> !bdev->driver->eviction_valuable(bo,
>>> place)) {
>>> @@ -824,8 +871,13 @@ static int ttm_mem_evict_first(struct
>>> ttm_bo_device *bdev,
>>>  }
>>>
>>>  if (!bo) {
>>> +   if 

[PATCH 2/2] enable syncobj test depending on capability

2019-05-22 Thread Chunming Zhou
Feature is controlled by DRM_CAP_SYNCOBJ_TIMELINE drm capability.

Signed-off-by: Chunming Zhou 
Reviewed-by: Christian König 
---
 tests/amdgpu/syncobj_tests.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/tests/amdgpu/syncobj_tests.c b/tests/amdgpu/syncobj_tests.c
index a0c627d7..869ed88e 100644
--- a/tests/amdgpu/syncobj_tests.c
+++ b/tests/amdgpu/syncobj_tests.c
@@ -22,6 +22,7 @@
 */
 
 #include "CUnit/Basic.h"
+#include "xf86drm.h"
 
 #include "amdgpu_test.h"
 #include "amdgpu_drm.h"
@@ -36,6 +37,13 @@ static void amdgpu_syncobj_timeline_test(void);
 
 CU_BOOL suite_syncobj_timeline_tests_enable(void)
 {
+   int r;
+   uint64_t cap = 0;
+
+   r = drmGetCap(drm_amdgpu[0], DRM_CAP_SYNCOBJ_TIMELINE, );
+   if (r || cap == 0)
+   return CU_FALSE;
+
return CU_TRUE;
 }
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 1/2] update drm.h

2019-05-22 Thread Chunming Zhou
   a) delta: only DRM_CAP_SYNCOBJ_TIMELINE
   b) Generated using make headers_install.
   c) Generated from origin/drm-misc-next commit 
982c0500fd1a8012c31d3c9dd8de285129904656"

Signed-off-by: Chunming Zhou 
Suggested-by: Michel Dänzer 
---
 include/drm/drm.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm.h b/include/drm/drm.h
index c893f3b4..438abde3 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -44,6 +44,7 @@ typedef unsigned int drm_handle_t;
 
 #else /* One of the BSDs */
 
+#include 
 #include 
 #include 
 typedef int8_t   __s8;
@@ -643,6 +644,7 @@ struct drm_gem_open {
 #define DRM_CAP_PAGE_FLIP_TARGET   0x11
 #define DRM_CAP_CRTC_IN_VBLANK_EVENT   0x12
 #define DRM_CAP_SYNCOBJ0x13
+#define DRM_CAP_SYNCOBJ_TIMELINE   0x14
 
 /** DRM_IOCTL_GET_CAP ioctl argument type */
 struct drm_get_cap {
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm] enable syncobj test depending on capability

2019-05-16 Thread Chunming Zhou
Feature is controlled by DRM_CAP_SYNCOBJ_TIMELINE drm capability.

Signed-off-by: Chunming Zhou 
---
 include/drm/drm.h| 1 +
 tests/amdgpu/syncobj_tests.c | 8 
 2 files changed, 9 insertions(+)

diff --git a/include/drm/drm.h b/include/drm/drm.h
index c893f3b4..532787bf 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -643,6 +643,7 @@ struct drm_gem_open {
 #define DRM_CAP_PAGE_FLIP_TARGET   0x11
 #define DRM_CAP_CRTC_IN_VBLANK_EVENT   0x12
 #define DRM_CAP_SYNCOBJ0x13
+#define DRM_CAP_SYNCOBJ_TIMELINE   0x14
 
 /** DRM_IOCTL_GET_CAP ioctl argument type */
 struct drm_get_cap {
diff --git a/tests/amdgpu/syncobj_tests.c b/tests/amdgpu/syncobj_tests.c
index a0c627d7..869ed88e 100644
--- a/tests/amdgpu/syncobj_tests.c
+++ b/tests/amdgpu/syncobj_tests.c
@@ -22,6 +22,7 @@
 */
 
 #include "CUnit/Basic.h"
+#include "xf86drm.h"
 
 #include "amdgpu_test.h"
 #include "amdgpu_drm.h"
@@ -36,6 +37,13 @@ static void amdgpu_syncobj_timeline_test(void);
 
 CU_BOOL suite_syncobj_timeline_tests_enable(void)
 {
+   int r;
+   uint64_t cap = 0;
+
+   r = drmGetCap(drm_amdgpu[0], DRM_CAP_SYNCOBJ_TIMELINE, );
+   if (r || cap == 0)
+   return CU_FALSE;
+
return CU_TRUE;
 }
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 1/7] add cs chunk for syncobj timeline

2019-05-16 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
Acked-by: Lionel Landwerlin 
---
 include/drm/amdgpu_drm.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h
index d0701ffc..3d0318e6 100644
--- a/include/drm/amdgpu_drm.h
+++ b/include/drm/amdgpu_drm.h
@@ -528,6 +528,8 @@ struct drm_amdgpu_gem_va {
 #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
 #define AMDGPU_CHUNK_ID_BO_HANDLES  0x06
 #define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT0x08
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL  0x09
 
 struct drm_amdgpu_cs_chunk {
__u32   chunk_id;
@@ -608,6 +610,13 @@ struct drm_amdgpu_cs_chunk_sem {
__u32 handle;
 };
 
+struct drm_amdgpu_cs_chunk_syncobj {
+   __u32 handle;
+   __u32 flags;
+   __u64 point;
+};
+
+
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD  1
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD2
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 4/7] add timeline signal/transfer ioctls v2

2019-05-16 Thread Chunming Zhou
v2: use one transfer ioctl

Signed-off-by: Chunming Zhou 
Reviewed-by: Lionel Landwerlin 
---
 xf86drm.c | 33 +
 xf86drm.h |  6 ++
 2 files changed, 39 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 1a717f02..953fc762 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4257,6 +4257,21 @@ drm_public int drmSyncobjSignal(int fd, const uint32_t 
*handles,
 return ret;
 }
 
+drm_public int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+   uint64_t *points, uint32_t handle_count)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uintptr_t)points;
+args.count_handles = handle_count;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, );
+return ret;
+}
+
 drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t 
*points,
  unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
@@ -4299,4 +4314,22 @@ drm_public int drmSyncobjQuery(int fd, uint32_t 
*handles, uint64_t *points,
 return 0;
 }
 
+drm_public int drmSyncobjTransfer(int fd,
+ uint32_t dst_handle, uint64_t dst_point,
+ uint32_t src_handle, uint64_t src_point,
+ uint32_t flags)
+{
+struct drm_syncobj_transfer args;
+int ret;
+
+memclear(args);
+args.src_handle = src_handle;
+args.dst_handle = dst_handle;
+args.src_point = src_point;
+args.dst_point = dst_point;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, );
 
+return ret;
+}
diff --git a/xf86drm.h b/xf86drm.h
index 60c7a84f..3fb1d1ca 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -876,12 +876,18 @@ extern int drmSyncobjWait(int fd, uint32_t *handles, 
unsigned num_handles,
  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t 
handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t 
handle_count);
+extern int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+   uint64_t *points, uint32_t handle_count);
 extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
  unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
  uint32_t *first_signaled);
 extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
   uint32_t handle_count);
+extern int drmSyncobjTransfer(int fd,
+ uint32_t dst_handle, uint64_t dst_point,
+ uint32_t src_handle, uint64_t src_point,
+ uint32_t flags);
 
 #if defined(__cplusplus)
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 3/7] wrap syncobj timeline query/wait APIs for amdgpu v3

2019-05-16 Thread Chunming Zhou
v2: symbos are stored in lexical order.
v3: drop export/import and extra query indirection

Signed-off-by: Chunming Zhou 
Acked-by: Christian König 
Acked-by: Lionel Landwerlin 
---
 amdgpu/amdgpu-symbol-check |  2 ++
 amdgpu/amdgpu.h| 39 ++
 amdgpu/amdgpu_cs.c | 23 ++
 3 files changed, 64 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 4d806922..d3c5bb89 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -53,8 +53,10 @@ amdgpu_cs_submit_raw
 amdgpu_cs_submit_raw2
 amdgpu_cs_syncobj_export_sync_file
 amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_query
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_wait
 amdgpu_cs_syncobj_wait
 amdgpu_cs_wait_fences
 amdgpu_cs_wait_semaphore
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index c44a495a..5ebfe1e3 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1536,6 +1536,45 @@ int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
   int64_t timeout_nsec, unsigned flags,
   uint32_t *first_signaled);
 
+/**
+ *  Wait for one or all sync objects on their points to signal.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [in] array of sync points to wait
+ * \param   num_handles - \c [in] self-explanatory
+ * \param   timeout_nsec - \c [in] self-explanatory
+ * \param   flags   - \c [in] a bitmask of DRM_SYNCOBJ_WAIT_FLAGS_*
+ * \param   first_signaled - \c [in] self-explanatory
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles,
+   int64_t timeout_nsec, unsigned flags,
+   uint32_t *first_signaled);
+/**
+ *  Query sync objects payloads.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [out] array of sync points returned, which presents
+ * syncobj payload.
+ * \param   num_handles - \c [in] self-explanatory
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles);
+
 /**
  *  Export kernel sync object to shareable fd.
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 7c5b9d13..9fcaf2c4 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -686,6 +686,29 @@ drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle 
dev,
  flags, first_signaled);
 }
 
+drm_public int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+  uint32_t *handles, uint64_t 
*points,
+  unsigned num_handles,
+  int64_t timeout_nsec, unsigned 
flags,
+  uint32_t *first_signaled)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTimelineWait(dev->fd, handles, points, num_handles,
+ timeout_nsec, flags, first_signaled);
+}
+
+drm_public int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+  uint32_t *handles, uint64_t *points,
+  unsigned num_handles)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjQuery(dev->fd, handles, points, num_handles);
+}
+
 drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
uint32_t handle,
int *shared_fd)
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 7/7] add syncobj timeline tests v3

2019-05-16 Thread Chunming Zhou
v2: drop DRM_SYNCOBJ_CREATE_TYPE_TIMELINE, fix timeout calculation,
fix some warnings
v3: add export/import and cpu signal testing cases

Signed-off-by: Chunming Zhou 
Acked-by: Christian König 
Acked-by: Lionel Landwerlin 
---
 tests/amdgpu/Makefile.am |   3 +-
 tests/amdgpu/amdgpu_test.c   |  11 ++
 tests/amdgpu/amdgpu_test.h   |  21 +++
 tests/amdgpu/meson.build |   2 +-
 tests/amdgpu/syncobj_tests.c | 290 +++
 5 files changed, 325 insertions(+), 2 deletions(-)
 create mode 100644 tests/amdgpu/syncobj_tests.c

diff --git a/tests/amdgpu/Makefile.am b/tests/amdgpu/Makefile.am
index 48278848..920882d0 100644
--- a/tests/amdgpu/Makefile.am
+++ b/tests/amdgpu/Makefile.am
@@ -34,4 +34,5 @@ amdgpu_test_SOURCES = \
uve_ib.h \
deadlock_tests.c \
vm_tests.c  \
-   ras_tests.c
+   ras_tests.c \
+   syncobj_tests.c
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
index 35c8bf6c..73403fb4 100644
--- a/tests/amdgpu/amdgpu_test.c
+++ b/tests/amdgpu/amdgpu_test.c
@@ -57,6 +57,7 @@
 #define DEADLOCK_TESTS_STR "Deadlock Tests"
 #define VM_TESTS_STR "VM Tests"
 #define RAS_TESTS_STR "RAS Tests"
+#define SYNCOBJ_TIMELINE_TESTS_STR "SYNCOBJ TIMELINE Tests"
 
 /**
  *  Open handles for amdgpu devices
@@ -123,6 +124,12 @@ static CU_SuiteInfo suites[] = {
.pCleanupFunc = suite_ras_tests_clean,
.pTests = ras_tests,
},
+   {
+   .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+   .pInitFunc = suite_syncobj_timeline_tests_init,
+   .pCleanupFunc = suite_syncobj_timeline_tests_clean,
+   .pTests = syncobj_timeline_tests,
+   },
 
CU_SUITE_INFO_NULL,
 };
@@ -176,6 +183,10 @@ static Suites_Active_Status suites_active_stat[] = {
.pName = RAS_TESTS_STR,
.pActive = suite_ras_tests_enable,
},
+   {
+   .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+   .pActive = suite_syncobj_timeline_tests_enable,
+   },
 };
 
 
diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h
index bcd0bc7e..36675ea3 100644
--- a/tests/amdgpu/amdgpu_test.h
+++ b/tests/amdgpu/amdgpu_test.h
@@ -216,6 +216,27 @@ CU_BOOL suite_ras_tests_enable(void);
 extern CU_TestInfo ras_tests[];
 
 
+/**
+ * Initialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_init();
+
+/**
+ * Deinitialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_syncobj_timeline_tests_enable(void);
+
+/**
+ * Tests in syncobj timeline test suite
+ */
+extern CU_TestInfo syncobj_timeline_tests[];
+
+
 /**
  * Helper functions
  */
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 95ed9305..1726cb43 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -24,7 +24,7 @@ if dep_cunit.found()
 files(
   'amdgpu_test.c', 'basic_tests.c', 'bo_tests.c', 'cs_tests.c',
   'vce_tests.c', 'uvd_enc_tests.c', 'vcn_tests.c', 'deadlock_tests.c',
-  'vm_tests.c', 'ras_tests.c',
+  'vm_tests.c', 'ras_tests.c', 'syncobj_tests.c',
 ),
 dependencies : [dep_cunit, dep_threads],
 include_directories : [inc_root, inc_drm, 
include_directories('../../amdgpu')],
diff --git a/tests/amdgpu/syncobj_tests.c b/tests/amdgpu/syncobj_tests.c
new file mode 100644
index ..a0c627d7
--- /dev/null
+++ b/tests/amdgpu/syncobj_tests.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include

[PATCH libdrm 5/7] expose timeline signal/export/import interfaces v2

2019-05-16 Thread Chunming Zhou
v2: adapt to new one transfer ioctl

Signed-off-by: Chunming Zhou 
Acked-by: Christian König 
Acked-by: Lionel Landwerlin 
---
 amdgpu/amdgpu-symbol-check |  3 ++
 amdgpu/amdgpu.h| 51 
 amdgpu/amdgpu_cs.c | 68 ++
 3 files changed, 122 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index d3c5bb89..274b4c6d 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -52,10 +52,13 @@ amdgpu_cs_submit
 amdgpu_cs_submit_raw
 amdgpu_cs_submit_raw2
 amdgpu_cs_syncobj_export_sync_file
+amdgpu_cs_syncobj_export_sync_file2
 amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_import_sync_file2
 amdgpu_cs_syncobj_query
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_signal
 amdgpu_cs_syncobj_timeline_wait
 amdgpu_cs_syncobj_wait
 amdgpu_cs_wait_fences
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 5ebfe1e3..d2480dbe 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1516,6 +1516,23 @@ int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
 int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
 const uint32_t *syncobjs, uint32_t syncobj_count);
 
+/**
+ * Signal kernel timeline sync objects.
+ *
+ * \param dev   - \c [in] device handle
+ * \param syncobjs  - \c [in] array of sync object handles
+ * \param points   - \c [in] array of timeline points
+ * \param syncobj_count - \c [in] number of handles in syncobjs
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs,
+ uint64_t *points,
+ uint32_t syncobj_count);
+
 /**
  *  Wait for one or all sync objects to signal.
  *
@@ -1633,7 +1650,41 @@ int 
amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
 int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
   uint32_t syncobj,
   int sync_file_fd);
+/**
+ *  Export kernel timeline sync object to a sync_file.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   syncobj- \c [in] sync object handle
+ * \param   point  - \c [in] timeline point
+ * \param   flags  - \c [in] flags
+ * \param   sync_file_fd - \c [out] sync_file file descriptor.
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+   uint32_t syncobj,
+   uint64_t point,
+   uint32_t flags,
+   int *sync_file_fd);
 
+/**
+ *  Import kernel timeline sync object from a sync_file.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   syncobj- \c [in] sync object handle
+ * \param   point  - \c [in] timeline point
+ * \param   sync_file_fd - \c [in] sync_file file descriptor.
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
+   uint32_t syncobj,
+   uint64_t point,
+   int sync_file_fd);
 /**
  * Export an amdgpu fence as a handle (syncobj or fd).
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 9fcaf2c4..daca4421 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -674,6 +674,18 @@ drm_public int 
amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
return drmSyncobjSignal(dev->fd, syncobjs, syncobj_count);
 }
 
+drm_public int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+const uint32_t *syncobjs,
+uint64_t *points,
+uint32_t syncobj_count)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTimelineSignal(dev->fd, syncobjs,
+   points, syncobj_count);
+}
+
 drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
  uint32_t *handles, unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
@@ -749,6 +761,62 @@ drm_public int 
amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
 }
 
+drm_public int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+  uint32_t syncobj,
+  

[PATCH libdrm 6/7] wrap transfer interfaces

2019-05-16 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
Acked-by: Christian König 
Acked-by: Lionel Landwerlin 
---
 amdgpu/amdgpu.h| 22 ++
 amdgpu/amdgpu_cs.c | 16 
 2 files changed, 38 insertions(+)

diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index d2480dbe..9d9b0832 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1685,6 +1685,28 @@ int 
amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
uint32_t syncobj,
uint64_t point,
int sync_file_fd);
+
+/**
+ *  transfer between syncbojs.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   dst_handle - \c [in] sync object handle
+ * \param   dst_point  - \c [in] timeline point, 0 presents dst is binary
+ * \param   src_handle - \c [in] sync object handle
+ * \param   src_point  - \c [in] timeline point, 0 presents src is binary
+ * \param   flags  - \c [in] flags
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+  uint32_t dst_handle,
+  uint64_t dst_point,
+  uint32_t src_handle,
+  uint64_t src_point,
+  uint32_t flags);
+
 /**
  * Export an amdgpu fence as a handle (syncobj or fd).
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index daca4421..977fa3cf 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -817,6 +817,22 @@ out:
return ret;
 }
 
+drm_public int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+ uint32_t dst_handle,
+ uint64_t dst_point,
+ uint32_t src_handle,
+ uint64_t src_point,
+ uint32_t flags)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTransfer(dev->fd,
+ dst_handle, dst_point,
+ src_handle, src_point,
+ flags);
+}
+
 drm_public int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
amdgpu_context_handle context,
amdgpu_bo_list_handle bo_list_handle,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 2/7] add timeline wait/query ioctl v2

2019-05-16 Thread Chunming Zhou
v2: drop export/import

Signed-off-by: Chunming Zhou 
Reviewed-by: Lionel Landwerlin 
---
 xf86drm.c | 44 
 xf86drm.h |  6 ++
 2 files changed, 50 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 2c19376b..1a717f02 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4256,3 +4256,47 @@ drm_public int drmSyncobjSignal(int fd, const uint32_t 
*handles,
 ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, );
 return ret;
 }
+
+drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t 
*points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+struct drm_syncobj_timeline_wait args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uintptr_t)points;
+args.timeout_nsec = timeout_nsec;
+args.count_handles = num_handles;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, );
+if (ret < 0)
+return -errno;
+
+if (first_signaled)
+*first_signaled = args.first_signaled;
+return ret;
+}
+
+
+drm_public int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+  uint32_t handle_count)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uintptr_t)points;
+args.count_handles = handle_count;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, );
+if (ret)
+return ret;
+return 0;
+}
+
+
diff --git a/xf86drm.h b/xf86drm.h
index 887ecc76..60c7a84f 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -876,6 +876,12 @@ extern int drmSyncobjWait(int fd, uint32_t *handles, 
unsigned num_handles,
  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t 
handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t 
handle_count);
+extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+  uint32_t handle_count);
 
 #if defined(__cplusplus)
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 5/7] expose timeline signal/export/import interfaces v2

2019-05-13 Thread Chunming Zhou
v2: adapt to new one transfer ioctl

Signed-off-by: Chunming Zhou 
Acked-by: Christian König 
---
 amdgpu/amdgpu-symbol-check |  3 ++
 amdgpu/amdgpu.h| 51 
 amdgpu/amdgpu_cs.c | 68 ++
 3 files changed, 122 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index d3c5bb89..274b4c6d 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -52,10 +52,13 @@ amdgpu_cs_submit
 amdgpu_cs_submit_raw
 amdgpu_cs_submit_raw2
 amdgpu_cs_syncobj_export_sync_file
+amdgpu_cs_syncobj_export_sync_file2
 amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_import_sync_file2
 amdgpu_cs_syncobj_query
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_signal
 amdgpu_cs_syncobj_timeline_wait
 amdgpu_cs_syncobj_wait
 amdgpu_cs_wait_fences
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 5ebfe1e3..d2480dbe 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1516,6 +1516,23 @@ int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
 int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
 const uint32_t *syncobjs, uint32_t syncobj_count);
 
+/**
+ * Signal kernel timeline sync objects.
+ *
+ * \param dev   - \c [in] device handle
+ * \param syncobjs  - \c [in] array of sync object handles
+ * \param points   - \c [in] array of timeline points
+ * \param syncobj_count - \c [in] number of handles in syncobjs
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs,
+ uint64_t *points,
+ uint32_t syncobj_count);
+
 /**
  *  Wait for one or all sync objects to signal.
  *
@@ -1633,7 +1650,41 @@ int 
amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
 int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
   uint32_t syncobj,
   int sync_file_fd);
+/**
+ *  Export kernel timeline sync object to a sync_file.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   syncobj- \c [in] sync object handle
+ * \param   point  - \c [in] timeline point
+ * \param   flags  - \c [in] flags
+ * \param   sync_file_fd - \c [out] sync_file file descriptor.
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+   uint32_t syncobj,
+   uint64_t point,
+   uint32_t flags,
+   int *sync_file_fd);
 
+/**
+ *  Import kernel timeline sync object from a sync_file.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   syncobj- \c [in] sync object handle
+ * \param   point  - \c [in] timeline point
+ * \param   sync_file_fd - \c [in] sync_file file descriptor.
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
+   uint32_t syncobj,
+   uint64_t point,
+   int sync_file_fd);
 /**
  * Export an amdgpu fence as a handle (syncobj or fd).
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 9fcaf2c4..daca4421 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -674,6 +674,18 @@ drm_public int 
amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
return drmSyncobjSignal(dev->fd, syncobjs, syncobj_count);
 }
 
+drm_public int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+const uint32_t *syncobjs,
+uint64_t *points,
+uint32_t syncobj_count)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTimelineSignal(dev->fd, syncobjs,
+   points, syncobj_count);
+}
+
 drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
  uint32_t *handles, unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
@@ -749,6 +761,62 @@ drm_public int 
amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
 }
 
+drm_public int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+  uint32_t syncobj,
+  

[PATCH libdrm 4/7] add timeline signal/transfer ioctls v2

2019-05-13 Thread Chunming Zhou
v2: use one transfer ioctl

Signed-off-by: Chunming Zhou 
---
 xf86drm.c | 33 +
 xf86drm.h |  6 ++
 2 files changed, 39 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 17e3d880..acd16fab 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4257,6 +4257,21 @@ drm_public int drmSyncobjSignal(int fd, const uint32_t 
*handles,
 return ret;
 }
 
+drm_public int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+   uint64_t *points, uint32_t handle_count)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.count_handles = handle_count;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, );
+return ret;
+}
+
 drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t 
*points,
  unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
@@ -4299,4 +4314,22 @@ drm_public int drmSyncobjQuery(int fd, uint32_t 
*handles, uint64_t *points,
 return 0;
 }
 
+drm_public int drmSyncobjTransfer(int fd,
+ uint32_t dst_handle, uint64_t dst_point,
+ uint32_t src_handle, uint64_t src_point,
+ uint32_t flags)
+{
+struct drm_syncobj_transfer args;
+int ret;
+
+memclear(args);
+args.src_handle = src_handle;
+args.dst_handle = dst_handle;
+args.src_point = src_point;
+args.dst_point = dst_point;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, );
 
+return ret;
+}
diff --git a/xf86drm.h b/xf86drm.h
index 60c7a84f..3fb1d1ca 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -876,12 +876,18 @@ extern int drmSyncobjWait(int fd, uint32_t *handles, 
unsigned num_handles,
  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t 
handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t 
handle_count);
+extern int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+   uint64_t *points, uint32_t handle_count);
 extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
  unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
  uint32_t *first_signaled);
 extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
   uint32_t handle_count);
+extern int drmSyncobjTransfer(int fd,
+ uint32_t dst_handle, uint64_t dst_point,
+ uint32_t src_handle, uint64_t src_point,
+ uint32_t flags);
 
 #if defined(__cplusplus)
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 7/7] add syncobj timeline tests v3

2019-05-13 Thread Chunming Zhou
v2: drop DRM_SYNCOBJ_CREATE_TYPE_TIMELINE, fix timeout calculation,
fix some warnings
v3: add export/import and cpu signal testing cases

Signed-off-by: Chunming Zhou 
Acked-by: Christian König 
---
 tests/amdgpu/Makefile.am |   3 +-
 tests/amdgpu/amdgpu_test.c   |  11 ++
 tests/amdgpu/amdgpu_test.h   |  21 +++
 tests/amdgpu/meson.build |   2 +-
 tests/amdgpu/syncobj_tests.c | 290 +++
 5 files changed, 325 insertions(+), 2 deletions(-)
 create mode 100644 tests/amdgpu/syncobj_tests.c

diff --git a/tests/amdgpu/Makefile.am b/tests/amdgpu/Makefile.am
index 48278848..920882d0 100644
--- a/tests/amdgpu/Makefile.am
+++ b/tests/amdgpu/Makefile.am
@@ -34,4 +34,5 @@ amdgpu_test_SOURCES = \
uve_ib.h \
deadlock_tests.c \
vm_tests.c  \
-   ras_tests.c
+   ras_tests.c \
+   syncobj_tests.c
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
index 35c8bf6c..73403fb4 100644
--- a/tests/amdgpu/amdgpu_test.c
+++ b/tests/amdgpu/amdgpu_test.c
@@ -57,6 +57,7 @@
 #define DEADLOCK_TESTS_STR "Deadlock Tests"
 #define VM_TESTS_STR "VM Tests"
 #define RAS_TESTS_STR "RAS Tests"
+#define SYNCOBJ_TIMELINE_TESTS_STR "SYNCOBJ TIMELINE Tests"
 
 /**
  *  Open handles for amdgpu devices
@@ -123,6 +124,12 @@ static CU_SuiteInfo suites[] = {
.pCleanupFunc = suite_ras_tests_clean,
.pTests = ras_tests,
},
+   {
+   .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+   .pInitFunc = suite_syncobj_timeline_tests_init,
+   .pCleanupFunc = suite_syncobj_timeline_tests_clean,
+   .pTests = syncobj_timeline_tests,
+   },
 
CU_SUITE_INFO_NULL,
 };
@@ -176,6 +183,10 @@ static Suites_Active_Status suites_active_stat[] = {
.pName = RAS_TESTS_STR,
.pActive = suite_ras_tests_enable,
},
+   {
+   .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+   .pActive = suite_syncobj_timeline_tests_enable,
+   },
 };
 
 
diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h
index bcd0bc7e..36675ea3 100644
--- a/tests/amdgpu/amdgpu_test.h
+++ b/tests/amdgpu/amdgpu_test.h
@@ -216,6 +216,27 @@ CU_BOOL suite_ras_tests_enable(void);
 extern CU_TestInfo ras_tests[];
 
 
+/**
+ * Initialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_init();
+
+/**
+ * Deinitialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_syncobj_timeline_tests_enable(void);
+
+/**
+ * Tests in syncobj timeline test suite
+ */
+extern CU_TestInfo syncobj_timeline_tests[];
+
+
 /**
  * Helper functions
  */
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 95ed9305..1726cb43 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -24,7 +24,7 @@ if dep_cunit.found()
 files(
   'amdgpu_test.c', 'basic_tests.c', 'bo_tests.c', 'cs_tests.c',
   'vce_tests.c', 'uvd_enc_tests.c', 'vcn_tests.c', 'deadlock_tests.c',
-  'vm_tests.c', 'ras_tests.c',
+  'vm_tests.c', 'ras_tests.c', 'syncobj_tests.c',
 ),
 dependencies : [dep_cunit, dep_threads],
 include_directories : [inc_root, inc_drm, 
include_directories('../../amdgpu')],
diff --git a/tests/amdgpu/syncobj_tests.c b/tests/amdgpu/syncobj_tests.c
new file mode 100644
index ..a0c627d7
--- /dev/null
+++ b/tests/amdgpu/syncobj_tests.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include 
+
+static  amdgpu_device_hand

[PATCH libdrm 6/7] wrap transfer interfaces

2019-05-13 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
Acked-by: Christian König 
---
 amdgpu/amdgpu.h| 22 ++
 amdgpu/amdgpu_cs.c | 16 
 2 files changed, 38 insertions(+)

diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index d2480dbe..9d9b0832 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1685,6 +1685,28 @@ int 
amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
uint32_t syncobj,
uint64_t point,
int sync_file_fd);
+
+/**
+ *  transfer between syncbojs.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   dst_handle - \c [in] sync object handle
+ * \param   dst_point  - \c [in] timeline point, 0 presents dst is binary
+ * \param   src_handle - \c [in] sync object handle
+ * \param   src_point  - \c [in] timeline point, 0 presents src is binary
+ * \param   flags  - \c [in] flags
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+  uint32_t dst_handle,
+  uint64_t dst_point,
+  uint32_t src_handle,
+  uint64_t src_point,
+  uint32_t flags);
+
 /**
  * Export an amdgpu fence as a handle (syncobj or fd).
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index daca4421..977fa3cf 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -817,6 +817,22 @@ out:
return ret;
 }
 
+drm_public int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+ uint32_t dst_handle,
+ uint64_t dst_point,
+ uint32_t src_handle,
+ uint64_t src_point,
+ uint32_t flags)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTransfer(dev->fd,
+ dst_handle, dst_point,
+ src_handle, src_point,
+ flags);
+}
+
 drm_public int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
amdgpu_context_handle context,
amdgpu_bo_list_handle bo_list_handle,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 3/7] wrap syncobj timeline query/wait APIs for amdgpu v3

2019-05-13 Thread Chunming Zhou
v2: symbos are stored in lexical order.
v3: drop export/import and extra query indirection

Signed-off-by: Chunming Zhou 
Acked-by: Christian König 
---
 amdgpu/amdgpu-symbol-check |  2 ++
 amdgpu/amdgpu.h| 39 ++
 amdgpu/amdgpu_cs.c | 23 ++
 3 files changed, 64 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 4d806922..d3c5bb89 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -53,8 +53,10 @@ amdgpu_cs_submit_raw
 amdgpu_cs_submit_raw2
 amdgpu_cs_syncobj_export_sync_file
 amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_query
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_wait
 amdgpu_cs_syncobj_wait
 amdgpu_cs_wait_fences
 amdgpu_cs_wait_semaphore
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index c44a495a..5ebfe1e3 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1536,6 +1536,45 @@ int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
   int64_t timeout_nsec, unsigned flags,
   uint32_t *first_signaled);
 
+/**
+ *  Wait for one or all sync objects on their points to signal.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [in] array of sync points to wait
+ * \param   num_handles - \c [in] self-explanatory
+ * \param   timeout_nsec - \c [in] self-explanatory
+ * \param   flags   - \c [in] a bitmask of DRM_SYNCOBJ_WAIT_FLAGS_*
+ * \param   first_signaled - \c [in] self-explanatory
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles,
+   int64_t timeout_nsec, unsigned flags,
+   uint32_t *first_signaled);
+/**
+ *  Query sync objects payloads.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [out] array of sync points returned, which presents
+ * syncobj payload.
+ * \param   num_handles - \c [in] self-explanatory
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles);
+
 /**
  *  Export kernel sync object to shareable fd.
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 7c5b9d13..9fcaf2c4 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -686,6 +686,29 @@ drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle 
dev,
  flags, first_signaled);
 }
 
+drm_public int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+  uint32_t *handles, uint64_t 
*points,
+  unsigned num_handles,
+  int64_t timeout_nsec, unsigned 
flags,
+  uint32_t *first_signaled)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTimelineWait(dev->fd, handles, points, num_handles,
+ timeout_nsec, flags, first_signaled);
+}
+
+drm_public int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+  uint32_t *handles, uint64_t *points,
+  unsigned num_handles)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjQuery(dev->fd, handles, points, num_handles);
+}
+
 drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
uint32_t handle,
int *shared_fd)
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 1/7] addr cs chunk for syncobj timeline

2019-05-13 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
---
 include/drm/amdgpu_drm.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h
index d0701ffc..3d0318e6 100644
--- a/include/drm/amdgpu_drm.h
+++ b/include/drm/amdgpu_drm.h
@@ -528,6 +528,8 @@ struct drm_amdgpu_gem_va {
 #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
 #define AMDGPU_CHUNK_ID_BO_HANDLES  0x06
 #define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT0x08
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL  0x09
 
 struct drm_amdgpu_cs_chunk {
__u32   chunk_id;
@@ -608,6 +610,13 @@ struct drm_amdgpu_cs_chunk_sem {
__u32 handle;
 };
 
+struct drm_amdgpu_cs_chunk_syncobj {
+   __u32 handle;
+   __u32 flags;
+   __u64 point;
+};
+
+
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD  1
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD2
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 2/7] add timeline wait/query ioctl v2

2019-05-13 Thread Chunming Zhou
v2: drop export/import

Signed-off-by: Chunming Zhou 
---
 xf86drm.c | 44 
 xf86drm.h |  6 ++
 2 files changed, 50 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 2c19376b..17e3d880 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4256,3 +4256,47 @@ drm_public int drmSyncobjSignal(int fd, const uint32_t 
*handles,
 ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, );
 return ret;
 }
+
+drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t 
*points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+struct drm_syncobj_timeline_wait args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.timeout_nsec = timeout_nsec;
+args.count_handles = num_handles;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, );
+if (ret < 0)
+return -errno;
+
+if (first_signaled)
+*first_signaled = args.first_signaled;
+return ret;
+}
+
+
+drm_public int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+  uint32_t handle_count)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.count_handles = handle_count;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, );
+if (ret)
+return ret;
+return 0;
+}
+
+
diff --git a/xf86drm.h b/xf86drm.h
index 887ecc76..60c7a84f 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -876,6 +876,12 @@ extern int drmSyncobjWait(int fd, uint32_t *handles, 
unsigned num_handles,
  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t 
handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t 
handle_count);
+extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+  uint32_t handle_count);
 
 #if defined(__cplusplus)
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 1/2] drm/ttm: fix busy memory to fail other user v7

2019-05-07 Thread Chunming Zhou
heavy gpu job could occupy memory long time, which lead other user fail to get 
memory.

basically pick up Christian idea:

1. Reserve the BO in DC using a ww_mutex ticket (trivial).
2. If we then run into this EBUSY condition in TTM check if the BO we need 
memory for (or rather the ww_mutex of its reservation object) has a ticket 
assigned.
3. If we have a ticket we grab a reference to the first BO on the LRU, drop the 
LRU lock and try to grab the reservation lock with the ticket.
4. If getting the reservation lock with the ticket succeeded we check if the BO 
is still the first one on the LRU in question (the BO could have moved).
5. If the BO is still the first one on the LRU in question we try to evict it 
as we would evict any other BO.
6. If any of the "If's" above fail we just back off and return -EBUSY.

v2: fix some minor check
v3: address Christian v2 comments.
v4: fix some missing
v5: handle first_bo unlock and bo_get/put
v6: abstract unified iterate function, and handle all possible usecase not only 
pinned bo.
v7: pass request bo->resv to ttm_bo_evict_first

Change-Id: I21423fb922f885465f13833c41df1e134364a8e7
Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/ttm/ttm_bo.c | 111 +--
 1 file changed, 94 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 8502b3ed2d88..f5e6328e4a57 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -766,11 +766,13 @@ EXPORT_SYMBOL(ttm_bo_eviction_valuable);
  * b. Otherwise, trylock it.
  */
 static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
-   struct ttm_operation_ctx *ctx, bool *locked)
+   struct ttm_operation_ctx *ctx, bool *locked, bool *busy)
 {
bool ret = false;
 
*locked = false;
+   if (busy)
+   *busy = false;
if (bo->resv == ctx->resv) {
reservation_object_assert_held(bo->resv);
if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT
@@ -779,35 +781,46 @@ static bool ttm_bo_evict_swapout_allowable(struct 
ttm_buffer_object *bo,
} else {
*locked = reservation_object_trylock(bo->resv);
ret = *locked;
+   if (!ret && busy)
+   *busy = true;
}
 
return ret;
 }
 
-static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
-  uint32_t mem_type,
-  const struct ttm_place *place,
-  struct ttm_operation_ctx *ctx)
+static struct ttm_buffer_object*
+ttm_mem_find_evitable_bo(struct ttm_bo_device *bdev,
+struct ttm_mem_type_manager *man,
+const struct ttm_place *place,
+struct ttm_operation_ctx *ctx,
+struct ttm_buffer_object **first_bo,
+bool *locked)
 {
-   struct ttm_bo_global *glob = bdev->glob;
-   struct ttm_mem_type_manager *man = >man[mem_type];
struct ttm_buffer_object *bo = NULL;
-   bool locked = false;
-   unsigned i;
-   int ret;
+   int i;
 
-   spin_lock(>lru_lock);
+   if (first_bo)
+   *first_bo = NULL;
for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
list_for_each_entry(bo, >lru[i], lru) {
-   if (!ttm_bo_evict_swapout_allowable(bo, ctx, ))
+   bool busy = false;
+
+   if (!ttm_bo_evict_swapout_allowable(bo, ctx, locked,
+   )) {
+   if (first_bo && !(*first_bo) && busy) {
+   ttm_bo_get(bo);
+   *first_bo = bo;
+   }
continue;
+   }
 
if (place && !bdev->driver->eviction_valuable(bo,
  place)) {
-   if (locked)
+   if (*locked)
reservation_object_unlock(bo->resv);
continue;
}
+
break;
}
 
@@ -818,9 +831,67 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
bo = NULL;
}
 
+   return bo;
+}
+
+static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
+  uint32_t mem_type,
+  const struct ttm_place *place,
+  struct ttm_operation_ctx *ctx,
+  struct reservation_object *request_resv)
+{
+   struct ttm_bo_global *glob = bdev->glob;
+   

[PATCH 2/2] drm/amd/display: use ttm_eu_reserve_buffers instead of amdgpu_bo_reserve

2019-05-07 Thread Chunming Zhou
add ticket for display bo, so that it can preempt busy bo.

Change-Id: I9f031cdcc8267de00e819ae303baa0a52df8ebb9
Signed-off-by: Chunming Zhou 
Reviewed-by: Christian König 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 ++-
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ac22f7351a42..3f36770946ab 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4176,6 +4176,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
struct amdgpu_device *adev;
struct amdgpu_bo *rbo;
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
+   struct list_head list;
+   struct ttm_validate_buffer tv;
+   struct ww_acquire_ctx ticket;
uint64_t tiling_flags;
uint32_t domain;
int r;
@@ -4192,9 +4195,17 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
obj = new_state->fb->obj[0];
rbo = gem_to_amdgpu_bo(obj);
adev = amdgpu_ttm_adev(rbo->tbo.bdev);
-   r = amdgpu_bo_reserve(rbo, false);
-   if (unlikely(r != 0))
+   INIT_LIST_HEAD();
+
+   tv.bo = >tbo;
+   tv.num_shared = 1;
+   list_add(, );
+
+   r = ttm_eu_reserve_buffers(, , false, NULL);
+   if (r) {
+   dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
return r;
+   }
 
if (plane->type != DRM_PLANE_TYPE_CURSOR)
domain = amdgpu_display_supported_domains(adev);
@@ -4205,21 +4216,21 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to pin framebuffer with error %d\n", 
r);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
return r;
}
 
r = amdgpu_ttm_alloc_gart(>tbo);
if (unlikely(r != 0)) {
amdgpu_bo_unpin(rbo);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
DRM_ERROR("%p bind failed\n", rbo);
return r;
}
 
amdgpu_bo_get_tiling_flags(rbo, _flags);
 
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
 
afb->address = amdgpu_bo_gpu_offset(rbo);
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 4/7] add timeline signal/transfer ioctls v2

2019-05-07 Thread Chunming Zhou
v2: use one transfer ioctl

Signed-off-by: Chunming Zhou 
---
 xf86drm.c | 33 +
 xf86drm.h |  6 ++
 2 files changed, 39 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 17e3d880..acd16fab 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4257,6 +4257,21 @@ drm_public int drmSyncobjSignal(int fd, const uint32_t 
*handles,
 return ret;
 }
 
+drm_public int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+   uint64_t *points, uint32_t handle_count)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.count_handles = handle_count;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, );
+return ret;
+}
+
 drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t 
*points,
  unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
@@ -4299,4 +4314,22 @@ drm_public int drmSyncobjQuery(int fd, uint32_t 
*handles, uint64_t *points,
 return 0;
 }
 
+drm_public int drmSyncobjTransfer(int fd,
+ uint32_t dst_handle, uint64_t dst_point,
+ uint32_t src_handle, uint64_t src_point,
+ uint32_t flags)
+{
+struct drm_syncobj_transfer args;
+int ret;
+
+memclear(args);
+args.src_handle = src_handle;
+args.dst_handle = dst_handle;
+args.src_point = src_point;
+args.dst_point = dst_point;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, );
 
+return ret;
+}
diff --git a/xf86drm.h b/xf86drm.h
index 60c7a84f..3fb1d1ca 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -876,12 +876,18 @@ extern int drmSyncobjWait(int fd, uint32_t *handles, 
unsigned num_handles,
  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t 
handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t 
handle_count);
+extern int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+   uint64_t *points, uint32_t handle_count);
 extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
  unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
  uint32_t *first_signaled);
 extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
   uint32_t handle_count);
+extern int drmSyncobjTransfer(int fd,
+ uint32_t dst_handle, uint64_t dst_point,
+ uint32_t src_handle, uint64_t src_point,
+ uint32_t flags);
 
 #if defined(__cplusplus)
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 6/7] wrap transfer interfaces

2019-05-07 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
---
 amdgpu/amdgpu.h| 22 ++
 amdgpu/amdgpu_cs.c | 16 
 2 files changed, 38 insertions(+)

diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index d2480dbe..9d9b0832 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1685,6 +1685,28 @@ int 
amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
uint32_t syncobj,
uint64_t point,
int sync_file_fd);
+
+/**
+ *  transfer between syncbojs.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   dst_handle - \c [in] sync object handle
+ * \param   dst_point  - \c [in] timeline point, 0 presents dst is binary
+ * \param   src_handle - \c [in] sync object handle
+ * \param   src_point  - \c [in] timeline point, 0 presents src is binary
+ * \param   flags  - \c [in] flags
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+  uint32_t dst_handle,
+  uint64_t dst_point,
+  uint32_t src_handle,
+  uint64_t src_point,
+  uint32_t flags);
+
 /**
  * Export an amdgpu fence as a handle (syncobj or fd).
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index daca4421..977fa3cf 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -817,6 +817,22 @@ out:
return ret;
 }
 
+drm_public int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+ uint32_t dst_handle,
+ uint64_t dst_point,
+ uint32_t src_handle,
+ uint64_t src_point,
+ uint32_t flags)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTransfer(dev->fd,
+ dst_handle, dst_point,
+ src_handle, src_point,
+ flags);
+}
+
 drm_public int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
amdgpu_context_handle context,
amdgpu_bo_list_handle bo_list_handle,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 5/7] expose timeline signal/export/import interfaces v2

2019-05-07 Thread Chunming Zhou
v2: adapt to new one transfer ioctl

Signed-off-by: Chunming Zhou 
---
 amdgpu/amdgpu-symbol-check |  3 ++
 amdgpu/amdgpu.h| 51 
 amdgpu/amdgpu_cs.c | 68 ++
 3 files changed, 122 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index d3c5bb89..274b4c6d 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -52,10 +52,13 @@ amdgpu_cs_submit
 amdgpu_cs_submit_raw
 amdgpu_cs_submit_raw2
 amdgpu_cs_syncobj_export_sync_file
+amdgpu_cs_syncobj_export_sync_file2
 amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_import_sync_file2
 amdgpu_cs_syncobj_query
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_signal
 amdgpu_cs_syncobj_timeline_wait
 amdgpu_cs_syncobj_wait
 amdgpu_cs_wait_fences
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 5ebfe1e3..d2480dbe 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1516,6 +1516,23 @@ int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
 int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
 const uint32_t *syncobjs, uint32_t syncobj_count);
 
+/**
+ * Signal kernel timeline sync objects.
+ *
+ * \param dev   - \c [in] device handle
+ * \param syncobjs  - \c [in] array of sync object handles
+ * \param points   - \c [in] array of timeline points
+ * \param syncobj_count - \c [in] number of handles in syncobjs
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs,
+ uint64_t *points,
+ uint32_t syncobj_count);
+
 /**
  *  Wait for one or all sync objects to signal.
  *
@@ -1633,7 +1650,41 @@ int 
amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
 int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
   uint32_t syncobj,
   int sync_file_fd);
+/**
+ *  Export kernel timeline sync object to a sync_file.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   syncobj- \c [in] sync object handle
+ * \param   point  - \c [in] timeline point
+ * \param   flags  - \c [in] flags
+ * \param   sync_file_fd - \c [out] sync_file file descriptor.
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+   uint32_t syncobj,
+   uint64_t point,
+   uint32_t flags,
+   int *sync_file_fd);
 
+/**
+ *  Import kernel timeline sync object from a sync_file.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   syncobj- \c [in] sync object handle
+ * \param   point  - \c [in] timeline point
+ * \param   sync_file_fd - \c [in] sync_file file descriptor.
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
+   uint32_t syncobj,
+   uint64_t point,
+   int sync_file_fd);
 /**
  * Export an amdgpu fence as a handle (syncobj or fd).
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 9fcaf2c4..daca4421 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -674,6 +674,18 @@ drm_public int 
amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
return drmSyncobjSignal(dev->fd, syncobjs, syncobj_count);
 }
 
+drm_public int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+const uint32_t *syncobjs,
+uint64_t *points,
+uint32_t syncobj_count)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTimelineSignal(dev->fd, syncobjs,
+   points, syncobj_count);
+}
+
 drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
  uint32_t *handles, unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
@@ -749,6 +761,62 @@ drm_public int 
amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
 }
 
+drm_public int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+  uint32_t syncobj,
+  uint64_t point,
+  

[PATCH libdrm 7/7] add syncobj timeline tests v3

2019-05-07 Thread Chunming Zhou
v2: drop DRM_SYNCOBJ_CREATE_TYPE_TIMELINE, fix timeout calculation,
fix some warnings
v3: add export/import and cpu signal testing cases

Signed-off-by: Chunming Zhou 
---
 tests/amdgpu/Makefile.am |   3 +-
 tests/amdgpu/amdgpu_test.c   |  11 ++
 tests/amdgpu/amdgpu_test.h   |  21 +++
 tests/amdgpu/meson.build |   2 +-
 tests/amdgpu/syncobj_tests.c | 290 +++
 5 files changed, 325 insertions(+), 2 deletions(-)
 create mode 100644 tests/amdgpu/syncobj_tests.c

diff --git a/tests/amdgpu/Makefile.am b/tests/amdgpu/Makefile.am
index 48278848..920882d0 100644
--- a/tests/amdgpu/Makefile.am
+++ b/tests/amdgpu/Makefile.am
@@ -34,4 +34,5 @@ amdgpu_test_SOURCES = \
uve_ib.h \
deadlock_tests.c \
vm_tests.c  \
-   ras_tests.c
+   ras_tests.c \
+   syncobj_tests.c
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
index 35c8bf6c..73403fb4 100644
--- a/tests/amdgpu/amdgpu_test.c
+++ b/tests/amdgpu/amdgpu_test.c
@@ -57,6 +57,7 @@
 #define DEADLOCK_TESTS_STR "Deadlock Tests"
 #define VM_TESTS_STR "VM Tests"
 #define RAS_TESTS_STR "RAS Tests"
+#define SYNCOBJ_TIMELINE_TESTS_STR "SYNCOBJ TIMELINE Tests"
 
 /**
  *  Open handles for amdgpu devices
@@ -123,6 +124,12 @@ static CU_SuiteInfo suites[] = {
.pCleanupFunc = suite_ras_tests_clean,
.pTests = ras_tests,
},
+   {
+   .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+   .pInitFunc = suite_syncobj_timeline_tests_init,
+   .pCleanupFunc = suite_syncobj_timeline_tests_clean,
+   .pTests = syncobj_timeline_tests,
+   },
 
CU_SUITE_INFO_NULL,
 };
@@ -176,6 +183,10 @@ static Suites_Active_Status suites_active_stat[] = {
.pName = RAS_TESTS_STR,
.pActive = suite_ras_tests_enable,
},
+   {
+   .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+   .pActive = suite_syncobj_timeline_tests_enable,
+   },
 };
 
 
diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h
index bcd0bc7e..36675ea3 100644
--- a/tests/amdgpu/amdgpu_test.h
+++ b/tests/amdgpu/amdgpu_test.h
@@ -216,6 +216,27 @@ CU_BOOL suite_ras_tests_enable(void);
 extern CU_TestInfo ras_tests[];
 
 
+/**
+ * Initialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_init();
+
+/**
+ * Deinitialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_syncobj_timeline_tests_enable(void);
+
+/**
+ * Tests in syncobj timeline test suite
+ */
+extern CU_TestInfo syncobj_timeline_tests[];
+
+
 /**
  * Helper functions
  */
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 95ed9305..1726cb43 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -24,7 +24,7 @@ if dep_cunit.found()
 files(
   'amdgpu_test.c', 'basic_tests.c', 'bo_tests.c', 'cs_tests.c',
   'vce_tests.c', 'uvd_enc_tests.c', 'vcn_tests.c', 'deadlock_tests.c',
-  'vm_tests.c', 'ras_tests.c',
+  'vm_tests.c', 'ras_tests.c', 'syncobj_tests.c',
 ),
 dependencies : [dep_cunit, dep_threads],
 include_directories : [inc_root, inc_drm, 
include_directories('../../amdgpu')],
diff --git a/tests/amdgpu/syncobj_tests.c b/tests/amdgpu/syncobj_tests.c
new file mode 100644
index ..a0c627d7
--- /dev/null
+++ b/tests/amdgpu/syncobj_tests.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include 
+
+static  amdgpu_device_handle device_handle;
+static  ui

[PATCH libdrm 3/7] wrap syncobj timeline query/wait APIs for amdgpu v3

2019-05-07 Thread Chunming Zhou
v2: symbos are stored in lexical order.
v3: drop export/import and extra query indirection

Signed-off-by: Chunming Zhou 
---
 amdgpu/amdgpu-symbol-check |  2 ++
 amdgpu/amdgpu.h| 39 ++
 amdgpu/amdgpu_cs.c | 23 ++
 3 files changed, 64 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 4d806922..d3c5bb89 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -53,8 +53,10 @@ amdgpu_cs_submit_raw
 amdgpu_cs_submit_raw2
 amdgpu_cs_syncobj_export_sync_file
 amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_query
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_wait
 amdgpu_cs_syncobj_wait
 amdgpu_cs_wait_fences
 amdgpu_cs_wait_semaphore
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index c44a495a..5ebfe1e3 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1536,6 +1536,45 @@ int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
   int64_t timeout_nsec, unsigned flags,
   uint32_t *first_signaled);
 
+/**
+ *  Wait for one or all sync objects on their points to signal.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [in] array of sync points to wait
+ * \param   num_handles - \c [in] self-explanatory
+ * \param   timeout_nsec - \c [in] self-explanatory
+ * \param   flags   - \c [in] a bitmask of DRM_SYNCOBJ_WAIT_FLAGS_*
+ * \param   first_signaled - \c [in] self-explanatory
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles,
+   int64_t timeout_nsec, unsigned flags,
+   uint32_t *first_signaled);
+/**
+ *  Query sync objects payloads.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [out] array of sync points returned, which presents
+ * syncobj payload.
+ * \param   num_handles - \c [in] self-explanatory
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles);
+
 /**
  *  Export kernel sync object to shareable fd.
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 7c5b9d13..9fcaf2c4 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -686,6 +686,29 @@ drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle 
dev,
  flags, first_signaled);
 }
 
+drm_public int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+  uint32_t *handles, uint64_t 
*points,
+  unsigned num_handles,
+  int64_t timeout_nsec, unsigned 
flags,
+  uint32_t *first_signaled)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTimelineWait(dev->fd, handles, points, num_handles,
+ timeout_nsec, flags, first_signaled);
+}
+
+drm_public int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+  uint32_t *handles, uint64_t *points,
+  unsigned num_handles)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjQuery(dev->fd, handles, points, num_handles);
+}
+
 drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
uint32_t handle,
int *shared_fd)
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 2/7] add timeline wait/query ioctl v2

2019-05-07 Thread Chunming Zhou
v2: drop export/import

Signed-off-by: Chunming Zhou 
---
 xf86drm.c | 44 
 xf86drm.h |  6 ++
 2 files changed, 50 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 2c19376b..17e3d880 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4256,3 +4256,47 @@ drm_public int drmSyncobjSignal(int fd, const uint32_t 
*handles,
 ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, );
 return ret;
 }
+
+drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t 
*points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+struct drm_syncobj_timeline_wait args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.timeout_nsec = timeout_nsec;
+args.count_handles = num_handles;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, );
+if (ret < 0)
+return -errno;
+
+if (first_signaled)
+*first_signaled = args.first_signaled;
+return ret;
+}
+
+
+drm_public int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+  uint32_t handle_count)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.count_handles = handle_count;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, );
+if (ret)
+return ret;
+return 0;
+}
+
+
diff --git a/xf86drm.h b/xf86drm.h
index 887ecc76..60c7a84f 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -876,6 +876,12 @@ extern int drmSyncobjWait(int fd, uint32_t *handles, 
unsigned num_handles,
  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t 
handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t 
handle_count);
+extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+  uint32_t handle_count);
 
 #if defined(__cplusplus)
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 1/7] addr cs chunk for syncobj timeline

2019-05-07 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
---
 include/drm/amdgpu_drm.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h
index d0701ffc..3d0318e6 100644
--- a/include/drm/amdgpu_drm.h
+++ b/include/drm/amdgpu_drm.h
@@ -528,6 +528,8 @@ struct drm_amdgpu_gem_va {
 #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
 #define AMDGPU_CHUNK_ID_BO_HANDLES  0x06
 #define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT0x08
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL  0x09
 
 struct drm_amdgpu_cs_chunk {
__u32   chunk_id;
@@ -608,6 +610,13 @@ struct drm_amdgpu_cs_chunk_sem {
__u32 handle;
 };
 
+struct drm_amdgpu_cs_chunk_syncobj {
+   __u32 handle;
+   __u32 flags;
+   __u64 point;
+};
+
+
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD  1
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD2
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 2/2] drm/amd/display: use ttm_eu_reserve_buffers instead of amdgpu_bo_reserve

2019-05-07 Thread Chunming Zhou
add ticket for display bo, so that it can preempt busy bo.

Change-Id: I9f031cdcc8267de00e819ae303baa0a52df8ebb9
Signed-off-by: Chunming Zhou 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 22 ++-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index ac22f7351a42..8633d52e3fbe 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4176,6 +4176,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
struct amdgpu_device *adev;
struct amdgpu_bo *rbo;
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
+   struct list_head list, duplicates;
+   struct ttm_validate_buffer tv;
+   struct ww_acquire_ctx ticket;
uint64_t tiling_flags;
uint32_t domain;
int r;
@@ -4192,9 +4195,18 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
obj = new_state->fb->obj[0];
rbo = gem_to_amdgpu_bo(obj);
adev = amdgpu_ttm_adev(rbo->tbo.bdev);
-   r = amdgpu_bo_reserve(rbo, false);
-   if (unlikely(r != 0))
+   INIT_LIST_HEAD();
+   INIT_LIST_HEAD();
+
+   tv.bo = >tbo;
+   tv.num_shared = 1;
+   list_add(, );
+
+   r = ttm_eu_reserve_buffers(, , false, );
+   if (r) {
+   dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
return r;
+   }
 
if (plane->type != DRM_PLANE_TYPE_CURSOR)
domain = amdgpu_display_supported_domains(adev);
@@ -4205,21 +4217,21 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to pin framebuffer with error %d\n", 
r);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
return r;
}
 
r = amdgpu_ttm_alloc_gart(>tbo);
if (unlikely(r != 0)) {
amdgpu_bo_unpin(rbo);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
DRM_ERROR("%p bind failed\n", rbo);
return r;
}
 
amdgpu_bo_get_tiling_flags(rbo, _flags);
 
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
 
afb->address = amdgpu_bo_gpu_offset(rbo);
 
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 1/2] drm/ttm: fix busy memory to fail other user v6

2019-05-07 Thread Chunming Zhou
heavy gpu job could occupy memory long time, which lead other user fail to get 
memory.

basically pick up Christian idea:

1. Reserve the BO in DC using a ww_mutex ticket (trivial).
2. If we then run into this EBUSY condition in TTM check if the BO we need 
memory for (or rather the ww_mutex of its reservation object) has a ticket 
assigned.
3. If we have a ticket we grab a reference to the first BO on the LRU, drop the 
LRU lock and try to grab the reservation lock with the ticket.
4. If getting the reservation lock with the ticket succeeded we check if the BO 
is still the first one on the LRU in question (the BO could have moved).
5. If the BO is still the first one on the LRU in question we try to evict it 
as we would evict any other BO.
6. If any of the "If's" above fail we just back off and return -EBUSY.

v2: fix some minor check
v3: address Christian v2 comments.
v4: fix some missing
v5: handle first_bo unlock and bo_get/put
v6: abstract unified iterate function, and handle all possible usecase not only 
pinned bo.

Change-Id: I21423fb922f885465f13833c41df1e134364a8e7
Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/ttm/ttm_bo.c | 113 ++-
 1 file changed, 97 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 8502b3ed2d88..bbf1d14d00a7 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -766,11 +766,13 @@ EXPORT_SYMBOL(ttm_bo_eviction_valuable);
  * b. Otherwise, trylock it.
  */
 static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
-   struct ttm_operation_ctx *ctx, bool *locked)
+   struct ttm_operation_ctx *ctx, bool *locked, bool *busy)
 {
bool ret = false;
 
*locked = false;
+   if (busy)
+   *busy = false;
if (bo->resv == ctx->resv) {
reservation_object_assert_held(bo->resv);
if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT
@@ -779,35 +781,45 @@ static bool ttm_bo_evict_swapout_allowable(struct 
ttm_buffer_object *bo,
} else {
*locked = reservation_object_trylock(bo->resv);
ret = *locked;
+   if (!ret && busy)
+   *busy = true;
}
 
return ret;
 }
 
-static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
-  uint32_t mem_type,
-  const struct ttm_place *place,
-  struct ttm_operation_ctx *ctx)
+static struct ttm_buffer_object*
+ttm_mem_find_evitable_bo(struct ttm_bo_device *bdev,
+struct ttm_mem_type_manager *man,
+const struct ttm_place *place,
+struct ttm_operation_ctx *ctx,
+struct ttm_buffer_object **first_bo,
+bool *locked)
 {
-   struct ttm_bo_global *glob = bdev->glob;
-   struct ttm_mem_type_manager *man = >man[mem_type];
struct ttm_buffer_object *bo = NULL;
-   bool locked = false;
-   unsigned i;
-   int ret;
+   int i;
 
-   spin_lock(>lru_lock);
+   if (first_bo)
+   *first_bo = NULL;
for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
list_for_each_entry(bo, >lru[i], lru) {
-   if (!ttm_bo_evict_swapout_allowable(bo, ctx, ))
+   bool busy = false;
+   if (!ttm_bo_evict_swapout_allowable(bo, ctx, locked,
+   )) {
+   if (first_bo && !(*first_bo) && busy) {
+   ttm_bo_get(bo);
+   *first_bo = bo;
+   }
continue;
+   }
 
if (place && !bdev->driver->eviction_valuable(bo,
  place)) {
-   if (locked)
+   if (*locked)
reservation_object_unlock(bo->resv);
continue;
}
+
break;
}
 
@@ -818,9 +830,66 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
bo = NULL;
}
 
+   return bo;
+}
+
+static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
+  uint32_t mem_type,
+  const struct ttm_place *place,
+  struct ttm_operation_ctx *ctx)
+{
+   struct ttm_bo_global *glob = bdev->glob;
+   struct ttm_mem_type_manager *man = >man[mem_type];
+   struct ttm_buffer_object *bo = NULL, *first_bo = NUL

[PATCH] drm/ttm: fix busy memory to fail other user v5

2019-04-30 Thread Chunming Zhou
heavy gpu job could occupy memory long time, which lead other user fail to get 
memory.

basically pick up Christian idea:

1. Reserve the BO in DC using a ww_mutex ticket (trivial).
2. If we then run into this EBUSY condition in TTM check if the BO we need 
memory for (or rather the ww_mutex of its reservation object) has a ticket 
assigned.
3. If we have a ticket we grab a reference to the first BO on the LRU, drop the 
LRU lock and try to grab the reservation lock with the ticket.
4. If getting the reservation lock with the ticket succeeded we check if the BO 
is still the first one on the LRU in question (the BO could have moved).
5. If the BO is still the first one on the LRU in question we try to evict it 
as we would evict any other BO.
6. If any of the "If's" above fail we just back off and return -EBUSY.

v2: fix some minor check
v3: address Christian v2 comments.
v4: fix some missing
v5: handle first_bo unlock and bo_get/put

Change-Id: I21423fb922f885465f13833c41df1e134364a8e7
Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c|  7 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 22 +++--
 drivers/gpu/drm/ttm/ttm_bo.c  | 81 +--
 3 files changed, 99 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index affde72b44db..523773e85284 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -811,7 +811,12 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 
domain,
 u64 min_offset, u64 max_offset)
 {
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
-   struct ttm_operation_ctx ctx = { false, false };
+   struct ttm_operation_ctx ctx = {
+   .interruptible = false,
+   .no_wait_gpu = false,
+   .resv = bo->tbo.resv,
+   .flags = 0
+   };
int r, i;
 
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a5cacf846e1b..cc3677c4a4c2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4101,6 +4101,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
struct amdgpu_device *adev;
struct amdgpu_bo *rbo;
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
+   struct list_head list, duplicates;
+   struct ttm_validate_buffer tv;
+   struct ww_acquire_ctx ticket;
uint64_t tiling_flags;
uint32_t domain;
int r;
@@ -4117,9 +4120,18 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
obj = new_state->fb->obj[0];
rbo = gem_to_amdgpu_bo(obj);
adev = amdgpu_ttm_adev(rbo->tbo.bdev);
-   r = amdgpu_bo_reserve(rbo, false);
-   if (unlikely(r != 0))
+   INIT_LIST_HEAD();
+   INIT_LIST_HEAD();
+
+   tv.bo = >tbo;
+   tv.num_shared = 1;
+   list_add(, );
+
+   r = ttm_eu_reserve_buffers(, , false, );
+   if (r) {
+   dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
return r;
+   }
 
if (plane->type != DRM_PLANE_TYPE_CURSOR)
domain = amdgpu_display_supported_domains(adev);
@@ -4130,21 +4142,21 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to pin framebuffer with error %d\n", 
r);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
return r;
}
 
r = amdgpu_ttm_alloc_gart(>tbo);
if (unlikely(r != 0)) {
amdgpu_bo_unpin(rbo);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
DRM_ERROR("%p bind failed\n", rbo);
return r;
}
 
amdgpu_bo_get_tiling_flags(rbo, _flags);
 
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
 
afb->address = amdgpu_bo_gpu_offset(rbo);
 
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 8502b3ed2d88..2c4963e105d9 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -766,11 +766,13 @@ EXPORT_SYMBOL(ttm_bo_eviction_valuable);
  * b. Otherwise, trylock it.
  */
 static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
-   struct ttm_operation_ctx *ctx, bool *locked)
+   struct ttm_operation_ctx *ctx, bool *locked, bool *busy)
 {
bool ret = false;
 
*locked = false;
+   if (busy)
+   *busy = false;
if (bo->

[PATCH] drm/ttm: fix busy memory to fail other user v5

2019-04-26 Thread Chunming Zhou
heavy gpu job could occupy memory long time, which lead other user fail to get 
memory.

basically pick up Christian idea:

1. Reserve the BO in DC using a ww_mutex ticket (trivial).
2. If we then run into this EBUSY condition in TTM check if the BO we need 
memory for (or rather the ww_mutex of its reservation object) has a ticket 
assigned.
3. If we have a ticket we grab a reference to the first BO on the LRU, drop the 
LRU lock and try to grab the reservation lock with the ticket.
4. If getting the reservation lock with the ticket succeeded we check if the BO 
is still the first one on the LRU in question (the BO could have moved).
5. If the BO is still the first one on the LRU in question we try to evict it 
as we would evict any other BO.
6. If any of the "If's" above fail we just back off and return -EBUSY.

v2: fix some minor check
v3: address Christian v2 comments.
v4: fix some missing
v5: handle first_bo unlock and bo_get/put

Change-Id: I21423fb922f885465f13833c41df1e134364a8e7
Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c|  6 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 -
 drivers/gpu/drm/ttm/ttm_bo.c  | 81 +--
 3 files changed, 99 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index affde72b44db..032edf477827 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -811,7 +811,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 
domain,
 u64 min_offset, u64 max_offset)
 {
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
-   struct ttm_operation_ctx ctx = { false, false };
+   struct ttm_operation_ctx ctx = {
+   .interruptible = false,
+   .no_wait_gpu = false,
+   .resv = bo->tbo.resv,
+   };
int r, i;
 
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a5cacf846e1b..2957ac38dcb0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4101,6 +4101,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
struct amdgpu_device *adev;
struct amdgpu_bo *rbo;
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
+   struct list_head list, duplicates;
+   struct ttm_validate_buffer tv;
+   struct ww_acquire_ctx ticket;
uint64_t tiling_flags;
uint32_t domain;
int r;
@@ -4120,6 +4123,18 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
r = amdgpu_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
+   INIT_LIST_HEAD();
+   INIT_LIST_HEAD();
+
+   tv.bo = >tbo;
+   tv.num_shared = 1;
+   list_add(, );
+
+   r = ttm_eu_reserve_buffers(, , false, );
+   if (r) {
+   dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
+   return r;
+   }
 
if (plane->type != DRM_PLANE_TYPE_CURSOR)
domain = amdgpu_display_supported_domains(adev);
@@ -4130,21 +4145,21 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to pin framebuffer with error %d\n", 
r);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
return r;
}
 
r = amdgpu_ttm_alloc_gart(>tbo);
if (unlikely(r != 0)) {
amdgpu_bo_unpin(rbo);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
DRM_ERROR("%p bind failed\n", rbo);
return r;
}
 
amdgpu_bo_get_tiling_flags(rbo, _flags);
 
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
 
afb->address = amdgpu_bo_gpu_offset(rbo);
 
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 8502b3ed2d88..2c4963e105d9 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -766,11 +766,13 @@ EXPORT_SYMBOL(ttm_bo_eviction_valuable);
  * b. Otherwise, trylock it.
  */
 static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
-   struct ttm_operation_ctx *ctx, bool *locked)
+   struct ttm_operation_ctx *ctx, bool *locked, bool *busy)
 {
bool ret = false;
 
*locked = false;
+   if (busy)
+   *busy = false;
if (bo->resv == ctx->resv) {
reservation_object_assert_held(bo->resv);
if (ctx->flags & TTM_OPT_FLAG_ALLOW

[PATCH] drm/ttm: fix busy memory to fail other user v4

2019-04-26 Thread Chunming Zhou
heavy gpu job could occupy memory long time, which lead other user fail to get 
memory.

basically pick up Christian idea:

1. Reserve the BO in DC using a ww_mutex ticket (trivial).
2. If we then run into this EBUSY condition in TTM check if the BO we need 
memory for (or rather the ww_mutex of its reservation object) has a ticket 
assigned.
3. If we have a ticket we grab a reference to the first BO on the LRU, drop the 
LRU lock and try to grab the reservation lock with the ticket.
4. If getting the reservation lock with the ticket succeeded we check if the BO 
is still the first one on the LRU in question (the BO could have moved).
5. If the BO is still the first one on the LRU in question we try to evict it 
as we would evict any other BO.
6. If any of the "If's" above fail we just back off and return -EBUSY.

v2: fix some minor check
v3: address Christian v2 comments.
v4: fix some missing

Change-Id: I21423fb922f885465f13833c41df1e134364a8e7
Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c|  6 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +-
 drivers/gpu/drm/ttm/ttm_bo.c  | 74 +--
 3 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index affde72b44db..032edf477827 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -811,7 +811,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 
domain,
 u64 min_offset, u64 max_offset)
 {
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
-   struct ttm_operation_ctx ctx = { false, false };
+   struct ttm_operation_ctx ctx = {
+   .interruptible = false,
+   .no_wait_gpu = false,
+   .resv = bo->tbo.resv,
+   };
int r, i;
 
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a5cacf846e1b..2957ac38dcb0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4101,6 +4101,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
struct amdgpu_device *adev;
struct amdgpu_bo *rbo;
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
+   struct list_head list, duplicates;
+   struct ttm_validate_buffer tv;
+   struct ww_acquire_ctx ticket;
uint64_t tiling_flags;
uint32_t domain;
int r;
@@ -4120,6 +4123,18 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
r = amdgpu_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
+   INIT_LIST_HEAD();
+   INIT_LIST_HEAD();
+
+   tv.bo = >tbo;
+   tv.num_shared = 1;
+   list_add(, );
+
+   r = ttm_eu_reserve_buffers(, , false, );
+   if (r) {
+   dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
+   return r;
+   }
 
if (plane->type != DRM_PLANE_TYPE_CURSOR)
domain = amdgpu_display_supported_domains(adev);
@@ -4130,21 +4145,21 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to pin framebuffer with error %d\n", 
r);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
return r;
}
 
r = amdgpu_ttm_alloc_gart(>tbo);
if (unlikely(r != 0)) {
amdgpu_bo_unpin(rbo);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
DRM_ERROR("%p bind failed\n", rbo);
return r;
}
 
amdgpu_bo_get_tiling_flags(rbo, _flags);
 
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
 
afb->address = amdgpu_bo_gpu_offset(rbo);
 
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 8502b3ed2d88..f4f506dad2b0 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -766,11 +766,12 @@ EXPORT_SYMBOL(ttm_bo_eviction_valuable);
  * b. Otherwise, trylock it.
  */
 static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
-   struct ttm_operation_ctx *ctx, bool *locked)
+   struct ttm_operation_ctx *ctx, bool *locked, bool *busy)
 {
bool ret = false;
 
*locked = false;
+   *busy = false;
if (bo->resv == ctx->resv) {
reservation_object_assert_held(bo->resv);
if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT
@@ -779,6 +780,8 @@ static bool ttm_bo_evict_swapout_a

[PATCH] drm/ttm: fix busy memory to fail other user v4

2019-04-26 Thread Chunming Zhou
heavy gpu job could occupy memory long time, which lead other user fail to get 
memory.

basically pick up Christian idea:

1. Reserve the BO in DC using a ww_mutex ticket (trivial).
2. If we then run into this EBUSY condition in TTM check if the BO we need 
memory for (or rather the ww_mutex of its reservation object) has a ticket 
assigned.
3. If we have a ticket we grab a reference to the first BO on the LRU, drop the 
LRU lock and try to grab the reservation lock with the ticket.
4. If getting the reservation lock with the ticket succeeded we check if the BO 
is still the first one on the LRU in question (the BO could have moved).
5. If the BO is still the first one on the LRU in question we try to evict it 
as we would evict any other BO.
6. If any of the "If's" above fail we just back off and return -EBUSY.

v2: fix some minor check
v3: address Christian v2 comments.
v4: fix some missing

Change-Id: I21423fb922f885465f13833c41df1e134364a8e7
Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c|  6 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +-
 drivers/gpu/drm/ttm/ttm_bo.c  | 70 +--
 3 files changed, 88 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index affde72b44db..032edf477827 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -811,7 +811,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 
domain,
 u64 min_offset, u64 max_offset)
 {
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
-   struct ttm_operation_ctx ctx = { false, false };
+   struct ttm_operation_ctx ctx = {
+   .interruptible = false,
+   .no_wait_gpu = false,
+   .resv = bo->tbo.resv,
+   };
int r, i;
 
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a5cacf846e1b..2957ac38dcb0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4101,6 +4101,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
struct amdgpu_device *adev;
struct amdgpu_bo *rbo;
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
+   struct list_head list, duplicates;
+   struct ttm_validate_buffer tv;
+   struct ww_acquire_ctx ticket;
uint64_t tiling_flags;
uint32_t domain;
int r;
@@ -4120,6 +4123,18 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
r = amdgpu_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
+   INIT_LIST_HEAD();
+   INIT_LIST_HEAD();
+
+   tv.bo = >tbo;
+   tv.num_shared = 1;
+   list_add(, );
+
+   r = ttm_eu_reserve_buffers(, , false, );
+   if (r) {
+   dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
+   return r;
+   }
 
if (plane->type != DRM_PLANE_TYPE_CURSOR)
domain = amdgpu_display_supported_domains(adev);
@@ -4130,21 +4145,21 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to pin framebuffer with error %d\n", 
r);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
return r;
}
 
r = amdgpu_ttm_alloc_gart(>tbo);
if (unlikely(r != 0)) {
amdgpu_bo_unpin(rbo);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
DRM_ERROR("%p bind failed\n", rbo);
return r;
}
 
amdgpu_bo_get_tiling_flags(rbo, _flags);
 
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
 
afb->address = amdgpu_bo_gpu_offset(rbo);
 
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 8502b3ed2d88..3348ca0423a1 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -766,11 +766,12 @@ EXPORT_SYMBOL(ttm_bo_eviction_valuable);
  * b. Otherwise, trylock it.
  */
 static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
-   struct ttm_operation_ctx *ctx, bool *locked)
+   struct ttm_operation_ctx *ctx, bool *locked, bool *busy)
 {
bool ret = false;
 
*locked = false;
+   *busy = false;
if (bo->resv == ctx->resv) {
reservation_object_assert_held(bo->resv);
if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT
@@ -779,6 +780,8 @@ static bool ttm_bo_evict_swapout_a

[PATCH] drm/ttm: fix busy memory to fail other user v3

2019-04-25 Thread Chunming Zhou
heavy gpu job could occupy memory long time, which lead other user fail to get 
memory.

basically pick up Christian idea:

1. Reserve the BO in DC using a ww_mutex ticket (trivial).
2. If we then run into this EBUSY condition in TTM check if the BO we need 
memory for (or rather the ww_mutex of its reservation object) has a ticket 
assigned.
3. If we have a ticket we grab a reference to the first BO on the LRU, drop the 
LRU lock and try to grab the reservation lock with the ticket.
4. If getting the reservation lock with the ticket succeeded we check if the BO 
is still the first one on the LRU in question (the BO could have moved).
5. If the BO is still the first one on the LRU in question we try to evict it 
as we would evict any other BO.
6. If any of the "If's" above fail we just back off and return -EBUSY.

v2: fix some minor check
v3: address Christian v2 comments.

Change-Id: I21423fb922f885465f13833c41df1e134364a8e7
Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c|  7 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 ++--
 drivers/gpu/drm/ttm/ttm_bo.c  | 48 +--
 3 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index affde72b44db..015bf62277d0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -811,7 +811,12 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 
domain,
 u64 min_offset, u64 max_offset)
 {
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
-   struct ttm_operation_ctx ctx = { false, false };
+   struct ttm_operation_ctx ctx = {
+   .interruptible = false,
+   .no_wait_gpu = false,
+   .resv = bo->tbo.resv,
+   .flags = TTM_OPT_FLAG_ALLOW_RES_EVICT
+   };
int r, i;
 
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a5cacf846e1b..2957ac38dcb0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4101,6 +4101,9 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
struct amdgpu_device *adev;
struct amdgpu_bo *rbo;
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
+   struct list_head list, duplicates;
+   struct ttm_validate_buffer tv;
+   struct ww_acquire_ctx ticket;
uint64_t tiling_flags;
uint32_t domain;
int r;
@@ -4120,6 +4123,18 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
r = amdgpu_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
+   INIT_LIST_HEAD();
+   INIT_LIST_HEAD();
+
+   tv.bo = >tbo;
+   tv.num_shared = 1;
+   list_add(, );
+
+   r = ttm_eu_reserve_buffers(, , false, );
+   if (r) {
+   dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
+   return r;
+   }
 
if (plane->type != DRM_PLANE_TYPE_CURSOR)
domain = amdgpu_display_supported_domains(adev);
@@ -4130,21 +4145,21 @@ static int dm_plane_helper_prepare_fb(struct drm_plane 
*plane,
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to pin framebuffer with error %d\n", 
r);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
return r;
}
 
r = amdgpu_ttm_alloc_gart(>tbo);
if (unlikely(r != 0)) {
amdgpu_bo_unpin(rbo);
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
DRM_ERROR("%p bind failed\n", rbo);
return r;
}
 
amdgpu_bo_get_tiling_flags(rbo, _flags);
 
-   amdgpu_bo_unreserve(rbo);
+   ttm_eu_backoff_reservation(, );
 
afb->address = amdgpu_bo_gpu_offset(rbo);
 
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 8502b3ed2d88..dbcf958d1b43 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -766,11 +766,12 @@ EXPORT_SYMBOL(ttm_bo_eviction_valuable);
  * b. Otherwise, trylock it.
  */
 static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
-   struct ttm_operation_ctx *ctx, bool *locked)
+   struct ttm_operation_ctx *ctx, bool *locked, bool *busy)
 {
bool ret = false;
 
*locked = false;
+   *busy = false;
if (bo->resv == ctx->resv) {
reservation_object_assert_held(bo->resv);
if (ctx->flags & TTM_OPT_FLAG_ALLOW_RES_EVICT
@@ -779,6 +780,8 @@ static b

Re: [PATCH] gpu/docs: Clarify what userspace means for gl

2019-04-24 Thread Chunming Zhou

在 2019/4/24 22:36, Daniel Vetter 写道:
> On Wed, Apr 24, 2019 at 4:28 PM Daniel Vetter  wrote:
>> On Wed, Apr 24, 2019 at 4:24 PM Zhou, David(ChunMing)
>>  wrote:
>>> Will linux be only mesa-linux? I thought linux is an  open linux.
>>> Which will impact our opengl/amdvlk(MIT open source), not sure Rocm:
>>> 1. how to deal with one uapi that opengl/amdvlk needs but mesa dont need? 
>>> reject?
>>> 2. one hw feature that opengl/amdvlk developers work on that but no mesa 
>>> developers work on, cannot upstream as well?
>>>
>>> I think above two would easily happen, because there are many employees 
>>> working on company project with many customer kinds of reqiurements, but 
>>> mesa not.
>> Well those are the questions I tried to have a clear answer for, to
>> avoid confusion, but looks like the agreement isn't perfect. But
>> there's pretty clear favour towards cross vendor userspace that's
>> collaboratively and openly developed like mesa. So whenever one of the
>> above cases you bring up happen we'll get to have a big thread on
>> dri-devel I guess.
> Aside, I think there's a pretty huge difference between rocm and
> amdvlk. rocm is developed openly and all that, the one nit there is is
> that it's not cross vendor. But then, there is no other vendor really
> (but amd still controls it all despite the usual "totally an open
> standard" lipstick in the marketing material). amdvlk otoh is open
> source in the narrowest legal sense only, and nothing else.

Do you mean if amdvlk is developed openly like Rocm does, amdvlk will be 
able to drive uapi without mesa admissable?


-David

>   And yes
> intel has some equally bad projects on the openess metric too with
> some of the more recent-ish changes in the userspace stack.
> -Daniel
>
>> -Daniel
>>
>>
>>> -David
>>>
>>>  Original Message 
>>> Subject: [PATCH] gpu/docs: Clarify what userspace means for gl
>>> From: Daniel Vetter
>>> To: DRI Development ,Mesa Dev
>>> CC: Jérôme Glisse ,Daniel Vetter ,Karol Herbst ,Kenneth Graunke ,Ben Skeggs 
>>> ,Daniel Vetter ,Sean Paul
>>>
>>> Clear rules avoid arguing.
>>>
>>> Note that this just aims to document current expectations. If that
>>> shifts (e.g. because gl isn't the main api anymore, replaced by vk),
>>> then we need to update this text.
>>>
>>> I think it'd be good to have an equally solid list on the kms side.
>>> But kms is much more meant to be a standard, and the list of userspace
>>> projects we've accepted in the past is constantly shifting and
>>> adjusting. So I figured I'll leave that as an exercise for later on.
>>>
>>> v2: Try to clarify that we don't want a mesa driver just for mesa's
>>> sake, and more clearly exclude anything that just doesn't make sense
>>> technically.  Example would be a compute driver that makes sense to be
>>> merged into drm (for kernel side code-sharing), but where the intended
>>> use is some single-source CUDA-style compute without ever bothering
>>> about any of the 3D/rendering side baggage that comes with gl/vk.
>>>
>>> v3: Drop vulkan for now, the situation there isn't as obviously
>>> clear-cut as on the gl side, and I don't want to tank this idea on a
>>> hot discussion about vk and mesa. Plus I think once we have 1-2 more
>>> vk drivers in mesa the situation on the vk side is clear-cut too, and
>>> we can do a follow-up patch to add vk to the list where we expect the
>>> userspace to be in upstream mesa. That's would give nice precedence to
>>> make it clear that this isn't cast in stone, but meant to reflect
>>> reality and should be adjusted as needed.
>>>
>>> v4: Fix typo.
>>>
>>> v5: Add a note to the commit message that this text needs to be
>>> updated when the situation changes.
>>>
>>> v6: Add a sentence why mesa will give the most meaningful review on gl
>>> stuff - it's a very active project with lots of developers.
>>>
>>> Acked-by: Dave Airlie  (v4)
>>> Acked-by: Eric Anholt  (v4)
>>> Acked-by: Alex Deucher  (v5)
>>> Acked-by: Sean Paul  (v5)
>>> Acked-by: Kenneth Graunke  (v5)
>>> Acked-by: Karol Herbst  (v5)
>>> Acked-by: Rob Clark 
>>> Acked-by: Jérôme Glisse 
>>> Acked-by: Bas Nieuwenhuizen 
>>> Acked-by: Ben Skeggs 
>>> Cc: Dave Airlie 
>>> Cc: Eric Anholt 
>>> Cc: Alex Deucher 
>>> Cc: Sean Paul 
>>> Cc: Kenneth Graunke 
>>> Cc: Karol Herbst 
>>> Cc: Rob Clark 
>>> Cc: Jérôme Glisse 
>>> Cc: Bas Nieuwenhuizen 
>>> Cc: Ben Skeggs 
>>> Signed-off-by: Daniel Vetter 
>>> ---
>>> I chatted with a pile of people in private, and there's clearly some
>>> solid support for this. But there's also some big concerns brought up
>>> by other people. The main one summed up is "what if everyone just
>>> ships vk, with a generic gl-on-vk like ANGLE?", but there's other
>>> concerns too.
>>>
>>> So all together I think this doesn't clear the bar of (almost)
>>> unanimous support which we need to make documentation actually help
>>> with clarifying what's expected. And if/when someone comes up with a
>>> more creative userspace approach for 

[PATCH] drm/ttm: fix busy memory to fail other user

2019-04-24 Thread Chunming Zhou
basically pick up Christian idea:

1. Reserve the BO in DC using a ww_mutex ticket (trivial).
2. If we then run into this EBUSY condition in TTM check if the BO we need 
memory for (or rather the ww_mutex of its reservation object) has a ticket 
assigned.
3. If we have a ticket we grab a reference to the first BO on the LRU, drop the 
LRU lock and try to grab the reservation lock with the ticket.
4. If getting the reservation lock with the ticket succeeded we check if the BO 
is still the first one on the LRU in question (the BO could have moved).
5. If the BO is still the first one on the LRU in question we try to evict it 
as we would evict any other BO.
6. If any of the "If's" above fail we just back off and return -EBUSY.

Change-Id: I21423fb922f885465f13833c41df1e134364a8e7
Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c| 14 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h|  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   |  2 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 22 +--
 drivers/gpu/drm/ttm/ttm_bo.c  | 58 +--
 include/drm/ttm/ttm_bo_api.h  |  1 +
 7 files changed, 86 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index affde72b44db..e08ff2244070 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -791,6 +791,7 @@ void amdgpu_bo_unref(struct amdgpu_bo **bo)
  * @domain: domain to be pinned to
  * @min_offset: the start of requested address range
  * @max_offset: the end of requested address range
+ * @ticket: struct ww_acquire_ctx ticket, if the pin BO has a ticket assigned
  *
  * Pins the buffer object according to requested domain and address range. If
  * the memory is unbound gart memory, binds the pages into gart table. Adjusts
@@ -808,10 +809,17 @@ void amdgpu_bo_unref(struct amdgpu_bo **bo)
  * 0 for success or a negative error code on failure.
  */
 int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
-u64 min_offset, u64 max_offset)
+u64 min_offset, u64 max_offset,
+struct ww_acquire_ctx *ticket)
 {
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
-   struct ttm_operation_ctx ctx = { false, false };
+   struct ttm_operation_ctx ctx = {
+.interruptible = false,
+.no_wait_gpu = false,
+.resv = bo->tbo.resv,
+   .ticket = ticket,
+.flags = TTM_OPT_FLAG_ALLOW_RES_EVICT
+};
int r, i;
 
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
@@ -907,7 +915,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 
domain,
  */
 int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain)
 {
-   return amdgpu_bo_pin_restricted(bo, domain, 0, 0);
+   return amdgpu_bo_pin_restricted(bo, domain, 0, 0, NULL);
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index c430e8259038..41e7fff7f3f2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -247,7 +247,8 @@ struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo);
 void amdgpu_bo_unref(struct amdgpu_bo **bo);
 int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain);
 int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
-u64 min_offset, u64 max_offset);
+u64 min_offset, u64 max_offset,
+struct ww_acquire_ctx *ticket);
 int amdgpu_bo_unpin(struct amdgpu_bo *bo);
 int amdgpu_bo_evict_vram(struct amdgpu_device *adev);
 int amdgpu_bo_init(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 22bd21efe6b1..dd31ce1a09e3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -1150,7 +1150,7 @@ static int amdgpu_ras_reserve_vram(struct amdgpu_device 
*adev,
r = amdgpu_bo_pin_restricted(bo,
AMDGPU_GEM_DOMAIN_VRAM,
offset,
-   offset + size);
+   offset + size, NULL);
if (r)
goto error_pin;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index afccca5b1f5f..e63af0debc7a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1661,7 +1661,7 @@ static int amdgpu_ttm_fw_reserve_vram_init(struct 
amdgpu_device *adev)
AMDGPU_GEM_DOMAIN_VRAM,
adev->fw_vram_usage.start_offset,
(adev->fw_vram_usage.start_offset +
-  

Re: [PATCH v5 6/6] drm/amdgpu: Avoid HW reset if guilty job already signaled.

2019-04-22 Thread Chunming Zhou
+Monk.

GPU reset is used widely in SRIOV, so need virtulizatino guy take a look.

But out of curious, why guilty job can signal more if the job is already 
set to guilty? set it wrongly?


-David

在 2019/4/18 23:00, Andrey Grodzovsky 写道:
> Also reject TDRs if another one already running.
>
> v2:
> Stop all schedulers across device and entire XGMI hive before
> force signaling HW fences.
> Avoid passing job_signaled to helper fnctions to keep all the decision
> making about skipping HW reset in one place.
>
> v3:
> Fix SW sched. hang after non HW reset. sched.hw_rq_count has to be balanced
> against it's decrement in drm_sched_stop in non HW reset case.
> v4: rebase
> v5: Revert v3 as we do it now in sceduler code.
>
> Signed-off-by: Andrey Grodzovsky 
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 143 
> +++--
>   1 file changed, 95 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index a0e165c..85f8792 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -3334,8 +3334,6 @@ static int amdgpu_device_pre_asic_reset(struct 
> amdgpu_device *adev,
>   if (!ring || !ring->sched.thread)
>   continue;
>   
> - drm_sched_stop(>sched, >base);
> -
>   /* after all hw jobs are reset, hw fence is meaningless, so 
> force_completion */
>   amdgpu_fence_driver_force_completion(ring);
>   }
> @@ -3343,6 +3341,7 @@ static int amdgpu_device_pre_asic_reset(struct 
> amdgpu_device *adev,
>   if(job)
>   drm_sched_increase_karma(>base);
>   
> + /* Don't suspend on bare metal if we are not going to HW reset the ASIC 
> */
>   if (!amdgpu_sriov_vf(adev)) {
>   
>   if (!need_full_reset)
> @@ -3480,37 +3479,21 @@ static int amdgpu_do_asic_reset(struct 
> amdgpu_hive_info *hive,
>   return r;
>   }
>   
> -static void amdgpu_device_post_asic_reset(struct amdgpu_device *adev)
> +static bool amdgpu_device_lock_adev(struct amdgpu_device *adev, bool trylock)
>   {
> - int i;
> -
> - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
> - struct amdgpu_ring *ring = adev->rings[i];
> -
> - if (!ring || !ring->sched.thread)
> - continue;
> -
> - if (!adev->asic_reset_res)
> - drm_sched_resubmit_jobs(>sched);
> + if (trylock) {
> + if (!mutex_trylock(>lock_reset))
> + return false;
> + } else
> + mutex_lock(>lock_reset);
>   
> - drm_sched_start(>sched, !adev->asic_reset_res);
> - }
> -
> - if (!amdgpu_device_has_dc_support(adev)) {
> - drm_helper_resume_force_mode(adev->ddev);
> - }
> -
> - adev->asic_reset_res = 0;
> -}
> -
> -static void amdgpu_device_lock_adev(struct amdgpu_device *adev)
> -{
> - mutex_lock(>lock_reset);
>   atomic_inc(>gpu_reset_counter);
>   adev->in_gpu_reset = 1;
>   /* Block kfd: SRIOV would do it separately */
>   if (!amdgpu_sriov_vf(adev))
>   amdgpu_amdkfd_pre_reset(adev);
> +
> + return true;
>   }
>   
>   static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
> @@ -3538,40 +3521,42 @@ static void amdgpu_device_unlock_adev(struct 
> amdgpu_device *adev)
>   int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
> struct amdgpu_job *job)
>   {
> - int r;
> + struct list_head device_list, *device_list_handle =  NULL;
> + bool need_full_reset, job_signaled;
>   struct amdgpu_hive_info *hive = NULL;
> - bool need_full_reset = false;
>   struct amdgpu_device *tmp_adev = NULL;
> - struct list_head device_list, *device_list_handle =  NULL;
> + int i, r = 0;
>   
> + need_full_reset = job_signaled = false;
>   INIT_LIST_HEAD(_list);
>   
>   dev_info(adev->dev, "GPU reset begin!\n");
>   
> + hive = amdgpu_get_xgmi_hive(adev, false);
> +
>   /*
> -  * In case of XGMI hive disallow concurrent resets to be triggered
> -  * by different nodes. No point also since the one node already 
> executing
> -  * reset will also reset all the other nodes in the hive.
> +  * Here we trylock to avoid chain of resets executing from
> +  * either trigger by jobs on different adevs in XGMI hive or jobs on
> +  * different schedulers for same device while this TO handler is 
> running.
> +  * We always reset all schedulers for device and all devices for XGMI
> +  * hive so that should take care of them too.
>*/
> - hive = amdgpu_get_xgmi_hive(adev, 0);
> - if (hive && adev->gmc.xgmi.num_physical_nodes > 1 &&
> - !mutex_trylock(>reset_lock))
> +
> + if (hive && !mutex_trylock(>reset_lock)) {
> + DRM_INFO("Bailing on TDR for s_job:%llx, hive: %llx as another 
> already in 

Re: [PATCH v5 4/6] drm/sched: Keep s_fence->parent pointer

2019-04-22 Thread Chunming Zhou
+Monk to response this patch.


在 2019/4/18 23:00, Andrey Grodzovsky 写道:
> For later driver's reference to see if the fence is signaled.
>
> v2: Move parent fence put to resubmit jobs.
>
> Signed-off-by: Andrey Grodzovsky 
> Reviewed-by: Christian König 
> ---
>   drivers/gpu/drm/scheduler/sched_main.c | 11 +--
>   1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> b/drivers/gpu/drm/scheduler/sched_main.c
> index 7816de7..03e6bd8 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -375,8 +375,6 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, 
> struct drm_sched_job *bad)
>   if (s_job->s_fence->parent &&
>   dma_fence_remove_callback(s_job->s_fence->parent,
> _job->cb)) {
> - dma_fence_put(s_job->s_fence->parent);
> - s_job->s_fence->parent = NULL;

I vaguely remember Monk set parent to be NULL to avoiod potiential free 
problem after callback removal.


-David


>   atomic_dec(>hw_rq_count);
>   } else {
>   /*
> @@ -403,6 +401,14 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, 
> struct drm_sched_job *bad)
>   sched->ops->free_job(s_job);
>   }
>   }
> +
> + /*
> +  * Stop pending timer in flight as we rearm it in  drm_sched_start. This
> +  * avoids the pending timeout work in progress to fire right away after
> +  * this TDR finished and before the newly restarted jobs had a
> +  * chance to complete.
> +  */
> + cancel_delayed_work(>work_tdr);
>   }
>   
>   EXPORT_SYMBOL(drm_sched_stop);
> @@ -477,6 +483,7 @@ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler 
> *sched)
>   if (found_guilty && s_job->s_fence->scheduled.context == 
> guilty_context)
>   dma_fence_set_error(_fence->finished, -ECANCELED);
>   
> + dma_fence_put(s_job->s_fence->parent);
>   s_job->s_fence->parent = sched->ops->run_job(s_job);
>   }
>   }
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v5 3/6] drm/scheduler: rework job destruction

2019-04-22 Thread Chunming Zhou
Hi Andrey,

static void drm_sched_process_job(struct dma_fence *f, struct 
dma_fence_cb *cb)
{
...
     spin_lock_irqsave(>job_list_lock, flags);
     /* remove job from ring_mirror_list */
     list_del_init(_job->node);
     spin_unlock_irqrestore(>job_list_lock, flags);
[David] How about just remove above to worker from irq process? Any 
problem? Maybe I missed previous your discussion, but I think removing 
lock for list is a risk for future maintenance although you make sure 
thread safe currently.

-David

...

     schedule_work(_job->finish_work);
}

在 2019/4/18 23:00, Andrey Grodzovsky 写道:
> From: Christian König 
>
> We now destroy finished jobs from the worker thread to make sure that
> we never destroy a job currently in timeout processing.
> By this we avoid holding lock around ring mirror list in drm_sched_stop
> which should solve a deadlock reported by a user.
>
> v2: Remove unused variable.
> v4: Move guilty job free into sched code.
> v5:
> Move sched->hw_rq_count to drm_sched_start to account for counter
> decrement in drm_sched_stop even when we don't call resubmit jobs
> if guily job did signal.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109692
>
> Signed-off-by: Christian König 
> Signed-off-by: Andrey Grodzovsky 
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |   9 +-
>   drivers/gpu/drm/etnaviv/etnaviv_dump.c |   4 -
>   drivers/gpu/drm/etnaviv/etnaviv_sched.c|   2 +-
>   drivers/gpu/drm/lima/lima_sched.c  |   2 +-
>   drivers/gpu/drm/panfrost/panfrost_job.c|   2 +-
>   drivers/gpu/drm/scheduler/sched_main.c | 159 
> +
>   drivers/gpu/drm/v3d/v3d_sched.c|   2 +-
>   include/drm/gpu_scheduler.h|   6 +-
>   8 files changed, 102 insertions(+), 84 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 7cee269..a0e165c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -3334,7 +3334,7 @@ static int amdgpu_device_pre_asic_reset(struct 
> amdgpu_device *adev,
>   if (!ring || !ring->sched.thread)
>   continue;
>   
> - drm_sched_stop(>sched);
> + drm_sched_stop(>sched, >base);
>   
>   /* after all hw jobs are reset, hw fence is meaningless, so 
> force_completion */
>   amdgpu_fence_driver_force_completion(ring);
> @@ -3343,8 +3343,6 @@ static int amdgpu_device_pre_asic_reset(struct 
> amdgpu_device *adev,
>   if(job)
>   drm_sched_increase_karma(>base);
>   
> -
> -
>   if (!amdgpu_sriov_vf(adev)) {
>   
>   if (!need_full_reset)
> @@ -3482,8 +3480,7 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info 
> *hive,
>   return r;
>   }
>   
> -static void amdgpu_device_post_asic_reset(struct amdgpu_device *adev,
> -   struct amdgpu_job *job)
> +static void amdgpu_device_post_asic_reset(struct amdgpu_device *adev)
>   {
>   int i;
>   
> @@ -3623,7 +3620,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device 
> *adev,
>   
>   /* Post ASIC reset for all devs .*/
>   list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) {
> - amdgpu_device_post_asic_reset(tmp_adev, tmp_adev == adev ? job 
> : NULL);
> + amdgpu_device_post_asic_reset(tmp_adev);
>   
>   if (r) {
>   /* bad news, how to tell it to userspace ? */
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c 
> b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
> index 33854c9..5778d9c 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c
> @@ -135,13 +135,11 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
>   mmu_size + gpu->buffer.size;
>   
>   /* Add in the active command buffers */
> - spin_lock_irqsave(>sched.job_list_lock, flags);
>   list_for_each_entry(s_job, >sched.ring_mirror_list, node) {
>   submit = to_etnaviv_submit(s_job);
>   file_size += submit->cmdbuf.size;
>   n_obj++;
>   }
> - spin_unlock_irqrestore(>sched.job_list_lock, flags);
>   
>   /* Add in the active buffer objects */
>   list_for_each_entry(vram, >mmu->mappings, mmu_node) {
> @@ -183,14 +181,12 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
> gpu->buffer.size,
> etnaviv_cmdbuf_get_va(>buffer));
>   
> - spin_lock_irqsave(>sched.job_list_lock, flags);
>   list_for_each_entry(s_job, >sched.ring_mirror_list, node) {
>   submit = to_etnaviv_submit(s_job);
>   etnaviv_core_dump_mem(, ETDUMP_BUF_CMD,
> submit->cmdbuf.vaddr, submit->cmdbuf.size,
> etnaviv_cmdbuf_get_va(>cmdbuf));
>   }
> - 

[PATCH] ttm: wait mem space if user allow while gpu busy

2019-04-22 Thread Chunming Zhou
heavy gpu job could occupy memory long time, which could lead to other
user fail to get memory.

Change-Id: I0b322d98cd76e5ac32b00462bbae8008d76c5e11
Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/ttm/ttm_bo.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 7c484729f9b2..6c596cc24bec 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -830,8 +830,10 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object 
*bo,
if (mem->mm_node)
break;
ret = ttm_mem_evict_first(bdev, mem_type, place, ctx);
-   if (unlikely(ret != 0))
-   return ret;
+   if (unlikely(ret != 0)) {
+   if (!ctx || ctx->no_wait_gpu || ret != -EBUSY)
+   return ret;
+   }
} while (1);
mem->mem_type = mem_type;
return ttm_bo_add_move_fence(bo, man, mem);
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: dynamic DMA-buf sharing between devices

2019-04-17 Thread Chunming Zhou
I like you do somethings step by step, you can ping me when they are ready.

-David

在 2019/4/17 21:59, Christian König 写道:
> On top of those I have 6 more patches in the pipeline to enable VRAM 
> P2P with DMA-buf.
>
> So that is not the end of the patch set :)
>
> Christian.
>
> Am 17.04.19 um 15:52 schrieb Chunming Zhou:
>> Thanks Christian, great job. I will verify it this week when I finish my
>> current work on hand.
>>
>> -David
>>
>> 在 2019/4/17 2:38, Christian König wrote:
>>> Hi everybody,
>>>
>>> core idea in this patch set is that DMA-buf importers can now 
>>> provide an optional invalidate callback. Using this callback and the 
>>> reservation object exporters can now avoid pinning DMA-buf memory 
>>> for a long time while sharing it between devices.
>>>
>>> I've already send out an older version roughly a year ago, but 
>>> didn't had time to further look into cleaning this up.
>>>
>>> The last time a major problem was that we would had to fix up all 
>>> drivers implementing DMA-buf at once.
>>>
>>> Now I avoid this by allowing mappings to be cached in the DMA-buf 
>>> attachment and so driver can optionally move over to the new 
>>> interface one by one.
>>>
>>> This is also a prerequisite to my patchset enabling sharing of 
>>> device memory with DMA-buf.
>>>
>>> Please review and/or comment,
>>> Christian.
>>>
>>>
>>> ___
>>> dri-devel mailing list
>>> dri-devel@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: dynamic DMA-buf sharing between devices

2019-04-17 Thread Chunming Zhou
Thanks Christian, great job. I will verify it this week when I finish my 
current work on hand.

-David

在 2019/4/17 2:38, Christian König wrote:
> Hi everybody,
>
> core idea in this patch set is that DMA-buf importers can now provide an 
> optional invalidate callback. Using this callback and the reservation object 
> exporters can now avoid pinning DMA-buf memory for a long time while sharing 
> it between devices.
>
> I've already send out an older version roughly a year ago, but didn't had 
> time to further look into cleaning this up.
>
> The last time a major problem was that we would had to fix up all drivers 
> implementing DMA-buf at once.
>
> Now I avoid this by allowing mappings to be cached in the DMA-buf attachment 
> and so driver can optionally move over to the new interface one by one.
>
> This is also a prerequisite to my patchset enabling sharing of device memory 
> with DMA-buf.
>
> Please review and/or comment,
> Christian.
>
>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 8/8] add syncobj timeline tests v3

2019-04-09 Thread Chunming Zhou
v2: drop DRM_SYNCOBJ_CREATE_TYPE_TIMELINE, fix timeout calculation,
fix some warnings
v3: add export/import and cpu signal testing cases

Signed-off-by: Chunming Zhou 
Signed-off-by: Christian König 
---
 tests/amdgpu/Makefile.am |   3 +-
 tests/amdgpu/amdgpu_test.c   |  11 ++
 tests/amdgpu/amdgpu_test.h   |  21 +++
 tests/amdgpu/meson.build |   2 +-
 tests/amdgpu/syncobj_tests.c | 290 +++
 5 files changed, 325 insertions(+), 2 deletions(-)
 create mode 100644 tests/amdgpu/syncobj_tests.c

diff --git a/tests/amdgpu/Makefile.am b/tests/amdgpu/Makefile.am
index 48278848..920882d0 100644
--- a/tests/amdgpu/Makefile.am
+++ b/tests/amdgpu/Makefile.am
@@ -34,4 +34,5 @@ amdgpu_test_SOURCES = \
uve_ib.h \
deadlock_tests.c \
vm_tests.c  \
-   ras_tests.c
+   ras_tests.c \
+   syncobj_tests.c
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
index 8fc7a0b9..214c7fce 100644
--- a/tests/amdgpu/amdgpu_test.c
+++ b/tests/amdgpu/amdgpu_test.c
@@ -57,6 +57,7 @@
 #define DEADLOCK_TESTS_STR "Deadlock Tests"
 #define VM_TESTS_STR "VM Tests"
 #define RAS_TESTS_STR "RAS Tests"
+#define SYNCOBJ_TIMELINE_TESTS_STR "SYNCOBJ TIMELINE Tests"
 
 /**
  *  Open handles for amdgpu devices
@@ -123,6 +124,12 @@ static CU_SuiteInfo suites[] = {
.pCleanupFunc = suite_ras_tests_clean,
.pTests = ras_tests,
},
+   {
+   .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+   .pInitFunc = suite_syncobj_timeline_tests_init,
+   .pCleanupFunc = suite_syncobj_timeline_tests_clean,
+   .pTests = syncobj_timeline_tests,
+   },
 
CU_SUITE_INFO_NULL,
 };
@@ -176,6 +183,10 @@ static Suites_Active_Status suites_active_stat[] = {
.pName = RAS_TESTS_STR,
.pActive = suite_ras_tests_enable,
},
+   {
+   .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+   .pActive = suite_syncobj_timeline_tests_enable,
+   },
 };
 
 
diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h
index bcd0bc7e..36675ea3 100644
--- a/tests/amdgpu/amdgpu_test.h
+++ b/tests/amdgpu/amdgpu_test.h
@@ -216,6 +216,27 @@ CU_BOOL suite_ras_tests_enable(void);
 extern CU_TestInfo ras_tests[];
 
 
+/**
+ * Initialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_init();
+
+/**
+ * Deinitialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_syncobj_timeline_tests_enable(void);
+
+/**
+ * Tests in syncobj timeline test suite
+ */
+extern CU_TestInfo syncobj_timeline_tests[];
+
+
 /**
  * Helper functions
  */
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 95ed9305..1726cb43 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -24,7 +24,7 @@ if dep_cunit.found()
 files(
   'amdgpu_test.c', 'basic_tests.c', 'bo_tests.c', 'cs_tests.c',
   'vce_tests.c', 'uvd_enc_tests.c', 'vcn_tests.c', 'deadlock_tests.c',
-  'vm_tests.c', 'ras_tests.c',
+  'vm_tests.c', 'ras_tests.c', 'syncobj_tests.c',
 ),
 dependencies : [dep_cunit, dep_threads],
 include_directories : [inc_root, inc_drm, 
include_directories('../../amdgpu')],
diff --git a/tests/amdgpu/syncobj_tests.c b/tests/amdgpu/syncobj_tests.c
new file mode 100644
index ..a0c627d7
--- /dev/null
+++ b/tests/amdgpu/syncobj_tests.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include 
+
+static  amdgpu_device_hand

[PATCH libdrm 3/8] add timeline wait/query ioctl v2

2019-04-09 Thread Chunming Zhou
v2: drop export/import

Signed-off-by: Chunming Zhou 
---
 xf86drm.c | 44 
 xf86drm.h |  6 ++
 2 files changed, 50 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 18ad7c58..66e0c985 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4279,3 +4279,47 @@ drm_public int drmSyncobjSignal(int fd, const uint32_t 
*handles,
 ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, );
 return ret;
 }
+
+drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t 
*points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+struct drm_syncobj_timeline_wait args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.timeout_nsec = timeout_nsec;
+args.count_handles = num_handles;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, );
+if (ret < 0)
+return -errno;
+
+if (first_signaled)
+*first_signaled = args.first_signaled;
+return ret;
+}
+
+
+drm_public int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+  uint32_t handle_count)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.count_handles = handle_count;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, );
+if (ret)
+return ret;
+return 0;
+}
+
+
diff --git a/xf86drm.h b/xf86drm.h
index 887ecc76..60c7a84f 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -876,6 +876,12 @@ extern int drmSyncobjWait(int fd, uint32_t *handles, 
unsigned num_handles,
  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t 
handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t 
handle_count);
+extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+  uint32_t handle_count);
 
 #if defined(__cplusplus)
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 4/8] wrap syncobj timeline query/wait APIs for amdgpu v3

2019-04-09 Thread Chunming Zhou
v2: symbos are stored in lexical order.
v3: drop export/import and extra query indirection

Signed-off-by: Chunming Zhou 
Signed-off-by: Christian König 
---
 amdgpu/amdgpu-symbol-check |  2 ++
 amdgpu/amdgpu.h| 39 ++
 amdgpu/amdgpu_cs.c | 23 ++
 3 files changed, 64 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 96a44b40..67ba3039 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -52,8 +52,10 @@ amdgpu_cs_submit_raw
 amdgpu_cs_submit_raw2
 amdgpu_cs_syncobj_export_sync_file
 amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_query
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_wait
 amdgpu_cs_syncobj_wait
 amdgpu_cs_wait_fences
 amdgpu_cs_wait_semaphore
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index d6de3b8d..dcf662e9 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1521,6 +1521,45 @@ int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
   int64_t timeout_nsec, unsigned flags,
   uint32_t *first_signaled);
 
+/**
+ *  Wait for one or all sync objects on their points to signal.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [in] array of sync points to wait
+ * \param   num_handles - \c [in] self-explanatory
+ * \param   timeout_nsec - \c [in] self-explanatory
+ * \param   flags   - \c [in] a bitmask of DRM_SYNCOBJ_WAIT_FLAGS_*
+ * \param   first_signaled - \c [in] self-explanatory
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles,
+   int64_t timeout_nsec, unsigned flags,
+   uint32_t *first_signaled);
+/**
+ *  Query sync objects payloads.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [out] array of sync points returned, which presents
+ * syncobj payload.
+ * \param   num_handles - \c [in] self-explanatory
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles);
+
 /**
  *  Export kernel sync object to shareable fd.
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 5bedf748..b8b0d566 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -661,6 +661,29 @@ drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle 
dev,
  flags, first_signaled);
 }
 
+drm_public int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+  uint32_t *handles, uint64_t 
*points,
+  unsigned num_handles,
+  int64_t timeout_nsec, unsigned 
flags,
+  uint32_t *first_signaled)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTimelineWait(dev->fd, handles, points, num_handles,
+ timeout_nsec, flags, first_signaled);
+}
+
+drm_public int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+  uint32_t *handles, uint64_t *points,
+  unsigned num_handles)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjQuery(dev->fd, handles, points, num_handles);
+}
+
 drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
uint32_t handle,
int *shared_fd)
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 2/8] addr cs chunk for syncobj timeline

2019-04-09 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
---
 include/drm/amdgpu_drm.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h
index e3a97da4..ab53f2e0 100644
--- a/include/drm/amdgpu_drm.h
+++ b/include/drm/amdgpu_drm.h
@@ -528,6 +528,8 @@ struct drm_amdgpu_gem_va {
 #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
 #define AMDGPU_CHUNK_ID_BO_HANDLES  0x06
 #define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT0x08
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL  0x09
 
 struct drm_amdgpu_cs_chunk {
__u32   chunk_id;
@@ -608,6 +610,13 @@ struct drm_amdgpu_cs_chunk_sem {
__u32 handle;
 };
 
+struct drm_amdgpu_cs_chunk_syncobj {
+   __u32 handle;
+   __u32 flags;
+   __u64 point;
+};
+
+
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD  1
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD2
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 6/8] expose timeline signal/export/import interfaces v2

2019-04-09 Thread Chunming Zhou
v2: adapt to new one transfer ioctl

Signed-off-by: Chunming Zhou 
---
 amdgpu/amdgpu-symbol-check |  3 ++
 amdgpu/amdgpu.h| 51 
 amdgpu/amdgpu_cs.c | 68 ++
 3 files changed, 122 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 67ba3039..0cc54e5e 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -51,10 +51,13 @@ amdgpu_cs_submit
 amdgpu_cs_submit_raw
 amdgpu_cs_submit_raw2
 amdgpu_cs_syncobj_export_sync_file
+amdgpu_cs_syncobj_export_sync_file2
 amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_import_sync_file2
 amdgpu_cs_syncobj_query
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_signal
 amdgpu_cs_syncobj_timeline_wait
 amdgpu_cs_syncobj_wait
 amdgpu_cs_wait_fences
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index dcf662e9..b5bd3ed9 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1501,6 +1501,23 @@ int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
 int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
 const uint32_t *syncobjs, uint32_t syncobj_count);
 
+/**
+ * Signal kernel timeline sync objects.
+ *
+ * \param dev   - \c [in] device handle
+ * \param syncobjs  - \c [in] array of sync object handles
+ * \param points   - \c [in] array of timeline points
+ * \param syncobj_count - \c [in] number of handles in syncobjs
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs,
+ uint64_t *points,
+ uint32_t syncobj_count);
+
 /**
  *  Wait for one or all sync objects to signal.
  *
@@ -1618,7 +1635,41 @@ int 
amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
 int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
   uint32_t syncobj,
   int sync_file_fd);
+/**
+ *  Export kernel timeline sync object to a sync_file.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   syncobj- \c [in] sync object handle
+ * \param   point  - \c [in] timeline point
+ * \param   flags  - \c [in] flags
+ * \param   sync_file_fd - \c [out] sync_file file descriptor.
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+   uint32_t syncobj,
+   uint64_t point,
+   uint32_t flags,
+   int *sync_file_fd);
 
+/**
+ *  Import kernel timeline sync object from a sync_file.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   syncobj- \c [in] sync object handle
+ * \param   point  - \c [in] timeline point
+ * \param   sync_file_fd - \c [in] sync_file file descriptor.
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
+   uint32_t syncobj,
+   uint64_t point,
+   int sync_file_fd);
 /**
  * Export an amdgpu fence as a handle (syncobj or fd).
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index b8b0d566..1c02d16f 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -649,6 +649,18 @@ drm_public int 
amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
return drmSyncobjSignal(dev->fd, syncobjs, syncobj_count);
 }
 
+drm_public int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+const uint32_t *syncobjs,
+uint64_t *points,
+uint32_t syncobj_count)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTimelineSignal(dev->fd, syncobjs,
+   points, syncobj_count);
+}
+
 drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
  uint32_t *handles, unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
@@ -724,6 +736,62 @@ drm_public int 
amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
 }
 
+drm_public int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+  uint32_t syncobj,
+  uint64_t point,
+  

[PATCH libdrm 7/8] wrap transfer interfaces

2019-04-09 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
---
 amdgpu/amdgpu.h| 22 ++
 amdgpu/amdgpu_cs.c | 16 
 2 files changed, 38 insertions(+)

diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index b5bd3ed9..2350835b 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1670,6 +1670,28 @@ int 
amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
uint32_t syncobj,
uint64_t point,
int sync_file_fd);
+
+/**
+ *  transfer between syncbojs.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   dst_handle - \c [in] sync object handle
+ * \param   dst_point  - \c [in] timeline point, 0 presents dst is binary
+ * \param   src_handle - \c [in] sync object handle
+ * \param   src_point  - \c [in] timeline point, 0 presents src is binary
+ * \param   flags  - \c [in] flags
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+  uint32_t dst_handle,
+  uint64_t dst_point,
+  uint32_t src_handle,
+  uint64_t src_point,
+  uint32_t flags);
+
 /**
  * Export an amdgpu fence as a handle (syncobj or fd).
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 1c02d16f..a1c1af55 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -792,6 +792,22 @@ out:
return ret;
 }
 
+drm_public int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+ uint32_t dst_handle,
+ uint64_t dst_point,
+ uint32_t src_handle,
+ uint64_t src_point,
+ uint32_t flags)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTransfer(dev->fd,
+ dst_handle, dst_point,
+ src_handle, src_point,
+ flags);
+}
+
 drm_public int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
amdgpu_context_handle context,
amdgpu_bo_list_handle bo_list_handle,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 5/8] add timeline signal/transfer ioctls v2

2019-04-09 Thread Chunming Zhou
v2: use one transfer ioctl

Signed-off-by: Chunming Zhou 
---
 xf86drm.c | 33 +
 xf86drm.h |  6 ++
 2 files changed, 39 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 66e0c985..d57c4218 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4280,6 +4280,21 @@ drm_public int drmSyncobjSignal(int fd, const uint32_t 
*handles,
 return ret;
 }
 
+drm_public int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+   uint64_t *points, uint32_t handle_count)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.count_handles = handle_count;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, );
+return ret;
+}
+
 drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t 
*points,
  unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
@@ -4322,4 +4337,22 @@ drm_public int drmSyncobjQuery(int fd, uint32_t 
*handles, uint64_t *points,
 return 0;
 }
 
+drm_public int drmSyncobjTransfer(int fd,
+ uint32_t dst_handle, uint64_t dst_point,
+ uint32_t src_handle, uint64_t src_point,
+ uint32_t flags)
+{
+struct drm_syncobj_transfer args;
+int ret;
+
+memclear(args);
+args.src_handle = src_handle;
+args.dst_handle = dst_handle;
+args.src_point = src_point;
+args.dst_point = dst_point;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, );
 
+return ret;
+}
diff --git a/xf86drm.h b/xf86drm.h
index 60c7a84f..3fb1d1ca 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -876,12 +876,18 @@ extern int drmSyncobjWait(int fd, uint32_t *handles, 
unsigned num_handles,
  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t 
handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t 
handle_count);
+extern int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+   uint64_t *points, uint32_t handle_count);
 extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
  unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
  uint32_t *first_signaled);
 extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
   uint32_t handle_count);
+extern int drmSyncobjTransfer(int fd,
+ uint32_t dst_handle, uint64_t dst_point,
+ uint32_t src_handle, uint64_t src_point,
+ uint32_t flags);
 
 #if defined(__cplusplus)
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 1/8] new syncobj extension v3

2019-04-09 Thread Chunming Zhou
v2: drop not implemented IOCTLs and flags
v3: add transfer/signal ioctls

Signed-off-by: Chunming Zhou 
Signed-off-by: Christian König 
---
 include/drm/drm.h | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/include/drm/drm.h b/include/drm/drm.h
index 85c685a2..26f51bca 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -729,8 +729,18 @@ struct drm_syncobj_handle {
__u32 pad;
 };
 
+struct drm_syncobj_transfer {
+__u32 src_handle;
+__u32 dst_handle;
+__u64 src_point;
+__u64 dst_point;
+__u32 flags;
+__u32 pad;
+};
+
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2)
 struct drm_syncobj_wait {
__u64 handles;
/* absolute timeout */
@@ -741,12 +751,31 @@ struct drm_syncobj_wait {
__u32 pad;
 };
 
+struct drm_syncobj_timeline_wait {
+__u64 handles;
+/* wait on specific timeline point for every handles*/
+__u64 points;
+/* absolute timeout */
+__s64 timeout_nsec;
+__u32 count_handles;
+__u32 flags;
+__u32 first_signaled; /* only valid when not waiting all */
+__u32 pad;
+};
+
 struct drm_syncobj_array {
__u64 handles;
__u32 count_handles;
__u32 pad;
 };
 
+struct drm_syncobj_timeline_array {
+__u64 handles;
+__u64 points;
+__u32 count_handles;
+__u32 pad;
+};
+
 /* Query current scanout sequence number */
 struct drm_crtc_get_sequence {
__u32 crtc_id;  /* requested crtc_id */
@@ -903,6 +932,12 @@ extern "C" {
 #define DRM_IOCTL_MODE_GET_LEASE   DRM_IOWR(0xC8, struct 
drm_mode_get_lease)
 #define DRM_IOCTL_MODE_REVOKE_LEASEDRM_IOWR(0xC9, struct 
drm_mode_revoke_lease)
 
+#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct 
drm_syncobj_timeline_wait)
+#define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct 
drm_syncobj_timeline_array)
+#define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct 
drm_syncobj_transfer)
+#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL   DRM_IOWR(0xCD, struct 
drm_syncobj_timeline_array)
+
+
 /**
  * Device specific ioctls should only be in their respective headers
  * The device specific ioctl range is from 0x40 to 0x9f.
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 8/8] add syncobj timeline tests v3

2019-04-01 Thread Chunming Zhou
v2: drop DRM_SYNCOBJ_CREATE_TYPE_TIMELINE, fix timeout calculation,
fix some warnings
v3: add export/import and cpu signal testing cases

Signed-off-by: Chunming Zhou 
Signed-off-by: Christian König 
---
 tests/amdgpu/Makefile.am |   3 +-
 tests/amdgpu/amdgpu_test.c   |  12 ++
 tests/amdgpu/amdgpu_test.h   |  21 +++
 tests/amdgpu/meson.build |   2 +-
 tests/amdgpu/syncobj_tests.c | 290 +++
 5 files changed, 326 insertions(+), 2 deletions(-)
 create mode 100644 tests/amdgpu/syncobj_tests.c

diff --git a/tests/amdgpu/Makefile.am b/tests/amdgpu/Makefile.am
index 447ff217..d3fbe2bb 100644
--- a/tests/amdgpu/Makefile.am
+++ b/tests/amdgpu/Makefile.am
@@ -33,4 +33,5 @@ amdgpu_test_SOURCES = \
vcn_tests.c \
uve_ib.h \
deadlock_tests.c \
-   vm_tests.c
+   vm_tests.c \
+   syncobj_tests.c
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
index a793ca7d..4377988d 100644
--- a/tests/amdgpu/amdgpu_test.c
+++ b/tests/amdgpu/amdgpu_test.c
@@ -56,6 +56,7 @@
 #define UVD_ENC_TESTS_STR "UVD ENC Tests"
 #define DEADLOCK_TESTS_STR "Deadlock Tests"
 #define VM_TESTS_STR "VM Tests"
+#define SYNCOBJ_TIMELINE_TESTS_STR "SYNCOBJ TIMELINE Tests"
 
 /**
  *  Open handles for amdgpu devices
@@ -116,6 +117,12 @@ static CU_SuiteInfo suites[] = {
.pCleanupFunc = suite_vm_tests_clean,
.pTests = vm_tests,
},
+   {
+   .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+   .pInitFunc = suite_syncobj_timeline_tests_init,
+   .pCleanupFunc = suite_syncobj_timeline_tests_clean,
+   .pTests = syncobj_timeline_tests,
+   },
 
CU_SUITE_INFO_NULL,
 };
@@ -165,6 +172,11 @@ static Suites_Active_Status suites_active_stat[] = {
.pName = VM_TESTS_STR,
.pActive = suite_vm_tests_enable,
},
+   {
+   .pName = SYNCOBJ_TIMELINE_TESTS_STR,
+   .pActive = suite_syncobj_timeline_tests_enable,
+   },
+
 };
 
 
diff --git a/tests/amdgpu/amdgpu_test.h b/tests/amdgpu/amdgpu_test.h
index af81eea8..24d64b64 100644
--- a/tests/amdgpu/amdgpu_test.h
+++ b/tests/amdgpu/amdgpu_test.h
@@ -194,6 +194,27 @@ CU_BOOL suite_vm_tests_enable(void);
  */
 extern CU_TestInfo vm_tests[];
 
+/**
+ * Initialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_init();
+
+/**
+ * Deinitialize syncobj timeline test suite
+ */
+int suite_syncobj_timeline_tests_clean();
+
+/**
+ * Decide if the suite is enabled by default or not.
+ */
+CU_BOOL suite_syncobj_timeline_tests_enable(void);
+
+/**
+ * Tests in syncobj timeline test suite
+ */
+extern CU_TestInfo syncobj_timeline_tests[];
+
+
 /**
  * Helper functions
  */
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index 4c1237c6..3ceec715 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -24,7 +24,7 @@ if dep_cunit.found()
 files(
   'amdgpu_test.c', 'basic_tests.c', 'bo_tests.c', 'cs_tests.c',
   'vce_tests.c', 'uvd_enc_tests.c', 'vcn_tests.c', 'deadlock_tests.c',
-  'vm_tests.c',
+  'vm_tests.c', 'syncobj_tests.c',
 ),
 dependencies : [dep_cunit, dep_threads],
 include_directories : [inc_root, inc_drm, 
include_directories('../../amdgpu')],
diff --git a/tests/amdgpu/syncobj_tests.c b/tests/amdgpu/syncobj_tests.c
new file mode 100644
index ..a0c627d7
--- /dev/null
+++ b/tests/amdgpu/syncobj_tests.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2017 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+*/
+
+#include "CUnit/Basic.h"
+
+#include "amdgpu_test.h"
+#include "amdgpu_drm.h"
+#include "amdgpu_internal.h"
+#include 
+
+static  amdgpu_device_handle device_handle;
+static  ui

[PATCH libdrm 6/8] expose timeline signal/export/import interfaces v2

2019-04-01 Thread Chunming Zhou
v2: adapt to new one transfer ioctl

Signed-off-by: Chunming Zhou 
---
 amdgpu/amdgpu-symbol-check |  3 ++
 amdgpu/amdgpu.h| 51 
 amdgpu/amdgpu_cs.c | 68 ++
 3 files changed, 122 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 67ba3039..0cc54e5e 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -51,10 +51,13 @@ amdgpu_cs_submit
 amdgpu_cs_submit_raw
 amdgpu_cs_submit_raw2
 amdgpu_cs_syncobj_export_sync_file
+amdgpu_cs_syncobj_export_sync_file2
 amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_import_sync_file2
 amdgpu_cs_syncobj_query
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_signal
 amdgpu_cs_syncobj_timeline_wait
 amdgpu_cs_syncobj_wait
 amdgpu_cs_wait_fences
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index dcf662e9..b5bd3ed9 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1501,6 +1501,23 @@ int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
 int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
 const uint32_t *syncobjs, uint32_t syncobj_count);
 
+/**
+ * Signal kernel timeline sync objects.
+ *
+ * \param dev   - \c [in] device handle
+ * \param syncobjs  - \c [in] array of sync object handles
+ * \param points   - \c [in] array of timeline points
+ * \param syncobj_count - \c [in] number of handles in syncobjs
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+*/
+int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+ const uint32_t *syncobjs,
+ uint64_t *points,
+ uint32_t syncobj_count);
+
 /**
  *  Wait for one or all sync objects to signal.
  *
@@ -1618,7 +1635,41 @@ int 
amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
 int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
   uint32_t syncobj,
   int sync_file_fd);
+/**
+ *  Export kernel timeline sync object to a sync_file.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   syncobj- \c [in] sync object handle
+ * \param   point  - \c [in] timeline point
+ * \param   flags  - \c [in] flags
+ * \param   sync_file_fd - \c [out] sync_file file descriptor.
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+   uint32_t syncobj,
+   uint64_t point,
+   uint32_t flags,
+   int *sync_file_fd);
 
+/**
+ *  Import kernel timeline sync object from a sync_file.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   syncobj- \c [in] sync object handle
+ * \param   point  - \c [in] timeline point
+ * \param   sync_file_fd - \c [in] sync_file file descriptor.
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
+   uint32_t syncobj,
+   uint64_t point,
+   int sync_file_fd);
 /**
  * Export an amdgpu fence as a handle (syncobj or fd).
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index b8b0d566..1c02d16f 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -649,6 +649,18 @@ drm_public int 
amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
return drmSyncobjSignal(dev->fd, syncobjs, syncobj_count);
 }
 
+drm_public int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
+const uint32_t *syncobjs,
+uint64_t *points,
+uint32_t syncobj_count)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTimelineSignal(dev->fd, syncobjs,
+   points, syncobj_count);
+}
+
 drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
  uint32_t *handles, unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
@@ -724,6 +736,62 @@ drm_public int 
amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
 }
 
+drm_public int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+  uint32_t syncobj,
+  uint64_t point,
+  

[PATCH libdrm 4/8] wrap syncobj timeline query/wait APIs for amdgpu v3

2019-04-01 Thread Chunming Zhou
v2: symbos are stored in lexical order.
v3: drop export/import and extra query indirection

Signed-off-by: Chunming Zhou 
Signed-off-by: Christian König 
---
 amdgpu/amdgpu-symbol-check |  2 ++
 amdgpu/amdgpu.h| 39 ++
 amdgpu/amdgpu_cs.c | 23 ++
 3 files changed, 64 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index 96a44b40..67ba3039 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -52,8 +52,10 @@ amdgpu_cs_submit_raw
 amdgpu_cs_submit_raw2
 amdgpu_cs_syncobj_export_sync_file
 amdgpu_cs_syncobj_import_sync_file
+amdgpu_cs_syncobj_query
 amdgpu_cs_syncobj_reset
 amdgpu_cs_syncobj_signal
+amdgpu_cs_syncobj_timeline_wait
 amdgpu_cs_syncobj_wait
 amdgpu_cs_wait_fences
 amdgpu_cs_wait_semaphore
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index d6de3b8d..dcf662e9 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1521,6 +1521,45 @@ int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
   int64_t timeout_nsec, unsigned flags,
   uint32_t *first_signaled);
 
+/**
+ *  Wait for one or all sync objects on their points to signal.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [in] array of sync points to wait
+ * \param   num_handles - \c [in] self-explanatory
+ * \param   timeout_nsec - \c [in] self-explanatory
+ * \param   flags   - \c [in] a bitmask of DRM_SYNCOBJ_WAIT_FLAGS_*
+ * \param   first_signaled - \c [in] self-explanatory
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles,
+   int64_t timeout_nsec, unsigned flags,
+   uint32_t *first_signaled);
+/**
+ *  Query sync objects payloads.
+ *
+ * \param   dev- \c [in] self-explanatory
+ * \param   handles - \c [in] array of sync object handles
+ * \param   points - \c [out] array of sync points returned, which presents
+ * syncobj payload.
+ * \param   num_handles - \c [in] self-explanatory
+ *
+ * \return   0 on success\n
+ *  -ETIME - Timeout
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+   uint32_t *handles, uint64_t *points,
+   unsigned num_handles);
+
 /**
  *  Export kernel sync object to shareable fd.
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 5bedf748..b8b0d566 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -661,6 +661,29 @@ drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle 
dev,
  flags, first_signaled);
 }
 
+drm_public int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
+  uint32_t *handles, uint64_t 
*points,
+  unsigned num_handles,
+  int64_t timeout_nsec, unsigned 
flags,
+  uint32_t *first_signaled)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTimelineWait(dev->fd, handles, points, num_handles,
+ timeout_nsec, flags, first_signaled);
+}
+
+drm_public int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
+  uint32_t *handles, uint64_t *points,
+  unsigned num_handles)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjQuery(dev->fd, handles, points, num_handles);
+}
+
 drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
uint32_t handle,
int *shared_fd)
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 5/8] add timeline signal/transfer ioctls v2

2019-04-01 Thread Chunming Zhou
v2: use one transfer ioctl

Signed-off-by: Chunming Zhou 
---
 xf86drm.c | 33 +
 xf86drm.h |  6 ++
 2 files changed, 39 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 66e0c985..d57c4218 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4280,6 +4280,21 @@ drm_public int drmSyncobjSignal(int fd, const uint32_t 
*handles,
 return ret;
 }
 
+drm_public int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+   uint64_t *points, uint32_t handle_count)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.count_handles = handle_count;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, );
+return ret;
+}
+
 drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t 
*points,
  unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
@@ -4322,4 +4337,22 @@ drm_public int drmSyncobjQuery(int fd, uint32_t 
*handles, uint64_t *points,
 return 0;
 }
 
+drm_public int drmSyncobjTransfer(int fd,
+ uint32_t dst_handle, uint64_t dst_point,
+ uint32_t src_handle, uint64_t src_point,
+ uint32_t flags)
+{
+struct drm_syncobj_transfer args;
+int ret;
+
+memclear(args);
+args.src_handle = src_handle;
+args.dst_handle = dst_handle;
+args.src_point = src_point;
+args.dst_point = dst_point;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TRANSFER, );
 
+return ret;
+}
diff --git a/xf86drm.h b/xf86drm.h
index 60c7a84f..3fb1d1ca 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -876,12 +876,18 @@ extern int drmSyncobjWait(int fd, uint32_t *handles, 
unsigned num_handles,
  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t 
handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t 
handle_count);
+extern int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
+   uint64_t *points, uint32_t handle_count);
 extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
  unsigned num_handles,
  int64_t timeout_nsec, unsigned flags,
  uint32_t *first_signaled);
 extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
   uint32_t handle_count);
+extern int drmSyncobjTransfer(int fd,
+ uint32_t dst_handle, uint64_t dst_point,
+ uint32_t src_handle, uint64_t src_point,
+ uint32_t flags);
 
 #if defined(__cplusplus)
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 7/8] wrap transfer interfaces

2019-04-01 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
---
 amdgpu/amdgpu.h| 22 ++
 amdgpu/amdgpu_cs.c | 16 
 2 files changed, 38 insertions(+)

diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index b5bd3ed9..2350835b 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1670,6 +1670,28 @@ int 
amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
uint32_t syncobj,
uint64_t point,
int sync_file_fd);
+
+/**
+ *  transfer between syncbojs.
+ *
+ * \param   dev- \c [in] device handle
+ * \param   dst_handle - \c [in] sync object handle
+ * \param   dst_point  - \c [in] timeline point, 0 presents dst is binary
+ * \param   src_handle - \c [in] sync object handle
+ * \param   src_point  - \c [in] timeline point, 0 presents src is binary
+ * \param   flags  - \c [in] flags
+ *
+ * \return   0 on success\n
+ *  <0 - Negative POSIX Error code
+ *
+ */
+int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+  uint32_t dst_handle,
+  uint64_t dst_point,
+  uint32_t src_handle,
+  uint64_t src_point,
+  uint32_t flags);
+
 /**
  * Export an amdgpu fence as a handle (syncobj or fd).
  *
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 1c02d16f..a1c1af55 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -792,6 +792,22 @@ out:
return ret;
 }
 
+drm_public int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
+ uint32_t dst_handle,
+ uint64_t dst_point,
+ uint32_t src_handle,
+ uint64_t src_point,
+ uint32_t flags)
+{
+   if (NULL == dev)
+   return -EINVAL;
+
+   return drmSyncobjTransfer(dev->fd,
+ dst_handle, dst_point,
+ src_handle, src_point,
+ flags);
+}
+
 drm_public int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
amdgpu_context_handle context,
amdgpu_bo_list_handle bo_list_handle,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 1/8] new syncobj extension v3

2019-04-01 Thread Chunming Zhou
v2: drop not implemented IOCTLs and flags
v3: add transfer/signal ioctls

Signed-off-by: Chunming Zhou 
Signed-off-by: Christian König 
---
 include/drm/drm.h | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/include/drm/drm.h b/include/drm/drm.h
index 85c685a2..26f51bca 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -729,8 +729,18 @@ struct drm_syncobj_handle {
__u32 pad;
 };
 
+struct drm_syncobj_transfer {
+__u32 src_handle;
+__u32 dst_handle;
+__u64 src_point;
+__u64 dst_point;
+__u32 flags;
+__u32 pad;
+};
+
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2)
 struct drm_syncobj_wait {
__u64 handles;
/* absolute timeout */
@@ -741,12 +751,31 @@ struct drm_syncobj_wait {
__u32 pad;
 };
 
+struct drm_syncobj_timeline_wait {
+__u64 handles;
+/* wait on specific timeline point for every handles*/
+__u64 points;
+/* absolute timeout */
+__s64 timeout_nsec;
+__u32 count_handles;
+__u32 flags;
+__u32 first_signaled; /* only valid when not waiting all */
+__u32 pad;
+};
+
 struct drm_syncobj_array {
__u64 handles;
__u32 count_handles;
__u32 pad;
 };
 
+struct drm_syncobj_timeline_array {
+__u64 handles;
+__u64 points;
+__u32 count_handles;
+__u32 pad;
+};
+
 /* Query current scanout sequence number */
 struct drm_crtc_get_sequence {
__u32 crtc_id;  /* requested crtc_id */
@@ -903,6 +932,12 @@ extern "C" {
 #define DRM_IOCTL_MODE_GET_LEASE   DRM_IOWR(0xC8, struct 
drm_mode_get_lease)
 #define DRM_IOCTL_MODE_REVOKE_LEASEDRM_IOWR(0xC9, struct 
drm_mode_revoke_lease)
 
+#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct 
drm_syncobj_timeline_wait)
+#define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct 
drm_syncobj_timeline_array)
+#define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct 
drm_syncobj_transfer)
+#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL   DRM_IOWR(0xCD, struct 
drm_syncobj_timeline_array)
+
+
 /**
  * Device specific ioctls should only be in their respective headers
  * The device specific ioctl range is from 0x40 to 0x9f.
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 3/8] add timeline wait/query ioctl v2

2019-04-01 Thread Chunming Zhou
v2: drop export/import

Signed-off-by: Chunming Zhou 
---
 xf86drm.c | 44 
 xf86drm.h |  6 ++
 2 files changed, 50 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 18ad7c58..66e0c985 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -4279,3 +4279,47 @@ drm_public int drmSyncobjSignal(int fd, const uint32_t 
*handles,
 ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_SIGNAL, );
 return ret;
 }
+
+drm_public int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t 
*points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled)
+{
+struct drm_syncobj_timeline_wait args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.timeout_nsec = timeout_nsec;
+args.count_handles = num_handles;
+args.flags = flags;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, );
+if (ret < 0)
+return -errno;
+
+if (first_signaled)
+*first_signaled = args.first_signaled;
+return ret;
+}
+
+
+drm_public int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+  uint32_t handle_count)
+{
+struct drm_syncobj_timeline_array args;
+int ret;
+
+memclear(args);
+args.handles = (uintptr_t)handles;
+args.points = (uint64_t)(uintptr_t)points;
+args.count_handles = handle_count;
+
+ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_QUERY, );
+if (ret)
+return ret;
+return 0;
+}
+
+
diff --git a/xf86drm.h b/xf86drm.h
index 887ecc76..60c7a84f 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -876,6 +876,12 @@ extern int drmSyncobjWait(int fd, uint32_t *handles, 
unsigned num_handles,
  uint32_t *first_signaled);
 extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t 
handle_count);
 extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t 
handle_count);
+extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points,
+ unsigned num_handles,
+ int64_t timeout_nsec, unsigned flags,
+ uint32_t *first_signaled);
+extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points,
+  uint32_t handle_count);
 
 #if defined(__cplusplus)
 }
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH libdrm 2/8] addr cs chunk for syncobj timeline

2019-04-01 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
---
 include/drm/amdgpu_drm.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h
index be84e43c..bfa04dd8 100644
--- a/include/drm/amdgpu_drm.h
+++ b/include/drm/amdgpu_drm.h
@@ -523,6 +523,8 @@ struct drm_amdgpu_gem_va {
 #define AMDGPU_CHUNK_ID_SYNCOBJ_IN  0x04
 #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
 #define AMDGPU_CHUNK_ID_BO_HANDLES  0x06
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT0x08
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL  0x09
 
 struct drm_amdgpu_cs_chunk {
__u32   chunk_id;
@@ -598,6 +600,13 @@ struct drm_amdgpu_cs_chunk_sem {
__u32 handle;
 };
 
+struct drm_amdgpu_cs_chunk_syncobj {
+   __u32 handle;
+   __u32 flags;
+   __u64 point;
+};
+
+
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD  1
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD2
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 5/9] drm/syncobj: use the timeline point in drm_syncobj_find_fence v4

2019-04-01 Thread Chunming Zhou
From: Christian König 

Implement finding the right timeline point in drm_syncobj_find_fence.

v2: return -EINVAL when the point is not submitted yet.
v3: fix reference counting bug, add flags handling as well
v4: add timeout for find fence

Signed-off-by: Christian König 
Cc: Lionel Landwerlin 
Reviewed-by: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_syncobj.c | 50 ---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 3a1be7f79de1..6c273e73d920 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -214,6 +214,8 @@ static void drm_syncobj_assign_null_handle(struct 
drm_syncobj *syncobj)
dma_fence_put(fence);
 }
 
+/* 5s default for wait submission */
+#define DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT 50ULL
 /**
  * drm_syncobj_find_fence - lookup and reference the fence in a sync object
  * @file_private: drm file private pointer
@@ -234,16 +236,58 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
   struct dma_fence **fence)
 {
struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
-   int ret = 0;
+   struct syncobj_wait_entry wait;
+   u64 timeout = nsecs_to_jiffies64(DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT);
+   int ret;
 
if (!syncobj)
return -ENOENT;
 
*fence = drm_syncobj_fence_get(syncobj);
-   if (!*fence) {
+   drm_syncobj_put(syncobj);
+
+   if (*fence) {
+   ret = dma_fence_chain_find_seqno(fence, point);
+   if (!ret)
+   return 0;
+   dma_fence_put(*fence);
+   } else {
ret = -EINVAL;
}
-   drm_syncobj_put(syncobj);
+
+   if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
+   return ret;
+
+   memset(, 0, sizeof(wait));
+   wait.task = current;
+   wait.point = point;
+   drm_syncobj_fence_add_wait(syncobj, );
+
+   do {
+   set_current_state(TASK_INTERRUPTIBLE);
+   if (wait.fence) {
+   ret = 0;
+   break;
+   }
+if (timeout == 0) {
+ret = -ETIME;
+break;
+}
+
+   if (signal_pending(current)) {
+   ret = -ERESTARTSYS;
+   break;
+   }
+
+timeout = schedule_timeout(timeout);
+   } while (1);
+
+   __set_current_state(TASK_RUNNING);
+   *fence = wait.fence;
+
+   if (wait.node.next)
+   drm_syncobj_remove_wait(syncobj, );
+
return ret;
 }
 EXPORT_SYMBOL(drm_syncobj_find_fence);
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 7/9] drm/syncobj: add transition iotcls between binary and timeline v2

2019-04-01 Thread Chunming Zhou
we need to import/export timeline point.

v2: unify to one transfer ioctl

Signed-off-by: Chunming Zhou 
Cc: Lionel Landwerlin 
Reviewed-by: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_internal.h |  2 +
 drivers/gpu/drm/drm_ioctl.c|  2 +
 drivers/gpu/drm/drm_syncobj.c  | 74 ++
 include/uapi/drm/drm.h | 10 +
 4 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 695179bb88dc..dd11ae5f1eef 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -180,6 +180,8 @@ int drm_syncobj_handle_to_fd_ioctl(struct drm_device *dev, 
void *data,
   struct drm_file *file_private);
 int drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_private);
+int drm_syncobj_transfer_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file_private);
 int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_private);
 int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 7a534c184e52..92b3b7b2fd81 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -686,6 +686,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, 
drm_syncobj_fd_to_handle_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TRANSFER, drm_syncobj_transfer_ioctl,
+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, 
drm_syncobj_timeline_wait_ioctl,
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 6c273e73d920..63d5d2bf35c2 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -680,6 +680,80 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, 
void *data,
>handle);
 }
 
+static int drm_syncobj_transfer_to_timeline(struct drm_file *file_private,
+   struct drm_syncobj_transfer *args)
+{
+   struct drm_syncobj *timeline_syncobj = NULL;
+   struct dma_fence *fence;
+   struct dma_fence_chain *chain;
+   int ret;
+
+   timeline_syncobj = drm_syncobj_find(file_private, args->dst_handle);
+   if (!timeline_syncobj) {
+   return -ENOENT;
+   }
+   ret = drm_syncobj_find_fence(file_private, args->src_handle,
+args->src_point, args->flags,
+);
+   if (ret)
+   goto err;
+   chain = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);
+   if (!chain) {
+   ret = -ENOMEM;
+   goto err1;
+   }
+   drm_syncobj_add_point(timeline_syncobj, chain, fence, args->dst_point);
+err1:
+   dma_fence_put(fence);
+err:
+   drm_syncobj_put(timeline_syncobj);
+
+   return ret;
+}
+
+static int
+drm_syncobj_transfer_to_binary(struct drm_file *file_private,
+  struct drm_syncobj_transfer *args)
+{
+   struct drm_syncobj *binary_syncobj = NULL;
+   struct dma_fence *fence;
+   int ret;
+
+   binary_syncobj = drm_syncobj_find(file_private, args->dst_handle);
+   if (!binary_syncobj)
+   return -ENOENT;
+   ret = drm_syncobj_find_fence(file_private, args->src_handle,
+args->src_point, args->flags, );
+   if (ret)
+   goto err;
+   drm_syncobj_replace_fence(binary_syncobj, fence);
+   dma_fence_put(fence);
+err:
+   drm_syncobj_put(binary_syncobj);
+
+   return ret;
+}
+int
+drm_syncobj_transfer_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file_private)
+{
+   struct drm_syncobj_transfer *args = data;
+   int ret;
+
+   if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+   return -ENODEV;
+
+   if (args->pad)
+   return -EINVAL;
+
+   if (args->dst_point)
+   ret = drm_syncobj_transfer_to_timeline(file_private, args);
+   else
+   ret = drm_syncobj_transfer_to_binary(file_private, args);
+
+   return ret;
+}
+
 static void syncobj_wait_fence_func(struct dma_fence *fence,
struct dma_fence_cb *cb)
 {
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index c62be0840ba5..e8d0d6b51875 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -735,6 +735,15 @@ struc

[PATCH 3/9] drm/syncobj: add support for timeline point wait v8

2019-04-01 Thread Chunming Zhou
points array is one-to-one match with syncobjs array.
v2:
add seperate ioctl for timeline point wait, otherwise break uapi.
v3:
userspace can specify two kinds waits::
a. Wait for time point to be completed.
b. and wait for time point to become available
v4:
rebase
v5:
add comment for xxx_WAIT_AVAILABLE
v6: rebase and rework on new container
v7: drop _WAIT_COMPLETED, it is the default anyway
v8: correctly handle garbage collected fences

Signed-off-by: Chunming Zhou 
Signed-off-by: Christian König 
Cc: Tobias Hector 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: Chris Wilson 
Cc: Lionel Landwerlin 
Reviewed-by: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_internal.h |   2 +
 drivers/gpu/drm/drm_ioctl.c|   2 +
 drivers/gpu/drm/drm_syncobj.c  | 153 ++---
 include/uapi/drm/drm.h |  15 
 4 files changed, 143 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 251d67e04c2d..331ac6225b58 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -182,6 +182,8 @@ int drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, 
void *data,
   struct drm_file *file_private);
 int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_private);
+int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file_private);
 int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_private);
 int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 687943df58e1..c984654646fa 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -688,6 +688,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, 
drm_syncobj_timeline_wait_ioctl,
+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_RESET, drm_syncobj_reset_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index dbe4a1c75fbc..b1262e92011c 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -61,6 +61,7 @@ struct syncobj_wait_entry {
struct task_struct *task;
struct dma_fence *fence;
struct dma_fence_cb fence_cb;
+   u64point;
 };
 
 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
@@ -95,6 +96,8 @@ EXPORT_SYMBOL(drm_syncobj_find);
 static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj,
   struct syncobj_wait_entry *wait)
 {
+   struct dma_fence *fence;
+
if (wait->fence)
return;
 
@@ -103,11 +106,15 @@ static void drm_syncobj_fence_add_wait(struct drm_syncobj 
*syncobj,
 * have the lock, try one more time just to be sure we don't add a
 * callback when a fence has already been set.
 */
-   if (syncobj->fence)
-   wait->fence = dma_fence_get(
-   rcu_dereference_protected(syncobj->fence, 1));
-   else
+   fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, 1));
+   if (!fence || dma_fence_chain_find_seqno(, wait->point)) {
+   dma_fence_put(fence);
list_add_tail(>node, >cb_list);
+   } else if (!fence) {
+   wait->fence = dma_fence_get_stub();
+   } else {
+   wait->fence = fence;
+   }
spin_unlock(>lock);
 }
 
@@ -150,10 +157,8 @@ void drm_syncobj_add_point(struct drm_syncobj *syncobj,
dma_fence_chain_init(chain, prev, fence, point);
rcu_assign_pointer(syncobj->fence, >base);
 
-   list_for_each_entry_safe(cur, tmp, >cb_list, node) {
-   list_del_init(>node);
+   list_for_each_entry_safe(cur, tmp, >cb_list, node)
syncobj_wait_syncobj_func(syncobj, cur);
-   }
spin_unlock(>lock);
 
/* Walk the chain once to trigger garbage collection */
@@ -185,10 +190,8 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
rcu_assign_pointer(syncobj->fence, fence);
 
if (fence != old_fence) {
-   list_for_each_entry_safe(cur, tmp, >cb_list, node) {
-   list_del_init(>node);
+   list_for_each_entry_safe(cur, tmp, >cb_list, node)
syncobj_wait_syncobj_func(syncobj, cur);
-   }
}

[PATCH 8/9] drm/syncobj: add timeline signal ioctl for syncobj v5

2019-04-01 Thread Chunming Zhou
v2: individually allocate chain array, since chain node is free independently.
v3: all existing points must be already signaled before cpu perform signal 
operation,
so add check condition for that.
v4: remove v3 change and add checking to prevent out-of-order
v5: unify binary and timeline

Signed-off-by: Chunming Zhou 
Cc: Tobias Hector 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: Chris Wilson 
Cc: Lionel Landwerlin 
Reviewed-by: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_internal.h |  2 +
 drivers/gpu/drm/drm_ioctl.c|  2 +
 drivers/gpu/drm/drm_syncobj.c  | 73 ++
 include/uapi/drm/drm.h |  1 +
 4 files changed, 78 insertions(+)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index dd11ae5f1eef..d9a483a5fce0 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -190,6 +190,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void 
*data,
struct drm_file *file_private);
 int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file_private);
+int drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_private);
 int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_private);
 
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 92b3b7b2fd81..d337f161909c 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -696,6 +696,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, 
drm_syncobj_timeline_signal_ioctl,
+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, 
DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 63d5d2bf35c2..f3ceeb504e6c 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1184,6 +1184,79 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void 
*data,
return ret;
 }
 
+int
+drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_private)
+{
+   struct drm_syncobj_timeline_array *args = data;
+   struct drm_syncobj **syncobjs;
+   struct dma_fence_chain **chains;
+   uint64_t *points;
+   uint32_t i, j;
+   int ret;
+
+   if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+   return -EOPNOTSUPP;
+
+   if (args->pad != 0)
+   return -EINVAL;
+
+   if (args->count_handles == 0)
+   return -EINVAL;
+
+   ret = drm_syncobj_array_find(file_private,
+u64_to_user_ptr(args->handles),
+args->count_handles,
+);
+   if (ret < 0)
+   return ret;
+
+   points = kmalloc_array(args->count_handles, sizeof(*points),
+  GFP_KERNEL);
+   if (!points) {
+   ret = -ENOMEM;
+   goto out;
+   }
+   if (!u64_to_user_ptr(args->points)) {
+   memset(points, 0, args->count_handles * sizeof(uint64_t));
+   } else if (copy_from_user(points, u64_to_user_ptr(args->points),
+ sizeof(uint64_t) * args->count_handles)) {
+   ret = -EFAULT;
+   goto err_points;
+   }
+
+   chains = kmalloc_array(args->count_handles, sizeof(void *), GFP_KERNEL);
+   if (!chains) {
+   ret = -ENOMEM;
+   goto err_points;
+   }
+   for (i = 0; i < args->count_handles; i++) {
+   chains[i] = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);
+   if (!chains[i]) {
+   for (j = 0; j < i; j++)
+   kfree(chains[j]);
+   ret = -ENOMEM;
+   goto err_chains;
+   }
+   }
+
+   for (i = 0; i < args->count_handles; i++) {
+   struct dma_fence *fence = dma_fence_get_stub();
+
+   drm_syncobj_add_point(syncobjs[i], chains[i],
+ fence, points[i]);
+   dma_fence_put(fence);
+   }
+err_chains:
+   kfree(chains);
+err_points:
+   kfree(points);
+out:
+   drm_syncobj_array_free(syncobjs, args->count_handles);
+
+   return ret;
+}
+
 int drm_syn

[PATCH 6/9] drm/amdgpu: add timeline support in amdgpu CS v3

2019-04-01 Thread Chunming Zhou
syncobj wait/signal operation is appending in command submission.
v2: separate to two kinds in/out_deps functions
v3: fix checking for timeline syncobj

Signed-off-by: Chunming Zhou 
Cc: Tobias Hector 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: Chris Wilson 
Cc: Lionel Landwerlin 
Reviewed-by: Lionel Landwerlin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h|  10 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 152 +
 include/uapi/drm/amdgpu_drm.h  |   8 ++
 3 files changed, 144 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 8d0d7f3dd5fb..deec2c796253 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -433,6 +433,12 @@ struct amdgpu_cs_chunk {
void*kdata;
 };
 
+struct amdgpu_cs_post_dep {
+   struct drm_syncobj *syncobj;
+   struct dma_fence_chain *chain;
+   u64 point;
+};
+
 struct amdgpu_cs_parser {
struct amdgpu_device*adev;
struct drm_file *filp;
@@ -462,8 +468,8 @@ struct amdgpu_cs_parser {
/* user fence */
struct amdgpu_bo_list_entry uf_entry;
 
-   unsigned num_post_dep_syncobjs;
-   struct drm_syncobj **post_dep_syncobjs;
+   unsignednum_post_deps;
+   struct amdgpu_cs_post_dep   *post_deps;
 };
 
 static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 52a5e4fdc95b..2f6239b6be6f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -215,6 +215,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser 
*p, union drm_amdgpu_cs
case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:
+   case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:
+   case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
break;
 
default:
@@ -804,9 +806,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser 
*parser, int error,
ttm_eu_backoff_reservation(>ticket,
   >validated);
 
-   for (i = 0; i < parser->num_post_dep_syncobjs; i++)
-   drm_syncobj_put(parser->post_dep_syncobjs[i]);
-   kfree(parser->post_dep_syncobjs);
+   for (i = 0; i < parser->num_post_deps; i++) {
+   drm_syncobj_put(parser->post_deps[i].syncobj);
+   kfree(parser->post_deps[i].chain);
+   }
+   kfree(parser->post_deps);
 
dma_fence_put(parser->fence);
 
@@ -1117,13 +1121,18 @@ static int amdgpu_cs_process_fence_dep(struct 
amdgpu_cs_parser *p,
 }
 
 static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
-uint32_t handle)
+uint32_t handle, u64 point,
+u64 flags)
 {
-   int r;
struct dma_fence *fence;
-   r = drm_syncobj_find_fence(p->filp, handle, 0, 0, );
-   if (r)
+   int r;
+
+   r = drm_syncobj_find_fence(p->filp, handle, point, flags, );
+   if (r) {
+   DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n",
+ handle, point, r);
return r;
+   }
 
r = amdgpu_sync_fence(p->adev, >job->sync, fence, true);
dma_fence_put(fence);
@@ -1134,46 +1143,118 @@ static int 
amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
 static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p,
struct amdgpu_cs_chunk *chunk)
 {
+   struct drm_amdgpu_cs_chunk_sem *deps;
unsigned num_deps;
int i, r;
-   struct drm_amdgpu_cs_chunk_sem *deps;
 
deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
num_deps = chunk->length_dw * 4 /
sizeof(struct drm_amdgpu_cs_chunk_sem);
+   for (i = 0; i < num_deps; ++i) {
+   r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle,
+ 0, 0);
+   if (r)
+   return r;
+   }
+
+   return 0;
+}
+
 
+static int amdgpu_cs_process_syncobj_timeline_in_dep(struct amdgpu_cs_parser 
*p,
+struct amdgpu_cs_chunk 
*chunk)
+{
+   struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps;
+   unsigned num_deps;
+   int i, r;
+
+   syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata;
+   num_deps = chunk->length_dw * 4 /
+   sizeof(struct drm_amdgpu_c

[PATCH 9/9] drm/amdgpu: update version for timeline syncobj support in amdgpu

2019-04-01 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
Reviewed-by: Lionel Landwerlin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 8a0732088640..4d8db87048d3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -74,9 +74,10 @@
  * - 3.28.0 - Add AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES
  * - 3.29.0 - Add AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID
  * - 3.30.0 - Add AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE.
+ * - 3.31.0 - Add syncobj timeline support to AMDGPU_CS.
  */
 #define KMS_DRIVER_MAJOR   3
-#define KMS_DRIVER_MINOR   30
+#define KMS_DRIVER_MINOR   31
 #define KMS_DRIVER_PATCHLEVEL  0
 
 int amdgpu_vram_limit = 0;
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 4/9] drm/syncobj: add timeline payload query ioctl v6

2019-04-01 Thread Chunming Zhou
user mode can query timeline payload.
v2: check return value of copy_to_user
v3: handle querying entry by entry
v4: rebase on new chain container, simplify interface
v5: query last signaled timeline point, not last point.
v6: add unorder point check

Signed-off-by: Chunming Zhou 
Cc: Tobias Hector 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: Chris Wilson 
Cc: Lionel Landwerlin 
Reviewed-by: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_internal.h |  2 ++
 drivers/gpu/drm/drm_ioctl.c|  2 ++
 drivers/gpu/drm/drm_syncobj.c  | 62 ++
 include/uapi/drm/drm.h | 10 ++
 4 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 331ac6225b58..695179bb88dc 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -188,6 +188,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void 
*data,
struct drm_file *file_private);
 int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file_private);
+int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file_private);
 
 /* drm_framebuffer.c */
 void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index c984654646fa..7a534c184e52 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -694,6 +694,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, 
DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, 
drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, 
DRM_MASTER|DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index b1262e92011c..3a1be7f79de1 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1065,3 +1065,65 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void 
*data,
 
return ret;
 }
+
+int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file_private)
+{
+   struct drm_syncobj_timeline_array *args = data;
+   struct drm_syncobj **syncobjs;
+   uint64_t __user *points = u64_to_user_ptr(args->points);
+   uint32_t i;
+   int ret;
+
+   if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+   return -ENODEV;
+
+   if (args->pad != 0)
+   return -EINVAL;
+
+   if (args->count_handles == 0)
+   return -EINVAL;
+
+   ret = drm_syncobj_array_find(file_private,
+u64_to_user_ptr(args->handles),
+args->count_handles,
+);
+   if (ret < 0)
+   return ret;
+
+   for (i = 0; i < args->count_handles; i++) {
+   struct dma_fence_chain *chain;
+   struct dma_fence *fence;
+   uint64_t point;
+
+   fence = drm_syncobj_fence_get(syncobjs[i]);
+   chain = to_dma_fence_chain(fence);
+   if (chain) {
+   struct dma_fence *iter, *last_signaled = NULL;
+
+   dma_fence_chain_for_each(iter, fence) {
+   if (!iter)
+   break;
+   dma_fence_put(last_signaled);
+   last_signaled = dma_fence_get(iter);
+   if 
(!to_dma_fence_chain(last_signaled)->prev_seqno)
+   /* It is most likely that timeline has
+* unorder points. */
+   break;
+   }
+   point = dma_fence_is_signaled(last_signaled) ?
+   last_signaled->seqno :
+   to_dma_fence_chain(last_signaled)->prev_seqno;
+   dma_fence_put(last_signaled);
+   } else {
+   point = 0;
+   }
+   ret = copy_to_user([i], , sizeof(uint64_t));
+   ret = ret ? -EFAULT : 0;
+   if (ret)
+   break;
+   }
+   drm_syncobj_array_free(syncobjs, args->count_handles);
+
+   return ret;
+}
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 44ebcdd9bd1

[PATCH 2/9] drm/syncobj: add new drm_syncobj_add_point interface v4

2019-04-01 Thread Chunming Zhou
From: Christian König 

Use the dma_fence_chain object to create a timeline of fence objects
instead of just replacing the existing fence.

v2: rebase and cleanup
v3: fix garbage collection parameters
v4: add unorder point check, print a warn calltrace

Signed-off-by: Christian König 
Cc: Lionel Landwerlin 
Reviewed-by: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_syncobj.c | 40 +++
 include/drm/drm_syncobj.h |  5 +
 2 files changed, 45 insertions(+)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 5329e66598c6..dbe4a1c75fbc 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -122,6 +122,46 @@ static void drm_syncobj_remove_wait(struct drm_syncobj 
*syncobj,
spin_unlock(>lock);
 }
 
+/**
+ * drm_syncobj_add_point - add new timeline point to the syncobj
+ * @syncobj: sync object to add timeline point do
+ * @chain: chain node to use to add the point
+ * @fence: fence to encapsulate in the chain node
+ * @point: sequence number to use for the point
+ *
+ * Add the chain node as new timeline point to the syncobj.
+ */
+void drm_syncobj_add_point(struct drm_syncobj *syncobj,
+  struct dma_fence_chain *chain,
+  struct dma_fence *fence,
+  uint64_t point)
+{
+   struct syncobj_wait_entry *cur, *tmp;
+   struct dma_fence *prev;
+
+   dma_fence_get(fence);
+
+   spin_lock(>lock);
+
+   prev = drm_syncobj_fence_get(syncobj);
+   /* You are adding an unorder point to timeline, which could cause 
payload returned from query_ioctl is 0! */
+   if (prev && prev->seqno >= point)
+   DRM_ERROR("You are adding an unorder point to timeline!\n");
+   dma_fence_chain_init(chain, prev, fence, point);
+   rcu_assign_pointer(syncobj->fence, >base);
+
+   list_for_each_entry_safe(cur, tmp, >cb_list, node) {
+   list_del_init(>node);
+   syncobj_wait_syncobj_func(syncobj, cur);
+   }
+   spin_unlock(>lock);
+
+   /* Walk the chain once to trigger garbage collection */
+   dma_fence_chain_for_each(fence, prev);
+   dma_fence_put(prev);
+}
+EXPORT_SYMBOL(drm_syncobj_add_point);
+
 /**
  * drm_syncobj_replace_fence - replace fence in a sync object.
  * @syncobj: Sync object to replace fence in
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
index 0311c9fdbd2f..6cf7243a1dc5 100644
--- a/include/drm/drm_syncobj.h
+++ b/include/drm/drm_syncobj.h
@@ -27,6 +27,7 @@
 #define __DRM_SYNCOBJ_H__
 
 #include 
+#include 
 
 struct drm_file;
 
@@ -112,6 +113,10 @@ drm_syncobj_fence_get(struct drm_syncobj *syncobj)
 
 struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
 u32 handle);
+void drm_syncobj_add_point(struct drm_syncobj *syncobj,
+  struct dma_fence_chain *chain,
+  struct dma_fence *fence,
+  uint64_t point);
 void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
   struct dma_fence *fence);
 int drm_syncobj_find_fence(struct drm_file *file_private,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 1/9] dma-buf: add new dma_fence_chain container v7

2019-04-01 Thread Chunming Zhou
From: Christian König 

Lockless container implementation similar to a dma_fence_array, but with
only two elements per node and automatic garbage collection.

v2: properly document dma_fence_chain_for_each, add dma_fence_chain_find_seqno,
drop prev reference during garbage collection if it's not a chain fence.
v3: use head and iterator for dma_fence_chain_for_each
v4: fix reference count in dma_fence_chain_enable_signaling
v5: fix iteration when walking each chain node
v6: add __rcu for member 'prev' of struct chain node
v7: fix rcu warnings from kernel robot

Signed-off-by: Christian König 
Cc: Lionel Landwerlin 
Reviewed-by: Lionel Landwerlin 
---
 drivers/dma-buf/Makefile  |   3 +-
 drivers/dma-buf/dma-fence-chain.c | 241 ++
 include/linux/dma-fence-chain.h   |  81 ++
 3 files changed, 324 insertions(+), 1 deletion(-)
 create mode 100644 drivers/dma-buf/dma-fence-chain.c
 create mode 100644 include/linux/dma-fence-chain.h

diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index 0913a6ccab5a..1f006e083eb9 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1,4 +1,5 @@
-obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o
+obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
+reservation.o seqno-fence.o
 obj-$(CONFIG_SYNC_FILE)+= sync_file.o
 obj-$(CONFIG_SW_SYNC)  += sw_sync.o sync_debug.o
 obj-$(CONFIG_UDMABUF)  += udmabuf.o
diff --git a/drivers/dma-buf/dma-fence-chain.c 
b/drivers/dma-buf/dma-fence-chain.c
new file mode 100644
index ..c729f98a7bd3
--- /dev/null
+++ b/drivers/dma-buf/dma-fence-chain.c
@@ -0,0 +1,241 @@
+/*
+ * fence-chain: chain fences together in a timeline
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ * Authors:
+ * Christian König 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+
+static bool dma_fence_chain_enable_signaling(struct dma_fence *fence);
+
+/**
+ * dma_fence_chain_get_prev - use RCU to get a reference to the previous fence
+ * @chain: chain node to get the previous node from
+ *
+ * Use dma_fence_get_rcu_safe to get a reference to the previous fence of the
+ * chain node.
+ */
+static struct dma_fence *dma_fence_chain_get_prev(struct dma_fence_chain 
*chain)
+{
+   struct dma_fence *prev;
+
+   rcu_read_lock();
+   prev = dma_fence_get_rcu_safe(>prev);
+   rcu_read_unlock();
+   return prev;
+}
+
+/**
+ * dma_fence_chain_walk - chain walking function
+ * @fence: current chain node
+ *
+ * Walk the chain to the next node. Returns the next fence or NULL if we are at
+ * the end of the chain. Garbage collects chain nodes which are already
+ * signaled.
+ */
+struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence)
+{
+   struct dma_fence_chain *chain, *prev_chain;
+   struct dma_fence *prev, *replacement, *tmp;
+
+   chain = to_dma_fence_chain(fence);
+   if (!chain) {
+   dma_fence_put(fence);
+   return NULL;
+   }
+
+   while ((prev = dma_fence_chain_get_prev(chain))) {
+
+   prev_chain = to_dma_fence_chain(prev);
+   if (prev_chain) {
+   if (!dma_fence_is_signaled(prev_chain->fence))
+   break;
+
+   replacement = dma_fence_chain_get_prev(prev_chain);
+   } else {
+   if (!dma_fence_is_signaled(prev))
+   break;
+
+   replacement = NULL;
+   }
+
+   tmp = cmpxchg((void **)>prev, (void *)prev, (void 
*)replacement);
+   if (tmp == prev)
+   dma_fence_put(tmp);
+   else
+   dma_fence_put(replacement);
+   dma_fence_put(prev);
+   }
+
+   dma_fence_put(fence);
+   return prev;
+}
+EXPORT_SYMBOL(dma_fence_chain_walk);
+
+/**
+ * dma_fence_chain_find_seqno - find fence chain node by seqno
+ * @pfence: pointer to the chain node where to start
+ * @seqno: the sequence number to search for
+ *
+ * Advance the fence pointer to the chain node which will signal this sequence
+ * number. If no sequence number is provided then this is a no-op.
+ *
+ * Returns EINVAL if the fence is not a chain node or the sequence number has
+ * not yet advanced far enough.
+ */
+int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno)
+{
+   struct dma_fence_chain *chain;
+
+   if (!seqno)
+   return 0;
+
+   

[PATCH 0/9] *** timeline syncobj support ***

2019-04-01 Thread Chunming Zhou
timeline syncobj gives user more flexibility and convenience to do 
sychronization.
Lionel has written cts and adapted ANV based on this patch set, and also 
reviewed
the patch set.
please someone from community helps to submit the patch set to drm-misc-next.

Christian König (3):
  dma-buf: add new dma_fence_chain container v7
  drm/syncobj: add new drm_syncobj_add_point interface v4
  drm/syncobj: use the timeline point in drm_syncobj_find_fence v4

Chunming Zhou (6):
  drm/syncobj: add support for timeline point wait v8
  drm/syncobj: add timeline payload query ioctl v6
  drm/amdgpu: add timeline support in amdgpu CS v3
  drm/syncobj: add transition iotcls between binary and timeline v2
  drm/syncobj: add timeline signal ioctl for syncobj v5
  drm/amdgpu: update version for timeline syncobj support in amdgpu

 drivers/dma-buf/Makefile|   3 +-
 drivers/dma-buf/dma-fence-chain.c   | 241 +
 drivers/gpu/drm/amd/amdgpu/amdgpu.h |  10 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  | 152 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |   3 +-
 drivers/gpu/drm/drm_internal.h  |   8 +
 drivers/gpu/drm/drm_ioctl.c |   8 +
 drivers/gpu/drm/drm_syncobj.c   | 446 ++--
 include/drm/drm_syncobj.h   |   5 +
 include/linux/dma-fence-chain.h |  81 +
 include/uapi/drm/amdgpu_drm.h   |   8 +
 include/uapi/drm/drm.h  |  36 ++
 12 files changed, 944 insertions(+), 57 deletions(-)
 create mode 100644 drivers/dma-buf/dma-fence-chain.c
 create mode 100644 include/linux/dma-fence-chain.h

-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 8/9] drm/syncobj: add timeline signal ioctl for syncobj v5

2019-03-28 Thread Chunming Zhou

在 2019/3/28 20:53, Lionel Landwerlin 写道:
> On 25/03/2019 08:32, Chunming Zhou wrote:
>> v2: individually allocate chain array, since chain node is free 
>> independently.
>> v3: all existing points must be already signaled before cpu perform 
>> signal operation,
>>  so add check condition for that.
>> v4: remove v3 change and add checking to prevent out-of-order
>> v5: unify binary and timeline
>>
>> Signed-off-by: Chunming Zhou 
>> Cc: Tobias Hector 
>> Cc: Jason Ekstrand 
>> Cc: Dave Airlie 
>> Cc: Chris Wilson 
>> Cc: Lionel Landwerlin 
>> ---
>>   drivers/gpu/drm/drm_internal.h |  2 +
>>   drivers/gpu/drm/drm_ioctl.c    |  2 +
>>   drivers/gpu/drm/drm_syncobj.c  | 73 ++
>>   include/uapi/drm/drm.h |  1 +
>>   4 files changed, 78 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_internal.h 
>> b/drivers/gpu/drm/drm_internal.h
>> index dd11ae5f1eef..d9a483a5fce0 100644
>> --- a/drivers/gpu/drm/drm_internal.h
>> +++ b/drivers/gpu/drm/drm_internal.h
>> @@ -190,6 +190,8 @@ int drm_syncobj_reset_ioctl(struct drm_device 
>> *dev, void *data,
>>   struct drm_file *file_private);
>>   int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
>>    struct drm_file *file_private);
>> +int drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void 
>> *data,
>> +  struct drm_file *file_private);
>>   int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
>>   struct drm_file *file_private);
>>   diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
>> index 92b3b7b2fd81..d337f161909c 100644
>> --- a/drivers/gpu/drm/drm_ioctl.c
>> +++ b/drivers/gpu/drm/drm_ioctl.c
>> @@ -696,6 +696,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>>     DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>   DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
>>     DRM_UNLOCKED|DRM_RENDER_ALLOW),
>> +    DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, 
>> drm_syncobj_timeline_signal_ioctl,
>> +  DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>   DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
>>     DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>   DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, 
>> drm_crtc_get_sequence_ioctl, DRM_UNLOCKED),
>> diff --git a/drivers/gpu/drm/drm_syncobj.c 
>> b/drivers/gpu/drm/drm_syncobj.c
>> index ee2d66e047e7..099596190845 100644
>> --- a/drivers/gpu/drm/drm_syncobj.c
>> +++ b/drivers/gpu/drm/drm_syncobj.c
>> @@ -1183,6 +1183,79 @@ drm_syncobj_signal_ioctl(struct drm_device 
>> *dev, void *data,
>>   return ret;
>>   }
>>   +int
>> +drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
>> +  struct drm_file *file_private)
>> +{
>> +    struct drm_syncobj_timeline_array *args = data;
>> +    struct drm_syncobj **syncobjs;
>> +    struct dma_fence_chain **chains;
>> +    uint64_t *points;
>> +    uint32_t i, j;
>> +    int ret;
>> +
>> +    if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
>> +    return -EOPNOTSUPP;
>> +
>> +    if (args->pad != 0)
>> +    return -EINVAL;
>> +
>> +    if (args->count_handles == 0)
>> +    return -EINVAL;
>> +
>> +    ret = drm_syncobj_array_find(file_private,
>> + u64_to_user_ptr(args->handles),
>> + args->count_handles,
>> + );
>> +    if (ret < 0)
>> +    return ret;
>> +
>> +    points = kmalloc_array(args->count_handles, sizeof(*points),
>> +   GFP_KERNEL);
>> +    if (!points) {
>> +    ret = -ENOMEM;
>> +    goto out;
>> +    }
>> +    if (!u64_to_user_ptr(args->points)) {
>> +    memset(points, 0, args->count_handles * sizeof(uint64_t));
>> +    } else if (copy_from_user(points, u64_to_user_ptr(args->points),
>> +  sizeof(uint64_t) * args->count_handles)) {
>> +    ret = -EFAULT;
>> +    goto err_points;
>> +    }
>> +
>> +    chains = kmalloc_array(args->count_handles, sizeof(void *), 
>> GFP_KERNEL);
>> +    if (!chains) {
>> +    ret = -ENOMEM;
>> +    goto err_points;
>> +    }
>> +    for (i = 0; i < args->count_handles; i++) {
>> +    chains[i] = kzalloc(sizeof(struct dma_fence_chain), 
>

[PATCH 9/9] drm/amdgpu: update version for timeline syncobj support in amdgpu

2019-03-25 Thread Chunming Zhou
Signed-off-by: Chunming Zhou 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 8a0732088640..4d8db87048d3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -74,9 +74,10 @@
  * - 3.28.0 - Add AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES
  * - 3.29.0 - Add AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID
  * - 3.30.0 - Add AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE.
+ * - 3.31.0 - Add syncobj timeline support to AMDGPU_CS.
  */
 #define KMS_DRIVER_MAJOR   3
-#define KMS_DRIVER_MINOR   30
+#define KMS_DRIVER_MINOR   31
 #define KMS_DRIVER_PATCHLEVEL  0
 
 int amdgpu_vram_limit = 0;
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 7/9] drm/syncobj: add transition iotcls between binary and timeline v2

2019-03-25 Thread Chunming Zhou
we need to import/export timeline point.

v2: unify to one transfer ioctl

Signed-off-by: Chunming Zhou 
Cc: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_internal.h |  2 +
 drivers/gpu/drm/drm_ioctl.c|  2 +
 drivers/gpu/drm/drm_syncobj.c  | 74 ++
 include/uapi/drm/drm.h | 10 +
 4 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 695179bb88dc..dd11ae5f1eef 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -180,6 +180,8 @@ int drm_syncobj_handle_to_fd_ioctl(struct drm_device *dev, 
void *data,
   struct drm_file *file_private);
 int drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_private);
+int drm_syncobj_transfer_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file_private);
 int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_private);
 int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 7a534c184e52..92b3b7b2fd81 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -686,6 +686,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, 
drm_syncobj_fd_to_handle_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TRANSFER, drm_syncobj_transfer_ioctl,
+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, 
drm_syncobj_timeline_wait_ioctl,
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 087fd4e7eaf3..ee2d66e047e7 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -679,6 +679,80 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, 
void *data,
>handle);
 }
 
+static int drm_syncobj_transfer_to_timeline(struct drm_file *file_private,
+   struct drm_syncobj_transfer *args)
+{
+   struct drm_syncobj *timeline_syncobj = NULL;
+   struct dma_fence *fence;
+   struct dma_fence_chain *chain;
+   int ret;
+
+   timeline_syncobj = drm_syncobj_find(file_private, args->dst_handle);
+   if (!timeline_syncobj) {
+   return -ENOENT;
+   }
+   ret = drm_syncobj_find_fence(file_private, args->src_handle,
+args->src_point, args->flags,
+);
+   if (ret)
+   goto err;
+   chain = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);
+   if (!chain) {
+   ret = -ENOMEM;
+   goto err1;
+   }
+   drm_syncobj_add_point(timeline_syncobj, chain, fence, args->dst_point);
+err1:
+   dma_fence_put(fence);
+err:
+   drm_syncobj_put(timeline_syncobj);
+
+   return ret;
+}
+
+static int
+drm_syncobj_transfer_to_binary(struct drm_file *file_private,
+  struct drm_syncobj_transfer *args)
+{
+   struct drm_syncobj *binary_syncobj = NULL;
+   struct dma_fence *fence;
+   int ret;
+
+   binary_syncobj = drm_syncobj_find(file_private, args->dst_handle);
+   if (!binary_syncobj)
+   return -ENOENT;
+   ret = drm_syncobj_find_fence(file_private, args->src_handle,
+args->src_point, args->flags, );
+   if (ret)
+   goto err;
+   drm_syncobj_replace_fence(binary_syncobj, fence);
+   dma_fence_put(fence);
+err:
+   drm_syncobj_put(binary_syncobj);
+
+   return ret;
+}
+int
+drm_syncobj_transfer_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file_private)
+{
+   struct drm_syncobj_transfer *args = data;
+   int ret;
+
+   if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+   return -ENODEV;
+
+   if (args->pad)
+   return -EINVAL;
+
+   if (args->dst_point)
+   ret = drm_syncobj_transfer_to_timeline(file_private, args);
+   else
+   ret = drm_syncobj_transfer_to_binary(file_private, args);
+
+   return ret;
+}
+
 static void syncobj_wait_fence_func(struct dma_fence *fence,
struct dma_fence_cb *cb)
 {
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index c62be0840ba5..e8d0d6b51875 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -735,6 +735,15 @@ struct drm_syncobj_handl

[PATCH 6/9] drm/amdgpu: add timeline support in amdgpu CS v3

2019-03-25 Thread Chunming Zhou
syncobj wait/signal operation is appending in command submission.
v2: separate to two kinds in/out_deps functions
v3: fix checking for timeline syncobj

Signed-off-by: Chunming Zhou 
Cc: Tobias Hector 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: Chris Wilson 
Cc: Lionel Landwerlin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h|  10 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 152 +
 include/uapi/drm/amdgpu_drm.h  |   8 ++
 3 files changed, 144 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 8d0d7f3dd5fb..deec2c796253 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -433,6 +433,12 @@ struct amdgpu_cs_chunk {
void*kdata;
 };
 
+struct amdgpu_cs_post_dep {
+   struct drm_syncobj *syncobj;
+   struct dma_fence_chain *chain;
+   u64 point;
+};
+
 struct amdgpu_cs_parser {
struct amdgpu_device*adev;
struct drm_file *filp;
@@ -462,8 +468,8 @@ struct amdgpu_cs_parser {
/* user fence */
struct amdgpu_bo_list_entry uf_entry;
 
-   unsigned num_post_dep_syncobjs;
-   struct drm_syncobj **post_dep_syncobjs;
+   unsignednum_post_deps;
+   struct amdgpu_cs_post_dep   *post_deps;
 };
 
 static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 52a5e4fdc95b..2f6239b6be6f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -215,6 +215,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser 
*p, union drm_amdgpu_cs
case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:
+   case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:
+   case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
break;
 
default:
@@ -804,9 +806,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser 
*parser, int error,
ttm_eu_backoff_reservation(>ticket,
   >validated);
 
-   for (i = 0; i < parser->num_post_dep_syncobjs; i++)
-   drm_syncobj_put(parser->post_dep_syncobjs[i]);
-   kfree(parser->post_dep_syncobjs);
+   for (i = 0; i < parser->num_post_deps; i++) {
+   drm_syncobj_put(parser->post_deps[i].syncobj);
+   kfree(parser->post_deps[i].chain);
+   }
+   kfree(parser->post_deps);
 
dma_fence_put(parser->fence);
 
@@ -1117,13 +1121,18 @@ static int amdgpu_cs_process_fence_dep(struct 
amdgpu_cs_parser *p,
 }
 
 static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
-uint32_t handle)
+uint32_t handle, u64 point,
+u64 flags)
 {
-   int r;
struct dma_fence *fence;
-   r = drm_syncobj_find_fence(p->filp, handle, 0, 0, );
-   if (r)
+   int r;
+
+   r = drm_syncobj_find_fence(p->filp, handle, point, flags, );
+   if (r) {
+   DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n",
+ handle, point, r);
return r;
+   }
 
r = amdgpu_sync_fence(p->adev, >job->sync, fence, true);
dma_fence_put(fence);
@@ -1134,46 +1143,118 @@ static int 
amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
 static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p,
struct amdgpu_cs_chunk *chunk)
 {
+   struct drm_amdgpu_cs_chunk_sem *deps;
unsigned num_deps;
int i, r;
-   struct drm_amdgpu_cs_chunk_sem *deps;
 
deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
num_deps = chunk->length_dw * 4 /
sizeof(struct drm_amdgpu_cs_chunk_sem);
+   for (i = 0; i < num_deps; ++i) {
+   r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle,
+ 0, 0);
+   if (r)
+   return r;
+   }
+
+   return 0;
+}
+
 
+static int amdgpu_cs_process_syncobj_timeline_in_dep(struct amdgpu_cs_parser 
*p,
+struct amdgpu_cs_chunk 
*chunk)
+{
+   struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps;
+   unsigned num_deps;
+   int i, r;
+
+   syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata;
+   num_deps = chunk->length_dw * 4 /
+   sizeof(struct drm_amdgpu_cs_chunk_syncobj);
for (i = 0; i < num_deps; ++i

[PATCH 8/9] drm/syncobj: add timeline signal ioctl for syncobj v5

2019-03-25 Thread Chunming Zhou
v2: individually allocate chain array, since chain node is free independently.
v3: all existing points must be already signaled before cpu perform signal 
operation,
so add check condition for that.
v4: remove v3 change and add checking to prevent out-of-order
v5: unify binary and timeline

Signed-off-by: Chunming Zhou 
Cc: Tobias Hector 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: Chris Wilson 
Cc: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_internal.h |  2 +
 drivers/gpu/drm/drm_ioctl.c|  2 +
 drivers/gpu/drm/drm_syncobj.c  | 73 ++
 include/uapi/drm/drm.h |  1 +
 4 files changed, 78 insertions(+)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index dd11ae5f1eef..d9a483a5fce0 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -190,6 +190,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void 
*data,
struct drm_file *file_private);
 int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file_private);
+int drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_private);
 int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_private);
 
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 92b3b7b2fd81..d337f161909c 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -696,6 +696,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, 
drm_syncobj_timeline_signal_ioctl,
+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, 
DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index ee2d66e047e7..099596190845 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1183,6 +1183,79 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void 
*data,
return ret;
 }
 
+int
+drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_private)
+{
+   struct drm_syncobj_timeline_array *args = data;
+   struct drm_syncobj **syncobjs;
+   struct dma_fence_chain **chains;
+   uint64_t *points;
+   uint32_t i, j;
+   int ret;
+
+   if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+   return -EOPNOTSUPP;
+
+   if (args->pad != 0)
+   return -EINVAL;
+
+   if (args->count_handles == 0)
+   return -EINVAL;
+
+   ret = drm_syncobj_array_find(file_private,
+u64_to_user_ptr(args->handles),
+args->count_handles,
+);
+   if (ret < 0)
+   return ret;
+
+   points = kmalloc_array(args->count_handles, sizeof(*points),
+  GFP_KERNEL);
+   if (!points) {
+   ret = -ENOMEM;
+   goto out;
+   }
+   if (!u64_to_user_ptr(args->points)) {
+   memset(points, 0, args->count_handles * sizeof(uint64_t));
+   } else if (copy_from_user(points, u64_to_user_ptr(args->points),
+ sizeof(uint64_t) * args->count_handles)) {
+   ret = -EFAULT;
+   goto err_points;
+   }
+
+   chains = kmalloc_array(args->count_handles, sizeof(void *), GFP_KERNEL);
+   if (!chains) {
+   ret = -ENOMEM;
+   goto err_points;
+   }
+   for (i = 0; i < args->count_handles; i++) {
+   chains[i] = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);
+   if (!chains[i]) {
+   for (j = 0; j < i; j++)
+   kfree(chains[j]);
+   ret = -ENOMEM;
+   goto err_chains;
+   }
+   }
+
+   for (i = 0; i < args->count_handles; i++) {
+   struct dma_fence *fence = dma_fence_get_stub();
+
+   drm_syncobj_add_point(syncobjs[i], chains[i],
+ fence, points[i]);
+   dma_fence_put(fence);
+   }
+err_chains:
+   kfree(chains);
+err_points:
+   kfree(points);
+out:
+   drm_syncobj_array_free(syncobjs, args->count_handles);
+
+   return ret;
+}
+
 int drm_syncobj_query_ioctl(struct drm_device *dev, void

[PATCH 5/9] drm/syncobj: use the timeline point in drm_syncobj_find_fence v4

2019-03-25 Thread Chunming Zhou
From: Christian König 

Implement finding the right timeline point in drm_syncobj_find_fence.

v2: return -EINVAL when the point is not submitted yet.
v3: fix reference counting bug, add flags handling as well
v4: add timeout for find fence

Signed-off-by: Christian König 
Cc: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_syncobj.c | 50 ---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 0e62a793c8dd..087fd4e7eaf3 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -213,6 +213,8 @@ static void drm_syncobj_assign_null_handle(struct 
drm_syncobj *syncobj)
dma_fence_put(fence);
 }
 
+/* 5s default for wait submission */
+#define DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT 50ULL
 /**
  * drm_syncobj_find_fence - lookup and reference the fence in a sync object
  * @file_private: drm file private pointer
@@ -233,16 +235,58 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
   struct dma_fence **fence)
 {
struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
-   int ret = 0;
+   struct syncobj_wait_entry wait;
+   u64 timeout = nsecs_to_jiffies64(DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT);
+   int ret;
 
if (!syncobj)
return -ENOENT;
 
*fence = drm_syncobj_fence_get(syncobj);
-   if (!*fence) {
+   drm_syncobj_put(syncobj);
+
+   if (*fence) {
+   ret = dma_fence_chain_find_seqno(fence, point);
+   if (!ret)
+   return 0;
+   dma_fence_put(*fence);
+   } else {
ret = -EINVAL;
}
-   drm_syncobj_put(syncobj);
+
+   if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
+   return ret;
+
+   memset(, 0, sizeof(wait));
+   wait.task = current;
+   wait.point = point;
+   drm_syncobj_fence_add_wait(syncobj, );
+
+   do {
+   set_current_state(TASK_INTERRUPTIBLE);
+   if (wait.fence) {
+   ret = 0;
+   break;
+   }
+if (timeout == 0) {
+ret = -ETIME;
+break;
+}
+
+   if (signal_pending(current)) {
+   ret = -ERESTARTSYS;
+   break;
+   }
+
+timeout = schedule_timeout(timeout);
+   } while (1);
+
+   __set_current_state(TASK_RUNNING);
+   *fence = wait.fence;
+
+   if (wait.node.next)
+   drm_syncobj_remove_wait(syncobj, );
+
return ret;
 }
 EXPORT_SYMBOL(drm_syncobj_find_fence);
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 4/9] drm/syncobj: add timeline payload query ioctl v6

2019-03-25 Thread Chunming Zhou
user mode can query timeline payload.
v2: check return value of copy_to_user
v3: handle querying entry by entry
v4: rebase on new chain container, simplify interface
v5: query last signaled timeline point, not last point.
v6: add unorder point check

Signed-off-by: Chunming Zhou 
Cc: Tobias Hector 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: Chris Wilson 
Cc: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_internal.h |  2 ++
 drivers/gpu/drm/drm_ioctl.c|  2 ++
 drivers/gpu/drm/drm_syncobj.c  | 62 ++
 include/uapi/drm/drm.h | 10 ++
 4 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 331ac6225b58..695179bb88dc 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -188,6 +188,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void 
*data,
struct drm_file *file_private);
 int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file_private);
+int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file_private);
 
 /* drm_framebuffer.c */
 void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index c984654646fa..7a534c184e52 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -694,6 +694,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
  DRM_UNLOCKED|DRM_RENDER_ALLOW),
+   DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
+ DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, 
DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, 
drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, 
DRM_MASTER|DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index eae51978cda4..0e62a793c8dd 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1064,3 +1064,65 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void 
*data,
 
return ret;
 }
+
+int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
+   struct drm_file *file_private)
+{
+   struct drm_syncobj_timeline_array *args = data;
+   struct drm_syncobj **syncobjs;
+   uint64_t __user *points = u64_to_user_ptr(args->points);
+   uint32_t i;
+   int ret;
+
+   if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+   return -ENODEV;
+
+   if (args->pad != 0)
+   return -EINVAL;
+
+   if (args->count_handles == 0)
+   return -EINVAL;
+
+   ret = drm_syncobj_array_find(file_private,
+u64_to_user_ptr(args->handles),
+args->count_handles,
+);
+   if (ret < 0)
+   return ret;
+
+   for (i = 0; i < args->count_handles; i++) {
+   struct dma_fence_chain *chain;
+   struct dma_fence *fence;
+   uint64_t point;
+
+   fence = drm_syncobj_fence_get(syncobjs[i]);
+   chain = to_dma_fence_chain(fence);
+   if (chain) {
+   struct dma_fence *iter, *last_signaled = NULL;
+
+   dma_fence_chain_for_each(iter, fence) {
+   if (!iter)
+   break;
+   dma_fence_put(last_signaled);
+   last_signaled = dma_fence_get(iter);
+   if 
(!to_dma_fence_chain(last_signaled)->prev_seqno)
+   /* It is most likely that timeline has
+* unorder points. */
+   break;
+   }
+   point = dma_fence_is_signaled(last_signaled) ?
+   last_signaled->seqno :
+   to_dma_fence_chain(last_signaled)->prev_seqno;
+   dma_fence_put(last_signaled);
+   } else {
+   point = 0;
+   }
+   ret = copy_to_user([i], , sizeof(uint64_t));
+   ret = ret ? -EFAULT : 0;
+   if (ret)
+   break;
+   }
+   drm_syncobj_array_free(syncobjs, args->count_handles);
+
+   return ret;
+}
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 44ebcdd9bd1d..c62be0840ba5 100644
--- a/

[PATCH 2/9] drm/syncobj: add new drm_syncobj_add_point interface v4

2019-03-25 Thread Chunming Zhou
From: Christian König 

Use the dma_fence_chain object to create a timeline of fence objects
instead of just replacing the existing fence.

v2: rebase and cleanup
v3: fix garbage collection parameters
v4: add unorder point check, print a warn calltrace

Signed-off-by: Christian König 
Cc: Lionel Landwerlin 
---
 drivers/gpu/drm/drm_syncobj.c | 39 +++
 include/drm/drm_syncobj.h |  5 +
 2 files changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 5329e66598c6..19a9ce638119 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -122,6 +122,45 @@ static void drm_syncobj_remove_wait(struct drm_syncobj 
*syncobj,
spin_unlock(>lock);
 }
 
+/**
+ * drm_syncobj_add_point - add new timeline point to the syncobj
+ * @syncobj: sync object to add timeline point do
+ * @chain: chain node to use to add the point
+ * @fence: fence to encapsulate in the chain node
+ * @point: sequence number to use for the point
+ *
+ * Add the chain node as new timeline point to the syncobj.
+ */
+void drm_syncobj_add_point(struct drm_syncobj *syncobj,
+  struct dma_fence_chain *chain,
+  struct dma_fence *fence,
+  uint64_t point)
+{
+   struct syncobj_wait_entry *cur, *tmp;
+   struct dma_fence *prev;
+
+   dma_fence_get(fence);
+
+   spin_lock(>lock);
+
+   prev = drm_syncobj_fence_get(syncobj);
+   /* You are adding an unorder point to timeline, which could cause 
payload returned from query_ioctl is 0! */
+   WARN_ON_ONCE(prev && prev->seqno >= point);
+   dma_fence_chain_init(chain, prev, fence, point);
+   rcu_assign_pointer(syncobj->fence, >base);
+
+   list_for_each_entry_safe(cur, tmp, >cb_list, node) {
+   list_del_init(>node);
+   syncobj_wait_syncobj_func(syncobj, cur);
+   }
+   spin_unlock(>lock);
+
+   /* Walk the chain once to trigger garbage collection */
+   dma_fence_chain_for_each(fence, prev);
+   dma_fence_put(prev);
+}
+EXPORT_SYMBOL(drm_syncobj_add_point);
+
 /**
  * drm_syncobj_replace_fence - replace fence in a sync object.
  * @syncobj: Sync object to replace fence in
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
index 0311c9fdbd2f..6cf7243a1dc5 100644
--- a/include/drm/drm_syncobj.h
+++ b/include/drm/drm_syncobj.h
@@ -27,6 +27,7 @@
 #define __DRM_SYNCOBJ_H__
 
 #include 
+#include 
 
 struct drm_file;
 
@@ -112,6 +113,10 @@ drm_syncobj_fence_get(struct drm_syncobj *syncobj)
 
 struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
 u32 handle);
+void drm_syncobj_add_point(struct drm_syncobj *syncobj,
+  struct dma_fence_chain *chain,
+  struct dma_fence *fence,
+  uint64_t point);
 void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
   struct dma_fence *fence);
 int drm_syncobj_find_fence(struct drm_file *file_private,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 1/9] dma-buf: add new dma_fence_chain container v7

2019-03-25 Thread Chunming Zhou
From: Christian König 

Lockless container implementation similar to a dma_fence_array, but with
only two elements per node and automatic garbage collection.

v2: properly document dma_fence_chain_for_each, add dma_fence_chain_find_seqno,
drop prev reference during garbage collection if it's not a chain fence.
v3: use head and iterator for dma_fence_chain_for_each
v4: fix reference count in dma_fence_chain_enable_signaling
v5: fix iteration when walking each chain node
v6: add __rcu for member 'prev' of struct chain node
v7: fix rcu warnings from kernel robot

Signed-off-by: Christian König 
Cc: Lionel Landwerlin 
---
 drivers/dma-buf/Makefile  |   3 +-
 drivers/dma-buf/dma-fence-chain.c | 241 ++
 include/linux/dma-fence-chain.h   |  81 ++
 3 files changed, 324 insertions(+), 1 deletion(-)
 create mode 100644 drivers/dma-buf/dma-fence-chain.c
 create mode 100644 include/linux/dma-fence-chain.h

diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index 0913a6ccab5a..1f006e083eb9 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1,4 +1,5 @@
-obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o
+obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
+reservation.o seqno-fence.o
 obj-$(CONFIG_SYNC_FILE)+= sync_file.o
 obj-$(CONFIG_SW_SYNC)  += sw_sync.o sync_debug.o
 obj-$(CONFIG_UDMABUF)  += udmabuf.o
diff --git a/drivers/dma-buf/dma-fence-chain.c 
b/drivers/dma-buf/dma-fence-chain.c
new file mode 100644
index ..c729f98a7bd3
--- /dev/null
+++ b/drivers/dma-buf/dma-fence-chain.c
@@ -0,0 +1,241 @@
+/*
+ * fence-chain: chain fences together in a timeline
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ * Authors:
+ * Christian König 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+
+static bool dma_fence_chain_enable_signaling(struct dma_fence *fence);
+
+/**
+ * dma_fence_chain_get_prev - use RCU to get a reference to the previous fence
+ * @chain: chain node to get the previous node from
+ *
+ * Use dma_fence_get_rcu_safe to get a reference to the previous fence of the
+ * chain node.
+ */
+static struct dma_fence *dma_fence_chain_get_prev(struct dma_fence_chain 
*chain)
+{
+   struct dma_fence *prev;
+
+   rcu_read_lock();
+   prev = dma_fence_get_rcu_safe(>prev);
+   rcu_read_unlock();
+   return prev;
+}
+
+/**
+ * dma_fence_chain_walk - chain walking function
+ * @fence: current chain node
+ *
+ * Walk the chain to the next node. Returns the next fence or NULL if we are at
+ * the end of the chain. Garbage collects chain nodes which are already
+ * signaled.
+ */
+struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence)
+{
+   struct dma_fence_chain *chain, *prev_chain;
+   struct dma_fence *prev, *replacement, *tmp;
+
+   chain = to_dma_fence_chain(fence);
+   if (!chain) {
+   dma_fence_put(fence);
+   return NULL;
+   }
+
+   while ((prev = dma_fence_chain_get_prev(chain))) {
+
+   prev_chain = to_dma_fence_chain(prev);
+   if (prev_chain) {
+   if (!dma_fence_is_signaled(prev_chain->fence))
+   break;
+
+   replacement = dma_fence_chain_get_prev(prev_chain);
+   } else {
+   if (!dma_fence_is_signaled(prev))
+   break;
+
+   replacement = NULL;
+   }
+
+   tmp = cmpxchg((void **)>prev, (void *)prev, (void 
*)replacement);
+   if (tmp == prev)
+   dma_fence_put(tmp);
+   else
+   dma_fence_put(replacement);
+   dma_fence_put(prev);
+   }
+
+   dma_fence_put(fence);
+   return prev;
+}
+EXPORT_SYMBOL(dma_fence_chain_walk);
+
+/**
+ * dma_fence_chain_find_seqno - find fence chain node by seqno
+ * @pfence: pointer to the chain node where to start
+ * @seqno: the sequence number to search for
+ *
+ * Advance the fence pointer to the chain node which will signal this sequence
+ * number. If no sequence number is provided then this is a no-op.
+ *
+ * Returns EINVAL if the fence is not a chain node or the sequence number has
+ * not yet advanced far enough.
+ */
+int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno)
+{
+   struct dma_fence_chain *chain;
+
+   if (!seqno)
+   return 0;
+
+   chain = 

  1   2   3   4   >