[PATCH 2/5] drm: Add Reusable task barrier.

Christian König ckoenig.leichtzumerken at gmail.com
Thu Dec 12 15:09:26 UTC 2019


Am 12.12.19 um 15:50 schrieb Grodzovsky, Andrey:
> [AMD Official Use Only - Internal Distribution Only]
>
> ______________________________________
> From: Christian König <ckoenig.leichtzumerken at gmail.com>
> Sent: 12 December 2019 03:31
> To: Alex Deucher; Grodzovsky, Andrey
> Cc: Deucher, Alexander; Ma, Le; Quan, Evan; amd-gfx list; Zhang, Hawking
> Subject: Re: [PATCH 2/5] drm: Add Reusable task barrier.
>
> Am 12.12.19 um 09:24 schrieb Christian König:
>> Am 11.12.19 um 21:19 schrieb Alex Deucher:
>>> On Wed, Dec 11, 2019 at 3:07 PM Andrey Grodzovsky
>>> <andrey.grodzovsky at amd.com> wrote:
>>>> It is used to synchronize N threads at a rendevouz point before
>>>> execution
>>>> of critical code that has to be started by all the threads at
>>>> approximatly
>>>> the same time.
>>>>
>>>> Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky at amd.com>
>>> You should resend to dri-devel since this task barrier is being added
>>> to common code.
>> Additional to that this whole thing has the potential to raise lockdep
>> warnings and if I'm not completely mistaken doesn't even work correctly.
> Can you give me a potential lockdep scenario ?

Lockdep usually complains if a lock is released from another thread than 
where it was locked from.

In the code you let each thread do a down() and then the last one does 
multiple up() calls.

But I think that is only illegal for mutexes, but legal for semaphores.

Christian.

>
> Andrey
>
>> See Linux kernel semaphores don't allow negative values (the count
>> field in struct semaphore is unsigned).
> Ok, forget what I've wrote. That indeed seems to be supported, some
> other drivers are already using semaphores the same way.
>
> Regards,
> Christian.
>
>> Regards,
>> Christian.
>>
>>> Alex
>>>
>>>> ---
>>>>    include/drm/task_barrier.h | 106
>>>> +++++++++++++++++++++++++++++++++++++++++++++
>>>>    1 file changed, 106 insertions(+)
>>>>    create mode 100644 include/drm/task_barrier.h
>>>>
>>>> diff --git a/include/drm/task_barrier.h b/include/drm/task_barrier.h
>>>> new file mode 100644
>>>> index 0000000..81fb0f7
>>>> --- /dev/null
>>>> +++ b/include/drm/task_barrier.h
>>>> @@ -0,0 +1,106 @@
>>>> +/*
>>>> + * Copyright 2019 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 <linux/semaphore.h>
>>>> +#include <linux/atomic.h>
>>>> +
>>>> +/*
>>>> + * Reusable 2 PHASE task barrier (randevouz point) implementation
>>>> for N tasks.
>>>> + * Based on the Little book of sempahores -
>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgreenteapress.com%2Fwp%2Fsemaphores%2F&data=02%7C01%7Candrey.grodzovsky%40amd.com%7C96f8c28ae4bd43f2922208d77eddb60f%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637117363029062995&sdata=6xXZXyDIKmQM8ET5hPIZ%2FbJrOMQqK4oYw8dGYS1rxcY%3D&reserved=0
>>>> + */
>>>> +
>>>> +
>>>> +
>>>> +#ifndef DRM_TASK_BARRIER_H_
>>>> +#define DRM_TASK_BARRIER_H_
>>>> +
>>>> +/*
>>>> + * Represents an instance of a task barrier.
>>>> + */
>>>> +struct task_barrier {
>>>> +       unsigned int n;
>>>> +       atomic_t count;
>>>> +       struct semaphore enter_turnstile;
>>>> +       struct semaphore exit_turnstile;
>>>> +};
>>>> +
>>>> +static inline void task_barrier_signal_turnstile(struct semaphore
>>>> *turnstile,
>>>> +                                                unsigned int n)
>>>> +{
>>>> +       int i;
>>>> +
>>>> +       for (i = 0 ; i < n; i++)
>>>> +               up(turnstile);
>>>> +}
>>>> +
>>>> +static inline void task_barrier_init(struct task_barrier *tb)
>>>> +{
>>>> +       tb->n = 0;
>>>> +       atomic_set(&tb->count, 0);
>>>> +       sema_init(&tb->enter_turnstile, 0);
>>>> +       sema_init(&tb->exit_turnstile, 0);
>>>> +}
>>>> +
>>>> +static inline void task_barrier_add_task(struct task_barrier *tb)
>>>> +{
>>>> +       tb->n++;
>>>> +}
>>>> +
>>>> +static inline void task_barrier_rem_task(struct task_barrier *tb)
>>>> +{
>>>> +       tb->n--;
>>>> +}
>>>> +
>>>> +/*
>>>> + * Lines up all the threads BEFORE the critical point.
>>>> + *
>>>> + * When all thread passed this code the entry barrier is back to
>>>> locked state.
>>>> + */
>>>> +static inline void task_barrier_enter(struct task_barrier *tb)
>>>> +{
>>>> +       if (atomic_inc_return(&tb->count) == tb->n)
>>>> + task_barrier_signal_turnstile(&tb->enter_turnstile, tb->n);
>>>> +
>>>> +       down(&tb->enter_turnstile);
>>>> +}
>>>> +
>>>> +/*
>>>> + * Lines up all the threads AFTER the critical point.
>>>> + *
>>>> + * This function is used to avoid any one thread running ahead of
>>>> the reset if
>>>> + * the barrier is used in a loop (repeatedly) .
>>>> + */
>>>> +static inline void task_barrier_exit(struct task_barrier *tb)
>>>> +{
>>>> +       if (atomic_dec_return(&tb->count) == 0)
>>>> + task_barrier_signal_turnstile(&tb->exit_turnstile, tb->n);
>>>> +
>>>> +       down(&tb->exit_turnstile);
>>>> +}
>>>> +
>>>> +static inline void task_barrier_full(struct task_barrier *tb)
>>>> +{
>>>> +       task_barrier_enter(tb);
>>>> +       task_barrier_exit(tb);
>>>> +}
>>>> +
>>>> +#endif
>>>> --
>>>> 2.7.4
>>>>
>>>> _______________________________________________
>>>> amd-gfx mailing list
>>>> amd-gfx at lists.freedesktop.org
>>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=02%7C01%7Candrey.grodzovsky%40amd.com%7C96f8c28ae4bd43f2922208d77eddb60f%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637117363029067994&sdata=4skEGGfYBmQco%2FaCXneWuR1p8l%2F0JS8IrLNx%2Bddzxos%3D&reserved=0
>>> _______________________________________________
>>> amd-gfx mailing list
>>> amd-gfx at lists.freedesktop.org
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=02%7C01%7Candrey.grodzovsky%40amd.com%7C96f8c28ae4bd43f2922208d77eddb60f%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637117363029067994&sdata=4skEGGfYBmQco%2FaCXneWuR1p8l%2F0JS8IrLNx%2Bddzxos%3D&reserved=0



More information about the amd-gfx mailing list