All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Koenig, Christian" <Christian.Koenig-5C7GfCeVMHo@public.gmane.org>
To: Lionel Landwerlin
	<lionel.g.landwerlin-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	"Zhou,
	David(ChunMing)" <David1.Zhou-5C7GfCeVMHo@public.gmane.org>,
	"dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org"
	<dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org>,
	"amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org"
	<amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org>,
	"jason-fQELhIk9awXprZlt/sZkLg@public.gmane.org"
	<jason-fQELhIk9awXprZlt/sZkLg@public.gmane.org>
Cc: Dave Airlie <airlied-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	Chris Wilson
	<chris-Y6uKTt2uX1cEflXRtASbqLVCufUGDwFn@public.gmane.org>,
	Daniel Rakos <Daniel.Rakos-5C7GfCeVMHo@public.gmane.org>,
	Bas Nieuwenhuizen
	<bas-dldO88ZXqoXqqjsSq9zF6IRWq/SkRNHw@public.gmane.org>
Subject: Re: [PATCH 3/9] drm/syncobj: add support for timeline point wait v8
Date: Mon, 18 Mar 2019 17:20:30 +0000	[thread overview]
Message-ID: <990db9e7-6cae-1165-637c-84aed3a9af49@amd.com> (raw)
In-Reply-To: <5b68b54a-5d8d-9666-bd45-aa53b6b295e7-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

