On 02/07/2021 15:32, Boris Brezillon wrote:
> Needed to keep VkQueues isolated from each other.
> 
> v3:
> * Limit the number of submitqueue per context to 16
> * Fix a deadlock
> 
> Signed-off-by: Boris Brezillon <boris.brezil...@collabora.com>

16 ought to be enough for anyone ;)

Reviewed-by: Steven Price <steven.pr...@arm.com>

> ---
>  drivers/gpu/drm/panfrost/Makefile             |   3 +-
>  drivers/gpu/drm/panfrost/panfrost_device.h    |   2 +-
>  drivers/gpu/drm/panfrost/panfrost_drv.c       |  69 +++++++--
>  drivers/gpu/drm/panfrost/panfrost_job.c       |  47 ++----
>  drivers/gpu/drm/panfrost/panfrost_job.h       |   9 +-
>  .../gpu/drm/panfrost/panfrost_submitqueue.c   | 136 ++++++++++++++++++
>  .../gpu/drm/panfrost/panfrost_submitqueue.h   |  27 ++++
>  include/uapi/drm/panfrost_drm.h               |  17 +++
>  8 files changed, 264 insertions(+), 46 deletions(-)
>  create mode 100644 drivers/gpu/drm/panfrost/panfrost_submitqueue.c
>  create mode 100644 drivers/gpu/drm/panfrost/panfrost_submitqueue.h
> 
> diff --git a/drivers/gpu/drm/panfrost/Makefile 
> b/drivers/gpu/drm/panfrost/Makefile
> index b71935862417..e99192b66ec9 100644
> --- a/drivers/gpu/drm/panfrost/Makefile
> +++ b/drivers/gpu/drm/panfrost/Makefile
> @@ -9,6 +9,7 @@ panfrost-y := \
>       panfrost_gpu.o \
>       panfrost_job.o \
>       panfrost_mmu.o \
> -     panfrost_perfcnt.o
> +     panfrost_perfcnt.o \
> +     panfrost_submitqueue.o
>  
>  obj-$(CONFIG_DRM_PANFROST) += panfrost.o
> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
> b/drivers/gpu/drm/panfrost/panfrost_device.h
> index 8b25278f34c8..51c0ba4e50f5 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_device.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h
> @@ -137,7 +137,7 @@ struct panfrost_mmu {
>  struct panfrost_file_priv {
>       struct panfrost_device *pfdev;
>  
> -     struct drm_sched_entity sched_entity[NUM_JOB_SLOTS];
> +     struct idr queues;
>  
>       struct panfrost_mmu *mmu;
>  };
> diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
> b/drivers/gpu/drm/panfrost/panfrost_drv.c
> index b6b5997c9366..6529e5972b47 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> @@ -19,6 +19,7 @@
>  #include "panfrost_job.h"
>  #include "panfrost_gpu.h"
>  #include "panfrost_perfcnt.h"
> +#include "panfrost_submitqueue.h"
>  
>  static bool unstable_ioctls;
>  module_param_unsafe(unstable_ioctls, bool, 0600);
> @@ -250,6 +251,7 @@ static int panfrost_ioctl_submit(struct drm_device *dev, 
> void *data,
>       struct panfrost_device *pfdev = dev->dev_private;
>       struct drm_panfrost_submit *args = data;
>       struct drm_syncobj *sync_out = NULL;
> +     struct panfrost_submitqueue *queue;
>       struct panfrost_job *job;
>       int ret = 0;
>  
> @@ -259,10 +261,16 @@ static int panfrost_ioctl_submit(struct drm_device 
> *dev, void *data,
>       if (args->requirements && args->requirements != PANFROST_JD_REQ_FS)
>               return -EINVAL;
>  
> +     queue = panfrost_submitqueue_get(file->driver_priv, 0);
> +     if (IS_ERR(queue))
> +             return PTR_ERR(queue);
> +
>       if (args->out_sync > 0) {
>               sync_out = drm_syncobj_find(file, args->out_sync);
> -             if (!sync_out)
> -                     return -ENODEV;
> +             if (!sync_out) {
> +                     ret = -ENODEV;
> +                     goto fail_put_queue;
> +             }
>       }
>  
>       job = kzalloc(sizeof(*job), GFP_KERNEL);
> @@ -289,7 +297,7 @@ static int panfrost_ioctl_submit(struct drm_device *dev, 
> void *data,
>       if (ret)
>               goto fail_job;
>  
> -     ret = panfrost_job_push(job);
> +     ret = panfrost_job_push(queue, job);
>       if (ret)
>               goto fail_job;
>  
> @@ -302,6 +310,8 @@ static int panfrost_ioctl_submit(struct drm_device *dev, 
> void *data,
>  fail_out_sync:
>       if (sync_out)
>               drm_syncobj_put(sync_out);
> +fail_put_queue:
> +     panfrost_submitqueue_put(queue);
>  
>       return ret;
>  }
> @@ -451,6 +461,36 @@ static int panfrost_ioctl_madvise(struct drm_device 
> *dev, void *data,
>       return ret;
>  }
>  
> +static int
> +panfrost_ioctl_create_submitqueue(struct drm_device *dev, void *data,
> +                               struct drm_file *file_priv)
> +{
> +     struct panfrost_file_priv *priv = file_priv->driver_priv;
> +     struct drm_panfrost_create_submitqueue *args = data;
> +     struct panfrost_submitqueue *queue;
> +
> +     queue = panfrost_submitqueue_create(priv, args->priority, args->flags);
> +     if (IS_ERR(queue))
> +             return PTR_ERR(queue);
> +
> +     args->id = queue->id;
> +     return 0;
> +}
> +
> +static int
> +panfrost_ioctl_destroy_submitqueue(struct drm_device *dev, void *data,
> +                                struct drm_file *file_priv)
> +{
> +     struct panfrost_file_priv *priv = file_priv->driver_priv;
> +     u32 id = *((u32 *)data);
> +
> +     /* Default queue can't be destroyed. */
> +     if (!id)
> +             return -ENOENT;
> +
> +     return panfrost_submitqueue_destroy(priv, id);
> +}
> +
>  int panfrost_unstable_ioctl_check(void)
>  {
>       if (!unstable_ioctls)
> @@ -465,6 +505,7 @@ panfrost_open(struct drm_device *dev, struct drm_file 
> *file)
>       int ret;
>       struct panfrost_device *pfdev = dev->dev_private;
>       struct panfrost_file_priv *panfrost_priv;
> +     struct panfrost_submitqueue *defaultqueue;
>  
>       panfrost_priv = kzalloc(sizeof(*panfrost_priv), GFP_KERNEL);
>       if (!panfrost_priv)
> @@ -479,13 +520,19 @@ panfrost_open(struct drm_device *dev, struct drm_file 
> *file)
>               goto err_free;
>       }
>  
> -     ret = panfrost_job_open(panfrost_priv);
> -     if (ret)
> -             goto err_job;
> +     idr_init(&panfrost_priv->queues);
> +     defaultqueue = panfrost_submitqueue_create(panfrost_priv,
> +                                                
> PANFROST_SUBMITQUEUE_PRIORITY_MEDIUM,
> +                                                0);
> +     if (IS_ERR(defaultqueue)) {
> +             ret = PTR_ERR(defaultqueue);
> +             goto err_destroy_idr;
> +     }
>  
>       return 0;
>  
> -err_job:
> +err_destroy_idr:
> +     idr_destroy(&panfrost_priv->queues);
>       panfrost_mmu_ctx_put(panfrost_priv->mmu);
>  err_free:
>       kfree(panfrost_priv);
> @@ -496,11 +543,15 @@ static void
>  panfrost_postclose(struct drm_device *dev, struct drm_file *file)
>  {
>       struct panfrost_file_priv *panfrost_priv = file->driver_priv;
> +     u32 id;
>  
>       panfrost_perfcnt_close(file);
> -     panfrost_job_close(panfrost_priv);
> +
> +     for (id = 0; idr_get_next(&panfrost_priv->queues, &id); id++)
> +             panfrost_submitqueue_destroy(panfrost_priv, id);
>  
>       panfrost_mmu_ctx_put(panfrost_priv->mmu);
> +     idr_destroy(&panfrost_priv->queues);
>       kfree(panfrost_priv);
>  }
>  
> @@ -517,6 +568,8 @@ static const struct drm_ioctl_desc 
> panfrost_drm_driver_ioctls[] = {
>       PANFROST_IOCTL(PERFCNT_ENABLE,  perfcnt_enable, DRM_RENDER_ALLOW),
>       PANFROST_IOCTL(PERFCNT_DUMP,    perfcnt_dump,   DRM_RENDER_ALLOW),
>       PANFROST_IOCTL(MADVISE,         madvise,        DRM_RENDER_ALLOW),
> +     PANFROST_IOCTL(CREATE_SUBMITQUEUE, create_submitqueue, 
> DRM_RENDER_ALLOW),
> +     PANFROST_IOCTL(DESTROY_SUBMITQUEUE, destroy_submitqueue, 
> DRM_RENDER_ALLOW),
>  };
>  
>  DEFINE_DRM_GEM_FOPS(panfrost_drm_driver_fops);
> diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c 
> b/drivers/gpu/drm/panfrost/panfrost_job.c
> index 152245b122be..56ae89272e19 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_job.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_job.c
> @@ -20,6 +20,7 @@
>  #include "panfrost_regs.h"
>  #include "panfrost_gpu.h"
>  #include "panfrost_mmu.h"
> +#include "panfrost_submitqueue.h"
>  
>  #define JOB_TIMEOUT_MS 500
>  
> @@ -276,15 +277,15 @@ static void panfrost_attach_object_fences(struct 
> panfrost_job *job)
>       }
>  }
>  
> -int panfrost_job_push(struct panfrost_job *job)
> +int panfrost_job_push(struct panfrost_submitqueue *queue,
> +                   struct panfrost_job *job)
>  {
>       struct panfrost_device *pfdev = job->pfdev;
>       int slot = panfrost_job_get_slot(job);
> -     struct drm_sched_entity *entity = &job->file_priv->sched_entity[slot];
> +     struct drm_sched_entity *entity = &queue->sched_entity[slot];
>       struct ww_acquire_ctx acquire_ctx;
>       int ret = 0;
>  
> -
>       ret = drm_gem_lock_reservations(job->bos, job->bo_count,
>                                           &acquire_ctx);
>       if (ret)
> @@ -881,43 +882,18 @@ void panfrost_job_fini(struct panfrost_device *pfdev)
>       destroy_workqueue(pfdev->reset.wq);
>  }
>  
> -int panfrost_job_open(struct panfrost_file_priv *panfrost_priv)
> +void panfrost_job_kill_queue(struct panfrost_submitqueue *queue)
>  {
> -     struct panfrost_device *pfdev = panfrost_priv->pfdev;
> -     struct panfrost_job_slot *js = pfdev->js;
> -     struct drm_gpu_scheduler *sched;
> -     int ret, i;
> +     struct panfrost_device *pfdev = queue->pfdev;
> +     int i, j;
>  
> -     for (i = 0; i < NUM_JOB_SLOTS; i++) {
> -             sched = &js->queue[i].sched;
> -             ret = drm_sched_entity_init(&panfrost_priv->sched_entity[i],
> -                                         DRM_SCHED_PRIORITY_NORMAL, &sched,
> -                                         1, NULL);
> -             if (WARN_ON(ret))
> -                     return ret;
> -     }
> -     return 0;
> -}
> -
> -void panfrost_job_close(struct panfrost_file_priv *panfrost_priv)
> -{
> -     struct panfrost_device *pfdev = panfrost_priv->pfdev;
> -     int i;
> -
> -     for (i = 0; i < NUM_JOB_SLOTS; i++)
> -             drm_sched_entity_destroy(&panfrost_priv->sched_entity[i]);
> -
> -     /* Kill in-flight jobs */
>       spin_lock(&pfdev->js->job_lock);
>       for (i = 0; i < NUM_JOB_SLOTS; i++) {
> -             struct drm_sched_entity *entity = 
> &panfrost_priv->sched_entity[i];
> -             int j;
> -
>               for (j = ARRAY_SIZE(pfdev->jobs[0]) - 1; j >= 0; j--) {
>                       struct panfrost_job *job = pfdev->jobs[i][j];
>                       u32 cmd;
>  
> -                     if (!job || job->base.entity != entity)
> +                     if (!job || job->base.entity != &queue->sched_entity[i])
>                               continue;
>  
>                       if (j == 1) {
> @@ -936,7 +912,6 @@ void panfrost_job_close(struct panfrost_file_priv 
> *panfrost_priv)
>                       } else {
>                               cmd = JS_COMMAND_HARD_STOP;
>                       }
> -
>                       job_write(pfdev, JS_COMMAND(i), cmd);
>               }
>       }
> @@ -956,3 +931,9 @@ int panfrost_job_is_idle(struct panfrost_device *pfdev)
>  
>       return true;
>  }
> +
> +struct drm_gpu_scheduler *
> +panfrost_job_get_sched(struct panfrost_device *pfdev, unsigned int js)
> +{
> +     return &pfdev->js->queue[js].sched;
> +}
> diff --git a/drivers/gpu/drm/panfrost/panfrost_job.h 
> b/drivers/gpu/drm/panfrost/panfrost_job.h
> index 1cbc3621b663..5c228bb431c0 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_job.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_job.h
> @@ -10,6 +10,7 @@
>  struct panfrost_device;
>  struct panfrost_gem_object;
>  struct panfrost_file_priv;
> +struct panfrost_submitqueue;
>  
>  struct panfrost_job {
>       struct drm_sched_job base;
> @@ -41,11 +42,13 @@ struct panfrost_job {
>  
>  int panfrost_job_init(struct panfrost_device *pfdev);
>  void panfrost_job_fini(struct panfrost_device *pfdev);
> -int panfrost_job_open(struct panfrost_file_priv *panfrost_priv);
> -void panfrost_job_close(struct panfrost_file_priv *panfrost_priv);
> -int panfrost_job_push(struct panfrost_job *job);
> +int panfrost_job_push(struct panfrost_submitqueue *queue,
> +                   struct panfrost_job *job);
>  void panfrost_job_put(struct panfrost_job *job);
>  void panfrost_job_enable_interrupts(struct panfrost_device *pfdev);
>  int panfrost_job_is_idle(struct panfrost_device *pfdev);
> +void panfrost_job_kill_queue(struct panfrost_submitqueue *queue);
> +struct drm_gpu_scheduler *
> +panfrost_job_get_sched(struct panfrost_device *pfdev, unsigned int js);
>  
>  #endif
> diff --git a/drivers/gpu/drm/panfrost/panfrost_submitqueue.c 
> b/drivers/gpu/drm/panfrost/panfrost_submitqueue.c
> new file mode 100644
> index 000000000000..c16fe110a264
> --- /dev/null
> +++ b/drivers/gpu/drm/panfrost/panfrost_submitqueue.c
> @@ -0,0 +1,136 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright 2021 Collabora ltd. */
> +
> +#include <linux/idr.h>
> +
> +#include "panfrost_device.h"
> +#include "panfrost_job.h"
> +#include "panfrost_submitqueue.h"
> +
> +#define PAN_MAX_SUBMITQUEUES 16
> +
> +static enum drm_sched_priority
> +to_sched_prio(enum panfrost_submitqueue_priority priority)
> +{
> +     switch (priority) {
> +     case PANFROST_SUBMITQUEUE_PRIORITY_LOW:
> +             return DRM_SCHED_PRIORITY_MIN;
> +     case PANFROST_SUBMITQUEUE_PRIORITY_MEDIUM:
> +             return DRM_SCHED_PRIORITY_NORMAL;
> +     case PANFROST_SUBMITQUEUE_PRIORITY_HIGH:
> +             return DRM_SCHED_PRIORITY_HIGH;
> +     default:
> +             break;
> +     }
> +
> +     return DRM_SCHED_PRIORITY_UNSET;
> +}
> +
> +static void
> +panfrost_submitqueue_cleanup(struct kref *ref)
> +{
> +     struct panfrost_submitqueue *queue;
> +     unsigned int i;
> +
> +     queue = container_of(ref, struct panfrost_submitqueue, refcount);
> +
> +     for (i = 0; i < NUM_JOB_SLOTS; i++)
> +             drm_sched_entity_destroy(&queue->sched_entity[i]);
> +
> +     /* Kill in-flight jobs */
> +     panfrost_job_kill_queue(queue);
> +
> +     kfree(queue);
> +}
> +
> +void panfrost_submitqueue_put(struct panfrost_submitqueue *queue)
> +{
> +     if (!IS_ERR_OR_NULL(queue))
> +             kref_put(&queue->refcount, panfrost_submitqueue_cleanup);
> +}
> +
> +struct panfrost_submitqueue *
> +panfrost_submitqueue_create(struct panfrost_file_priv *ctx,
> +                         enum panfrost_submitqueue_priority priority,
> +                         u32 flags)
> +{
> +     struct panfrost_submitqueue *queue;
> +     enum drm_sched_priority sched_prio;
> +     int ret, i;
> +
> +     if (flags || priority >= PANFROST_SUBMITQUEUE_PRIORITY_COUNT)
> +             return ERR_PTR(-EINVAL);
> +
> +     queue = kzalloc(sizeof(*queue), GFP_KERNEL);
> +     if (!queue)
> +             return ERR_PTR(-ENOMEM);
> +
> +     queue->pfdev = ctx->pfdev;
> +     sched_prio = to_sched_prio(priority);
> +     for (i = 0; i < NUM_JOB_SLOTS; i++) {
> +             struct drm_gpu_scheduler *sched;
> +
> +             sched = panfrost_job_get_sched(ctx->pfdev, i);
> +             ret = drm_sched_entity_init(&queue->sched_entity[i],
> +                                         sched_prio, &sched, 1, NULL);
> +             if (ret)
> +                     break;
> +     }
> +
> +     if (ret) {
> +             for (i--; i >= 0; i--)
> +                     drm_sched_entity_destroy(&queue->sched_entity[i]);
> +
> +             return ERR_PTR(ret);
> +     }
> +
> +     kref_init(&queue->refcount);
> +
> +     idr_preload(GFP_KERNEL);
> +     idr_lock(&ctx->queues);
> +     ret = idr_alloc(&ctx->queues, queue, 0, PAN_MAX_SUBMITQUEUES,
> +                     GFP_NOWAIT);
> +     if (ret >= 0)
> +             queue->id = ret;
> +     idr_unlock(&ctx->queues);
> +     idr_preload_end();
> +
> +     if (ret < 0) {
> +             panfrost_submitqueue_put(queue);
> +             return ERR_PTR(ret);
> +     }
> +
> +     return queue;
> +}
> +
> +int panfrost_submitqueue_destroy(struct panfrost_file_priv *ctx, u32 id)
> +{
> +     struct panfrost_submitqueue *queue;
> +
> +     idr_lock(&ctx->queues);
> +     queue = idr_remove(&ctx->queues, id);
> +     idr_unlock(&ctx->queues);
> +
> +     if (!queue)
> +             return -ENOENT;
> +
> +     panfrost_submitqueue_put(queue);
> +     return 0;
> +}
> +
> +struct panfrost_submitqueue *
> +panfrost_submitqueue_get(struct panfrost_file_priv *ctx, u32 id)
> +{
> +     struct panfrost_submitqueue *queue;
> +
> +     idr_lock(&ctx->queues);
> +     queue = idr_find(&ctx->queues, id);
> +     if (queue)
> +             kref_get(&queue->refcount);
> +     idr_unlock(&ctx->queues);
> +
> +     if (!queue)
> +             return ERR_PTR(-ENOENT);
> +
> +     return queue;
> +}
> diff --git a/drivers/gpu/drm/panfrost/panfrost_submitqueue.h 
> b/drivers/gpu/drm/panfrost/panfrost_submitqueue.h
> new file mode 100644
> index 000000000000..cde736d97cf6
> --- /dev/null
> +++ b/drivers/gpu/drm/panfrost/panfrost_submitqueue.h
> @@ -0,0 +1,27 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright 2032 Collabora ltd. */
> +
> +#ifndef __PANFROST_SUBMITQUEUE_H__
> +#define __PANFROST_SUBMITQUEUE_H__
> +
> +#include <drm/panfrost_drm.h>
> +
> +struct panfrost_submitqueue {
> +     struct kref refcount;
> +     struct panfrost_device *pfdev;
> +     u32 id;
> +     struct drm_sched_entity sched_entity[NUM_JOB_SLOTS];
> +};
> +
> +struct panfrost_file_priv;
> +
> +struct panfrost_submitqueue *
> +panfrost_submitqueue_create(struct panfrost_file_priv *ctx,
> +                         enum panfrost_submitqueue_priority priority,
> +                         u32 flags);
> +int panfrost_submitqueue_destroy(struct panfrost_file_priv *ctx, u32 id);
> +struct panfrost_submitqueue *
> +panfrost_submitqueue_get(struct panfrost_file_priv *ctx, u32 id);
> +void panfrost_submitqueue_put(struct panfrost_submitqueue *queue);
> +
> +#endif
> diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h
> index 45d6c600475c..7ee02fd1ac75 100644
> --- a/include/uapi/drm/panfrost_drm.h
> +++ b/include/uapi/drm/panfrost_drm.h
> @@ -21,6 +21,8 @@ extern "C" {
>  #define DRM_PANFROST_PERFCNT_ENABLE          0x06
>  #define DRM_PANFROST_PERFCNT_DUMP            0x07
>  #define DRM_PANFROST_MADVISE                 0x08
> +#define DRM_PANFROST_CREATE_SUBMITQUEUE              0x09
> +#define DRM_PANFROST_DESTROY_SUBMITQUEUE     0x0a
>  
>  #define DRM_IOCTL_PANFROST_SUBMIT            DRM_IOW(DRM_COMMAND_BASE + 
> DRM_PANFROST_SUBMIT, struct drm_panfrost_submit)
>  #define DRM_IOCTL_PANFROST_WAIT_BO           DRM_IOW(DRM_COMMAND_BASE + 
> DRM_PANFROST_WAIT_BO, struct drm_panfrost_wait_bo)
> @@ -29,6 +31,8 @@ extern "C" {
>  #define DRM_IOCTL_PANFROST_GET_PARAM         DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_PANFROST_GET_PARAM, struct drm_panfrost_get_param)
>  #define DRM_IOCTL_PANFROST_GET_BO_OFFSET     DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_PANFROST_GET_BO_OFFSET, struct drm_panfrost_get_bo_offset)
>  #define DRM_IOCTL_PANFROST_MADVISE           DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_PANFROST_MADVISE, struct drm_panfrost_madvise)
> +#define DRM_IOCTL_PANFROST_CREATE_SUBMITQUEUE        
> DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_CREATE_SUBMITQUEUE, struct 
> drm_panfrost_create_submitqueue)
> +#define DRM_IOCTL_PANFROST_DESTROY_SUBMITQUEUE       
> DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_DESTROY_SUBMITQUEUE, __u32)
>  
>  /*
>   * Unstable ioctl(s): only exposed when the unsafe unstable_ioctls module
> @@ -224,6 +228,19 @@ struct drm_panfrost_madvise {
>       __u32 retained;       /* out, whether backing store still exists */
>  };
>  
> +enum panfrost_submitqueue_priority {
> +     PANFROST_SUBMITQUEUE_PRIORITY_LOW = 0,
> +     PANFROST_SUBMITQUEUE_PRIORITY_MEDIUM,
> +     PANFROST_SUBMITQUEUE_PRIORITY_HIGH,
> +     PANFROST_SUBMITQUEUE_PRIORITY_COUNT,
> +};
> +
> +struct drm_panfrost_create_submitqueue {
> +     __u32 flags;    /* in, PANFROST_SUBMITQUEUE_x */
> +     __u32 priority; /* in, enum panfrost_submitqueue_priority */
> +     __u32 id;       /* out, identifier */
> +};
> +
>  #define PANFROST_BO_REF_EXCLUSIVE    0x1
>  
>  #if defined(__cplusplus)
> 

Reply via email to