Am 18.03.19 um 17:59 schrieb Lionel Landwerlin:
> On 15/03/2019 12:09, Chunming Zhou wrote:
>> 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 <david1.zhou@amd.com>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> Cc: Daniel Rakos <Daniel.Rakos@amd.com>
>> Cc: Jason Ekstrand <jason@jlekstrand.net>
>> Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
>> Cc: Dave Airlie <airlied@redhat.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> ---
>>   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 19a9ce638119..eae51978cda4 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;
>> +    u64    point;
>>   };
>>     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(&fence, wait->point)) {
>> +        dma_fence_put(fence);
>>           list_add_tail(&wait->node, &syncobj->cb_list);
>> +    } else if (!fence) {
>> +        wait->fence = dma_fence_get_stub();
>> +    } else {
>> +        wait->fence = fence;
>> +    }
>>       spin_unlock(&syncobj->lock);
>>   }
>>   @@ -149,10 +156,8 @@ void drm_syncobj_add_point(struct drm_syncobj 
>> *syncobj,
>>       dma_fence_chain_init(chain, prev, fence, point);
>>       rcu_assign_pointer(syncobj->fence, &chain->base);
>>   -    list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) {
>> -        list_del_init(&cur->node);
>> +    list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node)
>>           syncobj_wait_syncobj_func(syncobj, cur);
>> -    }
>>       spin_unlock(&syncobj->lock);
>>         /* Walk the chain once to trigger garbage collection */
>> @@ -184,10 +189,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, &syncobj->cb_list, node) {
>> -            list_del_init(&cur->node);
>> +        list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node)
>>               syncobj_wait_syncobj_func(syncobj, cur);
>> -        }
>>       }
>>         spin_unlock(&syncobj->lock);
>> @@ -644,13 +647,27 @@ static void syncobj_wait_fence_func(struct 
>> dma_fence *fence,
>>   static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
>>                         struct syncobj_wait_entry *wait)
>>   {
>> +    struct dma_fence *fence;
>> +
>>       /* This happens inside the syncobj lock */
>> -    wait->fence = 
>> dma_fence_get(rcu_dereference_protected(syncobj->fence,
>> - lockdep_is_held(&syncobj->lock)));
>> +    fence = rcu_dereference_protected(syncobj->fence,
>> +                      lockdep_is_held(&syncobj->lock));
>> +    dma_fence_get(fence);
>> +    if (!fence || dma_fence_chain_find_seqno(&fence, wait->point)) {
>> +        dma_fence_put(fence);
>> +        return;
>> +    } else if (!fence) {
>> +        wait->fence = dma_fence_get_stub();
>> +    } else {
>> +        wait->fence = fence;
>> +    }
>> +
>>       wake_up_process(wait->task);
>> +    list_del_init(&wait->node);
>>   }
>>     static signed long drm_syncobj_array_wait_timeout(struct 
>> drm_syncobj **syncobjs,
>> +                          void __user *user_points,
>>                             uint32_t count,
>>                             uint32_t flags,
>>                             signed long timeout,
>> @@ -658,12 +675,27 @@ static signed long 
>> drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>>   {
>>       struct syncobj_wait_entry *entries;
>>       struct dma_fence *fence;
>> +    uint64_t *points;
>>       uint32_t signaled_count, i;
>>   -    entries = kcalloc(count, sizeof(*entries), GFP_KERNEL);
>> -    if (!entries)
>> +    points = kmalloc_array(count, sizeof(*points), GFP_KERNEL);
>> +    if (points == NULL)
>>           return -ENOMEM;
>>   +    if (!user_points) {
>> +        memset(points, 0, count * sizeof(uint64_t));
>> +
>> +    } else if (copy_from_user(points, user_points,
>> +                  sizeof(uint64_t) * count)) {
>> +        timeout = -EFAULT;
>> +        goto err_free_points;
>> +    }
>> +
>> +    entries = kcalloc(count, sizeof(*entries), GFP_KERNEL);
>> +    if (!entries) {
>> +        timeout = -ENOMEM;
>> +        goto err_free_points;
>> +    }
>>       /* Walk the list of sync objects and initialize entries. We do
>>        * this up-front so that we can properly return -EINVAL if 
>> there is
>>        * a syncobj with a missing fence and then never have the 
>> chance of
>> @@ -671,9 +703,13 @@ static signed long 
>> drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>>        */
>>       signaled_count = 0;
>>       for (i = 0; i < count; ++i) {
>> +        struct dma_fence *fence;
>> +
>>           entries[i].task = current;
>> -        entries[i].fence = drm_syncobj_fence_get(syncobjs[i]);
>> -        if (!entries[i].fence) {
>> +        entries[i].point = points[i];
>> +        fence = drm_syncobj_fence_get(syncobjs[i]);
>> +        if (!fence || dma_fence_chain_find_seqno(&fence, points[i])) {
>> +            dma_fence_put(fence);
>>               if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
>>                   continue;
>>               } else {
>> @@ -682,7 +718,13 @@ static signed long 
>> drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>>               }
>>           }
>>   -        if (dma_fence_is_signaled(entries[i].fence)) {
>> +        if (fence)
>> +            entries[i].fence = fence;
>> +        else
>> +            entries[i].fence = dma_fence_get_stub();
>> +
>> +        if ((flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE) ||
>
>
> Hey David,
>
> Could you remind me what DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE is used 
> for?
>
> I didn't have a use for it in userspace,

The flag is used to wait for fences for a sequence number to show up.

Christian.

>
> Thanks,
>
> -Lionel
>
>
>> + dma_fence_is_signaled(entries[i].fence)) {
>>               if (signaled_count == 0 && idx)
>>                   *idx = i;
>>               signaled_count++;
>> @@ -715,7 +757,8 @@ static signed long 
>> drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>>               if (!fence)
>>                   continue;
>>   -            if (dma_fence_is_signaled(fence) ||
>> +            if ((flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE) ||
>> +                dma_fence_is_signaled(fence) ||
>>                   (!entries[i].fence_cb.func &&
>>                    dma_fence_add_callback(fence,
>>                               &entries[i].fence_cb,
>> @@ -760,6 +803,9 @@ static signed long 
>> drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
>>       }
>>       kfree(entries);
>>   +err_free_points:
>> +    kfree(points);
>> +
>>       return timeout;
>>   }
>>   @@ -799,19 +845,33 @@ EXPORT_SYMBOL(drm_timeout_abs_to_jiffies);
>>   static int drm_syncobj_array_wait(struct drm_device *dev,
>>                     struct drm_file *file_private,
>>                     struct drm_syncobj_wait *wait,
>> -                  struct drm_syncobj **syncobjs)
>> +                  struct drm_syncobj_timeline_wait *timeline_wait,
>> +                  struct drm_syncobj **syncobjs, bool timeline)
>>   {
>> -    signed long timeout = 
>> drm_timeout_abs_to_jiffies(wait->timeout_nsec);
>> +    signed long timeout = 0;
>>       uint32_t first = ~0;
>>   -    timeout = drm_syncobj_array_wait_timeout(syncobjs,
>> -                         wait->count_handles,
>> -                         wait->flags,
>> -                         timeout, &first);
>> -    if (timeout < 0)
>> -        return timeout;
>> -
>> -    wait->first_signaled = first;
>> +    if (!timeline) {
>> +        timeout = drm_timeout_abs_to_jiffies(wait->timeout_nsec);
>> +        timeout = drm_syncobj_array_wait_timeout(syncobjs,
>> +                             NULL,
>> +                             wait->count_handles,
>> +                             wait->flags,
>> +                             timeout, &first);
>> +        if (timeout < 0)
>> +            return timeout;
>> +        wait->first_signaled = first;
>> +    } else {
>> +        timeout = 
>> drm_timeout_abs_to_jiffies(timeline_wait->timeout_nsec);
>> +        timeout = drm_syncobj_array_wait_timeout(syncobjs,
>> + u64_to_user_ptr(timeline_wait->points),
>> +                             timeline_wait->count_handles,
>> +                             timeline_wait->flags,
>> +                             timeout, &first);
>> +        if (timeout < 0)
>> +            return timeout;
>> +        timeline_wait->first_signaled = first;
>> +    }
>>       return 0;
>>   }
>>   @@ -897,13 +957,48 @@ drm_syncobj_wait_ioctl(struct drm_device 
>> *dev, void *data,
>>           return ret;
>>         ret = drm_syncobj_array_wait(dev, file_private,
>> -                     args, syncobjs);
>> +                     args, NULL, syncobjs, false);
>>         drm_syncobj_array_free(syncobjs, args->count_handles);
>>         return ret;
>>   }
>>   +int
>> +drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data,
>> +                struct drm_file *file_private)
>> +{
>> +    struct drm_syncobj_timeline_wait *args = data;
>> +    struct drm_syncobj **syncobjs;
>> +    int ret = 0;
>> +
>> +    if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
>> +        return -ENODEV;
>> +
>> +    if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
>> +                DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT |
>> +                DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE))
>> +        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,
>> +                     &syncobjs);
>> +    if (ret < 0)
>> +        return ret;
>> +
>> +    ret = drm_syncobj_array_wait(dev, file_private,
>> +                     NULL, args, syncobjs, true);
>> +
>> +    drm_syncobj_array_free(syncobjs, args->count_handles);
>> +
>> +    return ret;
>> +}
>> +
>> +
>>   int
>>   drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
>>               struct drm_file *file_private)
>> diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
>> index 300f336633f2..0092111d002c 100644
>> --- a/include/uapi/drm/drm.h
>> +++ b/include/uapi/drm/drm.h
>> @@ -737,6 +737,7 @@ struct drm_syncobj_handle {
>>     #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 */
>> @@ -747,6 +748,19 @@ 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;
>> @@ -909,6 +923,7 @@ extern "C" {
>>   #define DRM_IOCTL_MODE_GET_LEASE    DRM_IOWR(0xC8, struct 
>> drm_mode_get_lease)
>>   #define DRM_IOCTL_MODE_REVOKE_LEASE    DRM_IOWR(0xC9, struct 
>> drm_mode_revoke_lease)
>>   +#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT    DRM_IOWR(0xCA, struct 
>> drm_syncobj_timeline_wait)
>>   /**
>>    * Device specific ioctls should only be in their respective headers
>>    * The device specific ioctl range is from 0x40 to 0x9f.
>
>

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  parent reply	other threads:[~2019-03-18 17:20 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-15 12:09 [PATCH 1/9] dma-buf: add new dma_fence_chain container v5 Chunming Zhou
2019-03-15 12:09 ` [PATCH 2/9] drm/syncobj: add new drm_syncobj_add_point interface v4 Chunming Zhou
2019-03-15 12:09 ` [PATCH 3/9] drm/syncobj: add support for timeline point wait v8 Chunming Zhou
2019-03-18 16:59   ` Lionel Landwerlin
     [not found]     ` <5b68b54a-5d8d-9666-bd45-aa53b6b295e7-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2019-03-18 17:20       ` Koenig, Christian [this message]
     [not found]         ` <990db9e7-6cae-1165-637c-84aed3a9af49-5C7GfCeVMHo@public.gmane.org>
2019-03-18 18:19           ` Lionel Landwerlin
2019-03-15 12:09 ` [PATCH 4/9] drm/syncobj: add timeline payload query ioctl v6 Chunming Zhou
2019-03-15 12:09 ` [PATCH 6/9] drm/amdgpu: add timeline support in amdgpu CS v3 Chunming Zhou
     [not found] ` <20190315120959.25489-1-david1.zhou-5C7GfCeVMHo@public.gmane.org>
2019-03-15 12:09   ` [PATCH 5/9] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3 Chunming Zhou
2019-03-16  1:10     ` kbuild test robot
2019-03-15 12:09   ` [PATCH 7/9] drm/syncobj: add transition iotcls between binary and timeline v2 Chunming Zhou
2019-03-15 12:09   ` [PATCH 8/9] drm/syncobj: add timeline signal ioctl for syncobj v3 Chunming Zhou
     [not found]     ` <20190315120959.25489-8-david1.zhou-5C7GfCeVMHo@public.gmane.org>
2019-03-19 11:54       ` Lionel Landwerlin
     [not found]         ` <78d9e191-7cdd-c9f1-c33e-2707b44e4932-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2019-03-20  3:53           ` zhoucm1
     [not found]             ` <e4f8f010-2649-f8fc-5949-9b652a3e977e-5C7GfCeVMHo@public.gmane.org>
2019-03-20 11:58               ` Lionel Landwerlin
2019-03-20 13:23               ` Lionel Landwerlin
2019-03-15 12:09   ` [PATCH 9/9] drm/amdgpu: update version for timeline syncobj support in amdgpu Chunming Zhou
2019-03-19 12:27   ` [PATCH 1/9] dma-buf: add new dma_fence_chain container v5 Lionel Landwerlin
     [not found]     ` <946e2cc2-eda7-7e7f-80ad-fa7161942930-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2019-03-19 12:29       ` Christian König
  -- strict thread matches above, loose matches on Subject: below --
2019-04-01  9:50 [PATCH 0/9] *** timeline syncobj support *** Chunming Zhou
2019-04-01  9:50 ` [PATCH 3/9] drm/syncobj: add support for timeline point wait v8 Chunming Zhou
2019-03-25  8:32 [PATCH 1/9] dma-buf: add new dma_fence_chain container v7 Chunming Zhou
     [not found] ` <20190325083224.2983-1-david1.zhou-5C7GfCeVMHo@public.gmane.org>
2019-03-25  8:32   ` [PATCH 3/9] drm/syncobj: add support for timeline point wait v8 Chunming Zhou
2019-03-20  5:47 [PATCH 1/9] dma-buf: add new dma_fence_chain container v6 Chunming Zhou
     [not found] ` <20190320054724.14636-1-david1.zhou-5C7GfCeVMHo@public.gmane.org>
2019-03-20  5:47   ` [PATCH 3/9] drm/syncobj: add support for timeline point wait v8 Chunming Zhou
2019-03-12  3:10 [PATCH 1/9] dma-buf: add new dma_fence_chain container v5 Chunming Zhou
2019-03-12  3:10 ` [PATCH 3/9] drm/syncobj: add support for timeline point wait v8 Chunming Zhou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=990db9e7-6cae-1165-637c-84aed3a9af49@amd.com \
    --to=christian.koenig-5c7gfcevmho@public.gmane.org \
    --cc=Daniel.Rakos-5C7GfCeVMHo@public.gmane.org \
    --cc=David1.Zhou-5C7GfCeVMHo@public.gmane.org \
    --cc=airlied-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=bas-dldO88ZXqoXqqjsSq9zF6IRWq/SkRNHw@public.gmane.org \
    --cc=chris-Y6uKTt2uX1cEflXRtASbqLVCufUGDwFn@public.gmane.org \
    --cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=jason-fQELhIk9awXprZlt/sZkLg@public.gmane.org \
    --cc=lionel.g.landwerlin-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.