AMD-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/10] AMDGPU usermode queues
@ 2023-04-24 17:38 Shashank Sharma
  2023-04-24 17:38 ` [PATCH v4 01/10] drm/amdgpu: UAPI for user queue management Shashank Sharma
                   ` (9 more replies)
  0 siblings, 10 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: pierre-eric.pelloux-prayer, contactshashanksharma, arvind.yadav,
	Shashank Sharma

This patch series introduces AMDGPU usermode queues for gfx workloads.
Usermode queues is a method of GPU workload submission into the graphics
hardware without any interaction with kernel/DRM schedulers. In this
method, a userspace graphics application can create its own workqueue
and submit it directly in the GPU HW.

The general idea of how this is supposed to work:
- The application creates the following GPU objetcs:
  - A queue object to hold the workload packets.
  - A read pointer object.
  - A write pointer object.
  - A doorbell page.
  - Shadow bufffer pages.
- The application picks a 32-bit offset in the doorbell page for this
  queue.
- The application uses the usermode_queue_create IOCTL introduced in
  this patch, by passing the GPU addresses of these objects (read ptr,
  write ptr, queue base address and 32-bit doorbell offset from the
  doorbell page)
- The kernel creates the queue and maps it in the HW.
- The application can start submitting the data in the queue as soon as
  the kernel IOCTL returns.
- After filling the workload data in the queue, the app must write the
  number of dwords added in the queue into the doorbell offset, and the
  GPU will start fetching the data.

libDRM changes for this series and a sample DRM test program can be found
in the MESA merge request here:
https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/287

This patch series depends on the doorbell-manager changes, which are being
reviewed here:
https://patchwork.freedesktop.org/series/115802/

Alex Deucher (1):
  drm/amdgpu: UAPI for user queue management

Arvind Yadav (1):
  drm/amdgpu: set FW parameters in v11_struct

Shashank Sharma (8):
  drm/amdgpu: add usermode queue base code
  drm/amdgpu: add new IOCTL for usermode queue
  drm/amdgpu: create GFX-gen11 MQD for userqueue
  drm/amdgpu: create context space for usermode queue
  drm/amdgpu: map usermode queue into MES
  drm/amdgpu: map wptr BO into GART
  drm/amdgpu: generate doorbell index for userqueue
  drm/amdgpu: cleanup leftover queues

 drivers/gpu/drm/amd/amdgpu/Makefile           |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu.h           |  10 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c       |   6 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 333 ++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 195 ++++++++++
 .../gpu/drm/amd/include/amdgpu_userqueue.h    |  66 ++++
 include/uapi/drm/amdgpu_drm.h                 |  95 +++++
 8 files changed, 708 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
 create mode 100644 drivers/gpu/drm/amd/include/amdgpu_userqueue.h

-- 
2.40.0


^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH v4 01/10] drm/amdgpu: UAPI for user queue management
  2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
@ 2023-04-24 17:38 ` Shashank Sharma
  2023-05-19 21:03   ` Alex Deucher
  2023-04-24 17:38 ` [PATCH v4 02/10] drm/amdgpu: add usermode queue base code Shashank Sharma
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: pierre-eric.pelloux-prayer, Shashank Sharma, arvind.yadav,
	Alex Deucher, contactshashanksharma, Christian Koenig

From: Alex Deucher <alexander.deucher@amd.com>

This patch intorduces new UAPI/IOCTL for usermode graphics
queue. The userspace app will fill this structure and request
the graphics driver to add a graphics work queue for it. The
output of this UAPI is a queue id.

This UAPI maps the queue into GPU, so the graphics app can start
submitting work to the queue as soon as the call returns.

V2: Addressed review comments from Alex and Christian
    - Make the doorbell offset's comment clearer
    - Change the output parameter name to queue_id

V3: Integration with doorbell manager

V4:
    - Updated the UAPI doc (Pierre-Eric)
    - Created a Union for engine specific MQDs (Alex)
    - Added Christian's R-B

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
---
 include/uapi/drm/amdgpu_drm.h | 95 +++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 4038abe8505a..083a1df8e8ef 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -54,6 +54,7 @@ extern "C" {
 #define DRM_AMDGPU_VM			0x13
 #define DRM_AMDGPU_FENCE_TO_HANDLE	0x14
 #define DRM_AMDGPU_SCHED		0x15
+#define DRM_AMDGPU_USERQ		0x16
 
 #define DRM_IOCTL_AMDGPU_GEM_CREATE	DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
 #define DRM_IOCTL_AMDGPU_GEM_MMAP	DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
@@ -71,6 +72,7 @@ extern "C" {
 #define DRM_IOCTL_AMDGPU_VM		DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_VM, union drm_amdgpu_vm)
 #define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle)
 #define DRM_IOCTL_AMDGPU_SCHED		DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_SCHED, union drm_amdgpu_sched)
+#define DRM_IOCTL_AMDGPU_USERQ		DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_USERQ, union drm_amdgpu_userq)
 
 /**
  * DOC: memory domains
@@ -302,6 +304,99 @@ union drm_amdgpu_ctx {
 	union drm_amdgpu_ctx_out out;
 };
 
+/* user queue IOCTL */
+#define AMDGPU_USERQ_OP_CREATE	1
+#define AMDGPU_USERQ_OP_FREE	2
+
+#define AMDGPU_USERQ_MQD_FLAGS_SECURE	(1 << 0)
+#define AMDGPU_USERQ_MQD_FLAGS_AQL	(1 << 1)
+
+/*
+ * MQD (memory queue descriptor) is a set of parameters which allow
+ * the GPU to uniquely define and identify a usermode queue.
+ */
+struct drm_amdgpu_userq_mqd_gfx {
+	/**
+	 * @flags: flags to indicate special function for queue like secure
+	 * buffer (TMZ). Unused for now.
+	 */
+	__u32   flags;
+	/**
+	 * @doorbell_handle: the handle of doorbell GEM object
+	 * associated to this client.
+	 */
+	__u32   doorbell_handle;
+	/**
+	 * @doorbell_offset: 32-bit offset of the doorbell in the doorbell bo.
+	 * Kernel will generate absolute doorbell offset using doorbell_handle
+	 * and doorbell_offset in the doorbell bo.
+	 */
+	__u32   doorbell_offset;
+	/**
+	 * @queue_va: Virtual address of the GPU memory which holds the queue
+	 * object. The queue holds the workload packets.
+	 */
+	__u64   queue_va;
+	/**
+	 * @queue_size: Size of the queue in bytes, this needs to be 256-byte
+	 * aligned.
+	 */
+	__u64   queue_size;
+	/**
+	 * @rptr_va : Virtual address of the GPU memory which holds the ring RPTR.
+	 * This object must be at least 8 byte in size and aligned to 8-byte offset.
+	 */
+	__u64   rptr_va;
+	/**
+	 * @wptr_va : Virtual address of the GPU memory which holds the ring WPTR.
+	 * This object must be at least 8 byte in size and aligned to 8-byte offset.
+	 *
+	 * Queue, RPTR and WPTR can come from the same object, as long as the size
+	 * and alignment related requirements are met.
+	 */
+	__u64   wptr_va;
+	/**
+	 * @shadow_va: Virtual address of the GPU memory to hold the shadow buffer.
+	 * This must be a from a separate GPU object, and must be at least 4-page
+	 * sized.
+	 */
+	__u64   shadow_va;
+};
+
+ /*
+  * MQD can be different for different GPU IP/engine. This union will
+  * contain structures of MQDs corresponding to different engines.
+  */
+union drm_amdgpu_userq_mqd {
+	struct drm_amdgpu_userq_mqd_gfx gfx;
+};
+
+struct drm_amdgpu_userq_in {
+	/** AMDGPU_USERQ_OP_* */
+	__u32	op;
+	/** Flags */
+	__u32	flags;
+	/** Queue handle for USERQ_OP_FREE */
+	__u32	queue_id;
+	/** the target GPU engine to execute workload (AMDGPU_HW_IP_*) */
+	__u32   ip_type;
+
+	/** Queue descriptor for USERQ_OP_CREATE */
+	union drm_amdgpu_userq_mqd mqd;
+};
+
+struct drm_amdgpu_userq_out {
+	/** Queue handle */
+	__u32	queue_id;
+	/** Flags */
+	__u32	flags;
+};
+
+union drm_amdgpu_userq {
+	struct drm_amdgpu_userq_in in;
+	struct drm_amdgpu_userq_out out;
+};
+
 /* vm ioctl */
 #define AMDGPU_VM_OP_RESERVE_VMID	1
 #define AMDGPU_VM_OP_UNRESERVE_VMID	2
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v4 02/10] drm/amdgpu: add usermode queue base code
  2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
  2023-04-24 17:38 ` [PATCH v4 01/10] drm/amdgpu: UAPI for user queue management Shashank Sharma
@ 2023-04-24 17:38 ` Shashank Sharma
  2023-04-25 12:03   ` Christian König
  2023-04-24 17:38 ` [PATCH v4 03/10] drm/amdgpu: add new IOCTL for usermode queue Shashank Sharma
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	Christian Koenig, arvind.yadav

From: Shashank Sharma <contactshashanksharma@gmail.com>

This patch adds skeleton code for amdgpu usermode queue. It contains:
- A new files with init functions of usermode queues.
- A queue context manager in driver private data.

V1: Worked on design review comments from RFC patch series:
(https://patchwork.freedesktop.org/series/112214/)
- Alex: Keep a list of queues, instead of single queue per process.
- Christian: Use the queue manager instead of global ptrs,
           Don't keep the queue structure in amdgpu_ctx

V2:
 - Reformatted code, split the big patch into two

V3:
- Integration with doorbell manager

V4:
- Align the structure member names to the largest member's column
  (Luben)
- Added SPDX license (Luben)

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Signed-off-by: Shashank Sharma <contactshashanksharma@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/Makefile           |  2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu.h           | 10 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c       |  6 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 40 +++++++++++++++
 .../gpu/drm/amd/include/amdgpu_userqueue.h    | 50 +++++++++++++++++++
 6 files changed, 108 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
 create mode 100644 drivers/gpu/drm/amd/include/amdgpu_userqueue.h

diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index 798d0e9a60b7..764801cc8203 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -210,6 +210,8 @@ amdgpu-y += \
 # add amdkfd interfaces
 amdgpu-y += amdgpu_amdkfd.o
 
+# add usermode queue
+amdgpu-y += amdgpu_userqueue.o
 
 ifneq ($(CONFIG_HSA_AMD),)
 AMDKFD_PATH := ../amdkfd
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 6b74df446694..c5f9af0e74ee 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -438,6 +438,14 @@ struct amdgpu_sa_manager {
 	uint32_t		align;
 };
 
+/* Gfx usermode queues */
+struct amdgpu_userq_mgr {
+	struct idr userq_idr;
+	struct mutex userq_mutex;
+	struct amdgpu_device *adev;
+	const struct amdgpu_userq_funcs *userq_funcs[AMDGPU_HW_IP_NUM];
+};
+
 /* sub-allocation buffer */
 struct amdgpu_sa_bo {
 	struct list_head		olist;
@@ -470,7 +478,6 @@ struct amdgpu_flip_work {
 	bool				async;
 };
 
-
 /*
  * file private structure
  */
@@ -482,6 +489,7 @@ struct amdgpu_fpriv {
 	struct mutex		bo_list_lock;
 	struct idr		bo_list_handles;
 	struct amdgpu_ctx_mgr	ctx_mgr;
+	struct amdgpu_userq_mgr	userq_mgr;
 };
 
 int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index b4f2d61ea0d5..2d6bcfd727c8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -52,6 +52,7 @@
 #include "amdgpu_ras.h"
 #include "amdgpu_xgmi.h"
 #include "amdgpu_reset.h"
+#include "amdgpu_userqueue.h"
 
 /*
  * KMS wrapper.
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 7aa7e52ca784..e1b6e658d51d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -43,6 +43,7 @@
 #include "amdgpu_gem.h"
 #include "amdgpu_display.h"
 #include "amdgpu_ras.h"
+#include "amdgpu_userqueue.h"
 
 void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)
 {
@@ -1187,6 +1188,10 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
 
 	amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev);
 
+	r = amdgpu_userq_mgr_init(&fpriv->userq_mgr, adev);
+	if (r)
+		DRM_WARN("Can't setup usermode queues, use legacy workload submission only\n");
+
 	file_priv->driver_priv = fpriv;
 	goto out_suspend;
 
@@ -1254,6 +1259,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
 
 	amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr);
 	amdgpu_vm_fini(adev, &fpriv->vm);
+	amdgpu_userq_mgr_fini(&fpriv->userq_mgr);
 
 	if (pasid)
 		amdgpu_pasid_free_delayed(pd->tbo.base.resv, pasid);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
new file mode 100644
index 000000000000..effc0c7c02cf
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2023 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 "amdgpu.h"
+
+int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev)
+{
+	mutex_init(&userq_mgr->userq_mutex);
+	idr_init_base(&userq_mgr->userq_idr, 1);
+	userq_mgr->adev = adev;
+
+	return 0;
+}
+
+void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
+{
+	idr_destroy(&userq_mgr->userq_idr);
+	mutex_destroy(&userq_mgr->userq_mutex);
+}
diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
new file mode 100644
index 000000000000..6fe5d8d73f37
--- /dev/null
+++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright 2023 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.
+ *
+ */
+
+#ifndef AMDGPU_USERQUEUE_H_
+#define AMDGPU_USERQUEUE_H_
+
+#include "amdgpu.h"
+#define AMDGPU_MAX_USERQ 512
+
+struct amdgpu_usermode_queue {
+	int			queue_id;
+	int			queue_type;
+	uint64_t		doorbell_handle;
+	uint64_t		flags;
+	struct amdgpu_mqd_prop	userq_prop;
+	struct amdgpu_userq_mgr *userq_mgr;
+	struct amdgpu_vm	*vm;
+};
+
+struct amdgpu_userq_funcs {
+	int  (*mqd_create)(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *uq);
+	void (*mqd_destroy)(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *uq);
+};
+
+int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev);
+
+void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr);
+
+#endif
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v4 03/10] drm/amdgpu: add new IOCTL for usermode queue
  2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
  2023-04-24 17:38 ` [PATCH v4 01/10] drm/amdgpu: UAPI for user queue management Shashank Sharma
  2023-04-24 17:38 ` [PATCH v4 02/10] drm/amdgpu: add usermode queue base code Shashank Sharma
@ 2023-04-24 17:38 ` Shashank Sharma
  2023-04-25 12:14   ` Christian König
  2023-04-24 17:38 ` [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue Shashank Sharma
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: pierre-eric.pelloux-prayer, Shashank Sharma, arvind.yadav,
	Alex Deucher, contactshashanksharma, Christian Koenig

This patch adds:
- A new IOCTL function to create and destroy
- A new structure to keep all the user queue data in one place.
- A function to generate unique index for the queue.

V1: Worked on review comments from RFC patch series:
  - Alex: Keep a list of queues, instead of single queue per process.
  - Christian: Use the queue manager instead of global ptrs,
           Don't keep the queue structure in amdgpu_ctx

V2: Worked on review comments:
 - Christian:
   - Formatting of text
   - There is no need for queuing of userqueues, with idr in place
 - Alex:
   - Remove use_doorbell, its unnecessary
   - Reuse amdgpu_mqd_props for saving mqd fields

 - Code formatting and re-arrangement

V3:
 - Integration with doorbell manager

V4:
 - Accommodate MQD union related changes in UAPI (Alex)
 - Do not set the queue size twice (Bas)

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 126 ++++++++++++++++++
 .../gpu/drm/amd/include/amdgpu_userqueue.h    |   2 +
 3 files changed, 129 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 2d6bcfd727c8..229976a2d0e7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2749,6 +2749,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
 	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(AMDGPU_USERQ, amdgpu_userq_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
 };
 
 static const struct drm_driver amdgpu_kms_driver = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
index effc0c7c02cf..333f31efbe7b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
@@ -23,6 +23,132 @@
  */
 
 #include "amdgpu.h"
+#include "amdgpu_vm.h"
+#include "amdgpu_userqueue.h"
+
+static inline int
+amdgpu_userqueue_index(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
+{
+	return idr_alloc(&uq_mgr->userq_idr, queue, 1, AMDGPU_MAX_USERQ, GFP_KERNEL);
+}
+
+static inline void
+amdgpu_userqueue_free_index(struct amdgpu_userq_mgr *uq_mgr, int queue_id)
+{
+	idr_remove(&uq_mgr->userq_idr, queue_id);
+}
+
+static struct amdgpu_usermode_queue *
+amdgpu_userqueue_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
+{
+	return idr_find(&uq_mgr->userq_idr, qid);
+}
+
+static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_userq *args)
+{
+	struct amdgpu_usermode_queue *queue;
+	struct amdgpu_fpriv *fpriv = filp->driver_priv;
+	struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
+	struct drm_amdgpu_userq_mqd_gfx *mqd_in = &args->in.mqd.gfx;
+	int r;
+
+	/* Do we support usermode queues on this GFX IP ? */
+	if (!uq_mgr->userq_funcs[AMDGPU_HW_IP_GFX]) {
+		DRM_ERROR("Usermode queue is not supported for this GFX IP\n");
+		return -EINVAL;
+	}
+
+	queue = kzalloc(sizeof(struct amdgpu_usermode_queue), GFP_KERNEL);
+	if (!queue) {
+		DRM_ERROR("Failed to allocate memory for queue\n");
+		return -ENOMEM;
+	}
+
+	mutex_lock(&uq_mgr->userq_mutex);
+	queue->userq_prop.wptr_gpu_addr = mqd_in->wptr_va;
+	queue->userq_prop.rptr_gpu_addr = mqd_in->rptr_va;
+	queue->userq_prop.queue_size = mqd_in->queue_size;
+	queue->userq_prop.hqd_base_gpu_addr = mqd_in->queue_va;
+
+	queue->doorbell_handle = mqd_in->doorbell_handle;
+	queue->queue_type = AMDGPU_HW_IP_GFX;
+	queue->flags = mqd_in->flags;
+	queue->vm = &fpriv->vm;
+	queue->queue_id = amdgpu_userqueue_index(uq_mgr, queue);
+	if (queue->queue_id < 0) {
+		DRM_ERROR("Failed to allocate a queue id\n");
+		r = queue->queue_id;
+		goto free_queue;
+	}
+
+	args->out.queue_id = queue->queue_id;
+	args->out.flags = 0;
+	mutex_unlock(&uq_mgr->userq_mutex);
+	return 0;
+
+free_queue:
+	mutex_unlock(&uq_mgr->userq_mutex);
+	kfree(queue);
+	return r;
+}
+
+static int amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq *args)
+{
+	u32 ip_type = args->in.ip_type;
+
+	switch (ip_type) {
+	case AMDGPU_HW_IP_GFX:
+		return amdgpu_userqueue_create_gfx(filp, args);
+	default:
+		DRM_ERROR("Usermode queue is not supported for this IP (%u)\n", ip_type);
+	}
+
+	return -EINVAL;
+}
+
+static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
+{
+	struct amdgpu_fpriv *fpriv = filp->driver_priv;
+	struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
+	struct amdgpu_usermode_queue *queue;
+
+	queue = amdgpu_userqueue_find(uq_mgr, queue_id);
+	if (!queue) {
+		DRM_DEBUG_DRIVER("Invalid queue id to destroy\n");
+		return;
+	}
+
+	mutex_lock(&uq_mgr->userq_mutex);
+	amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
+	mutex_unlock(&uq_mgr->userq_mutex);
+	kfree(queue);
+}
+
+int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
+		       struct drm_file *filp)
+{
+	union drm_amdgpu_userq *args = data;
+	int r = 0;
+
+	switch (args->in.op) {
+	case AMDGPU_USERQ_OP_CREATE:
+		r = amdgpu_userqueue_create(filp, args);
+		if (r)
+			DRM_ERROR("Failed to create usermode queue\n");
+		break;
+
+	case AMDGPU_USERQ_OP_FREE:
+		amdgpu_userqueue_destroy(filp, args->in.queue_id);
+		break;
+
+	default:
+		DRM_ERROR("Invalid user queue op specified: %d\n", args->in.op);
+		return -EINVAL;
+	}
+
+	return r;
+}
+
 
 int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev)
 {
diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
index 6fe5d8d73f37..8d8f6b3bcda5 100644
--- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
+++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
@@ -43,6 +43,8 @@ struct amdgpu_userq_funcs {
 	void (*mqd_destroy)(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *uq);
 };
 
+int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
+
 int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev);
 
 void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr);
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue
  2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
                   ` (2 preceding siblings ...)
  2023-04-24 17:38 ` [PATCH v4 03/10] drm/amdgpu: add new IOCTL for usermode queue Shashank Sharma
@ 2023-04-24 17:38 ` Shashank Sharma
  2023-04-25 12:27   ` Christian König
  2023-05-19 21:19   ` Alex Deucher
  2023-04-24 17:38 ` [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue Shashank Sharma
                   ` (5 subsequent siblings)
  9 siblings, 2 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: pierre-eric.pelloux-prayer, Shashank Sharma, arvind.yadav,
	Alex Deucher, contactshashanksharma, Christian Koenig

A Memory queue descriptor (MQD) of a userqueue defines it in
the hw's context. As MQD format can vary between different
graphics IPs, we need gfx GEN specific handlers to create MQDs.

This patch:
- Introduces MQD handler functions for the usermode queues.
- Adds new functions to create and destroy userqueue MQD for
  GFX-GEN-11 IP

V1: Worked on review comments from Alex:
    - Make MQD functions GEN and IP specific

V2: Worked on review comments from Alex:
    - Reuse the existing adev->mqd[ip] for MQD creation
    - Formatting and arrangement of code

V3:
    - Integration with doorbell manager

V4: Review comments addressed:
    - Do not create a new file for userq, reuse gfx_v11_0.c (Alex)
    - Align name of structure members (Luben)
    - Don't break up the Cc tag list and the Sob tag list in commit
      message (Luben)

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 25 ++++++++
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 +++++++++++++++++++
 .../gpu/drm/amd/include/amdgpu_userqueue.h    |  7 +++
 3 files changed, 89 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
index 333f31efbe7b..e95fb35b0cb5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
@@ -81,6 +81,14 @@ static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_u
 		goto free_queue;
 	}
 
+	if (uq_mgr->userq_funcs[queue->queue_type]->mqd_create) {
+		r = uq_mgr->userq_funcs[queue->queue_type]->mqd_create(uq_mgr, queue);
+		if (r) {
+			DRM_ERROR("Failed to create/map userqueue MQD\n");
+			goto free_queue;
+		}
+	}
+
 	args->out.queue_id = queue->queue_id;
 	args->out.flags = 0;
 	mutex_unlock(&uq_mgr->userq_mutex);
@@ -119,6 +127,8 @@ static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
 	}
 
 	mutex_lock(&uq_mgr->userq_mutex);
+	if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
+		uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
 	amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
 	mutex_unlock(&uq_mgr->userq_mutex);
 	kfree(queue);
@@ -149,6 +159,20 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
 	return r;
 }
 
+extern const struct amdgpu_userq_funcs userq_gfx_v11_funcs;
+
+static void
+amdgpu_userqueue_setup_ip_funcs(struct amdgpu_userq_mgr *uq_mgr)
+{
+	int maj;
+	struct amdgpu_device *adev = uq_mgr->adev;
+	uint32_t version = adev->ip_versions[GC_HWIP][0];
+
+	/* We support usermode queue only for GFX IP as of now */
+	maj = IP_VERSION_MAJ(version);
+	if (maj == 11)
+		uq_mgr->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_gfx_v11_funcs;
+}
 
 int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev)
 {
@@ -156,6 +180,7 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi
 	idr_init_base(&userq_mgr->userq_idr, 1);
 	userq_mgr->adev = adev;
 
+	amdgpu_userqueue_setup_ip_funcs(userq_mgr);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index a56c6e106d00..9f7b14966ac8 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -30,6 +30,7 @@
 #include "amdgpu_psp.h"
 #include "amdgpu_smu.h"
 #include "amdgpu_atomfirmware.h"
+#include "amdgpu_userqueue.h"
 #include "imu_v11_0.h"
 #include "soc21.h"
 #include "nvd.h"
@@ -6404,3 +6405,59 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
 	.rev = 0,
 	.funcs = &gfx_v11_0_ip_funcs,
 };
+
+static int
+gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
+{
+	struct amdgpu_device *adev = uq_mgr->adev;
+	struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
+	struct amdgpu_mqd *gfx_v11_mqd = &adev->mqds[queue->queue_type];
+	int size = gfx_v11_mqd->mqd_size;
+	int r;
+
+	r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
+				    AMDGPU_GEM_DOMAIN_GTT,
+				    &mqd->obj,
+				    &mqd->gpu_addr,
+				    &mqd->cpu_ptr);
+	if (r) {
+		DRM_ERROR("Failed to allocate bo for userqueue (%d)", r);
+		return r;
+	}
+
+	memset(mqd->cpu_ptr, 0, size);
+	r = amdgpu_bo_reserve(mqd->obj, false);
+	if (unlikely(r != 0)) {
+		DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
+		goto free_mqd;
+	}
+
+	queue->userq_prop.use_doorbell = true;
+	queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
+	r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, &queue->userq_prop);
+	amdgpu_bo_unreserve(mqd->obj);
+	if (r) {
+		DRM_ERROR("Failed to init MQD for queue\n");
+		goto free_mqd;
+	}
+
+	DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
+	return 0;
+
+free_mqd:
+	amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
+	return r;
+}
+
+static void
+gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
+{
+	struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
+
+	amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
+}
+
+const struct amdgpu_userq_funcs userq_gfx_v11_funcs = {
+	.mqd_create = gfx_v11_userq_mqd_create,
+	.mqd_destroy = gfx_v11_userq_mqd_destroy,
+};
diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
index 8d8f6b3bcda5..e7da27918bd2 100644
--- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
+++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
@@ -28,6 +28,12 @@
 #include "amdgpu.h"
 #define AMDGPU_MAX_USERQ 512
 
+struct amdgpu_userq_ctx_space {
+	uint64_t	 gpu_addr;
+	void		 *cpu_ptr;
+	struct amdgpu_bo *obj;
+};
+
 struct amdgpu_usermode_queue {
 	int			queue_id;
 	int			queue_type;
@@ -36,6 +42,7 @@ struct amdgpu_usermode_queue {
 	struct amdgpu_mqd_prop	userq_prop;
 	struct amdgpu_userq_mgr *userq_mgr;
 	struct amdgpu_vm	*vm;
+	struct amdgpu_userq_ctx_space mqd;
 };
 
 struct amdgpu_userq_funcs {
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue
  2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
                   ` (3 preceding siblings ...)
  2023-04-24 17:38 ` [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue Shashank Sharma
@ 2023-04-24 17:38 ` Shashank Sharma
  2023-04-25 12:30   ` Christian König
  2023-05-19 21:21   ` Alex Deucher
  2023-04-24 17:38 ` [PATCH v4 06/10] drm/amdgpu: set FW parameters in v11_struct Shashank Sharma
                   ` (4 subsequent siblings)
  9 siblings, 2 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: pierre-eric.pelloux-prayer, Shashank Sharma, arvind.yadav,
	Alex Deucher, contactshashanksharma, Christian Koenig

The FW expects us to allocate at least one page as context
space to process gang, process, GDS and FW  related work.
This patch creates a joint object for the same, and calculates
GPU space offsets for each of these spaces.

V1: Addressed review comments on RFC patch:
    Alex: Make this function IP specific

V2: Addressed review comments from Christian
    - Allocate only one object for total FW space, and calculate
      offsets for each of these objects.

V3: Integration with doorbell manager
V4: Review comments:
    - Remove shadow from FW space list from cover letter (Alex)
    - Alignment of macro (Luben)

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 ++++++++++++++++++-
 .../gpu/drm/amd/include/amdgpu_userqueue.h    |  6 ++
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 9f7b14966ac8..f6b33faea86f 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -53,6 +53,11 @@
 #define GFX11_NUM_GFX_RINGS		1
 #define GFX11_MEC_HPD_SIZE	2048
 
+#define AMDGPU_USERQ_PROC_CTX_SZ   PAGE_SIZE
+#define AMDGPU_USERQ_GANG_CTX_SZ   PAGE_SIZE
+#define AMDGPU_USERQ_FW_CTX_SZ     PAGE_SIZE
+#define AMDGPU_USERQ_GDS_CTX_SZ    PAGE_SIZE
+
 #define RLCG_UCODE_LOADING_START_ADDRESS	0x00002000L
 #define RLC_PG_DELAY_3_DEFAULT_GC_11_0_1	0x1388
 
@@ -6406,6 +6411,44 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
 	.funcs = &gfx_v11_0_ip_funcs,
 };
 
+static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
+					  struct amdgpu_usermode_queue *queue)
+{
+	struct amdgpu_device *adev = uq_mgr->adev;
+	struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
+	int r, size;
+
+	/*
+	 * The FW expects at least one page space allocated for
+	 * process ctx, gang ctx, gds ctx, fw ctx each.
+	 */
+	size = AMDGPU_USERQ_PROC_CTX_SZ + AMDGPU_USERQ_FW_CTX_SZ +
+	       AMDGPU_USERQ_GANG_CTX_SZ + AMDGPU_USERQ_GDS_CTX_SZ;
+	r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
+				    AMDGPU_GEM_DOMAIN_GTT,
+				    &ctx->obj,
+				    &ctx->gpu_addr,
+				    &ctx->cpu_ptr);
+	if (r) {
+		DRM_ERROR("Failed to allocate ctx space bo for userqueue, err:%d\n", r);
+		return r;
+	}
+
+	queue->proc_ctx_gpu_addr = ctx->gpu_addr;
+	queue->gang_ctx_gpu_addr = queue->proc_ctx_gpu_addr + AMDGPU_USERQ_PROC_CTX_SZ;
+	queue->fw_ctx_gpu_addr = queue->gang_ctx_gpu_addr + AMDGPU_USERQ_GANG_CTX_SZ;
+	queue->gds_ctx_gpu_addr = queue->fw_ctx_gpu_addr + AMDGPU_USERQ_FW_CTX_SZ;
+	return 0;
+}
+
+static void gfx_v11_userq_destroy_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
+					    struct amdgpu_usermode_queue *queue)
+{
+	struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
+
+	amdgpu_bo_free_kernel(&ctx->obj, &ctx->gpu_addr, &ctx->cpu_ptr);
+}
+
 static int
 gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
 {
@@ -6426,10 +6469,16 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
 	}
 
 	memset(mqd->cpu_ptr, 0, size);
+	r = gfx_v11_userq_create_ctx_space(uq_mgr, queue);
+	if (r) {
+		DRM_ERROR("Failed to create CTX space for userqueue (%d)\n", r);
+		goto free_mqd;
+	}
+
 	r = amdgpu_bo_reserve(mqd->obj, false);
 	if (unlikely(r != 0)) {
 		DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
-		goto free_mqd;
+		goto free_ctx;
 	}
 
 	queue->userq_prop.use_doorbell = true;
@@ -6438,12 +6487,15 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
 	amdgpu_bo_unreserve(mqd->obj);
 	if (r) {
 		DRM_ERROR("Failed to init MQD for queue\n");
-		goto free_mqd;
+		goto free_ctx;
 	}
 
 	DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
 	return 0;
 
+free_ctx:
+	gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
+
 free_mqd:
 	amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
 	return r;
@@ -6454,6 +6506,7 @@ gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
 {
 	struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
 
+	gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
 	amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
 }
 
diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
index e7da27918bd2..11e8ad649f6e 100644
--- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
+++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
@@ -38,11 +38,17 @@ struct amdgpu_usermode_queue {
 	int			queue_id;
 	int			queue_type;
 	uint64_t		doorbell_handle;
+	uint64_t		proc_ctx_gpu_addr;
+	uint64_t		gang_ctx_gpu_addr;
+	uint64_t		gds_ctx_gpu_addr;
+	uint64_t		fw_ctx_gpu_addr;
+	uint64_t		shadow_ctx_gpu_addr;
 	uint64_t		flags;
 	struct amdgpu_mqd_prop	userq_prop;
 	struct amdgpu_userq_mgr *userq_mgr;
 	struct amdgpu_vm	*vm;
 	struct amdgpu_userq_ctx_space mqd;
+	struct amdgpu_userq_ctx_space fw_space;
 };
 
 struct amdgpu_userq_funcs {
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v4 06/10] drm/amdgpu: set FW parameters in v11_struct
  2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
                   ` (4 preceding siblings ...)
  2023-04-24 17:38 ` [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue Shashank Sharma
@ 2023-04-24 17:38 ` Shashank Sharma
  2023-04-25 12:32   ` Christian König
  2023-05-19 21:22   ` Alex Deucher
  2023-04-24 17:38 ` [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES Shashank Sharma
                   ` (3 subsequent siblings)
  9 siblings, 2 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: pierre-eric.pelloux-prayer, Shashank Sharma, arvind.yadav,
	Alex Deucher, contactshashanksharma, Christian Koenig

From: Arvind Yadav <arvind.yadav@amd.com>

This patch sets new parameters defined in v11_struct for
usermode queue with the respective allocated gpu context
space addresses.

V4: Split the patch into two parts, keep only the set parameter
    part in this series (Alex).

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Cc: Shashank Sharma <shashank.sharma@amd.com>
Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index f6b33faea86f..86de35292f69 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -6411,6 +6411,21 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
 	.funcs = &gfx_v11_0_ip_funcs,
 };
 
+static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
+					struct amdgpu_usermode_queue *queue)
+{
+	struct v11_gfx_mqd *mqd = queue->mqd.cpu_ptr;
+
+	mqd->shadow_base_lo = queue->shadow_ctx_gpu_addr & 0xfffffffc;
+	mqd->shadow_base_hi = upper_32_bits(queue->shadow_ctx_gpu_addr);
+
+	mqd->gds_bkup_base_lo = queue->gds_ctx_gpu_addr & 0xfffffffc;
+	mqd->gds_bkup_base_hi = upper_32_bits(queue->gds_ctx_gpu_addr);
+
+	mqd->fw_work_area_base_lo = queue->fw_ctx_gpu_addr & 0xfffffffc;
+	mqd->fw_work_area_base_lo = upper_32_bits(queue->fw_ctx_gpu_addr);
+}
+
 static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
 					  struct amdgpu_usermode_queue *queue)
 {
@@ -6484,12 +6499,14 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
 	queue->userq_prop.use_doorbell = true;
 	queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
 	r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, &queue->userq_prop);
-	amdgpu_bo_unreserve(mqd->obj);
 	if (r) {
+		amdgpu_bo_unreserve(mqd->obj);
 		DRM_ERROR("Failed to init MQD for queue\n");
 		goto free_ctx;
 	}
 
+	gfx_v11_userq_set_ctx_space(uq_mgr, queue);
+	amdgpu_bo_unreserve(mqd->obj);
 	DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
 	return 0;
 
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES
  2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
                   ` (5 preceding siblings ...)
  2023-04-24 17:38 ` [PATCH v4 06/10] drm/amdgpu: set FW parameters in v11_struct Shashank Sharma
@ 2023-04-24 17:38 ` Shashank Sharma
  2023-04-25 12:34   ` Christian König
  2023-05-19 21:22   ` Alex Deucher
  2023-04-24 17:38 ` [PATCH v4 08/10] drm/amdgpu: map wptr BO into GART Shashank Sharma
                   ` (2 subsequent siblings)
  9 siblings, 2 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: pierre-eric.pelloux-prayer, Shashank Sharma, arvind.yadav,
	Alex Deucher, contactshashanksharma, Christian Koenig

This patch adds new functions to map/unmap a usermode queue into
the FW, using the MES ring. As soon as this mapping is done, the
queue would  be considered ready to accept the workload.

V1: Addressed review comments from Alex on the RFC patch series
    - Map/Unmap should be IP specific.
V2:
    Addressed review comments from Christian:
    - Fix the wptr_mc_addr calculation (moved into another patch)
    Addressed review comments from Alex:
    - Do not add fptrs for map/unmap

V3: Integration with doorbell manager
V4: Rebase

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 67 ++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 86de35292f69..7a45d68091ec 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -31,6 +31,7 @@
 #include "amdgpu_smu.h"
 #include "amdgpu_atomfirmware.h"
 #include "amdgpu_userqueue.h"
+#include "amdgpu_mes.h"
 #include "imu_v11_0.h"
 #include "soc21.h"
 #include "nvd.h"
@@ -6411,6 +6412,64 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
 	.funcs = &gfx_v11_0_ip_funcs,
 };
 
+static int gfx_v11_userq_map(struct amdgpu_userq_mgr *uq_mgr,
+			     struct amdgpu_usermode_queue *queue)
+{
+	struct amdgpu_device *adev = uq_mgr->adev;
+	struct mes_add_queue_input queue_input;
+	int r;
+
+	memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
+
+	queue_input.process_va_start = 0;
+	queue_input.process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT;
+	queue_input.process_quantum = 100000; /* 10ms */
+	queue_input.gang_quantum = 10000; /* 1ms */
+	queue_input.paging = false;
+
+	queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
+	queue_input.process_context_addr = queue->proc_ctx_gpu_addr;
+	queue_input.inprocess_gang_priority = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
+	queue_input.gang_global_priority_level = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
+
+	queue_input.process_id = queue->vm->pasid;
+	queue_input.queue_type = queue->queue_type;
+	queue_input.mqd_addr = queue->mqd.gpu_addr;
+	queue_input.wptr_addr = queue->userq_prop.wptr_gpu_addr;
+	queue_input.queue_size = queue->userq_prop.queue_size >> 2;
+	queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
+	queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(queue->vm->root.bo);
+
+	amdgpu_mes_lock(&adev->mes);
+	r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
+	amdgpu_mes_unlock(&adev->mes);
+	if (r) {
+		DRM_ERROR("Failed to map queue in HW, err (%d)\n", r);
+		return r;
+	}
+
+	DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", queue->queue_id);
+	return 0;
+}
+
+static void gfx_v11_userq_unmap(struct amdgpu_userq_mgr *uq_mgr,
+				struct amdgpu_usermode_queue *queue)
+{
+	struct amdgpu_device *adev = uq_mgr->adev;
+	struct mes_remove_queue_input queue_input;
+	int r;
+
+	memset(&queue_input, 0x0, sizeof(struct mes_remove_queue_input));
+	queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
+	queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
+
+	amdgpu_mes_lock(&adev->mes);
+	r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
+	amdgpu_mes_unlock(&adev->mes);
+	if (r)
+		DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r);
+}
+
 static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
 					struct amdgpu_usermode_queue *queue)
 {
@@ -6507,6 +6566,13 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
 
 	gfx_v11_userq_set_ctx_space(uq_mgr, queue);
 	amdgpu_bo_unreserve(mqd->obj);
+
+	/* Map the queue in HW using MES ring */
+	r = gfx_v11_userq_map(uq_mgr, queue);
+	if (r) {
+		DRM_ERROR("Failed to map userqueue (%d)\n", r);
+		goto free_ctx;
+	}
 	DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
 	return 0;
 
@@ -6523,6 +6589,7 @@ gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
 {
 	struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
 
+	gfx_v11_userq_unmap(uq_mgr, queue);
 	gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
 	amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
 }
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v4 08/10] drm/amdgpu: map wptr BO into GART
  2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
                   ` (6 preceding siblings ...)
  2023-04-24 17:38 ` [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES Shashank Sharma
@ 2023-04-24 17:38 ` Shashank Sharma
  2023-04-25 12:36   ` Christian König
  2023-04-24 17:38 ` [PATCH v4 09/10] drm/amdgpu: generate doorbell index for userqueue Shashank Sharma
  2023-04-24 17:38 ` [PATCH v4 10/10] drm/amdgpu: cleanup leftover queues Shashank Sharma
  9 siblings, 1 reply; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: pierre-eric.pelloux-prayer, Shashank Sharma, arvind.yadav,
	Alex Deucher, contactshashanksharma, Christian Koenig

To support oversubscription, MES FW expects WPTR BOs to
be mapped into GART, before they are submitted to usermode
queues. This patch adds a function for the same.

V4: fix the wptr value before mapping lookup (Bas, Christian).

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 90 +++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        |  1 +
 .../gpu/drm/amd/include/amdgpu_userqueue.h    |  1 +
 3 files changed, 92 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
index e95fb35b0cb5..385cd51b6c96 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
@@ -44,6 +44,89 @@ amdgpu_userqueue_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
 	return idr_find(&uq_mgr->userq_idr, qid);
 }
 
+static int
+amdgpu_userqueue_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo)
+{
+	int ret;
+
+	ret = amdgpu_bo_reserve(bo, true);
+	if (ret) {
+		DRM_ERROR("Failed to reserve bo. ret %d\n", ret);
+		goto err_reserve_bo_failed;
+	}
+
+	ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT);
+	if (ret) {
+		DRM_ERROR("Failed to pin bo. ret %d\n", ret);
+		goto err_pin_bo_failed;
+	}
+
+	ret = amdgpu_ttm_alloc_gart(&bo->tbo);
+	if (ret) {
+		DRM_ERROR("Failed to bind bo to GART. ret %d\n", ret);
+		goto err_map_bo_gart_failed;
+	}
+
+	amdgpu_bo_unreserve(bo);
+	bo = amdgpu_bo_ref(bo);
+
+	return 0;
+
+err_map_bo_gart_failed:
+	amdgpu_bo_unpin(bo);
+err_pin_bo_failed:
+	amdgpu_bo_unreserve(bo);
+err_reserve_bo_failed:
+
+	return ret;
+}
+
+
+static int
+amdgpu_userqueue_create_wptr_mapping(struct amdgpu_device *adev,
+				     struct drm_file *filp,
+				     struct amdgpu_usermode_queue *queue)
+{
+	struct amdgpu_bo_va_mapping *wptr_mapping;
+	struct amdgpu_vm *wptr_vm;
+	struct amdgpu_bo *wptr_bo = NULL;
+	uint64_t wptr = queue->userq_prop.wptr_gpu_addr;
+	int ret;
+
+	wptr_vm = queue->vm;
+	ret = amdgpu_bo_reserve(wptr_vm->root.bo, false);
+	if (ret)
+		goto err_wptr_map_gart;
+
+	wptr &= AMDGPU_GMC_HOLE_MASK;
+	wptr_mapping = amdgpu_vm_bo_lookup_mapping(wptr_vm, wptr >> PAGE_SHIFT);
+	amdgpu_bo_unreserve(wptr_vm->root.bo);
+	if (!wptr_mapping) {
+		DRM_ERROR("Failed to lookup wptr bo\n");
+		ret = -EINVAL;
+		goto err_wptr_map_gart;
+	}
+
+	wptr_bo = wptr_mapping->bo_va->base.bo;
+	if (wptr_bo->tbo.base.size > PAGE_SIZE) {
+		DRM_ERROR("Requested GART mapping for wptr bo larger than one page\n");
+		ret = -EINVAL;
+		goto err_wptr_map_gart;
+	}
+
+	ret = amdgpu_userqueue_map_gtt_bo_to_gart(adev, wptr_bo);
+	if (ret) {
+		DRM_ERROR("Failed to map wptr bo to GART\n");
+		goto err_wptr_map_gart;
+	}
+
+	queue->wptr_mc_addr = wptr_bo->tbo.resource->start << PAGE_SHIFT;
+	return 0;
+
+err_wptr_map_gart:
+	return ret;
+}
+
 static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_userq *args)
 {
 	struct amdgpu_usermode_queue *queue;
@@ -81,6 +164,13 @@ static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_u
 		goto free_queue;
 	}
 
+	r = amdgpu_userqueue_create_wptr_mapping(uq_mgr->adev, filp, queue);
+	if (r) {
+		DRM_ERROR("Failed to map WPTR (0x%llx) for userqueue\n",
+			   queue->userq_prop.wptr_gpu_addr);
+		goto free_queue;
+	}
+
 	if (uq_mgr->userq_funcs[queue->queue_type]->mqd_create) {
 		r = uq_mgr->userq_funcs[queue->queue_type]->mqd_create(uq_mgr, queue);
 		if (r) {
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 7a45d68091ec..6eeae0206d8a 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -6439,6 +6439,7 @@ static int gfx_v11_userq_map(struct amdgpu_userq_mgr *uq_mgr,
 	queue_input.queue_size = queue->userq_prop.queue_size >> 2;
 	queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
 	queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(queue->vm->root.bo);
+	queue_input.wptr_mc_addr = queue->wptr_mc_addr;
 
 	amdgpu_mes_lock(&adev->mes);
 	r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
index 11e8ad649f6e..0001ecd710a7 100644
--- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
+++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
@@ -38,6 +38,7 @@ struct amdgpu_usermode_queue {
 	int			queue_id;
 	int			queue_type;
 	uint64_t		doorbell_handle;
+	uint64_t		wptr_mc_addr;
 	uint64_t		proc_ctx_gpu_addr;
 	uint64_t		gang_ctx_gpu_addr;
 	uint64_t		gds_ctx_gpu_addr;
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v4 09/10] drm/amdgpu: generate doorbell index for userqueue
  2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
                   ` (7 preceding siblings ...)
  2023-04-24 17:38 ` [PATCH v4 08/10] drm/amdgpu: map wptr BO into GART Shashank Sharma
@ 2023-04-24 17:38 ` Shashank Sharma
  2023-04-25 12:38   ` Christian König
  2023-04-24 17:38 ` [PATCH v4 10/10] drm/amdgpu: cleanup leftover queues Shashank Sharma
  9 siblings, 1 reply; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: pierre-eric.pelloux-prayer, Shashank Sharma, arvind.yadav,
	Alex Deucher, contactshashanksharma, Christian Koenig

The userspace sends us the doorbell object and the doobell index
to be used for the usermode queue, but the FW expects the absolute
doorbell index on the PCI BAR in the MQD. This patch adds a function
to convert this relative doorbell index to the absolute doorbell index.

This patch is dependent on the doorbell manager series being reviewed
here: https://patchwork.freedesktop.org/series/115802/

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
index 385cd51b6c96..fbc9cb5c24ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
@@ -44,6 +44,30 @@ amdgpu_userqueue_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
 	return idr_find(&uq_mgr->userq_idr, qid);
 }
 
+static uint64_t
+amdgpu_userqueue_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr,
+				    struct amdgpu_usermode_queue *queue,
+				    struct drm_file *filp,
+				    uint32_t doorbell_index)
+{
+	struct drm_gem_object *gobj;
+	struct amdgpu_bo *db_bo;
+	uint64_t index;
+
+	gobj = drm_gem_object_lookup(filp, queue->doorbell_handle);
+	if (gobj == NULL) {
+		DRM_ERROR("Can't find GEM object for doorbell\n");
+		return -EINVAL;
+	}
+
+	db_bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
+	drm_gem_object_put(gobj);
+
+	index = amdgpu_doorbell_index_on_bar(uq_mgr->adev, db_bo, doorbell_index);
+	DRM_DEBUG_DRIVER("[Usermode queues] doorbell index=%lld\n", index);
+	return index;
+}
+
 static int
 amdgpu_userqueue_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo)
 {
@@ -133,6 +157,7 @@ static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_u
 	struct amdgpu_fpriv *fpriv = filp->driver_priv;
 	struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
 	struct drm_amdgpu_userq_mqd_gfx *mqd_in = &args->in.mqd.gfx;
+	uint64_t index;
 	int r;
 
 	/* Do we support usermode queues on this GFX IP ? */
@@ -154,6 +179,14 @@ static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_u
 	queue->userq_prop.hqd_base_gpu_addr = mqd_in->queue_va;
 
 	queue->doorbell_handle = mqd_in->doorbell_handle;
+	index = amdgpu_userqueue_get_doorbell_index(uq_mgr, queue, filp, mqd_in->doorbell_offset);
+	if (index == (uint64_t)-EINVAL) {
+		DRM_ERROR("Invalid doorbell object\n");
+		r = -EINVAL;
+		goto free_queue;
+	}
+
+	queue->userq_prop.doorbell_index = index;
 	queue->queue_type = AMDGPU_HW_IP_GFX;
 	queue->flags = mqd_in->flags;
 	queue->vm = &fpriv->vm;
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v4 10/10] drm/amdgpu: cleanup leftover queues
  2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
                   ` (8 preceding siblings ...)
  2023-04-24 17:38 ` [PATCH v4 09/10] drm/amdgpu: generate doorbell index for userqueue Shashank Sharma
@ 2023-04-24 17:38 ` Shashank Sharma
  2023-04-25 12:40   ` Christian König
  9 siblings, 1 reply; 45+ messages in thread
From: Shashank Sharma @ 2023-04-24 17:38 UTC (permalink / raw)
  To: amd-gfx
  Cc: pierre-eric.pelloux-prayer, Shashank Sharma, arvind.yadav,
	Bas Nieuwenhuizen, Alex Deucher, contactshashanksharma,
	Christian Koenig

This patch adds code to cleanup any leftover userqueues which
a user might have missed to destroy due to a crash or any other
programming error.

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Suggested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 31 +++++++++++++++----
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
index fbc9cb5c24ad..27201a0b1441 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
@@ -237,6 +237,18 @@ static int amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq
 	return -EINVAL;
 }
 
+static void
+amdgpu_userqueue_cleanup(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
+{
+	mutex_lock(&uq_mgr->userq_mutex);
+	if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
+		uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
+
+	amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
+	mutex_unlock(&uq_mgr->userq_mutex);
+	kfree(queue);
+}
+
 static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
 {
 	struct amdgpu_fpriv *fpriv = filp->driver_priv;
@@ -249,12 +261,7 @@ static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
 		return;
 	}
 
-	mutex_lock(&uq_mgr->userq_mutex);
-	if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
-		uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
-	amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
-	mutex_unlock(&uq_mgr->userq_mutex);
-	kfree(queue);
+	amdgpu_userqueue_cleanup(uq_mgr, queue);
 }
 
 int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
@@ -307,8 +314,20 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi
 	return 0;
 }
 
+static void amdgpu_userqueue_cleanup_residue(int queue_id, void *ptr, void *data)
+{
+	struct amdgpu_userq_mgr *uq_mgr = data;
+	struct amdgpu_usermode_queue *queue = ptr;
+
+	amdgpu_userqueue_cleanup(uq_mgr, queue);
+}
+
 void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
 {
+	idr_for_each(&userq_mgr->userq_idr,
+		     amdgpu_userqueue_cleanup_residue,
+		     userq_mgr);
+
 	idr_destroy(&userq_mgr->userq_idr);
 	mutex_destroy(&userq_mgr->userq_mutex);
 }
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 02/10] drm/amdgpu: add usermode queue base code
  2023-04-24 17:38 ` [PATCH v4 02/10] drm/amdgpu: add usermode queue base code Shashank Sharma
@ 2023-04-25 12:03   ` Christian König
  2023-04-25 12:19     ` Shashank Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 12:03 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav



Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch adds skeleton code for amdgpu usermode queue. It contains:
> - A new files with init functions of usermode queues.
> - A queue context manager in driver private data.
>
> V1: Worked on design review comments from RFC patch series:
> (https://patchwork.freedesktop.org/series/112214/)
> - Alex: Keep a list of queues, instead of single queue per process.
> - Christian: Use the queue manager instead of global ptrs,
>             Don't keep the queue structure in amdgpu_ctx
>
> V2:
>   - Reformatted code, split the big patch into two
>
> V3:
> - Integration with doorbell manager
>
> V4:
> - Align the structure member names to the largest member's column
>    (Luben)
> - Added SPDX license (Luben)
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <contactshashanksharma@gmail.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/Makefile           |  2 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h           | 10 +++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  1 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c       |  6 +++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 40 +++++++++++++++
>   .../gpu/drm/amd/include/amdgpu_userqueue.h    | 50 +++++++++++++++++++
>   6 files changed, 108 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>   create mode 100644 drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
> index 798d0e9a60b7..764801cc8203 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> @@ -210,6 +210,8 @@ amdgpu-y += \
>   # add amdkfd interfaces
>   amdgpu-y += amdgpu_amdkfd.o
>   
> +# add usermode queue
> +amdgpu-y += amdgpu_userqueue.o
>   
>   ifneq ($(CONFIG_HSA_AMD),)
>   AMDKFD_PATH := ../amdkfd
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 6b74df446694..c5f9af0e74ee 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -438,6 +438,14 @@ struct amdgpu_sa_manager {
>   	uint32_t		align;
>   };
>   
> +/* Gfx usermode queues */
> +struct amdgpu_userq_mgr {
> +	struct idr userq_idr;
> +	struct mutex userq_mutex;
> +	struct amdgpu_device *adev;
> +	const struct amdgpu_userq_funcs *userq_funcs[AMDGPU_HW_IP_NUM];
> +};
> +

Please but that into amdgpu_userqueue.h as well. We want to decommission 
amdgpu.h over time.

>   /* sub-allocation buffer */
>   struct amdgpu_sa_bo {
>   	struct list_head		olist;
> @@ -470,7 +478,6 @@ struct amdgpu_flip_work {
>   	bool				async;
>   };
>   
> -
>   /*
>    * file private structure
>    */
> @@ -482,6 +489,7 @@ struct amdgpu_fpriv {
>   	struct mutex		bo_list_lock;
>   	struct idr		bo_list_handles;
>   	struct amdgpu_ctx_mgr	ctx_mgr;
> +	struct amdgpu_userq_mgr	userq_mgr;
>   };
>   
>   int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index b4f2d61ea0d5..2d6bcfd727c8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -52,6 +52,7 @@
>   #include "amdgpu_ras.h"
>   #include "amdgpu_xgmi.h"
>   #include "amdgpu_reset.h"
> +#include "amdgpu_userqueue.h"
>   
>   /*
>    * KMS wrapper.
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 7aa7e52ca784..e1b6e658d51d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -43,6 +43,7 @@
>   #include "amdgpu_gem.h"
>   #include "amdgpu_display.h"
>   #include "amdgpu_ras.h"
> +#include "amdgpu_userqueue.h"
>   
>   void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)
>   {
> @@ -1187,6 +1188,10 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
>   
>   	amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev);
>   
> +	r = amdgpu_userq_mgr_init(&fpriv->userq_mgr, adev);
> +	if (r)
> +		DRM_WARN("Can't setup usermode queues, use legacy workload submission only\n");
> +
>   	file_priv->driver_priv = fpriv;
>   	goto out_suspend;
>   
> @@ -1254,6 +1259,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
>   
>   	amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr);
>   	amdgpu_vm_fini(adev, &fpriv->vm);
> +	amdgpu_userq_mgr_fini(&fpriv->userq_mgr);
>   
>   	if (pasid)
>   		amdgpu_pasid_free_delayed(pd->tbo.base.resv, pasid);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> new file mode 100644
> index 000000000000..effc0c7c02cf
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> @@ -0,0 +1,40 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright 2023 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 "amdgpu.h"
> +
> +int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev)
> +{
> +	mutex_init(&userq_mgr->userq_mutex);
> +	idr_init_base(&userq_mgr->userq_idr, 1);
> +	userq_mgr->adev = adev;
> +
> +	return 0;
> +}
> +
> +void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
> +{
> +	idr_destroy(&userq_mgr->userq_idr);
> +	mutex_destroy(&userq_mgr->userq_mutex);
> +}
> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> new file mode 100644
> index 000000000000..6fe5d8d73f37
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> @@ -0,0 +1,50 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright 2023 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.
> + *
> + */
> +
> +#ifndef AMDGPU_USERQUEUE_H_
> +#define AMDGPU_USERQUEUE_H_
> +
> +#include "amdgpu.h"

Please don't include amdgpu.h here.

Most structures can be forward defined, only amdgpu_mqd_prop is really 
needed and that should be included separately.

Christian.

> +#define AMDGPU_MAX_USERQ 512
> +
> +struct amdgpu_usermode_queue {
> +	int			queue_id;
> +	int			queue_type;
> +	uint64_t		doorbell_handle;
> +	uint64_t		flags;
> +	struct amdgpu_mqd_prop	userq_prop;
> +	struct amdgpu_userq_mgr *userq_mgr;
> +	struct amdgpu_vm	*vm;
> +};
> +
> +struct amdgpu_userq_funcs {
> +	int  (*mqd_create)(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *uq);
> +	void (*mqd_destroy)(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *uq);
> +};
> +
> +int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev);
> +
> +void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr);
> +
> +#endif


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 03/10] drm/amdgpu: add new IOCTL for usermode queue
  2023-04-24 17:38 ` [PATCH v4 03/10] drm/amdgpu: add new IOCTL for usermode queue Shashank Sharma
@ 2023-04-25 12:14   ` Christian König
  2023-04-25 12:21     ` Shashank Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 12:14 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav

Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> This patch adds:
> - A new IOCTL function to create and destroy
> - A new structure to keep all the user queue data in one place.
> - A function to generate unique index for the queue.
>
> V1: Worked on review comments from RFC patch series:
>    - Alex: Keep a list of queues, instead of single queue per process.
>    - Christian: Use the queue manager instead of global ptrs,
>             Don't keep the queue structure in amdgpu_ctx
>
> V2: Worked on review comments:
>   - Christian:
>     - Formatting of text
>     - There is no need for queuing of userqueues, with idr in place
>   - Alex:
>     - Remove use_doorbell, its unnecessary
>     - Reuse amdgpu_mqd_props for saving mqd fields
>
>   - Code formatting and re-arrangement
>
> V3:
>   - Integration with doorbell manager
>
> V4:
>   - Accommodate MQD union related changes in UAPI (Alex)
>   - Do not set the queue size twice (Bas)
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |   1 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 126 ++++++++++++++++++
>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |   2 +
>   3 files changed, 129 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 2d6bcfd727c8..229976a2d0e7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -2749,6 +2749,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
>   	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(AMDGPU_USERQ, amdgpu_userq_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
>   };
>   
>   static const struct drm_driver amdgpu_kms_driver = {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> index effc0c7c02cf..333f31efbe7b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> @@ -23,6 +23,132 @@
>    */
>   
>   #include "amdgpu.h"
> +#include "amdgpu_vm.h"
> +#include "amdgpu_userqueue.h"
> +
> +static inline int
> +amdgpu_userqueue_index(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)

Maybe call that handle instead of index. And I don't think you actually 
need those wrapper functions, see below.

> +{
> +	return idr_alloc(&uq_mgr->userq_idr, queue, 1, AMDGPU_MAX_USERQ, GFP_KERNEL);
> +}
> +
> +static inline void
> +amdgpu_userqueue_free_index(struct amdgpu_userq_mgr *uq_mgr, int queue_id)
> +{
> +	idr_remove(&uq_mgr->userq_idr, queue_id);
> +}
> +
> +static struct amdgpu_usermode_queue *
> +amdgpu_userqueue_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
> +{
> +	return idr_find(&uq_mgr->userq_idr, qid);
> +}
> +
> +static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_userq *args)
> +{
> +	struct amdgpu_usermode_queue *queue;
> +	struct amdgpu_fpriv *fpriv = filp->driver_priv;
> +	struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
> +	struct drm_amdgpu_userq_mqd_gfx *mqd_in = &args->in.mqd.gfx;
> +	int r;
> +
> +	/* Do we support usermode queues on this GFX IP ? */
> +	if (!uq_mgr->userq_funcs[AMDGPU_HW_IP_GFX]) {
> +		DRM_ERROR("Usermode queue is not supported for this GFX IP\n");
> +		return -EINVAL;
> +	}
> +
> +	queue = kzalloc(sizeof(struct amdgpu_usermode_queue), GFP_KERNEL);
> +	if (!queue) {
> +		DRM_ERROR("Failed to allocate memory for queue\n");
> +		return -ENOMEM;
> +	}
> +
> +	mutex_lock(&uq_mgr->userq_mutex);
> +	queue->userq_prop.wptr_gpu_addr = mqd_in->wptr_va;
> +	queue->userq_prop.rptr_gpu_addr = mqd_in->rptr_va;
> +	queue->userq_prop.queue_size = mqd_in->queue_size;
> +	queue->userq_prop.hqd_base_gpu_addr = mqd_in->queue_va;
> +
> +	queue->doorbell_handle = mqd_in->doorbell_handle;
> +	queue->queue_type = AMDGPU_HW_IP_GFX;
> +	queue->flags = mqd_in->flags;
> +	queue->vm = &fpriv->vm;
> +	queue->queue_id = amdgpu_userqueue_index(uq_mgr, queue);

It is usually good practice to *not* store those handles inside the 
object they refer to, background is that this always creates a circle 
reference (handle->object, object->handle).

Additional to that I would move registering the userspace handle out of 
this function.

> +	if (queue->queue_id < 0) {
> +		DRM_ERROR("Failed to allocate a queue id\n");
> +		r = queue->queue_id;
> +		goto free_queue;
> +	}
> +
> +	args->out.queue_id = queue->queue_id;
> +	args->out.flags = 0;
> +	mutex_unlock(&uq_mgr->userq_mutex);
> +	return 0;
> +
> +free_queue:
> +	mutex_unlock(&uq_mgr->userq_mutex);
> +	kfree(queue);
> +	return r;
> +}
> +
> +static int amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq *args)
> +{
> +	u32 ip_type = args->in.ip_type;
> +
> +	switch (ip_type) {
> +	case AMDGPU_HW_IP_GFX:
> +		return amdgpu_userqueue_create_gfx(filp, args);
> +	default:
> +		DRM_ERROR("Usermode queue is not supported for this IP (%u)\n", ip_type);
> +	}

Instead insert the idr_alloc() or more generally handle alloc here.

Christian.

> +
> +	return -EINVAL;
> +}
> +
> +static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
> +{
> +	struct amdgpu_fpriv *fpriv = filp->driver_priv;
> +	struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
> +	struct amdgpu_usermode_queue *queue;
> +
> +	queue = amdgpu_userqueue_find(uq_mgr, queue_id);
> +	if (!queue) {
> +		DRM_DEBUG_DRIVER("Invalid queue id to destroy\n");
> +		return;
> +	}
> +
> +	mutex_lock(&uq_mgr->userq_mutex);
> +	amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
> +	mutex_unlock(&uq_mgr->userq_mutex);
> +	kfree(queue);
> +}
> +
> +int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
> +		       struct drm_file *filp)
> +{
> +	union drm_amdgpu_userq *args = data;
> +	int r = 0;
> +
> +	switch (args->in.op) {
> +	case AMDGPU_USERQ_OP_CREATE:
> +		r = amdgpu_userqueue_create(filp, args);
> +		if (r)
> +			DRM_ERROR("Failed to create usermode queue\n");
> +		break;
> +
> +	case AMDGPU_USERQ_OP_FREE:
> +		amdgpu_userqueue_destroy(filp, args->in.queue_id);
> +		break;
> +
> +	default:
> +		DRM_ERROR("Invalid user queue op specified: %d\n", args->in.op);
> +		return -EINVAL;
> +	}
> +
> +	return r;
> +}
> +
>   
>   int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev)
>   {
> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> index 6fe5d8d73f37..8d8f6b3bcda5 100644
> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> @@ -43,6 +43,8 @@ struct amdgpu_userq_funcs {
>   	void (*mqd_destroy)(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *uq);
>   };
>   
> +int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
> +
>   int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev);
>   
>   void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr);


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 02/10] drm/amdgpu: add usermode queue base code
  2023-04-25 12:03   ` Christian König
@ 2023-04-25 12:19     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 12:19 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav

Thanks for the review, Christian.

Inline,

On 25/04/2023 14:03, Christian König wrote:
>
>
> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch adds skeleton code for amdgpu usermode queue. It contains:
>> - A new files with init functions of usermode queues.
>> - A queue context manager in driver private data.
>>
>> V1: Worked on design review comments from RFC patch series:
>> (https://patchwork.freedesktop.org/series/112214/)
>> - Alex: Keep a list of queues, instead of single queue per process.
>> - Christian: Use the queue manager instead of global ptrs,
>>             Don't keep the queue structure in amdgpu_ctx
>>
>> V2:
>>   - Reformatted code, split the big patch into two
>>
>> V3:
>> - Integration with doorbell manager
>>
>> V4:
>> - Align the structure member names to the largest member's column
>>    (Luben)
>> - Added SPDX license (Luben)
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Shashank Sharma <contactshashanksharma@gmail.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/Makefile           |  2 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu.h           | 10 +++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |  1 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c       |  6 +++
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 40 +++++++++++++++
>>   .../gpu/drm/amd/include/amdgpu_userqueue.h    | 50 +++++++++++++++++++
>>   6 files changed, 108 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>>   create mode 100644 drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
>> b/drivers/gpu/drm/amd/amdgpu/Makefile
>> index 798d0e9a60b7..764801cc8203 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
>> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
>> @@ -210,6 +210,8 @@ amdgpu-y += \
>>   # add amdkfd interfaces
>>   amdgpu-y += amdgpu_amdkfd.o
>>   +# add usermode queue
>> +amdgpu-y += amdgpu_userqueue.o
>>     ifneq ($(CONFIG_HSA_AMD),)
>>   AMDKFD_PATH := ../amdkfd
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> index 6b74df446694..c5f9af0e74ee 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> @@ -438,6 +438,14 @@ struct amdgpu_sa_manager {
>>       uint32_t        align;
>>   };
>>   +/* Gfx usermode queues */
>> +struct amdgpu_userq_mgr {
>> +    struct idr userq_idr;
>> +    struct mutex userq_mutex;
>> +    struct amdgpu_device *adev;
>> +    const struct amdgpu_userq_funcs *userq_funcs[AMDGPU_HW_IP_NUM];
>> +};
>> +
>
> Please but that into amdgpu_userqueue.h as well. We want to 
> decommission amdgpu.h over time.
>
Noted,
>>   /* sub-allocation buffer */
>>   struct amdgpu_sa_bo {
>>       struct list_head        olist;
>> @@ -470,7 +478,6 @@ struct amdgpu_flip_work {
>>       bool                async;
>>   };
>>   -
>>   /*
>>    * file private structure
>>    */
>> @@ -482,6 +489,7 @@ struct amdgpu_fpriv {
>>       struct mutex        bo_list_lock;
>>       struct idr        bo_list_handles;
>>       struct amdgpu_ctx_mgr    ctx_mgr;
>> +    struct amdgpu_userq_mgr    userq_mgr;
>>   };
>>     int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv 
>> **fpriv);
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> index b4f2d61ea0d5..2d6bcfd727c8 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> @@ -52,6 +52,7 @@
>>   #include "amdgpu_ras.h"
>>   #include "amdgpu_xgmi.h"
>>   #include "amdgpu_reset.h"
>> +#include "amdgpu_userqueue.h"
>>     /*
>>    * KMS wrapper.
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>> index 7aa7e52ca784..e1b6e658d51d 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>> @@ -43,6 +43,7 @@
>>   #include "amdgpu_gem.h"
>>   #include "amdgpu_display.h"
>>   #include "amdgpu_ras.h"
>> +#include "amdgpu_userqueue.h"
>>     void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)
>>   {
>> @@ -1187,6 +1188,10 @@ int amdgpu_driver_open_kms(struct drm_device 
>> *dev, struct drm_file *file_priv)
>>         amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev);
>>   +    r = amdgpu_userq_mgr_init(&fpriv->userq_mgr, adev);
>> +    if (r)
>> +        DRM_WARN("Can't setup usermode queues, use legacy workload 
>> submission only\n");
>> +
>>       file_priv->driver_priv = fpriv;
>>       goto out_suspend;
>>   @@ -1254,6 +1259,7 @@ void amdgpu_driver_postclose_kms(struct 
>> drm_device *dev,
>>         amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr);
>>       amdgpu_vm_fini(adev, &fpriv->vm);
>> +    amdgpu_userq_mgr_fini(&fpriv->userq_mgr);
>>         if (pasid)
>>           amdgpu_pasid_free_delayed(pd->tbo.base.resv, pasid);
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> new file mode 100644
>> index 000000000000..effc0c7c02cf
>> --- /dev/null
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> @@ -0,0 +1,40 @@
>> +// SPDX-License-Identifier: MIT
>> +/*
>> + * Copyright 2023 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 "amdgpu.h"
>> +
>> +int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct 
>> amdgpu_device *adev)
>> +{
>> +    mutex_init(&userq_mgr->userq_mutex);
>> +    idr_init_base(&userq_mgr->userq_idr, 1);
>> +    userq_mgr->adev = adev;
>> +
>> +    return 0;
>> +}
>> +
>> +void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
>> +{
>> +    idr_destroy(&userq_mgr->userq_idr);
>> +    mutex_destroy(&userq_mgr->userq_mutex);
>> +}
>> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h 
>> b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> new file mode 100644
>> index 000000000000..6fe5d8d73f37
>> --- /dev/null
>> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> @@ -0,0 +1,50 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright 2023 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.
>> + *
>> + */
>> +
>> +#ifndef AMDGPU_USERQUEUE_H_
>> +#define AMDGPU_USERQUEUE_H_
>> +
>> +#include "amdgpu.h"
>
> Please don't include amdgpu.h here.
>
> Most structures can be forward defined, only amdgpu_mqd_prop is really 
> needed and that should be included separately.
>
> Christian.
>
Noted, let me try this out.

- Shashank

>> +#define AMDGPU_MAX_USERQ 512
>> +
>> +struct amdgpu_usermode_queue {
>> +    int            queue_id;
>> +    int            queue_type;
>> +    uint64_t        doorbell_handle;
>> +    uint64_t        flags;
>> +    struct amdgpu_mqd_prop    userq_prop;
>> +    struct amdgpu_userq_mgr *userq_mgr;
>> +    struct amdgpu_vm    *vm;
>> +};
>> +
>> +struct amdgpu_userq_funcs {
>> +    int  (*mqd_create)(struct amdgpu_userq_mgr *uq_mgr, struct 
>> amdgpu_usermode_queue *uq);
>> +    void (*mqd_destroy)(struct amdgpu_userq_mgr *uq_mgr, struct 
>> amdgpu_usermode_queue *uq);
>> +};
>> +
>> +int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct 
>> amdgpu_device *adev);
>> +
>> +void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr);
>> +
>> +#endif
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 03/10] drm/amdgpu: add new IOCTL for usermode queue
  2023-04-25 12:14   ` Christian König
@ 2023-04-25 12:21     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 12:21 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav


On 25/04/2023 14:14, Christian König wrote:
> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>> This patch adds:
>> - A new IOCTL function to create and destroy
>> - A new structure to keep all the user queue data in one place.
>> - A function to generate unique index for the queue.
>>
>> V1: Worked on review comments from RFC patch series:
>>    - Alex: Keep a list of queues, instead of single queue per process.
>>    - Christian: Use the queue manager instead of global ptrs,
>>             Don't keep the queue structure in amdgpu_ctx
>>
>> V2: Worked on review comments:
>>   - Christian:
>>     - Formatting of text
>>     - There is no need for queuing of userqueues, with idr in place
>>   - Alex:
>>     - Remove use_doorbell, its unnecessary
>>     - Reuse amdgpu_mqd_props for saving mqd fields
>>
>>   - Code formatting and re-arrangement
>>
>> V3:
>>   - Integration with doorbell manager
>>
>> V4:
>>   - Accommodate MQD union related changes in UAPI (Alex)
>>   - Do not set the queue size twice (Bas)
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |   1 +
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 126 ++++++++++++++++++
>>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |   2 +
>>   3 files changed, 129 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> index 2d6bcfd727c8..229976a2d0e7 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> @@ -2749,6 +2749,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] 
>> = {
>>       DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, 
>> DRM_AUTH|DRM_RENDER_ALLOW),
>>       DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, 
>> DRM_AUTH|DRM_RENDER_ALLOW),
>>       DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, 
>> DRM_AUTH|DRM_RENDER_ALLOW),
>> +    DRM_IOCTL_DEF_DRV(AMDGPU_USERQ, amdgpu_userq_ioctl, 
>> DRM_AUTH|DRM_RENDER_ALLOW),
>>   };
>>     static const struct drm_driver amdgpu_kms_driver = {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> index effc0c7c02cf..333f31efbe7b 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> @@ -23,6 +23,132 @@
>>    */
>>     #include "amdgpu.h"
>> +#include "amdgpu_vm.h"
>> +#include "amdgpu_userqueue.h"
>> +
>> +static inline int
>> +amdgpu_userqueue_index(struct amdgpu_userq_mgr *uq_mgr, struct 
>> amdgpu_usermode_queue *queue)
>
> Maybe call that handle instead of index. And I don't think you 
> actually need those wrapper functions, see below.
>
>> +{
>> +    return idr_alloc(&uq_mgr->userq_idr, queue, 1, AMDGPU_MAX_USERQ, 
>> GFP_KERNEL);
>> +}
>> +
>> +static inline void
>> +amdgpu_userqueue_free_index(struct amdgpu_userq_mgr *uq_mgr, int 
>> queue_id)
>> +{
>> +    idr_remove(&uq_mgr->userq_idr, queue_id);
>> +}
>> +
>> +static struct amdgpu_usermode_queue *
>> +amdgpu_userqueue_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
>> +{
>> +    return idr_find(&uq_mgr->userq_idr, qid);
>> +}
>> +
>> +static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union 
>> drm_amdgpu_userq *args)
>> +{
>> +    struct amdgpu_usermode_queue *queue;
>> +    struct amdgpu_fpriv *fpriv = filp->driver_priv;
>> +    struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
>> +    struct drm_amdgpu_userq_mqd_gfx *mqd_in = &args->in.mqd.gfx;
>> +    int r;
>> +
>> +    /* Do we support usermode queues on this GFX IP ? */
>> +    if (!uq_mgr->userq_funcs[AMDGPU_HW_IP_GFX]) {
>> +        DRM_ERROR("Usermode queue is not supported for this GFX IP\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    queue = kzalloc(sizeof(struct amdgpu_usermode_queue), GFP_KERNEL);
>> +    if (!queue) {
>> +        DRM_ERROR("Failed to allocate memory for queue\n");
>> +        return -ENOMEM;
>> +    }
>> +
>> +    mutex_lock(&uq_mgr->userq_mutex);
>> +    queue->userq_prop.wptr_gpu_addr = mqd_in->wptr_va;
>> +    queue->userq_prop.rptr_gpu_addr = mqd_in->rptr_va;
>> +    queue->userq_prop.queue_size = mqd_in->queue_size;
>> +    queue->userq_prop.hqd_base_gpu_addr = mqd_in->queue_va;
>> +
>> +    queue->doorbell_handle = mqd_in->doorbell_handle;
>> +    queue->queue_type = AMDGPU_HW_IP_GFX;
>> +    queue->flags = mqd_in->flags;
>> +    queue->vm = &fpriv->vm;
>> +    queue->queue_id = amdgpu_userqueue_index(uq_mgr, queue);
>
> It is usually good practice to *not* store those handles inside the 
> object they refer to, background is that this always creates a circle 
> reference (handle->object, object->handle).
>
> Additional to that I would move registering the userspace handle out 
> of this function.
I guess idr should be good enough to get me the queue ptr, and I don't 
have to save the queue id in queue.
>
>> +    if (queue->queue_id < 0) {
>> +        DRM_ERROR("Failed to allocate a queue id\n");
>> +        r = queue->queue_id;
>> +        goto free_queue;
>> +    }
>> +
>> +    args->out.queue_id = queue->queue_id;
>> +    args->out.flags = 0;
>> +    mutex_unlock(&uq_mgr->userq_mutex);
>> +    return 0;
>> +
>> +free_queue:
>> +    mutex_unlock(&uq_mgr->userq_mutex);
>> +    kfree(queue);
>> +    return r;
>> +}
>> +
>> +static int amdgpu_userqueue_create(struct drm_file *filp, union 
>> drm_amdgpu_userq *args)
>> +{
>> +    u32 ip_type = args->in.ip_type;
>> +
>> +    switch (ip_type) {
>> +    case AMDGPU_HW_IP_GFX:
>> +        return amdgpu_userqueue_create_gfx(filp, args);
>> +    default:
>> +        DRM_ERROR("Usermode queue is not supported for this IP 
>> (%u)\n", ip_type);
>> +    }
>
> Instead insert the idr_alloc() or more generally handle alloc here.

Noted,

- Shashank

>
> Christian.
>
>> +
>> +    return -EINVAL;
>> +}
>> +
>> +static void amdgpu_userqueue_destroy(struct drm_file *filp, int 
>> queue_id)
>> +{
>> +    struct amdgpu_fpriv *fpriv = filp->driver_priv;
>> +    struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
>> +    struct amdgpu_usermode_queue *queue;
>> +
>> +    queue = amdgpu_userqueue_find(uq_mgr, queue_id);
>> +    if (!queue) {
>> +        DRM_DEBUG_DRIVER("Invalid queue id to destroy\n");
>> +        return;
>> +    }
>> +
>> +    mutex_lock(&uq_mgr->userq_mutex);
>> +    amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
>> +    mutex_unlock(&uq_mgr->userq_mutex);
>> +    kfree(queue);
>> +}
>> +
>> +int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
>> +               struct drm_file *filp)
>> +{
>> +    union drm_amdgpu_userq *args = data;
>> +    int r = 0;
>> +
>> +    switch (args->in.op) {
>> +    case AMDGPU_USERQ_OP_CREATE:
>> +        r = amdgpu_userqueue_create(filp, args);
>> +        if (r)
>> +            DRM_ERROR("Failed to create usermode queue\n");
>> +        break;
>> +
>> +    case AMDGPU_USERQ_OP_FREE:
>> +        amdgpu_userqueue_destroy(filp, args->in.queue_id);
>> +        break;
>> +
>> +    default:
>> +        DRM_ERROR("Invalid user queue op specified: %d\n", 
>> args->in.op);
>> +        return -EINVAL;
>> +    }
>> +
>> +    return r;
>> +}
>> +
>>     int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, 
>> struct amdgpu_device *adev)
>>   {
>> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h 
>> b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> index 6fe5d8d73f37..8d8f6b3bcda5 100644
>> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> @@ -43,6 +43,8 @@ struct amdgpu_userq_funcs {
>>       void (*mqd_destroy)(struct amdgpu_userq_mgr *uq_mgr, struct 
>> amdgpu_usermode_queue *uq);
>>   };
>>   +int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct 
>> drm_file *filp);
>> +
>>   int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, 
>> struct amdgpu_device *adev);
>>     void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr);
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue
  2023-04-24 17:38 ` [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue Shashank Sharma
@ 2023-04-25 12:27   ` Christian König
  2023-04-25 13:10     ` Shashank Sharma
  2023-05-19 21:19   ` Alex Deucher
  1 sibling, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 12:27 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav

Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> A Memory queue descriptor (MQD) of a userqueue defines it in
> the hw's context. As MQD format can vary between different
> graphics IPs, we need gfx GEN specific handlers to create MQDs.
>
> This patch:
> - Introduces MQD handler functions for the usermode queues.
> - Adds new functions to create and destroy userqueue MQD for
>    GFX-GEN-11 IP
>
> V1: Worked on review comments from Alex:
>      - Make MQD functions GEN and IP specific
>
> V2: Worked on review comments from Alex:
>      - Reuse the existing adev->mqd[ip] for MQD creation
>      - Formatting and arrangement of code
>
> V3:
>      - Integration with doorbell manager
>
> V4: Review comments addressed:
>      - Do not create a new file for userq, reuse gfx_v11_0.c (Alex)
>      - Align name of structure members (Luben)
>      - Don't break up the Cc tag list and the Sob tag list in commit
>        message (Luben)
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 25 ++++++++
>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 +++++++++++++++++++
>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  7 +++
>   3 files changed, 89 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> index 333f31efbe7b..e95fb35b0cb5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> @@ -81,6 +81,14 @@ static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_u
>   		goto free_queue;
>   	}
>   
> +	if (uq_mgr->userq_funcs[queue->queue_type]->mqd_create) {
> +		r = uq_mgr->userq_funcs[queue->queue_type]->mqd_create(uq_mgr, queue);
> +		if (r) {
> +			DRM_ERROR("Failed to create/map userqueue MQD\n");
> +			goto free_queue;
> +		}
> +	}
> +
>   	args->out.queue_id = queue->queue_id;
>   	args->out.flags = 0;
>   	mutex_unlock(&uq_mgr->userq_mutex);
> @@ -119,6 +127,8 @@ static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
>   	}
>   
>   	mutex_lock(&uq_mgr->userq_mutex);
> +	if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
> +		uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
>   	amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
>   	mutex_unlock(&uq_mgr->userq_mutex);
>   	kfree(queue);
> @@ -149,6 +159,20 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
>   	return r;
>   }
>   
> +extern const struct amdgpu_userq_funcs userq_gfx_v11_funcs;
> +
> +static void
> +amdgpu_userqueue_setup_ip_funcs(struct amdgpu_userq_mgr *uq_mgr)
> +{
> +	int maj;
> +	struct amdgpu_device *adev = uq_mgr->adev;
> +	uint32_t version = adev->ip_versions[GC_HWIP][0];
> +
> +	/* We support usermode queue only for GFX IP as of now */
> +	maj = IP_VERSION_MAJ(version);
> +	if (maj == 11)
> +		uq_mgr->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_gfx_v11_funcs;
> +}
>   
>   int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev)
>   {
> @@ -156,6 +180,7 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi
>   	idr_init_base(&userq_mgr->userq_idr, 1);
>   	userq_mgr->adev = adev;
>   
> +	amdgpu_userqueue_setup_ip_funcs(userq_mgr);
>   	return 0;
>   }
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> index a56c6e106d00..9f7b14966ac8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> @@ -30,6 +30,7 @@
>   #include "amdgpu_psp.h"
>   #include "amdgpu_smu.h"
>   #include "amdgpu_atomfirmware.h"
> +#include "amdgpu_userqueue.h"
>   #include "imu_v11_0.h"
>   #include "soc21.h"
>   #include "nvd.h"
> @@ -6404,3 +6405,59 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>   	.rev = 0,
>   	.funcs = &gfx_v11_0_ip_funcs,
>   };
> +
> +static int
> +gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
> +{
> +	struct amdgpu_device *adev = uq_mgr->adev;
> +	struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
> +	struct amdgpu_mqd *gfx_v11_mqd = &adev->mqds[queue->queue_type];
> +	int size = gfx_v11_mqd->mqd_size;
> +	int r;
> +
> +	r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
> +				    AMDGPU_GEM_DOMAIN_GTT,
> +				    &mqd->obj,
> +				    &mqd->gpu_addr,
> +				    &mqd->cpu_ptr);
> +	if (r) {
> +		DRM_ERROR("Failed to allocate bo for userqueue (%d)", r);
> +		return r;
> +	}
> +
> +	memset(mqd->cpu_ptr, 0, size);
> +	r = amdgpu_bo_reserve(mqd->obj, false);
> +	if (unlikely(r != 0)) {
> +		DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
> +		goto free_mqd;
> +	}

This reserve/unreserve dance here doesn't seem to make much sense. Why 
do you do that?

Christian.

> +
> +	queue->userq_prop.use_doorbell = true;
> +	queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;

Are those the only two parameters needed? If yes we should probably drop 
the userq_prop structure and give them directly.

Christian.

> +	r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, &queue->userq_prop);
> +	amdgpu_bo_unreserve(mqd->obj);
> +	if (r) {
> +		DRM_ERROR("Failed to init MQD for queue\n");
> +		goto free_mqd;
> +	}
> +
> +	DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
> +	return 0;
> +
> +free_mqd:
> +	amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
> +	return r;
> +}
> +
> +static void
> +gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
> +{
> +	struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
> +
> +	amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
> +}
> +
> +const struct amdgpu_userq_funcs userq_gfx_v11_funcs = {
> +	.mqd_create = gfx_v11_userq_mqd_create,
> +	.mqd_destroy = gfx_v11_userq_mqd_destroy,
> +};
> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> index 8d8f6b3bcda5..e7da27918bd2 100644
> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> @@ -28,6 +28,12 @@
>   #include "amdgpu.h"
>   #define AMDGPU_MAX_USERQ 512
>   
> +struct amdgpu_userq_ctx_space {
> +	uint64_t	 gpu_addr;
> +	void		 *cpu_ptr;
> +	struct amdgpu_bo *obj;
> +};
> +
>   struct amdgpu_usermode_queue {
>   	int			queue_id;
>   	int			queue_type;
> @@ -36,6 +42,7 @@ struct amdgpu_usermode_queue {
>   	struct amdgpu_mqd_prop	userq_prop;
>   	struct amdgpu_userq_mgr *userq_mgr;
>   	struct amdgpu_vm	*vm;
> +	struct amdgpu_userq_ctx_space mqd;
>   };
>   
>   struct amdgpu_userq_funcs {


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue
  2023-04-24 17:38 ` [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue Shashank Sharma
@ 2023-04-25 12:30   ` Christian König
  2023-04-25 13:13     ` Shashank Sharma
  2023-05-19 21:21   ` Alex Deucher
  1 sibling, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 12:30 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav

Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> The FW expects us to allocate at least one page as context
> space to process gang, process, GDS and FW  related work.
> This patch creates a joint object for the same, and calculates
> GPU space offsets for each of these spaces.
>
> V1: Addressed review comments on RFC patch:
>      Alex: Make this function IP specific
>
> V2: Addressed review comments from Christian
>      - Allocate only one object for total FW space, and calculate
>        offsets for each of these objects.
>
> V3: Integration with doorbell manager
> V4: Review comments:
>      - Remove shadow from FW space list from cover letter (Alex)
>      - Alignment of macro (Luben)
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 ++++++++++++++++++-
>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  6 ++
>   2 files changed, 61 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> index 9f7b14966ac8..f6b33faea86f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> @@ -53,6 +53,11 @@
>   #define GFX11_NUM_GFX_RINGS		1
>   #define GFX11_MEC_HPD_SIZE	2048
>   
> +#define AMDGPU_USERQ_PROC_CTX_SZ   PAGE_SIZE
> +#define AMDGPU_USERQ_GANG_CTX_SZ   PAGE_SIZE
> +#define AMDGPU_USERQ_FW_CTX_SZ     PAGE_SIZE
> +#define AMDGPU_USERQ_GDS_CTX_SZ    PAGE_SIZE
> +
>   #define RLCG_UCODE_LOADING_START_ADDRESS	0x00002000L
>   #define RLC_PG_DELAY_3_DEFAULT_GC_11_0_1	0x1388
>   
> @@ -6406,6 +6411,44 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>   	.funcs = &gfx_v11_0_ip_funcs,
>   };
>   
> +static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
> +					  struct amdgpu_usermode_queue *queue)
> +{
> +	struct amdgpu_device *adev = uq_mgr->adev;
> +	struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
> +	int r, size;
> +
> +	/*
> +	 * The FW expects at least one page space allocated for
> +	 * process ctx, gang ctx, gds ctx, fw ctx each.
> +	 */
> +	size = AMDGPU_USERQ_PROC_CTX_SZ + AMDGPU_USERQ_FW_CTX_SZ +
> +	       AMDGPU_USERQ_GANG_CTX_SZ + AMDGPU_USERQ_GDS_CTX_SZ;
> +	r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
> +				    AMDGPU_GEM_DOMAIN_GTT,
> +				    &ctx->obj,
> +				    &ctx->gpu_addr,
> +				    &ctx->cpu_ptr);

Wasn't this stuff provided by userspace now?

Christian.

> +	if (r) {
> +		DRM_ERROR("Failed to allocate ctx space bo for userqueue, err:%d\n", r);
> +		return r;
> +	}
> +
> +	queue->proc_ctx_gpu_addr = ctx->gpu_addr;
> +	queue->gang_ctx_gpu_addr = queue->proc_ctx_gpu_addr + AMDGPU_USERQ_PROC_CTX_SZ;
> +	queue->fw_ctx_gpu_addr = queue->gang_ctx_gpu_addr + AMDGPU_USERQ_GANG_CTX_SZ;
> +	queue->gds_ctx_gpu_addr = queue->fw_ctx_gpu_addr + AMDGPU_USERQ_FW_CTX_SZ;
> +	return 0;
> +}
> +
> +static void gfx_v11_userq_destroy_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
> +					    struct amdgpu_usermode_queue *queue)
> +{
> +	struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
> +
> +	amdgpu_bo_free_kernel(&ctx->obj, &ctx->gpu_addr, &ctx->cpu_ptr);
> +}
> +
>   static int
>   gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
>   {
> @@ -6426,10 +6469,16 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>   	}
>   
>   	memset(mqd->cpu_ptr, 0, size);
> +	r = gfx_v11_userq_create_ctx_space(uq_mgr, queue);
> +	if (r) {
> +		DRM_ERROR("Failed to create CTX space for userqueue (%d)\n", r);
> +		goto free_mqd;
> +	}
> +
>   	r = amdgpu_bo_reserve(mqd->obj, false);
>   	if (unlikely(r != 0)) {
>   		DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
> -		goto free_mqd;
> +		goto free_ctx;
>   	}
>   
>   	queue->userq_prop.use_doorbell = true;
> @@ -6438,12 +6487,15 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>   	amdgpu_bo_unreserve(mqd->obj);
>   	if (r) {
>   		DRM_ERROR("Failed to init MQD for queue\n");
> -		goto free_mqd;
> +		goto free_ctx;
>   	}
>   
>   	DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>   	return 0;
>   
> +free_ctx:
> +	gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
> +
>   free_mqd:
>   	amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>   	return r;
> @@ -6454,6 +6506,7 @@ gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
>   {
>   	struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>   
> +	gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>   	amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>   }
>   
> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> index e7da27918bd2..11e8ad649f6e 100644
> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> @@ -38,11 +38,17 @@ struct amdgpu_usermode_queue {
>   	int			queue_id;
>   	int			queue_type;
>   	uint64_t		doorbell_handle;
> +	uint64_t		proc_ctx_gpu_addr;
> +	uint64_t		gang_ctx_gpu_addr;
> +	uint64_t		gds_ctx_gpu_addr;
> +	uint64_t		fw_ctx_gpu_addr;
> +	uint64_t		shadow_ctx_gpu_addr;
>   	uint64_t		flags;
>   	struct amdgpu_mqd_prop	userq_prop;
>   	struct amdgpu_userq_mgr *userq_mgr;
>   	struct amdgpu_vm	*vm;
>   	struct amdgpu_userq_ctx_space mqd;
> +	struct amdgpu_userq_ctx_space fw_space;
>   };
>   
>   struct amdgpu_userq_funcs {


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 06/10] drm/amdgpu: set FW parameters in v11_struct
  2023-04-24 17:38 ` [PATCH v4 06/10] drm/amdgpu: set FW parameters in v11_struct Shashank Sharma
@ 2023-04-25 12:32   ` Christian König
  2023-04-25 13:27     ` Shashank Sharma
  2023-05-19 21:22   ` Alex Deucher
  1 sibling, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 12:32 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav

Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> From: Arvind Yadav <arvind.yadav@amd.com>
>
> This patch sets new parameters defined in v11_struct for
> usermode queue with the respective allocated gpu context
> space addresses.
>
> V4: Split the patch into two parts, keep only the set parameter
>      part in this series (Alex).
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Cc: Shashank Sharma <shashank.sharma@amd.com>
> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 19 ++++++++++++++++++-
>   1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> index f6b33faea86f..86de35292f69 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> @@ -6411,6 +6411,21 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>   	.funcs = &gfx_v11_0_ip_funcs,
>   };
>   
> +static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
> +					struct amdgpu_usermode_queue *queue)
> +{
> +	struct v11_gfx_mqd *mqd = queue->mqd.cpu_ptr;
> +
> +	mqd->shadow_base_lo = queue->shadow_ctx_gpu_addr & 0xfffffffc;
> +	mqd->shadow_base_hi = upper_32_bits(queue->shadow_ctx_gpu_addr);
> +
> +	mqd->gds_bkup_base_lo = queue->gds_ctx_gpu_addr & 0xfffffffc;
> +	mqd->gds_bkup_base_hi = upper_32_bits(queue->gds_ctx_gpu_addr);
> +
> +	mqd->fw_work_area_base_lo = queue->fw_ctx_gpu_addr & 0xfffffffc;
> +	mqd->fw_work_area_base_lo = upper_32_bits(queue->fw_ctx_gpu_addr);

Mhm, first of all please use lower_32_bits() here instead of the mask.

Then are you sure that is correct? The shadow, csa, gds are supposed to 
be VAs as far as I know, but you use MC addresses here.

Christian.

> +}
> +
>   static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
>   					  struct amdgpu_usermode_queue *queue)
>   {
> @@ -6484,12 +6499,14 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>   	queue->userq_prop.use_doorbell = true;
>   	queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
>   	r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, &queue->userq_prop);
> -	amdgpu_bo_unreserve(mqd->obj);
>   	if (r) {
> +		amdgpu_bo_unreserve(mqd->obj);
>   		DRM_ERROR("Failed to init MQD for queue\n");
>   		goto free_ctx;
>   	}
>   
> +	gfx_v11_userq_set_ctx_space(uq_mgr, queue);
> +	amdgpu_bo_unreserve(mqd->obj);
>   	DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>   	return 0;
>   


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES
  2023-04-24 17:38 ` [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES Shashank Sharma
@ 2023-04-25 12:34   ` Christian König
  2023-04-25 13:31     ` Shashank Sharma
  2023-05-19 21:22   ` Alex Deucher
  1 sibling, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 12:34 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav

Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> This patch adds new functions to map/unmap a usermode queue into
> the FW, using the MES ring. As soon as this mapping is done, the
> queue would  be considered ready to accept the workload.
>
> V1: Addressed review comments from Alex on the RFC patch series
>      - Map/Unmap should be IP specific.
> V2:
>      Addressed review comments from Christian:
>      - Fix the wptr_mc_addr calculation (moved into another patch)
>      Addressed review comments from Alex:
>      - Do not add fptrs for map/unmap
>
> V3: Integration with doorbell manager
> V4: Rebase
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 67 ++++++++++++++++++++++++++
>   1 file changed, 67 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> index 86de35292f69..7a45d68091ec 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> @@ -31,6 +31,7 @@
>   #include "amdgpu_smu.h"
>   #include "amdgpu_atomfirmware.h"
>   #include "amdgpu_userqueue.h"
> +#include "amdgpu_mes.h"
>   #include "imu_v11_0.h"
>   #include "soc21.h"
>   #include "nvd.h"
> @@ -6411,6 +6412,64 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>   	.funcs = &gfx_v11_0_ip_funcs,
>   };
>   
> +static int gfx_v11_userq_map(struct amdgpu_userq_mgr *uq_mgr,
> +			     struct amdgpu_usermode_queue *queue)
> +{
> +	struct amdgpu_device *adev = uq_mgr->adev;
> +	struct mes_add_queue_input queue_input;
> +	int r;
> +
> +	memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
> +
> +	queue_input.process_va_start = 0;
> +	queue_input.process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT;

Could be that this is wrong. What is that value used for?

> +	queue_input.process_quantum = 100000; /* 10ms */
> +	queue_input.gang_quantum = 10000; /* 1ms */
> +	queue_input.paging = false;
> +
> +	queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
> +	queue_input.process_context_addr = queue->proc_ctx_gpu_addr;
> +	queue_input.inprocess_gang_priority = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
> +	queue_input.gang_global_priority_level = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
> +
> +	queue_input.process_id = queue->vm->pasid;
> +	queue_input.queue_type = queue->queue_type;
> +	queue_input.mqd_addr = queue->mqd.gpu_addr;
> +	queue_input.wptr_addr = queue->userq_prop.wptr_gpu_addr;
> +	queue_input.queue_size = queue->userq_prop.queue_size >> 2;
> +	queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
> +	queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(queue->vm->root.bo);

You need to implement some mechanism to keep those page tables and all 
resources in place.

Christian.

> +
> +	amdgpu_mes_lock(&adev->mes);
> +	r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
> +	amdgpu_mes_unlock(&adev->mes);
> +	if (r) {
> +		DRM_ERROR("Failed to map queue in HW, err (%d)\n", r);
> +		return r;
> +	}
> +
> +	DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", queue->queue_id);
> +	return 0;
> +}
> +
> +static void gfx_v11_userq_unmap(struct amdgpu_userq_mgr *uq_mgr,
> +				struct amdgpu_usermode_queue *queue)
> +{
> +	struct amdgpu_device *adev = uq_mgr->adev;
> +	struct mes_remove_queue_input queue_input;
> +	int r;
> +
> +	memset(&queue_input, 0x0, sizeof(struct mes_remove_queue_input));
> +	queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
> +	queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
> +
> +	amdgpu_mes_lock(&adev->mes);
> +	r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
> +	amdgpu_mes_unlock(&adev->mes);
> +	if (r)
> +		DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r);
> +}
> +
>   static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
>   					struct amdgpu_usermode_queue *queue)
>   {
> @@ -6507,6 +6566,13 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>   
>   	gfx_v11_userq_set_ctx_space(uq_mgr, queue);
>   	amdgpu_bo_unreserve(mqd->obj);
> +
> +	/* Map the queue in HW using MES ring */
> +	r = gfx_v11_userq_map(uq_mgr, queue);
> +	if (r) {
> +		DRM_ERROR("Failed to map userqueue (%d)\n", r);
> +		goto free_ctx;
> +	}
>   	DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>   	return 0;
>   
> @@ -6523,6 +6589,7 @@ gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
>   {
>   	struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>   
> +	gfx_v11_userq_unmap(uq_mgr, queue);
>   	gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>   	amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>   }


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 08/10] drm/amdgpu: map wptr BO into GART
  2023-04-24 17:38 ` [PATCH v4 08/10] drm/amdgpu: map wptr BO into GART Shashank Sharma
@ 2023-04-25 12:36   ` Christian König
  2023-04-25 13:33     ` Shashank Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 12:36 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav

Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> To support oversubscription, MES FW expects WPTR BOs to
> be mapped into GART, before they are submitted to usermode
> queues. This patch adds a function for the same.
>
> V4: fix the wptr value before mapping lookup (Bas, Christian).
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 90 +++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        |  1 +
>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  1 +
>   3 files changed, 92 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> index e95fb35b0cb5..385cd51b6c96 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> @@ -44,6 +44,89 @@ amdgpu_userqueue_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
>   	return idr_find(&uq_mgr->userq_idr, qid);
>   }
>   
> +static int
> +amdgpu_userqueue_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo)
> +{
> +	int ret;
> +
> +	ret = amdgpu_bo_reserve(bo, true);
> +	if (ret) {
> +		DRM_ERROR("Failed to reserve bo. ret %d\n", ret);
> +		goto err_reserve_bo_failed;
> +	}
> +
> +	ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT);
> +	if (ret) {
> +		DRM_ERROR("Failed to pin bo. ret %d\n", ret);
> +		goto err_pin_bo_failed;
> +	}
> +
> +	ret = amdgpu_ttm_alloc_gart(&bo->tbo);
> +	if (ret) {
> +		DRM_ERROR("Failed to bind bo to GART. ret %d\n", ret);
> +		goto err_map_bo_gart_failed;
> +	}

Either pinning *or* allocating GART, but not both!

I think calling amdgpu_ttm_alloc_gart() is the right thing to do here.

> +
> +	amdgpu_bo_unreserve(bo);
> +	bo = amdgpu_bo_ref(bo);
> +
> +	return 0;
> +
> +err_map_bo_gart_failed:
> +	amdgpu_bo_unpin(bo);
> +err_pin_bo_failed:
> +	amdgpu_bo_unreserve(bo);
> +err_reserve_bo_failed:
> +
> +	return ret;
> +}
> +
> +
> +static int
> +amdgpu_userqueue_create_wptr_mapping(struct amdgpu_device *adev,
> +				     struct drm_file *filp,
> +				     struct amdgpu_usermode_queue *queue)
> +{
> +	struct amdgpu_bo_va_mapping *wptr_mapping;
> +	struct amdgpu_vm *wptr_vm;
> +	struct amdgpu_bo *wptr_bo = NULL;
> +	uint64_t wptr = queue->userq_prop.wptr_gpu_addr;
> +	int ret;
> +
> +	wptr_vm = queue->vm;
> +	ret = amdgpu_bo_reserve(wptr_vm->root.bo, false);

All the handling must be done with the VM and all resource locks held.

So this should be something the caller of the function does.

Regards,
Christian.

> +	if (ret)
> +		goto err_wptr_map_gart;
> +
> +	wptr &= AMDGPU_GMC_HOLE_MASK;
> +	wptr_mapping = amdgpu_vm_bo_lookup_mapping(wptr_vm, wptr >> PAGE_SHIFT);
> +	amdgpu_bo_unreserve(wptr_vm->root.bo);
> +	if (!wptr_mapping) {
> +		DRM_ERROR("Failed to lookup wptr bo\n");
> +		ret = -EINVAL;
> +		goto err_wptr_map_gart;
> +	}
> +
> +	wptr_bo = wptr_mapping->bo_va->base.bo;
> +	if (wptr_bo->tbo.base.size > PAGE_SIZE) {
> +		DRM_ERROR("Requested GART mapping for wptr bo larger than one page\n");
> +		ret = -EINVAL;
> +		goto err_wptr_map_gart;
> +	}
> +
> +	ret = amdgpu_userqueue_map_gtt_bo_to_gart(adev, wptr_bo);
> +	if (ret) {
> +		DRM_ERROR("Failed to map wptr bo to GART\n");
> +		goto err_wptr_map_gart;
> +	}
> +
> +	queue->wptr_mc_addr = wptr_bo->tbo.resource->start << PAGE_SHIFT;
> +	return 0;
> +
> +err_wptr_map_gart:
> +	return ret;
> +}
> +
>   static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_userq *args)
>   {
>   	struct amdgpu_usermode_queue *queue;
> @@ -81,6 +164,13 @@ static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_u
>   		goto free_queue;
>   	}
>   
> +	r = amdgpu_userqueue_create_wptr_mapping(uq_mgr->adev, filp, queue);
> +	if (r) {
> +		DRM_ERROR("Failed to map WPTR (0x%llx) for userqueue\n",
> +			   queue->userq_prop.wptr_gpu_addr);
> +		goto free_queue;
> +	}
> +
>   	if (uq_mgr->userq_funcs[queue->queue_type]->mqd_create) {
>   		r = uq_mgr->userq_funcs[queue->queue_type]->mqd_create(uq_mgr, queue);
>   		if (r) {
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> index 7a45d68091ec..6eeae0206d8a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> @@ -6439,6 +6439,7 @@ static int gfx_v11_userq_map(struct amdgpu_userq_mgr *uq_mgr,
>   	queue_input.queue_size = queue->userq_prop.queue_size >> 2;
>   	queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
>   	queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(queue->vm->root.bo);
> +	queue_input.wptr_mc_addr = queue->wptr_mc_addr;
>   
>   	amdgpu_mes_lock(&adev->mes);
>   	r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> index 11e8ad649f6e..0001ecd710a7 100644
> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> @@ -38,6 +38,7 @@ struct amdgpu_usermode_queue {
>   	int			queue_id;
>   	int			queue_type;
>   	uint64_t		doorbell_handle;
> +	uint64_t		wptr_mc_addr;
>   	uint64_t		proc_ctx_gpu_addr;
>   	uint64_t		gang_ctx_gpu_addr;
>   	uint64_t		gds_ctx_gpu_addr;


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 09/10] drm/amdgpu: generate doorbell index for userqueue
  2023-04-24 17:38 ` [PATCH v4 09/10] drm/amdgpu: generate doorbell index for userqueue Shashank Sharma
@ 2023-04-25 12:38   ` Christian König
  2023-04-25 13:34     ` Shashank Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 12:38 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav

Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> The userspace sends us the doorbell object and the doobell index
> to be used for the usermode queue, but the FW expects the absolute
> doorbell index on the PCI BAR in the MQD. This patch adds a function
> to convert this relative doorbell index to the absolute doorbell index.
>
> This patch is dependent on the doorbell manager series being reviewed
> here: https://patchwork.freedesktop.org/series/115802/
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 33 +++++++++++++++++++
>   1 file changed, 33 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> index 385cd51b6c96..fbc9cb5c24ad 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> @@ -44,6 +44,30 @@ amdgpu_userqueue_find(struct amdgpu_userq_mgr *uq_mgr, int qid)
>   	return idr_find(&uq_mgr->userq_idr, qid);
>   }
>   
> +static uint64_t
> +amdgpu_userqueue_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr,
> +				    struct amdgpu_usermode_queue *queue,
> +				    struct drm_file *filp,
> +				    uint32_t doorbell_index)
> +{
> +	struct drm_gem_object *gobj;
> +	struct amdgpu_bo *db_bo;
> +	uint64_t index;
> +
> +	gobj = drm_gem_object_lookup(filp, queue->doorbell_handle);
> +	if (gobj == NULL) {
> +		DRM_ERROR("Can't find GEM object for doorbell\n");
> +		return -EINVAL;
> +	}
> +
> +	db_bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));

That looks like we are leaking the object reference here.

Christian.

> +	drm_gem_object_put(gobj);
> +
> +	index = amdgpu_doorbell_index_on_bar(uq_mgr->adev, db_bo, doorbell_index);
> +	DRM_DEBUG_DRIVER("[Usermode queues] doorbell index=%lld\n", index);
> +	return index;
> +}
> +
>   static int
>   amdgpu_userqueue_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_bo *bo)
>   {
> @@ -133,6 +157,7 @@ static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_u
>   	struct amdgpu_fpriv *fpriv = filp->driver_priv;
>   	struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
>   	struct drm_amdgpu_userq_mqd_gfx *mqd_in = &args->in.mqd.gfx;
> +	uint64_t index;
>   	int r;
>   
>   	/* Do we support usermode queues on this GFX IP ? */
> @@ -154,6 +179,14 @@ static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_u
>   	queue->userq_prop.hqd_base_gpu_addr = mqd_in->queue_va;
>   
>   	queue->doorbell_handle = mqd_in->doorbell_handle;
> +	index = amdgpu_userqueue_get_doorbell_index(uq_mgr, queue, filp, mqd_in->doorbell_offset);
> +	if (index == (uint64_t)-EINVAL) {
> +		DRM_ERROR("Invalid doorbell object\n");
> +		r = -EINVAL;
> +		goto free_queue;
> +	}
> +
> +	queue->userq_prop.doorbell_index = index;
>   	queue->queue_type = AMDGPU_HW_IP_GFX;
>   	queue->flags = mqd_in->flags;
>   	queue->vm = &fpriv->vm;


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 10/10] drm/amdgpu: cleanup leftover queues
  2023-04-24 17:38 ` [PATCH v4 10/10] drm/amdgpu: cleanup leftover queues Shashank Sharma
@ 2023-04-25 12:40   ` Christian König
  2023-04-25 13:34     ` Shashank Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 12:40 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav, Bas Nieuwenhuizen



Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> This patch adds code to cleanup any leftover userqueues which
> a user might have missed to destroy due to a crash or any other
> programming error.
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Suggested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 31 +++++++++++++++----
>   1 file changed, 25 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> index fbc9cb5c24ad..27201a0b1441 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> @@ -237,6 +237,18 @@ static int amdgpu_userqueue_create(struct drm_file *filp, union drm_amdgpu_userq
>   	return -EINVAL;
>   }
>   
> +static void
> +amdgpu_userqueue_cleanup(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
> +{
> +	mutex_lock(&uq_mgr->userq_mutex);
> +	if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
> +		uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
> +
> +	amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
> +	mutex_unlock(&uq_mgr->userq_mutex);
> +	kfree(queue);
> +}
> +
>   static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
>   {
>   	struct amdgpu_fpriv *fpriv = filp->driver_priv;
> @@ -249,12 +261,7 @@ static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
>   		return;
>   	}
>   
> -	mutex_lock(&uq_mgr->userq_mutex);
> -	if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
> -		uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
> -	amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
> -	mutex_unlock(&uq_mgr->userq_mutex);
> -	kfree(queue);
> +	amdgpu_userqueue_cleanup(uq_mgr, queue);
>   }
>   
>   int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
> @@ -307,8 +314,20 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi
>   	return 0;
>   }
>   
> +static void amdgpu_userqueue_cleanup_residue(int queue_id, void *ptr, void *data)
> +{
> +	struct amdgpu_userq_mgr *uq_mgr = data;
> +	struct amdgpu_usermode_queue *queue = ptr;
> +
> +	amdgpu_userqueue_cleanup(uq_mgr, queue);
> +}
> +
>   void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
>   {
> +	idr_for_each(&userq_mgr->userq_idr,
> +		     amdgpu_userqueue_cleanup_residue,
> +		     userq_mgr);
> +

Better use idr_for_each_entry() here.

Christian.
>   	idr_destroy(&userq_mgr->userq_idr);
>   	mutex_destroy(&userq_mgr->userq_mutex);
>   }


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue
  2023-04-25 12:27   ` Christian König
@ 2023-04-25 13:10     ` Shashank Sharma
  2023-04-25 13:45       ` Christian König
  0 siblings, 1 reply; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 13:10 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav


On 25/04/2023 14:27, Christian König wrote:
> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>> A Memory queue descriptor (MQD) of a userqueue defines it in
>> the hw's context. As MQD format can vary between different
>> graphics IPs, we need gfx GEN specific handlers to create MQDs.
>>
>> This patch:
>> - Introduces MQD handler functions for the usermode queues.
>> - Adds new functions to create and destroy userqueue MQD for
>>    GFX-GEN-11 IP
>>
>> V1: Worked on review comments from Alex:
>>      - Make MQD functions GEN and IP specific
>>
>> V2: Worked on review comments from Alex:
>>      - Reuse the existing adev->mqd[ip] for MQD creation
>>      - Formatting and arrangement of code
>>
>> V3:
>>      - Integration with doorbell manager
>>
>> V4: Review comments addressed:
>>      - Do not create a new file for userq, reuse gfx_v11_0.c (Alex)
>>      - Align name of structure members (Luben)
>>      - Don't break up the Cc tag list and the Sob tag list in commit
>>        message (Luben)
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 25 ++++++++
>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 +++++++++++++++++++
>>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  7 +++
>>   3 files changed, 89 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> index 333f31efbe7b..e95fb35b0cb5 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> @@ -81,6 +81,14 @@ static int amdgpu_userqueue_create_gfx(struct 
>> drm_file *filp, union drm_amdgpu_u
>>           goto free_queue;
>>       }
>>   +    if (uq_mgr->userq_funcs[queue->queue_type]->mqd_create) {
>> +        r = 
>> uq_mgr->userq_funcs[queue->queue_type]->mqd_create(uq_mgr, queue);
>> +        if (r) {
>> +            DRM_ERROR("Failed to create/map userqueue MQD\n");
>> +            goto free_queue;
>> +        }
>> +    }
>> +
>>       args->out.queue_id = queue->queue_id;
>>       args->out.flags = 0;
>>       mutex_unlock(&uq_mgr->userq_mutex);
>> @@ -119,6 +127,8 @@ static void amdgpu_userqueue_destroy(struct 
>> drm_file *filp, int queue_id)
>>       }
>>         mutex_lock(&uq_mgr->userq_mutex);
>> +    if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
>> + uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
>>       amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
>>       mutex_unlock(&uq_mgr->userq_mutex);
>>       kfree(queue);
>> @@ -149,6 +159,20 @@ int amdgpu_userq_ioctl(struct drm_device *dev, 
>> void *data,
>>       return r;
>>   }
>>   +extern const struct amdgpu_userq_funcs userq_gfx_v11_funcs;
>> +
>> +static void
>> +amdgpu_userqueue_setup_ip_funcs(struct amdgpu_userq_mgr *uq_mgr)
>> +{
>> +    int maj;
>> +    struct amdgpu_device *adev = uq_mgr->adev;
>> +    uint32_t version = adev->ip_versions[GC_HWIP][0];
>> +
>> +    /* We support usermode queue only for GFX IP as of now */
>> +    maj = IP_VERSION_MAJ(version);
>> +    if (maj == 11)
>> +        uq_mgr->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_gfx_v11_funcs;
>> +}
>>     int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, 
>> struct amdgpu_device *adev)
>>   {
>> @@ -156,6 +180,7 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr 
>> *userq_mgr, struct amdgpu_devi
>>       idr_init_base(&userq_mgr->userq_idr, 1);
>>       userq_mgr->adev = adev;
>>   +    amdgpu_userqueue_setup_ip_funcs(userq_mgr);
>>       return 0;
>>   }
>>   diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
>> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> index a56c6e106d00..9f7b14966ac8 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> @@ -30,6 +30,7 @@
>>   #include "amdgpu_psp.h"
>>   #include "amdgpu_smu.h"
>>   #include "amdgpu_atomfirmware.h"
>> +#include "amdgpu_userqueue.h"
>>   #include "imu_v11_0.h"
>>   #include "soc21.h"
>>   #include "nvd.h"
>> @@ -6404,3 +6405,59 @@ const struct amdgpu_ip_block_version 
>> gfx_v11_0_ip_block =
>>       .rev = 0,
>>       .funcs = &gfx_v11_0_ip_funcs,
>>   };
>> +
>> +static int
>> +gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct 
>> amdgpu_usermode_queue *queue)
>> +{
>> +    struct amdgpu_device *adev = uq_mgr->adev;
>> +    struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>> +    struct amdgpu_mqd *gfx_v11_mqd = &adev->mqds[queue->queue_type];
>> +    int size = gfx_v11_mqd->mqd_size;
>> +    int r;
>> +
>> +    r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
>> +                    AMDGPU_GEM_DOMAIN_GTT,
>> +                    &mqd->obj,
>> +                    &mqd->gpu_addr,
>> +                    &mqd->cpu_ptr);
>> +    if (r) {
>> +        DRM_ERROR("Failed to allocate bo for userqueue (%d)", r);
>> +        return r;
>> +    }
>> +
>> +    memset(mqd->cpu_ptr, 0, size);
>> +    r = amdgpu_bo_reserve(mqd->obj, false);
>> +    if (unlikely(r != 0)) {
>> +        DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
>> +        goto free_mqd;
>> +    }
>
> This reserve/unreserve dance here doesn't seem to make much sense. Why 
> do you do that?
We wanted to make sure that the MQD buffer is reserved until we fill it. 
Does it sound incorrect ?
>
> Christian.
>
>> +
>> +    queue->userq_prop.use_doorbell = true;
>> +    queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
>
> Are those the only two parameters needed? If yes we should probably 
> drop the userq_prop structure and give them directly.
In patch set 1 and 2, everything was getting stored directly in the 
queue, but then we decided to re-use the existing init_mqd() functions 
from each of the IP engines.

If you see the prototype of mqd->init_mqd(), it expects userq_prop 
structure as input parameters, so we encapsulated a subset of queue to 
this structure.

- Shashank

>
> Christian.
>
>> +    r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, 
>> &queue->userq_prop);
>> +    amdgpu_bo_unreserve(mqd->obj);
>> +    if (r) {
>> +        DRM_ERROR("Failed to init MQD for queue\n");
>> +        goto free_mqd;
>> +    }
>> +
>> +    DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>> +    return 0;
>> +
>> +free_mqd:
>> +    amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>> +    return r;
>> +}
>> +
>> +static void
>> +gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct 
>> amdgpu_usermode_queue *queue)
>> +{
>> +    struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>> +
>> +    amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>> +}
>> +
>> +const struct amdgpu_userq_funcs userq_gfx_v11_funcs = {
>> +    .mqd_create = gfx_v11_userq_mqd_create,
>> +    .mqd_destroy = gfx_v11_userq_mqd_destroy,
>> +};
>> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h 
>> b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> index 8d8f6b3bcda5..e7da27918bd2 100644
>> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> @@ -28,6 +28,12 @@
>>   #include "amdgpu.h"
>>   #define AMDGPU_MAX_USERQ 512
>>   +struct amdgpu_userq_ctx_space {
>> +    uint64_t     gpu_addr;
>> +    void         *cpu_ptr;
>> +    struct amdgpu_bo *obj;
>> +};
>> +
>>   struct amdgpu_usermode_queue {
>>       int            queue_id;
>>       int            queue_type;
>> @@ -36,6 +42,7 @@ struct amdgpu_usermode_queue {
>>       struct amdgpu_mqd_prop    userq_prop;
>>       struct amdgpu_userq_mgr *userq_mgr;
>>       struct amdgpu_vm    *vm;
>> +    struct amdgpu_userq_ctx_space mqd;
>>   };
>>     struct amdgpu_userq_funcs {
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue
  2023-04-25 12:30   ` Christian König
@ 2023-04-25 13:13     ` Shashank Sharma
  2023-04-25 17:38       ` Deucher, Alexander
  0 siblings, 1 reply; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 13:13 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav


On 25/04/2023 14:30, Christian König wrote:
> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>> The FW expects us to allocate at least one page as context
>> space to process gang, process, GDS and FW  related work.
>> This patch creates a joint object for the same, and calculates
>> GPU space offsets for each of these spaces.
>>
>> V1: Addressed review comments on RFC patch:
>>      Alex: Make this function IP specific
>>
>> V2: Addressed review comments from Christian
>>      - Allocate only one object for total FW space, and calculate
>>        offsets for each of these objects.
>>
>> V3: Integration with doorbell manager
>> V4: Review comments:
>>      - Remove shadow from FW space list from cover letter (Alex)
>>      - Alignment of macro (Luben)
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 ++++++++++++++++++-
>>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  6 ++
>>   2 files changed, 61 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
>> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> index 9f7b14966ac8..f6b33faea86f 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> @@ -53,6 +53,11 @@
>>   #define GFX11_NUM_GFX_RINGS        1
>>   #define GFX11_MEC_HPD_SIZE    2048
>>   +#define AMDGPU_USERQ_PROC_CTX_SZ   PAGE_SIZE
>> +#define AMDGPU_USERQ_GANG_CTX_SZ   PAGE_SIZE
>> +#define AMDGPU_USERQ_FW_CTX_SZ     PAGE_SIZE
>> +#define AMDGPU_USERQ_GDS_CTX_SZ    PAGE_SIZE
>> +
>>   #define RLCG_UCODE_LOADING_START_ADDRESS    0x00002000L
>>   #define RLC_PG_DELAY_3_DEFAULT_GC_11_0_1    0x1388
>>   @@ -6406,6 +6411,44 @@ const struct amdgpu_ip_block_version 
>> gfx_v11_0_ip_block =
>>       .funcs = &gfx_v11_0_ip_funcs,
>>   };
>>   +static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr 
>> *uq_mgr,
>> +                      struct amdgpu_usermode_queue *queue)
>> +{
>> +    struct amdgpu_device *adev = uq_mgr->adev;
>> +    struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
>> +    int r, size;
>> +
>> +    /*
>> +     * The FW expects at least one page space allocated for
>> +     * process ctx, gang ctx, gds ctx, fw ctx each.
>> +     */
>> +    size = AMDGPU_USERQ_PROC_CTX_SZ + AMDGPU_USERQ_FW_CTX_SZ +
>> +           AMDGPU_USERQ_GANG_CTX_SZ + AMDGPU_USERQ_GDS_CTX_SZ;
>> +    r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
>> +                    AMDGPU_GEM_DOMAIN_GTT,
>> +                    &ctx->obj,
>> +                    &ctx->gpu_addr,
>> +                    &ctx->cpu_ptr);
>
> Wasn't this stuff provided by userspace now?
>
The last I checked, only the shadow buffer was coming from userspace, 
and we were thinking about other stuff. I might not be well updated if 
there any recent development here with the short term solution.

- Shashank

> Christian.
>
>> +    if (r) {
>> +        DRM_ERROR("Failed to allocate ctx space bo for userqueue, 
>> err:%d\n", r);
>> +        return r;
>> +    }
>> +
>> +    queue->proc_ctx_gpu_addr = ctx->gpu_addr;
>> +    queue->gang_ctx_gpu_addr = queue->proc_ctx_gpu_addr + 
>> AMDGPU_USERQ_PROC_CTX_SZ;
>> +    queue->fw_ctx_gpu_addr = queue->gang_ctx_gpu_addr + 
>> AMDGPU_USERQ_GANG_CTX_SZ;
>> +    queue->gds_ctx_gpu_addr = queue->fw_ctx_gpu_addr + 
>> AMDGPU_USERQ_FW_CTX_SZ;
>> +    return 0;
>> +}
>> +
>> +static void gfx_v11_userq_destroy_ctx_space(struct amdgpu_userq_mgr 
>> *uq_mgr,
>> +                        struct amdgpu_usermode_queue *queue)
>> +{
>> +    struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
>> +
>> +    amdgpu_bo_free_kernel(&ctx->obj, &ctx->gpu_addr, &ctx->cpu_ptr);
>> +}
>> +
>>   static int
>>   gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct 
>> amdgpu_usermode_queue *queue)
>>   {
>> @@ -6426,10 +6469,16 @@ gfx_v11_userq_mqd_create(struct 
>> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>>       }
>>         memset(mqd->cpu_ptr, 0, size);
>> +    r = gfx_v11_userq_create_ctx_space(uq_mgr, queue);
>> +    if (r) {
>> +        DRM_ERROR("Failed to create CTX space for userqueue (%d)\n", 
>> r);
>> +        goto free_mqd;
>> +    }
>> +
>>       r = amdgpu_bo_reserve(mqd->obj, false);
>>       if (unlikely(r != 0)) {
>>           DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
>> -        goto free_mqd;
>> +        goto free_ctx;
>>       }
>>         queue->userq_prop.use_doorbell = true;
>> @@ -6438,12 +6487,15 @@ gfx_v11_userq_mqd_create(struct 
>> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>>       amdgpu_bo_unreserve(mqd->obj);
>>       if (r) {
>>           DRM_ERROR("Failed to init MQD for queue\n");
>> -        goto free_mqd;
>> +        goto free_ctx;
>>       }
>>         DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>>       return 0;
>>   +free_ctx:
>> +    gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>> +
>>   free_mqd:
>>       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>       return r;
>> @@ -6454,6 +6506,7 @@ gfx_v11_userq_mqd_destroy(struct 
>> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
>>   {
>>       struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>>   +    gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>>       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>   }
>>   diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h 
>> b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> index e7da27918bd2..11e8ad649f6e 100644
>> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> @@ -38,11 +38,17 @@ struct amdgpu_usermode_queue {
>>       int            queue_id;
>>       int            queue_type;
>>       uint64_t        doorbell_handle;
>> +    uint64_t        proc_ctx_gpu_addr;
>> +    uint64_t        gang_ctx_gpu_addr;
>> +    uint64_t        gds_ctx_gpu_addr;
>> +    uint64_t        fw_ctx_gpu_addr;
>> +    uint64_t        shadow_ctx_gpu_addr;
>>       uint64_t        flags;
>>       struct amdgpu_mqd_prop    userq_prop;
>>       struct amdgpu_userq_mgr *userq_mgr;
>>       struct amdgpu_vm    *vm;
>>       struct amdgpu_userq_ctx_space mqd;
>> +    struct amdgpu_userq_ctx_space fw_space;
>>   };
>>     struct amdgpu_userq_funcs {
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 06/10] drm/amdgpu: set FW parameters in v11_struct
  2023-04-25 12:32   ` Christian König
@ 2023-04-25 13:27     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 13:27 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav


On 25/04/2023 14:32, Christian König wrote:
> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>> From: Arvind Yadav <arvind.yadav@amd.com>
>>
>> This patch sets new parameters defined in v11_struct for
>> usermode queue with the respective allocated gpu context
>> space addresses.
>>
>> V4: Split the patch into two parts, keep only the set parameter
>>      part in this series (Alex).
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Cc: Shashank Sharma <shashank.sharma@amd.com>
>> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 19 ++++++++++++++++++-
>>   1 file changed, 18 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
>> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> index f6b33faea86f..86de35292f69 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> @@ -6411,6 +6411,21 @@ const struct amdgpu_ip_block_version 
>> gfx_v11_0_ip_block =
>>       .funcs = &gfx_v11_0_ip_funcs,
>>   };
>>   +static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr 
>> *uq_mgr,
>> +                    struct amdgpu_usermode_queue *queue)
>> +{
>> +    struct v11_gfx_mqd *mqd = queue->mqd.cpu_ptr;
>> +
>> +    mqd->shadow_base_lo = queue->shadow_ctx_gpu_addr & 0xfffffffc;
>> +    mqd->shadow_base_hi = upper_32_bits(queue->shadow_ctx_gpu_addr);
>> +
>> +    mqd->gds_bkup_base_lo = queue->gds_ctx_gpu_addr & 0xfffffffc;
>> +    mqd->gds_bkup_base_hi = upper_32_bits(queue->gds_ctx_gpu_addr);
>> +
>> +    mqd->fw_work_area_base_lo = queue->fw_ctx_gpu_addr & 0xfffffffc;
>> +    mqd->fw_work_area_base_lo = upper_32_bits(queue->fw_ctx_gpu_addr);
>
> Mhm, first of all please use lower_32_bits() here instead of the mask.
>
Noted,
> Then are you sure that is correct? The shadow, csa, gds are supposed 
> to be VAs as far as I know, but you use MC addresses here.

In my understanding, only the shadow area needs to be VA, which is true 
here as its being allocated by the user. We have tested the code and we 
did not see any problem yet, but I can cross check this and come back.

- Shashank

>
>
> Christian.
>
>> +}
>> +
>>   static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr 
>> *uq_mgr,
>>                         struct amdgpu_usermode_queue *queue)
>>   {
>> @@ -6484,12 +6499,14 @@ gfx_v11_userq_mqd_create(struct 
>> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>>       queue->userq_prop.use_doorbell = true;
>>       queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
>>       r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, 
>> &queue->userq_prop);
>> -    amdgpu_bo_unreserve(mqd->obj);
>>       if (r) {
>> +        amdgpu_bo_unreserve(mqd->obj);
>>           DRM_ERROR("Failed to init MQD for queue\n");
>>           goto free_ctx;
>>       }
>>   +    gfx_v11_userq_set_ctx_space(uq_mgr, queue);
>> +    amdgpu_bo_unreserve(mqd->obj);
>>       DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>>       return 0;
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES
  2023-04-25 12:34   ` Christian König
@ 2023-04-25 13:31     ` Shashank Sharma
  2023-04-25 15:33       ` Christian König
  0 siblings, 1 reply; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 13:31 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav


On 25/04/2023 14:34, Christian König wrote:
> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>> This patch adds new functions to map/unmap a usermode queue into
>> the FW, using the MES ring. As soon as this mapping is done, the
>> queue would  be considered ready to accept the workload.
>>
>> V1: Addressed review comments from Alex on the RFC patch series
>>      - Map/Unmap should be IP specific.
>> V2:
>>      Addressed review comments from Christian:
>>      - Fix the wptr_mc_addr calculation (moved into another patch)
>>      Addressed review comments from Alex:
>>      - Do not add fptrs for map/unmap
>>
>> V3: Integration with doorbell manager
>> V4: Rebase
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 67 ++++++++++++++++++++++++++
>>   1 file changed, 67 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
>> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> index 86de35292f69..7a45d68091ec 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> @@ -31,6 +31,7 @@
>>   #include "amdgpu_smu.h"
>>   #include "amdgpu_atomfirmware.h"
>>   #include "amdgpu_userqueue.h"
>> +#include "amdgpu_mes.h"
>>   #include "imu_v11_0.h"
>>   #include "soc21.h"
>>   #include "nvd.h"
>> @@ -6411,6 +6412,64 @@ const struct amdgpu_ip_block_version 
>> gfx_v11_0_ip_block =
>>       .funcs = &gfx_v11_0_ip_funcs,
>>   };
>>   +static int gfx_v11_userq_map(struct amdgpu_userq_mgr *uq_mgr,
>> +                 struct amdgpu_usermode_queue *queue)
>> +{
>> +    struct amdgpu_device *adev = uq_mgr->adev;
>> +    struct mes_add_queue_input queue_input;
>> +    int r;
>> +
>> +    memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
>> +
>> +    queue_input.process_va_start = 0;
>> +    queue_input.process_va_end = (adev->vm_manager.max_pfn - 1) << 
>> AMDGPU_GPU_PAGE_SHIFT;
>
> Could be that this is wrong. What is that value used for?
>
Both start and end are required by MES FW for mapping the MQD. The value 
here is generated same as in KFD userqueue.
>> +    queue_input.process_quantum = 100000; /* 10ms */
>> +    queue_input.gang_quantum = 10000; /* 1ms */
>> +    queue_input.paging = false;
>> +
>> +    queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
>> +    queue_input.process_context_addr = queue->proc_ctx_gpu_addr;
>> +    queue_input.inprocess_gang_priority = 
>> AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
>> +    queue_input.gang_global_priority_level = 
>> AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
>> +
>> +    queue_input.process_id = queue->vm->pasid;
>> +    queue_input.queue_type = queue->queue_type;
>> +    queue_input.mqd_addr = queue->mqd.gpu_addr;
>> +    queue_input.wptr_addr = queue->userq_prop.wptr_gpu_addr;
>> +    queue_input.queue_size = queue->userq_prop.queue_size >> 2;
>> +    queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
>> +    queue_input.page_table_base_addr = 
>> amdgpu_gmc_pd_addr(queue->vm->root.bo);
>
> You need to implement some mechanism to keep those page tables and all 
> resources in place.

I don't get it, would you mind elaborating this please ?

- Shashank

>
> Christian.
>
>> +
>> +    amdgpu_mes_lock(&adev->mes);
>> +    r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
>> +    amdgpu_mes_unlock(&adev->mes);
>> +    if (r) {
>> +        DRM_ERROR("Failed to map queue in HW, err (%d)\n", r);
>> +        return r;
>> +    }
>> +
>> +    DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", 
>> queue->queue_id);
>> +    return 0;
>> +}
>> +
>> +static void gfx_v11_userq_unmap(struct amdgpu_userq_mgr *uq_mgr,
>> +                struct amdgpu_usermode_queue *queue)
>> +{
>> +    struct amdgpu_device *adev = uq_mgr->adev;
>> +    struct mes_remove_queue_input queue_input;
>> +    int r;
>> +
>> +    memset(&queue_input, 0x0, sizeof(struct mes_remove_queue_input));
>> +    queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
>> +    queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
>> +
>> +    amdgpu_mes_lock(&adev->mes);
>> +    r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
>> +    amdgpu_mes_unlock(&adev->mes);
>> +    if (r)
>> +        DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r);
>> +}
>> +
>>   static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr 
>> *uq_mgr,
>>                       struct amdgpu_usermode_queue *queue)
>>   {
>> @@ -6507,6 +6566,13 @@ gfx_v11_userq_mqd_create(struct 
>> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>>         gfx_v11_userq_set_ctx_space(uq_mgr, queue);
>>       amdgpu_bo_unreserve(mqd->obj);
>> +
>> +    /* Map the queue in HW using MES ring */
>> +    r = gfx_v11_userq_map(uq_mgr, queue);
>> +    if (r) {
>> +        DRM_ERROR("Failed to map userqueue (%d)\n", r);
>> +        goto free_ctx;
>> +    }
>>       DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>>       return 0;
>>   @@ -6523,6 +6589,7 @@ gfx_v11_userq_mqd_destroy(struct 
>> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
>>   {
>>       struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>>   +    gfx_v11_userq_unmap(uq_mgr, queue);
>>       gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>>       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>   }
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 08/10] drm/amdgpu: map wptr BO into GART
  2023-04-25 12:36   ` Christian König
@ 2023-04-25 13:33     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 13:33 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav


On 25/04/2023 14:36, Christian König wrote:
> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>> To support oversubscription, MES FW expects WPTR BOs to
>> be mapped into GART, before they are submitted to usermode
>> queues. This patch adds a function for the same.
>>
>> V4: fix the wptr value before mapping lookup (Bas, Christian).
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 90 +++++++++++++++++++
>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        |  1 +
>>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  1 +
>>   3 files changed, 92 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> index e95fb35b0cb5..385cd51b6c96 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> @@ -44,6 +44,89 @@ amdgpu_userqueue_find(struct amdgpu_userq_mgr 
>> *uq_mgr, int qid)
>>       return idr_find(&uq_mgr->userq_idr, qid);
>>   }
>>   +static int
>> +amdgpu_userqueue_map_gtt_bo_to_gart(struct amdgpu_device *adev, 
>> struct amdgpu_bo *bo)
>> +{
>> +    int ret;
>> +
>> +    ret = amdgpu_bo_reserve(bo, true);
>> +    if (ret) {
>> +        DRM_ERROR("Failed to reserve bo. ret %d\n", ret);
>> +        goto err_reserve_bo_failed;
>> +    }
>> +
>> +    ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT);
>> +    if (ret) {
>> +        DRM_ERROR("Failed to pin bo. ret %d\n", ret);
>> +        goto err_pin_bo_failed;
>> +    }
>> +
>> +    ret = amdgpu_ttm_alloc_gart(&bo->tbo);
>> +    if (ret) {
>> +        DRM_ERROR("Failed to bind bo to GART. ret %d\n", ret);
>> +        goto err_map_bo_gart_failed;
>> +    }
>
> Either pinning *or* allocating GART, but not both!
>
> I think calling amdgpu_ttm_alloc_gart() is the right thing to do here.
>
Ah, silly me :), Thanks for pointing this out.

>> +
>> +    amdgpu_bo_unreserve(bo);
>> +    bo = amdgpu_bo_ref(bo);
>> +
>> +    return 0;
>> +
>> +err_map_bo_gart_failed:
>> +    amdgpu_bo_unpin(bo);
>> +err_pin_bo_failed:
>> +    amdgpu_bo_unreserve(bo);
>> +err_reserve_bo_failed:
>> +
>> +    return ret;
>> +}
>> +
>> +
>> +static int
>> +amdgpu_userqueue_create_wptr_mapping(struct amdgpu_device *adev,
>> +                     struct drm_file *filp,
>> +                     struct amdgpu_usermode_queue *queue)
>> +{
>> +    struct amdgpu_bo_va_mapping *wptr_mapping;
>> +    struct amdgpu_vm *wptr_vm;
>> +    struct amdgpu_bo *wptr_bo = NULL;
>> +    uint64_t wptr = queue->userq_prop.wptr_gpu_addr;
>> +    int ret;
>> +
>> +    wptr_vm = queue->vm;
>> +    ret = amdgpu_bo_reserve(wptr_vm->root.bo, false);
>
> All the handling must be done with the VM and all resource locks held.
>
> So this should be something the caller of the function does.

Noted, will add the protections.

- Shashank

>
> Regards,
> Christian.
>
>> +    if (ret)
>> +        goto err_wptr_map_gart;
>> +
>> +    wptr &= AMDGPU_GMC_HOLE_MASK;
>> +    wptr_mapping = amdgpu_vm_bo_lookup_mapping(wptr_vm, wptr >> 
>> PAGE_SHIFT);
>> +    amdgpu_bo_unreserve(wptr_vm->root.bo);
>> +    if (!wptr_mapping) {
>> +        DRM_ERROR("Failed to lookup wptr bo\n");
>> +        ret = -EINVAL;
>> +        goto err_wptr_map_gart;
>> +    }
>> +
>> +    wptr_bo = wptr_mapping->bo_va->base.bo;
>> +    if (wptr_bo->tbo.base.size > PAGE_SIZE) {
>> +        DRM_ERROR("Requested GART mapping for wptr bo larger than 
>> one page\n");
>> +        ret = -EINVAL;
>> +        goto err_wptr_map_gart;
>> +    }
>> +
>> +    ret = amdgpu_userqueue_map_gtt_bo_to_gart(adev, wptr_bo);
>> +    if (ret) {
>> +        DRM_ERROR("Failed to map wptr bo to GART\n");
>> +        goto err_wptr_map_gart;
>> +    }
>> +
>> +    queue->wptr_mc_addr = wptr_bo->tbo.resource->start << PAGE_SHIFT;
>> +    return 0;
>> +
>> +err_wptr_map_gart:
>> +    return ret;
>> +}
>> +
>>   static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union 
>> drm_amdgpu_userq *args)
>>   {
>>       struct amdgpu_usermode_queue *queue;
>> @@ -81,6 +164,13 @@ static int amdgpu_userqueue_create_gfx(struct 
>> drm_file *filp, union drm_amdgpu_u
>>           goto free_queue;
>>       }
>>   +    r = amdgpu_userqueue_create_wptr_mapping(uq_mgr->adev, filp, 
>> queue);
>> +    if (r) {
>> +        DRM_ERROR("Failed to map WPTR (0x%llx) for userqueue\n",
>> +               queue->userq_prop.wptr_gpu_addr);
>> +        goto free_queue;
>> +    }
>> +
>>       if (uq_mgr->userq_funcs[queue->queue_type]->mqd_create) {
>>           r = 
>> uq_mgr->userq_funcs[queue->queue_type]->mqd_create(uq_mgr, queue);
>>           if (r) {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
>> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> index 7a45d68091ec..6eeae0206d8a 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> @@ -6439,6 +6439,7 @@ static int gfx_v11_userq_map(struct 
>> amdgpu_userq_mgr *uq_mgr,
>>       queue_input.queue_size = queue->userq_prop.queue_size >> 2;
>>       queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
>>       queue_input.page_table_base_addr = 
>> amdgpu_gmc_pd_addr(queue->vm->root.bo);
>> +    queue_input.wptr_mc_addr = queue->wptr_mc_addr;
>>         amdgpu_mes_lock(&adev->mes);
>>       r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
>> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h 
>> b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> index 11e8ad649f6e..0001ecd710a7 100644
>> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> @@ -38,6 +38,7 @@ struct amdgpu_usermode_queue {
>>       int            queue_id;
>>       int            queue_type;
>>       uint64_t        doorbell_handle;
>> +    uint64_t        wptr_mc_addr;
>>       uint64_t        proc_ctx_gpu_addr;
>>       uint64_t        gang_ctx_gpu_addr;
>>       uint64_t        gds_ctx_gpu_addr;
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 09/10] drm/amdgpu: generate doorbell index for userqueue
  2023-04-25 12:38   ` Christian König
@ 2023-04-25 13:34     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 13:34 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav


On 25/04/2023 14:38, Christian König wrote:
> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>> The userspace sends us the doorbell object and the doobell index
>> to be used for the usermode queue, but the FW expects the absolute
>> doorbell index on the PCI BAR in the MQD. This patch adds a function
>> to convert this relative doorbell index to the absolute doorbell index.
>>
>> This patch is dependent on the doorbell manager series being reviewed
>> here: https://patchwork.freedesktop.org/series/115802/
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 33 +++++++++++++++++++
>>   1 file changed, 33 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> index 385cd51b6c96..fbc9cb5c24ad 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> @@ -44,6 +44,30 @@ amdgpu_userqueue_find(struct amdgpu_userq_mgr 
>> *uq_mgr, int qid)
>>       return idr_find(&uq_mgr->userq_idr, qid);
>>   }
>>   +static uint64_t
>> +amdgpu_userqueue_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr,
>> +                    struct amdgpu_usermode_queue *queue,
>> +                    struct drm_file *filp,
>> +                    uint32_t doorbell_index)
>> +{
>> +    struct drm_gem_object *gobj;
>> +    struct amdgpu_bo *db_bo;
>> +    uint64_t index;
>> +
>> +    gobj = drm_gem_object_lookup(filp, queue->doorbell_handle);
>> +    if (gobj == NULL) {
>> +        DRM_ERROR("Can't find GEM object for doorbell\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    db_bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
>
> That looks like we are leaking the object reference here.
>
That's correct, I will fix it.

- Shashank

> Christian.
>
>> +    drm_gem_object_put(gobj);
>> +
>> +    index = amdgpu_doorbell_index_on_bar(uq_mgr->adev, db_bo, 
>> doorbell_index);
>> +    DRM_DEBUG_DRIVER("[Usermode queues] doorbell index=%lld\n", index);
>> +    return index;
>> +}
>> +
>>   static int
>>   amdgpu_userqueue_map_gtt_bo_to_gart(struct amdgpu_device *adev, 
>> struct amdgpu_bo *bo)
>>   {
>> @@ -133,6 +157,7 @@ static int amdgpu_userqueue_create_gfx(struct 
>> drm_file *filp, union drm_amdgpu_u
>>       struct amdgpu_fpriv *fpriv = filp->driver_priv;
>>       struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
>>       struct drm_amdgpu_userq_mqd_gfx *mqd_in = &args->in.mqd.gfx;
>> +    uint64_t index;
>>       int r;
>>         /* Do we support usermode queues on this GFX IP ? */
>> @@ -154,6 +179,14 @@ static int amdgpu_userqueue_create_gfx(struct 
>> drm_file *filp, union drm_amdgpu_u
>>       queue->userq_prop.hqd_base_gpu_addr = mqd_in->queue_va;
>>         queue->doorbell_handle = mqd_in->doorbell_handle;
>> +    index = amdgpu_userqueue_get_doorbell_index(uq_mgr, queue, filp, 
>> mqd_in->doorbell_offset);
>> +    if (index == (uint64_t)-EINVAL) {
>> +        DRM_ERROR("Invalid doorbell object\n");
>> +        r = -EINVAL;
>> +        goto free_queue;
>> +    }
>> +
>> +    queue->userq_prop.doorbell_index = index;
>>       queue->queue_type = AMDGPU_HW_IP_GFX;
>>       queue->flags = mqd_in->flags;
>>       queue->vm = &fpriv->vm;
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 10/10] drm/amdgpu: cleanup leftover queues
  2023-04-25 12:40   ` Christian König
@ 2023-04-25 13:34     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 13:34 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav, Bas Nieuwenhuizen


On 25/04/2023 14:40, Christian König wrote:
>
>
> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>> This patch adds code to cleanup any leftover userqueues which
>> a user might have missed to destroy due to a crash or any other
>> programming error.
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Suggested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
>> Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 31 +++++++++++++++----
>>   1 file changed, 25 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> index fbc9cb5c24ad..27201a0b1441 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> @@ -237,6 +237,18 @@ static int amdgpu_userqueue_create(struct 
>> drm_file *filp, union drm_amdgpu_userq
>>       return -EINVAL;
>>   }
>>   +static void
>> +amdgpu_userqueue_cleanup(struct amdgpu_userq_mgr *uq_mgr, struct 
>> amdgpu_usermode_queue *queue)
>> +{
>> +    mutex_lock(&uq_mgr->userq_mutex);
>> +    if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
>> + uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
>> +
>> +    amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
>> +    mutex_unlock(&uq_mgr->userq_mutex);
>> +    kfree(queue);
>> +}
>> +
>>   static void amdgpu_userqueue_destroy(struct drm_file *filp, int 
>> queue_id)
>>   {
>>       struct amdgpu_fpriv *fpriv = filp->driver_priv;
>> @@ -249,12 +261,7 @@ static void amdgpu_userqueue_destroy(struct 
>> drm_file *filp, int queue_id)
>>           return;
>>       }
>>   -    mutex_lock(&uq_mgr->userq_mutex);
>> -    if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
>> - uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
>> -    amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
>> -    mutex_unlock(&uq_mgr->userq_mutex);
>> -    kfree(queue);
>> +    amdgpu_userqueue_cleanup(uq_mgr, queue);
>>   }
>>     int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
>> @@ -307,8 +314,20 @@ int amdgpu_userq_mgr_init(struct 
>> amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi
>>       return 0;
>>   }
>>   +static void amdgpu_userqueue_cleanup_residue(int queue_id, void 
>> *ptr, void *data)
>> +{
>> +    struct amdgpu_userq_mgr *uq_mgr = data;
>> +    struct amdgpu_usermode_queue *queue = ptr;
>> +
>> +    amdgpu_userqueue_cleanup(uq_mgr, queue);
>> +}
>> +
>>   void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr)
>>   {
>> +    idr_for_each(&userq_mgr->userq_idr,
>> +             amdgpu_userqueue_cleanup_residue,
>> +             userq_mgr);
>> +
>
> Better use idr_for_each_entry() here.

Noted, will update it.

- Shashank

>
> Christian.
>> idr_destroy(&userq_mgr->userq_idr);
>>       mutex_destroy(&userq_mgr->userq_mutex);
>>   }
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue
  2023-04-25 13:10     ` Shashank Sharma
@ 2023-04-25 13:45       ` Christian König
  2023-04-25 17:02         ` Shashank Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 13:45 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav

Am 25.04.23 um 15:10 schrieb Shashank Sharma:
>
> On 25/04/2023 14:27, Christian König wrote:
>> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>>> A Memory queue descriptor (MQD) of a userqueue defines it in
>>> the hw's context. As MQD format can vary between different
>>> graphics IPs, we need gfx GEN specific handlers to create MQDs.
>>>
>>> This patch:
>>> - Introduces MQD handler functions for the usermode queues.
>>> - Adds new functions to create and destroy userqueue MQD for
>>>    GFX-GEN-11 IP
>>>
>>> V1: Worked on review comments from Alex:
>>>      - Make MQD functions GEN and IP specific
>>>
>>> V2: Worked on review comments from Alex:
>>>      - Reuse the existing adev->mqd[ip] for MQD creation
>>>      - Formatting and arrangement of code
>>>
>>> V3:
>>>      - Integration with doorbell manager
>>>
>>> V4: Review comments addressed:
>>>      - Do not create a new file for userq, reuse gfx_v11_0.c (Alex)
>>>      - Align name of structure members (Luben)
>>>      - Don't break up the Cc tag list and the Sob tag list in commit
>>>        message (Luben)
>>>
>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>> Cc: Christian Koenig <christian.koenig@amd.com>
>>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>>> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
>>> ---
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 25 ++++++++
>>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 
>>> +++++++++++++++++++
>>>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  7 +++
>>>   3 files changed, 89 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>>> index 333f31efbe7b..e95fb35b0cb5 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>>> @@ -81,6 +81,14 @@ static int amdgpu_userqueue_create_gfx(struct 
>>> drm_file *filp, union drm_amdgpu_u
>>>           goto free_queue;
>>>       }
>>>   +    if (uq_mgr->userq_funcs[queue->queue_type]->mqd_create) {
>>> +        r = 
>>> uq_mgr->userq_funcs[queue->queue_type]->mqd_create(uq_mgr, queue);
>>> +        if (r) {
>>> +            DRM_ERROR("Failed to create/map userqueue MQD\n");
>>> +            goto free_queue;
>>> +        }
>>> +    }
>>> +
>>>       args->out.queue_id = queue->queue_id;
>>>       args->out.flags = 0;
>>>       mutex_unlock(&uq_mgr->userq_mutex);
>>> @@ -119,6 +127,8 @@ static void amdgpu_userqueue_destroy(struct 
>>> drm_file *filp, int queue_id)
>>>       }
>>>         mutex_lock(&uq_mgr->userq_mutex);
>>> +    if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
>>> + uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
>>>       amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
>>>       mutex_unlock(&uq_mgr->userq_mutex);
>>>       kfree(queue);
>>> @@ -149,6 +159,20 @@ int amdgpu_userq_ioctl(struct drm_device *dev, 
>>> void *data,
>>>       return r;
>>>   }
>>>   +extern const struct amdgpu_userq_funcs userq_gfx_v11_funcs;
>>> +
>>> +static void
>>> +amdgpu_userqueue_setup_ip_funcs(struct amdgpu_userq_mgr *uq_mgr)
>>> +{
>>> +    int maj;
>>> +    struct amdgpu_device *adev = uq_mgr->adev;
>>> +    uint32_t version = adev->ip_versions[GC_HWIP][0];
>>> +
>>> +    /* We support usermode queue only for GFX IP as of now */
>>> +    maj = IP_VERSION_MAJ(version);
>>> +    if (maj == 11)
>>> +        uq_mgr->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_gfx_v11_funcs;
>>> +}
>>>     int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, 
>>> struct amdgpu_device *adev)
>>>   {
>>> @@ -156,6 +180,7 @@ int amdgpu_userq_mgr_init(struct 
>>> amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi
>>>       idr_init_base(&userq_mgr->userq_idr, 1);
>>>       userq_mgr->adev = adev;
>>>   +    amdgpu_userqueue_setup_ip_funcs(userq_mgr);
>>>       return 0;
>>>   }
>>>   diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
>>> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>> index a56c6e106d00..9f7b14966ac8 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>> @@ -30,6 +30,7 @@
>>>   #include "amdgpu_psp.h"
>>>   #include "amdgpu_smu.h"
>>>   #include "amdgpu_atomfirmware.h"
>>> +#include "amdgpu_userqueue.h"
>>>   #include "imu_v11_0.h"
>>>   #include "soc21.h"
>>>   #include "nvd.h"
>>> @@ -6404,3 +6405,59 @@ const struct amdgpu_ip_block_version 
>>> gfx_v11_0_ip_block =
>>>       .rev = 0,
>>>       .funcs = &gfx_v11_0_ip_funcs,
>>>   };
>>> +
>>> +static int
>>> +gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct 
>>> amdgpu_usermode_queue *queue)
>>> +{
>>> +    struct amdgpu_device *adev = uq_mgr->adev;
>>> +    struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>>> +    struct amdgpu_mqd *gfx_v11_mqd = &adev->mqds[queue->queue_type];
>>> +    int size = gfx_v11_mqd->mqd_size;
>>> +    int r;
>>> +
>>> +    r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
>>> +                    AMDGPU_GEM_DOMAIN_GTT,
>>> +                    &mqd->obj,
>>> +                    &mqd->gpu_addr,
>>> +                    &mqd->cpu_ptr);
>>> +    if (r) {
>>> +        DRM_ERROR("Failed to allocate bo for userqueue (%d)", r);
>>> +        return r;
>>> +    }
>>> +
>>> +    memset(mqd->cpu_ptr, 0, size);
>>> +    r = amdgpu_bo_reserve(mqd->obj, false);
>>> +    if (unlikely(r != 0)) {
>>> +        DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
>>> +        goto free_mqd;
>>> +    }
>>
>> This reserve/unreserve dance here doesn't seem to make much sense. 
>> Why do you do that?
> We wanted to make sure that the MQD buffer is reserved until we fill 
> it. Does it sound incorrect ?

Yeah, that sounds strongly like we have some misunderstanding.

Reserving a buffer is needed for two thing:
1. Prevent that it moves around.
2. Change some parameters of the BO.

Since the BO is a pinned kernel BO neither of those two use cases seems 
to be the case here.

So why do you reserve the BO here?

>>
>> Christian.
>>
>>> +
>>> +    queue->userq_prop.use_doorbell = true;
>>> +    queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
>>
>> Are those the only two parameters needed? If yes we should probably 
>> drop the userq_prop structure and give them directly.
> In patch set 1 and 2, everything was getting stored directly in the 
> queue, but then we decided to re-use the existing init_mqd() functions 
> from each of the IP engines.
>
> If you see the prototype of mqd->init_mqd(), it expects userq_prop 
> structure as input parameters, so we encapsulated a subset of queue to 
> this structure.

Yeah, the question is if the init_mqd() interface is a good idea or if 
we should re-work that as well?

Christian.

>
> - Shashank
>
>>
>> Christian.
>>
>>> +    r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, 
>>> &queue->userq_prop);
>>> +    amdgpu_bo_unreserve(mqd->obj);
>>> +    if (r) {
>>> +        DRM_ERROR("Failed to init MQD for queue\n");
>>> +        goto free_mqd;
>>> +    }
>>> +
>>> +    DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>>> +    return 0;
>>> +
>>> +free_mqd:
>>> +    amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>> +    return r;
>>> +}
>>> +
>>> +static void
>>> +gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct 
>>> amdgpu_usermode_queue *queue)
>>> +{
>>> +    struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>>> +
>>> +    amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>> +}
>>> +
>>> +const struct amdgpu_userq_funcs userq_gfx_v11_funcs = {
>>> +    .mqd_create = gfx_v11_userq_mqd_create,
>>> +    .mqd_destroy = gfx_v11_userq_mqd_destroy,
>>> +};
>>> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h 
>>> b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>>> index 8d8f6b3bcda5..e7da27918bd2 100644
>>> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>>> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>>> @@ -28,6 +28,12 @@
>>>   #include "amdgpu.h"
>>>   #define AMDGPU_MAX_USERQ 512
>>>   +struct amdgpu_userq_ctx_space {
>>> +    uint64_t     gpu_addr;
>>> +    void         *cpu_ptr;
>>> +    struct amdgpu_bo *obj;
>>> +};
>>> +
>>>   struct amdgpu_usermode_queue {
>>>       int            queue_id;
>>>       int            queue_type;
>>> @@ -36,6 +42,7 @@ struct amdgpu_usermode_queue {
>>>       struct amdgpu_mqd_prop    userq_prop;
>>>       struct amdgpu_userq_mgr *userq_mgr;
>>>       struct amdgpu_vm    *vm;
>>> +    struct amdgpu_userq_ctx_space mqd;
>>>   };
>>>     struct amdgpu_userq_funcs {
>>


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES
  2023-04-25 13:31     ` Shashank Sharma
@ 2023-04-25 15:33       ` Christian König
  2023-04-25 16:56         ` Shashank Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Christian König @ 2023-04-25 15:33 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav

Am 25.04.23 um 15:31 schrieb Shashank Sharma:
>
> On 25/04/2023 14:34, Christian König wrote:
>> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>>> This patch adds new functions to map/unmap a usermode queue into
>>> the FW, using the MES ring. As soon as this mapping is done, the
>>> queue would  be considered ready to accept the workload.
>>>
>>> V1: Addressed review comments from Alex on the RFC patch series
>>>      - Map/Unmap should be IP specific.
>>> V2:
>>>      Addressed review comments from Christian:
>>>      - Fix the wptr_mc_addr calculation (moved into another patch)
>>>      Addressed review comments from Alex:
>>>      - Do not add fptrs for map/unmap
>>>
>>> V3: Integration with doorbell manager
>>> V4: Rebase
>>>
>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>> Cc: Christian Koenig <christian.koenig@amd.com>
>>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>>> ---
>>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 67 
>>> ++++++++++++++++++++++++++
>>>   1 file changed, 67 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
>>> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>> index 86de35292f69..7a45d68091ec 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>> @@ -31,6 +31,7 @@
>>>   #include "amdgpu_smu.h"
>>>   #include "amdgpu_atomfirmware.h"
>>>   #include "amdgpu_userqueue.h"
>>> +#include "amdgpu_mes.h"
>>>   #include "imu_v11_0.h"
>>>   #include "soc21.h"
>>>   #include "nvd.h"
>>> @@ -6411,6 +6412,64 @@ const struct amdgpu_ip_block_version 
>>> gfx_v11_0_ip_block =
>>>       .funcs = &gfx_v11_0_ip_funcs,
>>>   };
>>>   +static int gfx_v11_userq_map(struct amdgpu_userq_mgr *uq_mgr,
>>> +                 struct amdgpu_usermode_queue *queue)
>>> +{
>>> +    struct amdgpu_device *adev = uq_mgr->adev;
>>> +    struct mes_add_queue_input queue_input;
>>> +    int r;
>>> +
>>> +    memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
>>> +
>>> +    queue_input.process_va_start = 0;
>>> +    queue_input.process_va_end = (adev->vm_manager.max_pfn - 1) << 
>>> AMDGPU_GPU_PAGE_SHIFT;
>>
>> Could be that this is wrong. What is that value used for?
>>
> Both start and end are required by MES FW for mapping the MQD. The 
> value here is generated same as in KFD userqueue.

Ok in this case then that's probably the values which will be written 
into the registers. So that's probably ok.

>>> +    queue_input.process_quantum = 100000; /* 10ms */
>>> +    queue_input.gang_quantum = 10000; /* 1ms */
>>> +    queue_input.paging = false;
>>> +
>>> +    queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
>>> +    queue_input.process_context_addr = queue->proc_ctx_gpu_addr;
>>> +    queue_input.inprocess_gang_priority = 
>>> AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
>>> +    queue_input.gang_global_priority_level = 
>>> AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
>>> +
>>> +    queue_input.process_id = queue->vm->pasid;
>>> +    queue_input.queue_type = queue->queue_type;
>>> +    queue_input.mqd_addr = queue->mqd.gpu_addr;
>>> +    queue_input.wptr_addr = queue->userq_prop.wptr_gpu_addr;
>>> +    queue_input.queue_size = queue->userq_prop.queue_size >> 2;
>>> +    queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
>>> +    queue_input.page_table_base_addr = 
>>> amdgpu_gmc_pd_addr(queue->vm->root.bo);
>>
>> You need to implement some mechanism to keep those page tables and 
>> all resources in place.
>
> I don't get it, would you mind elaborating this please ?

We need something like the KFD eviction fence. Probably best if we have 
a call on that.

Christian.

>
> - Shashank
>
>>
>> Christian.
>>
>>> +
>>> +    amdgpu_mes_lock(&adev->mes);
>>> +    r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
>>> +    amdgpu_mes_unlock(&adev->mes);
>>> +    if (r) {
>>> +        DRM_ERROR("Failed to map queue in HW, err (%d)\n", r);
>>> +        return r;
>>> +    }
>>> +
>>> +    DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", 
>>> queue->queue_id);
>>> +    return 0;
>>> +}
>>> +
>>> +static void gfx_v11_userq_unmap(struct amdgpu_userq_mgr *uq_mgr,
>>> +                struct amdgpu_usermode_queue *queue)
>>> +{
>>> +    struct amdgpu_device *adev = uq_mgr->adev;
>>> +    struct mes_remove_queue_input queue_input;
>>> +    int r;
>>> +
>>> +    memset(&queue_input, 0x0, sizeof(struct mes_remove_queue_input));
>>> +    queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
>>> +    queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
>>> +
>>> +    amdgpu_mes_lock(&adev->mes);
>>> +    r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
>>> +    amdgpu_mes_unlock(&adev->mes);
>>> +    if (r)
>>> +        DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r);
>>> +}
>>> +
>>>   static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr 
>>> *uq_mgr,
>>>                       struct amdgpu_usermode_queue *queue)
>>>   {
>>> @@ -6507,6 +6566,13 @@ gfx_v11_userq_mqd_create(struct 
>>> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>>>         gfx_v11_userq_set_ctx_space(uq_mgr, queue);
>>>       amdgpu_bo_unreserve(mqd->obj);
>>> +
>>> +    /* Map the queue in HW using MES ring */
>>> +    r = gfx_v11_userq_map(uq_mgr, queue);
>>> +    if (r) {
>>> +        DRM_ERROR("Failed to map userqueue (%d)\n", r);
>>> +        goto free_ctx;
>>> +    }
>>>       DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>>>       return 0;
>>>   @@ -6523,6 +6589,7 @@ gfx_v11_userq_mqd_destroy(struct 
>>> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
>>>   {
>>>       struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>>>   +    gfx_v11_userq_unmap(uq_mgr, queue);
>>>       gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>>>       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>>   }
>>


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES
  2023-04-25 15:33       ` Christian König
@ 2023-04-25 16:56         ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 16:56 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav


On 25/04/2023 17:33, Christian König wrote:
> Am 25.04.23 um 15:31 schrieb Shashank Sharma:
>>
>> On 25/04/2023 14:34, Christian König wrote:
>>> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>>>> This patch adds new functions to map/unmap a usermode queue into
>>>> the FW, using the MES ring. As soon as this mapping is done, the
>>>> queue would  be considered ready to accept the workload.
>>>>
>>>> V1: Addressed review comments from Alex on the RFC patch series
>>>>      - Map/Unmap should be IP specific.
>>>> V2:
>>>>      Addressed review comments from Christian:
>>>>      - Fix the wptr_mc_addr calculation (moved into another patch)
>>>>      Addressed review comments from Alex:
>>>>      - Do not add fptrs for map/unmap
>>>>
>>>> V3: Integration with doorbell manager
>>>> V4: Rebase
>>>>
>>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>>> Cc: Christian Koenig <christian.koenig@amd.com>
>>>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>>>> ---
>>>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 67 
>>>> ++++++++++++++++++++++++++
>>>>   1 file changed, 67 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
>>>> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>>> index 86de35292f69..7a45d68091ec 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>>> @@ -31,6 +31,7 @@
>>>>   #include "amdgpu_smu.h"
>>>>   #include "amdgpu_atomfirmware.h"
>>>>   #include "amdgpu_userqueue.h"
>>>> +#include "amdgpu_mes.h"
>>>>   #include "imu_v11_0.h"
>>>>   #include "soc21.h"
>>>>   #include "nvd.h"
>>>> @@ -6411,6 +6412,64 @@ const struct amdgpu_ip_block_version 
>>>> gfx_v11_0_ip_block =
>>>>       .funcs = &gfx_v11_0_ip_funcs,
>>>>   };
>>>>   +static int gfx_v11_userq_map(struct amdgpu_userq_mgr *uq_mgr,
>>>> +                 struct amdgpu_usermode_queue *queue)
>>>> +{
>>>> +    struct amdgpu_device *adev = uq_mgr->adev;
>>>> +    struct mes_add_queue_input queue_input;
>>>> +    int r;
>>>> +
>>>> +    memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
>>>> +
>>>> +    queue_input.process_va_start = 0;
>>>> +    queue_input.process_va_end = (adev->vm_manager.max_pfn - 1) << 
>>>> AMDGPU_GPU_PAGE_SHIFT;
>>>
>>> Could be that this is wrong. What is that value used for?
>>>
>> Both start and end are required by MES FW for mapping the MQD. The 
>> value here is generated same as in KFD userqueue.
>
> Ok in this case then that's probably the values which will be written 
> into the registers. So that's probably ok.
>
>>>> +    queue_input.process_quantum = 100000; /* 10ms */
>>>> +    queue_input.gang_quantum = 10000; /* 1ms */
>>>> +    queue_input.paging = false;
>>>> +
>>>> +    queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
>>>> +    queue_input.process_context_addr = queue->proc_ctx_gpu_addr;
>>>> +    queue_input.inprocess_gang_priority = 
>>>> AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
>>>> +    queue_input.gang_global_priority_level = 
>>>> AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
>>>> +
>>>> +    queue_input.process_id = queue->vm->pasid;
>>>> +    queue_input.queue_type = queue->queue_type;
>>>> +    queue_input.mqd_addr = queue->mqd.gpu_addr;
>>>> +    queue_input.wptr_addr = queue->userq_prop.wptr_gpu_addr;
>>>> +    queue_input.queue_size = queue->userq_prop.queue_size >> 2;
>>>> +    queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
>>>> +    queue_input.page_table_base_addr = 
>>>> amdgpu_gmc_pd_addr(queue->vm->root.bo);
>>>
>>> You need to implement some mechanism to keep those page tables and 
>>> all resources in place.
>>
>> I don't get it, would you mind elaborating this please ?
>
> We need something like the KFD eviction fence. Probably best if we 
> have a call on that.

Noted,

- Shashank

>
> Christian.
>
>>
>> - Shashank
>>
>>>
>>> Christian.
>>>
>>>> +
>>>> +    amdgpu_mes_lock(&adev->mes);
>>>> +    r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
>>>> +    amdgpu_mes_unlock(&adev->mes);
>>>> +    if (r) {
>>>> +        DRM_ERROR("Failed to map queue in HW, err (%d)\n", r);
>>>> +        return r;
>>>> +    }
>>>> +
>>>> +    DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", 
>>>> queue->queue_id);
>>>> +    return 0;
>>>> +}
>>>> +
>>>> +static void gfx_v11_userq_unmap(struct amdgpu_userq_mgr *uq_mgr,
>>>> +                struct amdgpu_usermode_queue *queue)
>>>> +{
>>>> +    struct amdgpu_device *adev = uq_mgr->adev;
>>>> +    struct mes_remove_queue_input queue_input;
>>>> +    int r;
>>>> +
>>>> +    memset(&queue_input, 0x0, sizeof(struct mes_remove_queue_input));
>>>> +    queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
>>>> +    queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
>>>> +
>>>> +    amdgpu_mes_lock(&adev->mes);
>>>> +    r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
>>>> +    amdgpu_mes_unlock(&adev->mes);
>>>> +    if (r)
>>>> +        DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r);
>>>> +}
>>>> +
>>>>   static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr 
>>>> *uq_mgr,
>>>>                       struct amdgpu_usermode_queue *queue)
>>>>   {
>>>> @@ -6507,6 +6566,13 @@ gfx_v11_userq_mqd_create(struct 
>>>> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>>>>         gfx_v11_userq_set_ctx_space(uq_mgr, queue);
>>>>       amdgpu_bo_unreserve(mqd->obj);
>>>> +
>>>> +    /* Map the queue in HW using MES ring */
>>>> +    r = gfx_v11_userq_map(uq_mgr, queue);
>>>> +    if (r) {
>>>> +        DRM_ERROR("Failed to map userqueue (%d)\n", r);
>>>> +        goto free_ctx;
>>>> +    }
>>>>       DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>>>>       return 0;
>>>>   @@ -6523,6 +6589,7 @@ gfx_v11_userq_mqd_destroy(struct 
>>>> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
>>>>   {
>>>>       struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>>>>   +    gfx_v11_userq_unmap(uq_mgr, queue);
>>>>       gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>>>>       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>>>   }
>>>
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue
  2023-04-25 13:45       ` Christian König
@ 2023-04-25 17:02         ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-04-25 17:02 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, pierre-eric.pelloux-prayer, contactshashanksharma,
	arvind.yadav


On 25/04/2023 15:45, Christian König wrote:
> Am 25.04.23 um 15:10 schrieb Shashank Sharma:
>>
>> On 25/04/2023 14:27, Christian König wrote:
>>> Am 24.04.23 um 19:38 schrieb Shashank Sharma:
>>>> A Memory queue descriptor (MQD) of a userqueue defines it in
>>>> the hw's context. As MQD format can vary between different
>>>> graphics IPs, we need gfx GEN specific handlers to create MQDs.
>>>>
>>>> This patch:
>>>> - Introduces MQD handler functions for the usermode queues.
>>>> - Adds new functions to create and destroy userqueue MQD for
>>>>    GFX-GEN-11 IP
>>>>
>>>> V1: Worked on review comments from Alex:
>>>>      - Make MQD functions GEN and IP specific
>>>>
>>>> V2: Worked on review comments from Alex:
>>>>      - Reuse the existing adev->mqd[ip] for MQD creation
>>>>      - Formatting and arrangement of code
>>>>
>>>> V3:
>>>>      - Integration with doorbell manager
>>>>
>>>> V4: Review comments addressed:
>>>>      - Do not create a new file for userq, reuse gfx_v11_0.c (Alex)
>>>>      - Align name of structure members (Luben)
>>>>      - Don't break up the Cc tag list and the Sob tag list in commit
>>>>        message (Luben)
>>>>
>>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>>> Cc: Christian Koenig <christian.koenig@amd.com>
>>>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>>>> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
>>>> ---
>>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 25 ++++++++
>>>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 
>>>> +++++++++++++++++++
>>>>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  7 +++
>>>>   3 files changed, 89 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c 
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>>>> index 333f31efbe7b..e95fb35b0cb5 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>>>> @@ -81,6 +81,14 @@ static int amdgpu_userqueue_create_gfx(struct 
>>>> drm_file *filp, union drm_amdgpu_u
>>>>           goto free_queue;
>>>>       }
>>>>   +    if (uq_mgr->userq_funcs[queue->queue_type]->mqd_create) {
>>>> +        r = 
>>>> uq_mgr->userq_funcs[queue->queue_type]->mqd_create(uq_mgr, queue);
>>>> +        if (r) {
>>>> +            DRM_ERROR("Failed to create/map userqueue MQD\n");
>>>> +            goto free_queue;
>>>> +        }
>>>> +    }
>>>> +
>>>>       args->out.queue_id = queue->queue_id;
>>>>       args->out.flags = 0;
>>>>       mutex_unlock(&uq_mgr->userq_mutex);
>>>> @@ -119,6 +127,8 @@ static void amdgpu_userqueue_destroy(struct 
>>>> drm_file *filp, int queue_id)
>>>>       }
>>>>         mutex_lock(&uq_mgr->userq_mutex);
>>>> +    if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
>>>> + uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
>>>>       amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
>>>>       mutex_unlock(&uq_mgr->userq_mutex);
>>>>       kfree(queue);
>>>> @@ -149,6 +159,20 @@ int amdgpu_userq_ioctl(struct drm_device *dev, 
>>>> void *data,
>>>>       return r;
>>>>   }
>>>>   +extern const struct amdgpu_userq_funcs userq_gfx_v11_funcs;
>>>> +
>>>> +static void
>>>> +amdgpu_userqueue_setup_ip_funcs(struct amdgpu_userq_mgr *uq_mgr)
>>>> +{
>>>> +    int maj;
>>>> +    struct amdgpu_device *adev = uq_mgr->adev;
>>>> +    uint32_t version = adev->ip_versions[GC_HWIP][0];
>>>> +
>>>> +    /* We support usermode queue only for GFX IP as of now */
>>>> +    maj = IP_VERSION_MAJ(version);
>>>> +    if (maj == 11)
>>>> +        uq_mgr->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_gfx_v11_funcs;
>>>> +}
>>>>     int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, 
>>>> struct amdgpu_device *adev)
>>>>   {
>>>> @@ -156,6 +180,7 @@ int amdgpu_userq_mgr_init(struct 
>>>> amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi
>>>>       idr_init_base(&userq_mgr->userq_idr, 1);
>>>>       userq_mgr->adev = adev;
>>>>   +    amdgpu_userqueue_setup_ip_funcs(userq_mgr);
>>>>       return 0;
>>>>   }
>>>>   diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
>>>> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>>> index a56c6e106d00..9f7b14966ac8 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>>>> @@ -30,6 +30,7 @@
>>>>   #include "amdgpu_psp.h"
>>>>   #include "amdgpu_smu.h"
>>>>   #include "amdgpu_atomfirmware.h"
>>>> +#include "amdgpu_userqueue.h"
>>>>   #include "imu_v11_0.h"
>>>>   #include "soc21.h"
>>>>   #include "nvd.h"
>>>> @@ -6404,3 +6405,59 @@ const struct amdgpu_ip_block_version 
>>>> gfx_v11_0_ip_block =
>>>>       .rev = 0,
>>>>       .funcs = &gfx_v11_0_ip_funcs,
>>>>   };
>>>> +
>>>> +static int
>>>> +gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct 
>>>> amdgpu_usermode_queue *queue)
>>>> +{
>>>> +    struct amdgpu_device *adev = uq_mgr->adev;
>>>> +    struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>>>> +    struct amdgpu_mqd *gfx_v11_mqd = &adev->mqds[queue->queue_type];
>>>> +    int size = gfx_v11_mqd->mqd_size;
>>>> +    int r;
>>>> +
>>>> +    r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
>>>> +                    AMDGPU_GEM_DOMAIN_GTT,
>>>> +                    &mqd->obj,
>>>> +                    &mqd->gpu_addr,
>>>> +                    &mqd->cpu_ptr);
>>>> +    if (r) {
>>>> +        DRM_ERROR("Failed to allocate bo for userqueue (%d)", r);
>>>> +        return r;
>>>> +    }
>>>> +
>>>> +    memset(mqd->cpu_ptr, 0, size);
>>>> +    r = amdgpu_bo_reserve(mqd->obj, false);
>>>> +    if (unlikely(r != 0)) {
>>>> +        DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
>>>> +        goto free_mqd;
>>>> +    }
>>>
>>> This reserve/unreserve dance here doesn't seem to make much sense. 
>>> Why do you do that?
>> We wanted to make sure that the MQD buffer is reserved until we fill 
>> it. Does it sound incorrect ?
>
> Yeah, that sounds strongly like we have some misunderstanding.
>
> Reserving a buffer is needed for two thing:
> 1. Prevent that it moves around.
> 2. Change some parameters of the BO.
>
> Since the BO is a pinned kernel BO neither of those two use cases 
> seems to be the case here.
>
> So why do you reserve the BO here?
>
I guess I missed the fact that Kernel BOs are already pinned, so we 
don't need this. I will remove this.

>>>
>>> Christian.
>>>
>>>> +
>>>> +    queue->userq_prop.use_doorbell = true;
>>>> +    queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
>>>
>>> Are those the only two parameters needed? If yes we should probably 
>>> drop the userq_prop structure and give them directly.
>> In patch set 1 and 2, everything was getting stored directly in the 
>> queue, but then we decided to re-use the existing init_mqd() 
>> functions from each of the IP engines.
>>
>> If you see the prototype of mqd->init_mqd(), it expects userq_prop 
>> structure as input parameters, so we encapsulated a subset of queue 
>> to this structure.
>
> Yeah, the question is if the init_mqd() interface is a good idea or if 
> we should re-work that as well?

I think is a good idea and we should keep it. This makes sure that the 
same code gets executed with both usermode_queue MQD initialization and 
kernel level/KIQ queue init.

- Shashank

>
> Christian.
>
>>
>> - Shashank
>>
>>>
>>> Christian.
>>>
>>>> +    r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, 
>>>> &queue->userq_prop);
>>>> +    amdgpu_bo_unreserve(mqd->obj);
>>>> +    if (r) {
>>>> +        DRM_ERROR("Failed to init MQD for queue\n");
>>>> +        goto free_mqd;
>>>> +    }
>>>> +
>>>> +    DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>>>> +    return 0;
>>>> +
>>>> +free_mqd:
>>>> +    amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>>> +    return r;
>>>> +}
>>>> +
>>>> +static void
>>>> +gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct 
>>>> amdgpu_usermode_queue *queue)
>>>> +{
>>>> +    struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>>>> +
>>>> +    amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>>> +}
>>>> +
>>>> +const struct amdgpu_userq_funcs userq_gfx_v11_funcs = {
>>>> +    .mqd_create = gfx_v11_userq_mqd_create,
>>>> +    .mqd_destroy = gfx_v11_userq_mqd_destroy,
>>>> +};
>>>> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h 
>>>> b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>>>> index 8d8f6b3bcda5..e7da27918bd2 100644
>>>> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>>>> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>>>> @@ -28,6 +28,12 @@
>>>>   #include "amdgpu.h"
>>>>   #define AMDGPU_MAX_USERQ 512
>>>>   +struct amdgpu_userq_ctx_space {
>>>> +    uint64_t     gpu_addr;
>>>> +    void         *cpu_ptr;
>>>> +    struct amdgpu_bo *obj;
>>>> +};
>>>> +
>>>>   struct amdgpu_usermode_queue {
>>>>       int            queue_id;
>>>>       int            queue_type;
>>>> @@ -36,6 +42,7 @@ struct amdgpu_usermode_queue {
>>>>       struct amdgpu_mqd_prop    userq_prop;
>>>>       struct amdgpu_userq_mgr *userq_mgr;
>>>>       struct amdgpu_vm    *vm;
>>>> +    struct amdgpu_userq_ctx_space mqd;
>>>>   };
>>>>     struct amdgpu_userq_funcs {
>>>
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue
  2023-04-25 13:13     ` Shashank Sharma
@ 2023-04-25 17:38       ` Deucher, Alexander
  2023-04-25 20:00         ` Sharma, Shashank
  0 siblings, 1 reply; 45+ messages in thread
From: Deucher, Alexander @ 2023-04-25 17:38 UTC (permalink / raw)
  To: Sharma, Shashank, Koenig, Christian,
	amd-gfx@lists.freedesktop.org
  Cc: Pelloux-Prayer, Pierre-Eric, contactshashanksharma@gmail.com,
	Yadav, Arvind

[Public]

> -----Original Message-----
> From: Sharma, Shashank <Shashank.Sharma@amd.com>
> Sent: Tuesday, April 25, 2023 9:13 AM
> To: Koenig, Christian <Christian.Koenig@amd.com>; amd-
> gfx@lists.freedesktop.org
> Cc: Yadav, Arvind <Arvind.Yadav@amd.com>; Pelloux-Prayer, Pierre-Eric
> <Pierre-eric.Pelloux-prayer@amd.com>;
> contactshashanksharma@gmail.com; Deucher, Alexander
> <Alexander.Deucher@amd.com>
> Subject: Re: [PATCH v4 05/10] drm/amdgpu: create context space for
> usermode queue
> 
> 
> On 25/04/2023 14:30, Christian König wrote:
> > Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> >> The FW expects us to allocate at least one page as context space to
> >> process gang, process, GDS and FW  related work.
> >> This patch creates a joint object for the same, and calculates GPU
> >> space offsets for each of these spaces.
> >>
> >> V1: Addressed review comments on RFC patch:
> >>      Alex: Make this function IP specific
> >>
> >> V2: Addressed review comments from Christian
> >>      - Allocate only one object for total FW space, and calculate
> >>        offsets for each of these objects.
> >>
> >> V3: Integration with doorbell manager
> >> V4: Review comments:
> >>      - Remove shadow from FW space list from cover letter (Alex)
> >>      - Alignment of macro (Luben)
> >>
> >> Cc: Alex Deucher <alexander.deucher@amd.com>
> >> Cc: Christian Koenig <christian.koenig@amd.com>
> >> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> >> ---
> >>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57
> >> ++++++++++++++++++-
> >>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  6 ++
> >>   2 files changed, 61 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> >> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> >> index 9f7b14966ac8..f6b33faea86f 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> >> @@ -53,6 +53,11 @@
> >>   #define GFX11_NUM_GFX_RINGS        1
> >>   #define GFX11_MEC_HPD_SIZE    2048
> >>   +#define AMDGPU_USERQ_PROC_CTX_SZ   PAGE_SIZE
> >> +#define AMDGPU_USERQ_GANG_CTX_SZ   PAGE_SIZE #define
> >> +AMDGPU_USERQ_FW_CTX_SZ     PAGE_SIZE #define
> AMDGPU_USERQ_GDS_CTX_SZ
> >> +PAGE_SIZE
> >> +
> >>   #define RLCG_UCODE_LOADING_START_ADDRESS    0x00002000L
> >>   #define RLC_PG_DELAY_3_DEFAULT_GC_11_0_1    0x1388
> >>   @@ -6406,6 +6411,44 @@ const struct amdgpu_ip_block_version
> >> gfx_v11_0_ip_block =
> >>       .funcs = &gfx_v11_0_ip_funcs,
> >>   };
> >>   +static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr
> >> *uq_mgr,
> >> +                      struct amdgpu_usermode_queue *queue) {
> >> +    struct amdgpu_device *adev = uq_mgr->adev;
> >> +    struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
> >> +    int r, size;
> >> +
> >> +    /*
> >> +     * The FW expects at least one page space allocated for
> >> +     * process ctx, gang ctx, gds ctx, fw ctx each.
> >> +     */
> >> +    size = AMDGPU_USERQ_PROC_CTX_SZ +
> AMDGPU_USERQ_FW_CTX_SZ +
> >> +           AMDGPU_USERQ_GANG_CTX_SZ +
> AMDGPU_USERQ_GDS_CTX_SZ;
> >> +    r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
> >> +                    AMDGPU_GEM_DOMAIN_GTT,
> >> +                    &ctx->obj,
> >> +                    &ctx->gpu_addr,
> >> +                    &ctx->cpu_ptr);
> >
> > Wasn't this stuff provided by userspace now?
> >
> The last I checked, only the shadow buffer was coming from userspace, and
> we were thinking about other stuff. I might not be well updated if there any
> recent development here with the short term solution.

CSA, GDS backup, and shadow are allocated by userspace now.

Alex

> 
> - Shashank
> 
> > Christian.
> >
> >> +    if (r) {
> >> +        DRM_ERROR("Failed to allocate ctx space bo for userqueue,
> >> err:%d\n", r);
> >> +        return r;
> >> +    }
> >> +
> >> +    queue->proc_ctx_gpu_addr = ctx->gpu_addr;
> >> +    queue->gang_ctx_gpu_addr = queue->proc_ctx_gpu_addr +
> >> AMDGPU_USERQ_PROC_CTX_SZ;
> >> +    queue->fw_ctx_gpu_addr = queue->gang_ctx_gpu_addr +
> >> AMDGPU_USERQ_GANG_CTX_SZ;
> >> +    queue->gds_ctx_gpu_addr = queue->fw_ctx_gpu_addr +
> >> AMDGPU_USERQ_FW_CTX_SZ;
> >> +    return 0;
> >> +}
> >> +
> >> +static void gfx_v11_userq_destroy_ctx_space(struct
> amdgpu_userq_mgr
> >> *uq_mgr,
> >> +                        struct amdgpu_usermode_queue *queue) {
> >> +    struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
> >> +
> >> +    amdgpu_bo_free_kernel(&ctx->obj, &ctx->gpu_addr, &ctx-
> >cpu_ptr);
> >> +}
> >> +
> >>   static int
> >>   gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct
> >> amdgpu_usermode_queue *queue)
> >>   {
> >> @@ -6426,10 +6469,16 @@ gfx_v11_userq_mqd_create(struct
> >> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
> >>       }
> >>         memset(mqd->cpu_ptr, 0, size);
> >> +    r = gfx_v11_userq_create_ctx_space(uq_mgr, queue);
> >> +    if (r) {
> >> +        DRM_ERROR("Failed to create CTX space for userqueue (%d)\n",
> >> r);
> >> +        goto free_mqd;
> >> +    }
> >> +
> >>       r = amdgpu_bo_reserve(mqd->obj, false);
> >>       if (unlikely(r != 0)) {
> >>           DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
> >> -        goto free_mqd;
> >> +        goto free_ctx;
> >>       }
> >>         queue->userq_prop.use_doorbell = true; @@ -6438,12 +6487,15
> >> @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr,
> struct
> >> amdgpu_usermode
> >>       amdgpu_bo_unreserve(mqd->obj);
> >>       if (r) {
> >>           DRM_ERROR("Failed to init MQD for queue\n");
> >> -        goto free_mqd;
> >> +        goto free_ctx;
> >>       }
> >>         DRM_DEBUG_DRIVER("MQD for queue %d created\n",
> >> queue->queue_id);
> >>       return 0;
> >>   +free_ctx:
> >> +    gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
> >> +
> >>   free_mqd:
> >>       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr,
> >> &mqd->cpu_ptr);
> >>       return r;
> >> @@ -6454,6 +6506,7 @@ gfx_v11_userq_mqd_destroy(struct
> >> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
> >>   {
> >>       struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
> >>   +    gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
> >>       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr,
> >> &mqd->cpu_ptr);
> >>   }
> >>   diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> >> b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> >> index e7da27918bd2..11e8ad649f6e 100644
> >> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> >> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> >> @@ -38,11 +38,17 @@ struct amdgpu_usermode_queue {
> >>       int            queue_id;
> >>       int            queue_type;
> >>       uint64_t        doorbell_handle;
> >> +    uint64_t        proc_ctx_gpu_addr;
> >> +    uint64_t        gang_ctx_gpu_addr;
> >> +    uint64_t        gds_ctx_gpu_addr;
> >> +    uint64_t        fw_ctx_gpu_addr;
> >> +    uint64_t        shadow_ctx_gpu_addr;
> >>       uint64_t        flags;
> >>       struct amdgpu_mqd_prop    userq_prop;
> >>       struct amdgpu_userq_mgr *userq_mgr;
> >>       struct amdgpu_vm    *vm;
> >>       struct amdgpu_userq_ctx_space mqd;
> >> +    struct amdgpu_userq_ctx_space fw_space;
> >>   };
> >>     struct amdgpu_userq_funcs {
> >

^ permalink raw reply	[flat|nested] 45+ messages in thread

* RE: [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue
  2023-04-25 17:38       ` Deucher, Alexander
@ 2023-04-25 20:00         ` Sharma, Shashank
  0 siblings, 0 replies; 45+ messages in thread
From: Sharma, Shashank @ 2023-04-25 20:00 UTC (permalink / raw)
  To: Deucher, Alexander, Koenig, Christian,
	amd-gfx@lists.freedesktop.org
  Cc: Pelloux-Prayer, Pierre-Eric, contactshashanksharma@gmail.com,
	Yadav, Arvind

[Public]

> CSA, GDS backup, and shadow are allocated by userspace now.

Noted Alex, thanks. I will update the patch series and userspace accordingly. 

Regards
Shashank

-----Original Message-----
From: Deucher, Alexander <Alexander.Deucher@amd.com> 
Sent: 25 April 2023 19:38
To: Sharma, Shashank <Shashank.Sharma@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org
Cc: Yadav, Arvind <Arvind.Yadav@amd.com>; Pelloux-Prayer, Pierre-Eric <Pierre-eric.Pelloux-prayer@amd.com>; contactshashanksharma@gmail.com
Subject: RE: [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue

[Public]

> -----Original Message-----
> From: Sharma, Shashank <Shashank.Sharma@amd.com>
> Sent: Tuesday, April 25, 2023 9:13 AM
> To: Koenig, Christian <Christian.Koenig@amd.com>; amd- 
> gfx@lists.freedesktop.org
> Cc: Yadav, Arvind <Arvind.Yadav@amd.com>; Pelloux-Prayer, Pierre-Eric 
> <Pierre-eric.Pelloux-prayer@amd.com>;
> contactshashanksharma@gmail.com; Deucher, Alexander 
> <Alexander.Deucher@amd.com>
> Subject: Re: [PATCH v4 05/10] drm/amdgpu: create context space for 
> usermode queue
> 
> 
> On 25/04/2023 14:30, Christian König wrote:
> > Am 24.04.23 um 19:38 schrieb Shashank Sharma:
> >> The FW expects us to allocate at least one page as context space to 
> >> process gang, process, GDS and FW  related work.
> >> This patch creates a joint object for the same, and calculates GPU 
> >> space offsets for each of these spaces.
> >>
> >> V1: Addressed review comments on RFC patch:
> >>      Alex: Make this function IP specific
> >>
> >> V2: Addressed review comments from Christian
> >>      - Allocate only one object for total FW space, and calculate
> >>        offsets for each of these objects.
> >>
> >> V3: Integration with doorbell manager
> >> V4: Review comments:
> >>      - Remove shadow from FW space list from cover letter (Alex)
> >>      - Alignment of macro (Luben)
> >>
> >> Cc: Alex Deucher <alexander.deucher@amd.com>
> >> Cc: Christian Koenig <christian.koenig@amd.com>
> >> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> >> ---
> >>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57
> >> ++++++++++++++++++-
> >>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  6 ++
> >>   2 files changed, 61 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> >> b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> >> index 9f7b14966ac8..f6b33faea86f 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> >> @@ -53,6 +53,11 @@
> >>   #define GFX11_NUM_GFX_RINGS        1
> >>   #define GFX11_MEC_HPD_SIZE    2048
> >>   +#define AMDGPU_USERQ_PROC_CTX_SZ   PAGE_SIZE
> >> +#define AMDGPU_USERQ_GANG_CTX_SZ   PAGE_SIZE #define 
> >> +AMDGPU_USERQ_FW_CTX_SZ     PAGE_SIZE #define
> AMDGPU_USERQ_GDS_CTX_SZ
> >> +PAGE_SIZE
> >> +
> >>   #define RLCG_UCODE_LOADING_START_ADDRESS    0x00002000L
> >>   #define RLC_PG_DELAY_3_DEFAULT_GC_11_0_1    0x1388
> >>   @@ -6406,6 +6411,44 @@ const struct amdgpu_ip_block_version 
> >> gfx_v11_0_ip_block =
> >>       .funcs = &gfx_v11_0_ip_funcs,
> >>   };
> >>   +static int gfx_v11_userq_create_ctx_space(struct 
> >> amdgpu_userq_mgr *uq_mgr,
> >> +                      struct amdgpu_usermode_queue *queue) {
> >> +    struct amdgpu_device *adev = uq_mgr->adev;
> >> +    struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
> >> +    int r, size;
> >> +
> >> +    /*
> >> +     * The FW expects at least one page space allocated for
> >> +     * process ctx, gang ctx, gds ctx, fw ctx each.
> >> +     */
> >> +    size = AMDGPU_USERQ_PROC_CTX_SZ +
> AMDGPU_USERQ_FW_CTX_SZ +
> >> +           AMDGPU_USERQ_GANG_CTX_SZ +
> AMDGPU_USERQ_GDS_CTX_SZ;
> >> +    r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
> >> +                    AMDGPU_GEM_DOMAIN_GTT,
> >> +                    &ctx->obj,
> >> +                    &ctx->gpu_addr,
> >> +                    &ctx->cpu_ptr);
> >
> > Wasn't this stuff provided by userspace now?
> >
> The last I checked, only the shadow buffer was coming from userspace, 
> and we were thinking about other stuff. I might not be well updated if 
> there any recent development here with the short term solution.

CSA, GDS backup, and shadow are allocated by userspace now.

Alex

> 
> - Shashank
> 
> > Christian.
> >
> >> +    if (r) {
> >> +        DRM_ERROR("Failed to allocate ctx space bo for userqueue,
> >> err:%d\n", r);
> >> +        return r;
> >> +    }
> >> +
> >> +    queue->proc_ctx_gpu_addr = ctx->gpu_addr;
> >> +    queue->gang_ctx_gpu_addr = queue->proc_ctx_gpu_addr +
> >> AMDGPU_USERQ_PROC_CTX_SZ;
> >> +    queue->fw_ctx_gpu_addr = queue->gang_ctx_gpu_addr +
> >> AMDGPU_USERQ_GANG_CTX_SZ;
> >> +    queue->gds_ctx_gpu_addr = queue->fw_ctx_gpu_addr +
> >> AMDGPU_USERQ_FW_CTX_SZ;
> >> +    return 0;
> >> +}
> >> +
> >> +static void gfx_v11_userq_destroy_ctx_space(struct
> amdgpu_userq_mgr
> >> *uq_mgr,
> >> +                        struct amdgpu_usermode_queue *queue) {
> >> +    struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
> >> +
> >> +    amdgpu_bo_free_kernel(&ctx->obj, &ctx->gpu_addr, &ctx-
> >cpu_ptr);
> >> +}
> >> +
> >>   static int
> >>   gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct 
> >> amdgpu_usermode_queue *queue)
> >>   {
> >> @@ -6426,10 +6469,16 @@ gfx_v11_userq_mqd_create(struct 
> >> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
> >>       }
> >>         memset(mqd->cpu_ptr, 0, size);
> >> +    r = gfx_v11_userq_create_ctx_space(uq_mgr, queue);
> >> +    if (r) {
> >> +        DRM_ERROR("Failed to create CTX space for userqueue 
> >> +(%d)\n",
> >> r);
> >> +        goto free_mqd;
> >> +    }
> >> +
> >>       r = amdgpu_bo_reserve(mqd->obj, false);
> >>       if (unlikely(r != 0)) {
> >>           DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
> >> -        goto free_mqd;
> >> +        goto free_ctx;
> >>       }
> >>         queue->userq_prop.use_doorbell = true; @@ -6438,12 +6487,15 
> >> @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr,
> struct
> >> amdgpu_usermode
> >>       amdgpu_bo_unreserve(mqd->obj);
> >>       if (r) {
> >>           DRM_ERROR("Failed to init MQD for queue\n");
> >> -        goto free_mqd;
> >> +        goto free_ctx;
> >>       }
> >>         DRM_DEBUG_DRIVER("MQD for queue %d created\n",
> >> queue->queue_id);
> >>       return 0;
> >>   +free_ctx:
> >> +    gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
> >> +
> >>   free_mqd:
> >>       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, 
> >> &mqd->cpu_ptr);
> >>       return r;
> >> @@ -6454,6 +6506,7 @@ gfx_v11_userq_mqd_destroy(struct 
> >> amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
> >>   {
> >>       struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
> >>   +    gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
> >>       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, 
> >> &mqd->cpu_ptr);
> >>   }
> >>   diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> >> b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> >> index e7da27918bd2..11e8ad649f6e 100644
> >> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> >> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> >> @@ -38,11 +38,17 @@ struct amdgpu_usermode_queue {
> >>       int            queue_id;
> >>       int            queue_type;
> >>       uint64_t        doorbell_handle;
> >> +    uint64_t        proc_ctx_gpu_addr;
> >> +    uint64_t        gang_ctx_gpu_addr;
> >> +    uint64_t        gds_ctx_gpu_addr;
> >> +    uint64_t        fw_ctx_gpu_addr;
> >> +    uint64_t        shadow_ctx_gpu_addr;
> >>       uint64_t        flags;
> >>       struct amdgpu_mqd_prop    userq_prop;
> >>       struct amdgpu_userq_mgr *userq_mgr;
> >>       struct amdgpu_vm    *vm;
> >>       struct amdgpu_userq_ctx_space mqd;
> >> +    struct amdgpu_userq_ctx_space fw_space;
> >>   };
> >>     struct amdgpu_userq_funcs {
> >

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 01/10] drm/amdgpu: UAPI for user queue management
  2023-04-24 17:38 ` [PATCH v4 01/10] drm/amdgpu: UAPI for user queue management Shashank Sharma
@ 2023-05-19 21:03   ` Alex Deucher
  2023-05-22  8:54     ` Shashank Sharma
  0 siblings, 1 reply; 45+ messages in thread
From: Alex Deucher @ 2023-05-19 21:03 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: pierre-eric.pelloux-prayer, arvind.yadav, amd-gfx, Alex Deucher,
	contactshashanksharma, Christian Koenig

On Mon, Apr 24, 2023 at 1:39 PM Shashank Sharma <shashank.sharma@amd.com> wrote:
>
> From: Alex Deucher <alexander.deucher@amd.com>
>
> This patch intorduces new UAPI/IOCTL for usermode graphics
> queue. The userspace app will fill this structure and request
> the graphics driver to add a graphics work queue for it. The
> output of this UAPI is a queue id.
>
> This UAPI maps the queue into GPU, so the graphics app can start
> submitting work to the queue as soon as the call returns.
>
> V2: Addressed review comments from Alex and Christian
>     - Make the doorbell offset's comment clearer
>     - Change the output parameter name to queue_id
>
> V3: Integration with doorbell manager
>
> V4:
>     - Updated the UAPI doc (Pierre-Eric)
>     - Created a Union for engine specific MQDs (Alex)
>     - Added Christian's R-B
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Reviewed-by: Christian König <christian.koenig@amd.com>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>  include/uapi/drm/amdgpu_drm.h | 95 +++++++++++++++++++++++++++++++++++
>  1 file changed, 95 insertions(+)
>
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index 4038abe8505a..083a1df8e8ef 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -54,6 +54,7 @@ extern "C" {
>  #define DRM_AMDGPU_VM                  0x13
>  #define DRM_AMDGPU_FENCE_TO_HANDLE     0x14
>  #define DRM_AMDGPU_SCHED               0x15
> +#define DRM_AMDGPU_USERQ               0x16
>
>  #define DRM_IOCTL_AMDGPU_GEM_CREATE    DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
>  #define DRM_IOCTL_AMDGPU_GEM_MMAP      DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
> @@ -71,6 +72,7 @@ extern "C" {
>  #define DRM_IOCTL_AMDGPU_VM            DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_VM, union drm_amdgpu_vm)
>  #define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle)
>  #define DRM_IOCTL_AMDGPU_SCHED         DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_SCHED, union drm_amdgpu_sched)
> +#define DRM_IOCTL_AMDGPU_USERQ         DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_USERQ, union drm_amdgpu_userq)
>
>  /**
>   * DOC: memory domains
> @@ -302,6 +304,99 @@ union drm_amdgpu_ctx {
>         union drm_amdgpu_ctx_out out;
>  };
>
> +/* user queue IOCTL */
> +#define AMDGPU_USERQ_OP_CREATE 1
> +#define AMDGPU_USERQ_OP_FREE   2
> +
> +#define AMDGPU_USERQ_MQD_FLAGS_SECURE  (1 << 0)
> +#define AMDGPU_USERQ_MQD_FLAGS_AQL     (1 << 1)
> +
> +/*
> + * MQD (memory queue descriptor) is a set of parameters which allow
> + * the GPU to uniquely define and identify a usermode queue.
> + */
> +struct drm_amdgpu_userq_mqd_gfx {
> +       /**
> +        * @flags: flags to indicate special function for queue like secure
> +        * buffer (TMZ). Unused for now.
> +        */
> +       __u32   flags;
> +       /**
> +        * @doorbell_handle: the handle of doorbell GEM object
> +        * associated to this client.
> +        */
> +       __u32   doorbell_handle;
> +       /**
> +        * @doorbell_offset: 32-bit offset of the doorbell in the doorbell bo.
> +        * Kernel will generate absolute doorbell offset using doorbell_handle
> +        * and doorbell_offset in the doorbell bo.
> +        */
> +       __u32   doorbell_offset;
> +       /**
> +        * @queue_va: Virtual address of the GPU memory which holds the queue
> +        * object. The queue holds the workload packets.
> +        */
> +       __u64   queue_va;
> +       /**
> +        * @queue_size: Size of the queue in bytes, this needs to be 256-byte
> +        * aligned.
> +        */
> +       __u64   queue_size;
> +       /**
> +        * @rptr_va : Virtual address of the GPU memory which holds the ring RPTR.
> +        * This object must be at least 8 byte in size and aligned to 8-byte offset.
> +        */
> +       __u64   rptr_va;
> +       /**
> +        * @wptr_va : Virtual address of the GPU memory which holds the ring WPTR.
> +        * This object must be at least 8 byte in size and aligned to 8-byte offset.
> +        *
> +        * Queue, RPTR and WPTR can come from the same object, as long as the size
> +        * and alignment related requirements are met.
> +        */
> +       __u64   wptr_va;
> +       /**
> +        * @shadow_va: Virtual address of the GPU memory to hold the shadow buffer.
> +        * This must be a from a separate GPU object, and must be at least 4-page
> +        * sized.
> +        */
> +       __u64   shadow_va;

You were planning to add the other pointers here as well for gds and csa right?

> +};
> +
> + /*
> +  * MQD can be different for different GPU IP/engine. This union will
> +  * contain structures of MQDs corresponding to different engines.
> +  */
> +union drm_amdgpu_userq_mqd {
> +       struct drm_amdgpu_userq_mqd_gfx gfx;
> +};
> +
> +struct drm_amdgpu_userq_in {
> +       /** AMDGPU_USERQ_OP_* */
> +       __u32   op;
> +       /** Flags */
> +       __u32   flags;
> +       /** Queue handle for USERQ_OP_FREE */
> +       __u32   queue_id;
> +       /** the target GPU engine to execute workload (AMDGPU_HW_IP_*) */
> +       __u32   ip_type;
> +
> +       /** Queue descriptor for USERQ_OP_CREATE */
> +       union drm_amdgpu_userq_mqd mqd;

Just thinking out loud here, I wonder if we should make this a
pointer/size element so that we could make this variable sized in case
some future MQD ends up being bigger.  I guess we could always add a
AMDGPU_USERQ_OP_CREATE2 if we ever need to expand it.

Alex

> +};
> +
> +struct drm_amdgpu_userq_out {
> +       /** Queue handle */
> +       __u32   queue_id;
> +       /** Flags */
> +       __u32   flags;
> +};
> +
> +union drm_amdgpu_userq {
> +       struct drm_amdgpu_userq_in in;
> +       struct drm_amdgpu_userq_out out;
> +};
> +
>  /* vm ioctl */
>  #define AMDGPU_VM_OP_RESERVE_VMID      1
>  #define AMDGPU_VM_OP_UNRESERVE_VMID    2
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue
  2023-04-24 17:38 ` [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue Shashank Sharma
  2023-04-25 12:27   ` Christian König
@ 2023-05-19 21:19   ` Alex Deucher
  2023-05-22  9:05     ` Shashank Sharma
  1 sibling, 1 reply; 45+ messages in thread
From: Alex Deucher @ 2023-05-19 21:19 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: pierre-eric.pelloux-prayer, arvind.yadav, amd-gfx, Alex Deucher,
	contactshashanksharma, Christian Koenig

On Mon, Apr 24, 2023 at 1:39 PM Shashank Sharma <shashank.sharma@amd.com> wrote:
>
> A Memory queue descriptor (MQD) of a userqueue defines it in
> the hw's context. As MQD format can vary between different
> graphics IPs, we need gfx GEN specific handlers to create MQDs.
>
> This patch:
> - Introduces MQD handler functions for the usermode queues.
> - Adds new functions to create and destroy userqueue MQD for
>   GFX-GEN-11 IP
>
> V1: Worked on review comments from Alex:
>     - Make MQD functions GEN and IP specific
>
> V2: Worked on review comments from Alex:
>     - Reuse the existing adev->mqd[ip] for MQD creation
>     - Formatting and arrangement of code
>
> V3:
>     - Integration with doorbell manager
>
> V4: Review comments addressed:
>     - Do not create a new file for userq, reuse gfx_v11_0.c (Alex)
>     - Align name of structure members (Luben)
>     - Don't break up the Cc tag list and the Sob tag list in commit
>       message (Luben)
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 25 ++++++++
>  drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 +++++++++++++++++++
>  .../gpu/drm/amd/include/amdgpu_userqueue.h    |  7 +++
>  3 files changed, 89 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> index 333f31efbe7b..e95fb35b0cb5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
> @@ -81,6 +81,14 @@ static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_u
>                 goto free_queue;
>         }
>
> +       if (uq_mgr->userq_funcs[queue->queue_type]->mqd_create) {
> +               r = uq_mgr->userq_funcs[queue->queue_type]->mqd_create(uq_mgr, queue);
> +               if (r) {
> +                       DRM_ERROR("Failed to create/map userqueue MQD\n");
> +                       goto free_queue;
> +               }
> +       }
> +
>         args->out.queue_id = queue->queue_id;
>         args->out.flags = 0;
>         mutex_unlock(&uq_mgr->userq_mutex);
> @@ -119,6 +127,8 @@ static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
>         }
>
>         mutex_lock(&uq_mgr->userq_mutex);
> +       if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
> +               uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
>         amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
>         mutex_unlock(&uq_mgr->userq_mutex);
>         kfree(queue);
> @@ -149,6 +159,20 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
>         return r;
>  }
>
> +extern const struct amdgpu_userq_funcs userq_gfx_v11_funcs;
> +
> +static void
> +amdgpu_userqueue_setup_ip_funcs(struct amdgpu_userq_mgr *uq_mgr)
> +{
> +       int maj;
> +       struct amdgpu_device *adev = uq_mgr->adev;
> +       uint32_t version = adev->ip_versions[GC_HWIP][0];
> +
> +       /* We support usermode queue only for GFX IP as of now */
> +       maj = IP_VERSION_MAJ(version);
> +       if (maj == 11)
> +               uq_mgr->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_gfx_v11_funcs;

Do we need to keep function pointers in uq_mgr?  It would be nice to
keep the logic in the IPs directly.  E.g, in gfx_v11_0.c, we could set
adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_gfx_v11_funcs;
then the userq code can just check

       if (adev->userq_funcs[queue->queue_type]->mqd_destroy)
               adev->userq_funcs[queue->queue_type]->mqd_destroy(adev, queue);

etc.

> +}
>
>  int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev)
>  {
> @@ -156,6 +180,7 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi
>         idr_init_base(&userq_mgr->userq_idr, 1);
>         userq_mgr->adev = adev;
>
> +       amdgpu_userqueue_setup_ip_funcs(userq_mgr);
>         return 0;
>  }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> index a56c6e106d00..9f7b14966ac8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> @@ -30,6 +30,7 @@
>  #include "amdgpu_psp.h"
>  #include "amdgpu_smu.h"
>  #include "amdgpu_atomfirmware.h"
> +#include "amdgpu_userqueue.h"
>  #include "imu_v11_0.h"
>  #include "soc21.h"
>  #include "nvd.h"
> @@ -6404,3 +6405,59 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>         .rev = 0,
>         .funcs = &gfx_v11_0_ip_funcs,
>  };
> +
> +static int
> +gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
> +{
> +       struct amdgpu_device *adev = uq_mgr->adev;
> +       struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
> +       struct amdgpu_mqd *gfx_v11_mqd = &adev->mqds[queue->queue_type];
> +       int size = gfx_v11_mqd->mqd_size;
> +       int r;
> +
> +       r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
> +                                   AMDGPU_GEM_DOMAIN_GTT,
> +                                   &mqd->obj,
> +                                   &mqd->gpu_addr,
> +                                   &mqd->cpu_ptr);
> +       if (r) {
> +               DRM_ERROR("Failed to allocate bo for userqueue (%d)", r);
> +               return r;
> +       }
> +
> +       memset(mqd->cpu_ptr, 0, size);
> +       r = amdgpu_bo_reserve(mqd->obj, false);
> +       if (unlikely(r != 0)) {
> +               DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
> +               goto free_mqd;
> +       }
> +
> +       queue->userq_prop.use_doorbell = true;
> +       queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
> +       r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, &queue->userq_prop);
> +       amdgpu_bo_unreserve(mqd->obj);
> +       if (r) {
> +               DRM_ERROR("Failed to init MQD for queue\n");
> +               goto free_mqd;
> +       }
> +
> +       DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
> +       return 0;
> +
> +free_mqd:
> +       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
> +       return r;
> +}
> +
> +static void
> +gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
> +{
> +       struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
> +
> +       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
> +}
> +
> +const struct amdgpu_userq_funcs userq_gfx_v11_funcs = {
> +       .mqd_create = gfx_v11_userq_mqd_create,
> +       .mqd_destroy = gfx_v11_userq_mqd_destroy,
> +};

These functions and structures should start with gfx_v11_0_ for consistency.

> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> index 8d8f6b3bcda5..e7da27918bd2 100644
> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> @@ -28,6 +28,12 @@
>  #include "amdgpu.h"
>  #define AMDGPU_MAX_USERQ 512
>
> +struct amdgpu_userq_ctx_space {
> +       uint64_t         gpu_addr;
> +       void             *cpu_ptr;
> +       struct amdgpu_bo *obj;
> +};
> +
>  struct amdgpu_usermode_queue {
>         int                     queue_id;
>         int                     queue_type;
> @@ -36,6 +42,7 @@ struct amdgpu_usermode_queue {
>         struct amdgpu_mqd_prop  userq_prop;
>         struct amdgpu_userq_mgr *userq_mgr;
>         struct amdgpu_vm        *vm;
> +       struct amdgpu_userq_ctx_space mqd;
>  };
>
>  struct amdgpu_userq_funcs {
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue
  2023-04-24 17:38 ` [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue Shashank Sharma
  2023-04-25 12:30   ` Christian König
@ 2023-05-19 21:21   ` Alex Deucher
  2023-05-22  9:05     ` Shashank Sharma
  1 sibling, 1 reply; 45+ messages in thread
From: Alex Deucher @ 2023-05-19 21:21 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: pierre-eric.pelloux-prayer, arvind.yadav, amd-gfx, Alex Deucher,
	contactshashanksharma, Christian Koenig

On Mon, Apr 24, 2023 at 1:39 PM Shashank Sharma <shashank.sharma@amd.com> wrote:
>
> The FW expects us to allocate at least one page as context
> space to process gang, process, GDS and FW  related work.
> This patch creates a joint object for the same, and calculates
> GPU space offsets for each of these spaces.
>
> V1: Addressed review comments on RFC patch:
>     Alex: Make this function IP specific
>
> V2: Addressed review comments from Christian
>     - Allocate only one object for total FW space, and calculate
>       offsets for each of these objects.
>
> V3: Integration with doorbell manager
> V4: Review comments:
>     - Remove shadow from FW space list from cover letter (Alex)
>     - Alignment of macro (Luben)
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 ++++++++++++++++++-
>  .../gpu/drm/amd/include/amdgpu_userqueue.h    |  6 ++
>  2 files changed, 61 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> index 9f7b14966ac8..f6b33faea86f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> @@ -53,6 +53,11 @@
>  #define GFX11_NUM_GFX_RINGS            1
>  #define GFX11_MEC_HPD_SIZE     2048
>
> +#define AMDGPU_USERQ_PROC_CTX_SZ   PAGE_SIZE
> +#define AMDGPU_USERQ_GANG_CTX_SZ   PAGE_SIZE
> +#define AMDGPU_USERQ_FW_CTX_SZ     PAGE_SIZE
> +#define AMDGPU_USERQ_GDS_CTX_SZ    PAGE_SIZE
> +
>  #define RLCG_UCODE_LOADING_START_ADDRESS       0x00002000L
>  #define RLC_PG_DELAY_3_DEFAULT_GC_11_0_1       0x1388
>
> @@ -6406,6 +6411,44 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>         .funcs = &gfx_v11_0_ip_funcs,
>  };
>
> +static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
> +                                         struct amdgpu_usermode_queue *queue)
> +{
> +       struct amdgpu_device *adev = uq_mgr->adev;
> +       struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
> +       int r, size;
> +
> +       /*
> +        * The FW expects at least one page space allocated for
> +        * process ctx, gang ctx, gds ctx, fw ctx each.
> +        */
> +       size = AMDGPU_USERQ_PROC_CTX_SZ + AMDGPU_USERQ_FW_CTX_SZ +
> +              AMDGPU_USERQ_GANG_CTX_SZ + AMDGPU_USERQ_GDS_CTX_SZ;
> +       r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
> +                                   AMDGPU_GEM_DOMAIN_GTT,
> +                                   &ctx->obj,
> +                                   &ctx->gpu_addr,
> +                                   &ctx->cpu_ptr);
> +       if (r) {
> +               DRM_ERROR("Failed to allocate ctx space bo for userqueue, err:%d\n", r);
> +               return r;
> +       }
> +
> +       queue->proc_ctx_gpu_addr = ctx->gpu_addr;
> +       queue->gang_ctx_gpu_addr = queue->proc_ctx_gpu_addr + AMDGPU_USERQ_PROC_CTX_SZ;
> +       queue->fw_ctx_gpu_addr = queue->gang_ctx_gpu_addr + AMDGPU_USERQ_GANG_CTX_SZ;
> +       queue->gds_ctx_gpu_addr = queue->fw_ctx_gpu_addr + AMDGPU_USERQ_FW_CTX_SZ;
> +       return 0;
> +}

Please use gfx_v11_0_ naming for consistency.

Alex

> +
> +static void gfx_v11_userq_destroy_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
> +                                           struct amdgpu_usermode_queue *queue)
> +{
> +       struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
> +
> +       amdgpu_bo_free_kernel(&ctx->obj, &ctx->gpu_addr, &ctx->cpu_ptr);
> +}
> +
>  static int
>  gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
>  {
> @@ -6426,10 +6469,16 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>         }
>
>         memset(mqd->cpu_ptr, 0, size);
> +       r = gfx_v11_userq_create_ctx_space(uq_mgr, queue);
> +       if (r) {
> +               DRM_ERROR("Failed to create CTX space for userqueue (%d)\n", r);
> +               goto free_mqd;
> +       }
> +
>         r = amdgpu_bo_reserve(mqd->obj, false);
>         if (unlikely(r != 0)) {
>                 DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
> -               goto free_mqd;
> +               goto free_ctx;
>         }
>
>         queue->userq_prop.use_doorbell = true;
> @@ -6438,12 +6487,15 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>         amdgpu_bo_unreserve(mqd->obj);
>         if (r) {
>                 DRM_ERROR("Failed to init MQD for queue\n");
> -               goto free_mqd;
> +               goto free_ctx;
>         }
>
>         DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>         return 0;
>
> +free_ctx:
> +       gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
> +
>  free_mqd:
>         amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>         return r;
> @@ -6454,6 +6506,7 @@ gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
>  {
>         struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>
> +       gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>         amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>  }
>
> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> index e7da27918bd2..11e8ad649f6e 100644
> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
> @@ -38,11 +38,17 @@ struct amdgpu_usermode_queue {
>         int                     queue_id;
>         int                     queue_type;
>         uint64_t                doorbell_handle;
> +       uint64_t                proc_ctx_gpu_addr;
> +       uint64_t                gang_ctx_gpu_addr;
> +       uint64_t                gds_ctx_gpu_addr;
> +       uint64_t                fw_ctx_gpu_addr;
> +       uint64_t                shadow_ctx_gpu_addr;
>         uint64_t                flags;
>         struct amdgpu_mqd_prop  userq_prop;
>         struct amdgpu_userq_mgr *userq_mgr;
>         struct amdgpu_vm        *vm;
>         struct amdgpu_userq_ctx_space mqd;
> +       struct amdgpu_userq_ctx_space fw_space;
>  };
>
>  struct amdgpu_userq_funcs {
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 06/10] drm/amdgpu: set FW parameters in v11_struct
  2023-04-24 17:38 ` [PATCH v4 06/10] drm/amdgpu: set FW parameters in v11_struct Shashank Sharma
  2023-04-25 12:32   ` Christian König
@ 2023-05-19 21:22   ` Alex Deucher
  2023-05-22  9:06     ` Shashank Sharma
  1 sibling, 1 reply; 45+ messages in thread
From: Alex Deucher @ 2023-05-19 21:22 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: pierre-eric.pelloux-prayer, arvind.yadav, amd-gfx, Alex Deucher,
	contactshashanksharma, Christian Koenig

On Mon, Apr 24, 2023 at 1:39 PM Shashank Sharma <shashank.sharma@amd.com> wrote:
>
> From: Arvind Yadav <arvind.yadav@amd.com>
>
> This patch sets new parameters defined in v11_struct for
> usermode queue with the respective allocated gpu context
> space addresses.
>
> V4: Split the patch into two parts, keep only the set parameter
>     part in this series (Alex).
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Cc: Shashank Sharma <shashank.sharma@amd.com>
> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> index f6b33faea86f..86de35292f69 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> @@ -6411,6 +6411,21 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>         .funcs = &gfx_v11_0_ip_funcs,
>  };
>
> +static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr *uq_mgr,


gfx_v11_0_ for consistency.

Alex

> +                                       struct amdgpu_usermode_queue *queue)
> +{
> +       struct v11_gfx_mqd *mqd = queue->mqd.cpu_ptr;
> +
> +       mqd->shadow_base_lo = queue->shadow_ctx_gpu_addr & 0xfffffffc;
> +       mqd->shadow_base_hi = upper_32_bits(queue->shadow_ctx_gpu_addr);
> +
> +       mqd->gds_bkup_base_lo = queue->gds_ctx_gpu_addr & 0xfffffffc;
> +       mqd->gds_bkup_base_hi = upper_32_bits(queue->gds_ctx_gpu_addr);
> +
> +       mqd->fw_work_area_base_lo = queue->fw_ctx_gpu_addr & 0xfffffffc;
> +       mqd->fw_work_area_base_lo = upper_32_bits(queue->fw_ctx_gpu_addr);
> +}
> +
>  static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
>                                           struct amdgpu_usermode_queue *queue)
>  {
> @@ -6484,12 +6499,14 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>         queue->userq_prop.use_doorbell = true;
>         queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
>         r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, &queue->userq_prop);
> -       amdgpu_bo_unreserve(mqd->obj);
>         if (r) {
> +               amdgpu_bo_unreserve(mqd->obj);
>                 DRM_ERROR("Failed to init MQD for queue\n");
>                 goto free_ctx;
>         }
>
> +       gfx_v11_userq_set_ctx_space(uq_mgr, queue);
> +       amdgpu_bo_unreserve(mqd->obj);
>         DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>         return 0;
>
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES
  2023-04-24 17:38 ` [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES Shashank Sharma
  2023-04-25 12:34   ` Christian König
@ 2023-05-19 21:22   ` Alex Deucher
  2023-05-22  9:06     ` Shashank Sharma
  1 sibling, 1 reply; 45+ messages in thread
From: Alex Deucher @ 2023-05-19 21:22 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: pierre-eric.pelloux-prayer, arvind.yadav, amd-gfx, Alex Deucher,
	contactshashanksharma, Christian Koenig

On Mon, Apr 24, 2023 at 1:39 PM Shashank Sharma <shashank.sharma@amd.com> wrote:
>
> This patch adds new functions to map/unmap a usermode queue into
> the FW, using the MES ring. As soon as this mapping is done, the
> queue would  be considered ready to accept the workload.
>
> V1: Addressed review comments from Alex on the RFC patch series
>     - Map/Unmap should be IP specific.
> V2:
>     Addressed review comments from Christian:
>     - Fix the wptr_mc_addr calculation (moved into another patch)
>     Addressed review comments from Alex:
>     - Do not add fptrs for map/unmap
>
> V3: Integration with doorbell manager
> V4: Rebase
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 67 ++++++++++++++++++++++++++
>  1 file changed, 67 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> index 86de35292f69..7a45d68091ec 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
> @@ -31,6 +31,7 @@
>  #include "amdgpu_smu.h"
>  #include "amdgpu_atomfirmware.h"
>  #include "amdgpu_userqueue.h"
> +#include "amdgpu_mes.h"
>  #include "imu_v11_0.h"
>  #include "soc21.h"
>  #include "nvd.h"
> @@ -6411,6 +6412,64 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>         .funcs = &gfx_v11_0_ip_funcs,
>  };
>
> +static int gfx_v11_userq_map(struct amdgpu_userq_mgr *uq_mgr,
> +                            struct amdgpu_usermode_queue *queue)
> +{
> +       struct amdgpu_device *adev = uq_mgr->adev;
> +       struct mes_add_queue_input queue_input;
> +       int r;
> +
> +       memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
> +
> +       queue_input.process_va_start = 0;
> +       queue_input.process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT;
> +       queue_input.process_quantum = 100000; /* 10ms */
> +       queue_input.gang_quantum = 10000; /* 1ms */
> +       queue_input.paging = false;
> +
> +       queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
> +       queue_input.process_context_addr = queue->proc_ctx_gpu_addr;
> +       queue_input.inprocess_gang_priority = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
> +       queue_input.gang_global_priority_level = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
> +
> +       queue_input.process_id = queue->vm->pasid;
> +       queue_input.queue_type = queue->queue_type;
> +       queue_input.mqd_addr = queue->mqd.gpu_addr;
> +       queue_input.wptr_addr = queue->userq_prop.wptr_gpu_addr;
> +       queue_input.queue_size = queue->userq_prop.queue_size >> 2;
> +       queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
> +       queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(queue->vm->root.bo);
> +
> +       amdgpu_mes_lock(&adev->mes);
> +       r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
> +       amdgpu_mes_unlock(&adev->mes);
> +       if (r) {
> +               DRM_ERROR("Failed to map queue in HW, err (%d)\n", r);
> +               return r;
> +       }
> +
> +       DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", queue->queue_id);
> +       return 0;
> +}
> +
> +static void gfx_v11_userq_unmap(struct amdgpu_userq_mgr *uq_mgr,
> +                               struct amdgpu_usermode_queue *queue)
> +{
> +       struct amdgpu_device *adev = uq_mgr->adev;
> +       struct mes_remove_queue_input queue_input;
> +       int r;
> +
> +       memset(&queue_input, 0x0, sizeof(struct mes_remove_queue_input));
> +       queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
> +       queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
> +
> +       amdgpu_mes_lock(&adev->mes);
> +       r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
> +       amdgpu_mes_unlock(&adev->mes);
> +       if (r)
> +               DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r);
> +}

gfx_v11_0_ for consistency.

Alex

> +
>  static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
>                                         struct amdgpu_usermode_queue *queue)
>  {
> @@ -6507,6 +6566,13 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>
>         gfx_v11_userq_set_ctx_space(uq_mgr, queue);
>         amdgpu_bo_unreserve(mqd->obj);
> +
> +       /* Map the queue in HW using MES ring */
> +       r = gfx_v11_userq_map(uq_mgr, queue);
> +       if (r) {
> +               DRM_ERROR("Failed to map userqueue (%d)\n", r);
> +               goto free_ctx;
> +       }
>         DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>         return 0;
>
> @@ -6523,6 +6589,7 @@ gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
>  {
>         struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>
> +       gfx_v11_userq_unmap(uq_mgr, queue);
>         gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>         amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>  }
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 01/10] drm/amdgpu: UAPI for user queue management
  2023-05-19 21:03   ` Alex Deucher
@ 2023-05-22  8:54     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-05-22  8:54 UTC (permalink / raw)
  To: Alex Deucher
  Cc: pierre-eric.pelloux-prayer, arvind.yadav, amd-gfx, Alex Deucher,
	contactshashanksharma, Christian Koenig

Hey Alex,

Thanks for the review comments, please find mine inline.

- Shashank

On 19/05/2023 23:03, Alex Deucher wrote:
> On Mon, Apr 24, 2023 at 1:39 PM Shashank Sharma <shashank.sharma@amd.com> wrote:
>> From: Alex Deucher <alexander.deucher@amd.com>
>>
>> This patch intorduces new UAPI/IOCTL for usermode graphics
>> queue. The userspace app will fill this structure and request
>> the graphics driver to add a graphics work queue for it. The
>> output of this UAPI is a queue id.
>>
>> This UAPI maps the queue into GPU, so the graphics app can start
>> submitting work to the queue as soon as the call returns.
>>
>> V2: Addressed review comments from Alex and Christian
>>      - Make the doorbell offset's comment clearer
>>      - Change the output parameter name to queue_id
>>
>> V3: Integration with doorbell manager
>>
>> V4:
>>      - Updated the UAPI doc (Pierre-Eric)
>>      - Created a Union for engine specific MQDs (Alex)
>>      - Added Christian's R-B
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Reviewed-by: Christian König <christian.koenig@amd.com>
>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> ---
>>   include/uapi/drm/amdgpu_drm.h | 95 +++++++++++++++++++++++++++++++++++
>>   1 file changed, 95 insertions(+)
>>
>> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
>> index 4038abe8505a..083a1df8e8ef 100644
>> --- a/include/uapi/drm/amdgpu_drm.h
>> +++ b/include/uapi/drm/amdgpu_drm.h
>> @@ -54,6 +54,7 @@ extern "C" {
>>   #define DRM_AMDGPU_VM                  0x13
>>   #define DRM_AMDGPU_FENCE_TO_HANDLE     0x14
>>   #define DRM_AMDGPU_SCHED               0x15
>> +#define DRM_AMDGPU_USERQ               0x16
>>
>>   #define DRM_IOCTL_AMDGPU_GEM_CREATE    DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
>>   #define DRM_IOCTL_AMDGPU_GEM_MMAP      DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
>> @@ -71,6 +72,7 @@ extern "C" {
>>   #define DRM_IOCTL_AMDGPU_VM            DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_VM, union drm_amdgpu_vm)
>>   #define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle)
>>   #define DRM_IOCTL_AMDGPU_SCHED         DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_SCHED, union drm_amdgpu_sched)
>> +#define DRM_IOCTL_AMDGPU_USERQ         DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_USERQ, union drm_amdgpu_userq)
>>
>>   /**
>>    * DOC: memory domains
>> @@ -302,6 +304,99 @@ union drm_amdgpu_ctx {
>>          union drm_amdgpu_ctx_out out;
>>   };
>>
>> +/* user queue IOCTL */
>> +#define AMDGPU_USERQ_OP_CREATE 1
>> +#define AMDGPU_USERQ_OP_FREE   2
>> +
>> +#define AMDGPU_USERQ_MQD_FLAGS_SECURE  (1 << 0)
>> +#define AMDGPU_USERQ_MQD_FLAGS_AQL     (1 << 1)
>> +
>> +/*
>> + * MQD (memory queue descriptor) is a set of parameters which allow
>> + * the GPU to uniquely define and identify a usermode queue.
>> + */
>> +struct drm_amdgpu_userq_mqd_gfx {
>> +       /**
>> +        * @flags: flags to indicate special function for queue like secure
>> +        * buffer (TMZ). Unused for now.
>> +        */
>> +       __u32   flags;
>> +       /**
>> +        * @doorbell_handle: the handle of doorbell GEM object
>> +        * associated to this client.
>> +        */
>> +       __u32   doorbell_handle;
>> +       /**
>> +        * @doorbell_offset: 32-bit offset of the doorbell in the doorbell bo.
>> +        * Kernel will generate absolute doorbell offset using doorbell_handle
>> +        * and doorbell_offset in the doorbell bo.
>> +        */
>> +       __u32   doorbell_offset;
>> +       /**
>> +        * @queue_va: Virtual address of the GPU memory which holds the queue
>> +        * object. The queue holds the workload packets.
>> +        */
>> +       __u64   queue_va;
>> +       /**
>> +        * @queue_size: Size of the queue in bytes, this needs to be 256-byte
>> +        * aligned.
>> +        */
>> +       __u64   queue_size;
>> +       /**
>> +        * @rptr_va : Virtual address of the GPU memory which holds the ring RPTR.
>> +        * This object must be at least 8 byte in size and aligned to 8-byte offset.
>> +        */
>> +       __u64   rptr_va;
>> +       /**
>> +        * @wptr_va : Virtual address of the GPU memory which holds the ring WPTR.
>> +        * This object must be at least 8 byte in size and aligned to 8-byte offset.
>> +        *
>> +        * Queue, RPTR and WPTR can come from the same object, as long as the size
>> +        * and alignment related requirements are met.
>> +        */
>> +       __u64   wptr_va;
>> +       /**
>> +        * @shadow_va: Virtual address of the GPU memory to hold the shadow buffer.
>> +        * This must be a from a separate GPU object, and must be at least 4-page
>> +        * sized.
>> +        */
>> +       __u64   shadow_va;
> You were planning to add the other pointers here as well for gds and csa right?
That was decided in this patch set only, from a different review 
comment, so we are yet to work on it :)
>
>> +};
>> +
>> + /*
>> +  * MQD can be different for different GPU IP/engine. This union will
>> +  * contain structures of MQDs corresponding to different engines.
>> +  */
>> +union drm_amdgpu_userq_mqd {
>> +       struct drm_amdgpu_userq_mqd_gfx gfx;
>> +};
>> +
>> +struct drm_amdgpu_userq_in {
>> +       /** AMDGPU_USERQ_OP_* */
>> +       __u32   op;
>> +       /** Flags */
>> +       __u32   flags;
>> +       /** Queue handle for USERQ_OP_FREE */
>> +       __u32   queue_id;
>> +       /** the target GPU engine to execute workload (AMDGPU_HW_IP_*) */
>> +       __u32   ip_type;
>> +
>> +       /** Queue descriptor for USERQ_OP_CREATE */
>> +       union drm_amdgpu_userq_mqd mqd;
> Just thinking out loud here, I wonder if we should make this a
> pointer/size element so that we could make this variable sized in case
> some future MQD ends up being bigger.  I guess we could always add a
> AMDGPU_USERQ_OP_CREATE2 if we ever need to expand it.

I think it is a good idea and sounds scalable as well. Then we might not 
even need a union, we can just define MQD size and a ptr.

- Shashank

> Alex
>
>> +};
>> +
>> +struct drm_amdgpu_userq_out {
>> +       /** Queue handle */
>> +       __u32   queue_id;
>> +       /** Flags */
>> +       __u32   flags;
>> +};
>> +
>> +union drm_amdgpu_userq {
>> +       struct drm_amdgpu_userq_in in;
>> +       struct drm_amdgpu_userq_out out;
>> +};
>> +
>>   /* vm ioctl */
>>   #define AMDGPU_VM_OP_RESERVE_VMID      1
>>   #define AMDGPU_VM_OP_UNRESERVE_VMID    2
>> --
>> 2.40.0
>>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue
  2023-05-19 21:19   ` Alex Deucher
@ 2023-05-22  9:05     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-05-22  9:05 UTC (permalink / raw)
  To: Alex Deucher
  Cc: pierre-eric.pelloux-prayer, arvind.yadav, amd-gfx, Alex Deucher,
	contactshashanksharma, Christian Koenig


On 19/05/2023 23:19, Alex Deucher wrote:
> On Mon, Apr 24, 2023 at 1:39 PM Shashank Sharma <shashank.sharma@amd.com> wrote:
>> A Memory queue descriptor (MQD) of a userqueue defines it in
>> the hw's context. As MQD format can vary between different
>> graphics IPs, we need gfx GEN specific handlers to create MQDs.
>>
>> This patch:
>> - Introduces MQD handler functions for the usermode queues.
>> - Adds new functions to create and destroy userqueue MQD for
>>    GFX-GEN-11 IP
>>
>> V1: Worked on review comments from Alex:
>>      - Make MQD functions GEN and IP specific
>>
>> V2: Worked on review comments from Alex:
>>      - Reuse the existing adev->mqd[ip] for MQD creation
>>      - Formatting and arrangement of code
>>
>> V3:
>>      - Integration with doorbell manager
>>
>> V4: Review comments addressed:
>>      - Do not create a new file for userq, reuse gfx_v11_0.c (Alex)
>>      - Align name of structure members (Luben)
>>      - Don't break up the Cc tag list and the Sob tag list in commit
>>        message (Luben)
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c | 25 ++++++++
>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 +++++++++++++++++++
>>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  7 +++
>>   3 files changed, 89 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> index 333f31efbe7b..e95fb35b0cb5 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userqueue.c
>> @@ -81,6 +81,14 @@ static int amdgpu_userqueue_create_gfx(struct drm_file *filp, union drm_amdgpu_u
>>                  goto free_queue;
>>          }
>>
>> +       if (uq_mgr->userq_funcs[queue->queue_type]->mqd_create) {
>> +               r = uq_mgr->userq_funcs[queue->queue_type]->mqd_create(uq_mgr, queue);
>> +               if (r) {
>> +                       DRM_ERROR("Failed to create/map userqueue MQD\n");
>> +                       goto free_queue;
>> +               }
>> +       }
>> +
>>          args->out.queue_id = queue->queue_id;
>>          args->out.flags = 0;
>>          mutex_unlock(&uq_mgr->userq_mutex);
>> @@ -119,6 +127,8 @@ static void amdgpu_userqueue_destroy(struct drm_file *filp, int queue_id)
>>          }
>>
>>          mutex_lock(&uq_mgr->userq_mutex);
>> +       if (uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy)
>> +               uq_mgr->userq_funcs[queue->queue_type]->mqd_destroy(uq_mgr, queue);
>>          amdgpu_userqueue_free_index(uq_mgr, queue->queue_id);
>>          mutex_unlock(&uq_mgr->userq_mutex);
>>          kfree(queue);
>> @@ -149,6 +159,20 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
>>          return r;
>>   }
>>
>> +extern const struct amdgpu_userq_funcs userq_gfx_v11_funcs;
>> +
>> +static void
>> +amdgpu_userqueue_setup_ip_funcs(struct amdgpu_userq_mgr *uq_mgr)
>> +{
>> +       int maj;
>> +       struct amdgpu_device *adev = uq_mgr->adev;
>> +       uint32_t version = adev->ip_versions[GC_HWIP][0];
>> +
>> +       /* We support usermode queue only for GFX IP as of now */
>> +       maj = IP_VERSION_MAJ(version);
>> +       if (maj == 11)
>> +               uq_mgr->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_gfx_v11_funcs;
> Do we need to keep function pointers in uq_mgr?  It would be nice to
> keep the logic in the IPs directly.  E.g, in gfx_v11_0.c, we could set
> adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_gfx_v11_funcs;
> then the userq code can just check
>
>         if (adev->userq_funcs[queue->queue_type]->mqd_destroy)
>                 adev->userq_funcs[queue->queue_type]->mqd_destroy(adev, queue);
>
> etc.

We have discussed about this here as well: 
https://patchwork.freedesktop.org/patch/529513/?series=113675&rev=2 
(which we probably could not follow up)

The problem is, in the discussion from first patch set we decided not to 
use adev for this, instead moved this in driver private from fptr.

>> +}
>>
>>   int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_device *adev)
>>   {
>> @@ -156,6 +180,7 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct amdgpu_devi
>>          idr_init_base(&userq_mgr->userq_idr, 1);
>>          userq_mgr->adev = adev;
>>
>> +       amdgpu_userqueue_setup_ip_funcs(userq_mgr);
>>          return 0;
>>   }
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> index a56c6e106d00..9f7b14966ac8 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> @@ -30,6 +30,7 @@
>>   #include "amdgpu_psp.h"
>>   #include "amdgpu_smu.h"
>>   #include "amdgpu_atomfirmware.h"
>> +#include "amdgpu_userqueue.h"
>>   #include "imu_v11_0.h"
>>   #include "soc21.h"
>>   #include "nvd.h"
>> @@ -6404,3 +6405,59 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>>          .rev = 0,
>>          .funcs = &gfx_v11_0_ip_funcs,
>>   };
>> +
>> +static int
>> +gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
>> +{
>> +       struct amdgpu_device *adev = uq_mgr->adev;
>> +       struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>> +       struct amdgpu_mqd *gfx_v11_mqd = &adev->mqds[queue->queue_type];
>> +       int size = gfx_v11_mqd->mqd_size;
>> +       int r;
>> +
>> +       r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
>> +                                   AMDGPU_GEM_DOMAIN_GTT,
>> +                                   &mqd->obj,
>> +                                   &mqd->gpu_addr,
>> +                                   &mqd->cpu_ptr);
>> +       if (r) {
>> +               DRM_ERROR("Failed to allocate bo for userqueue (%d)", r);
>> +               return r;
>> +       }
>> +
>> +       memset(mqd->cpu_ptr, 0, size);
>> +       r = amdgpu_bo_reserve(mqd->obj, false);
>> +       if (unlikely(r != 0)) {
>> +               DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
>> +               goto free_mqd;
>> +       }
>> +
>> +       queue->userq_prop.use_doorbell = true;
>> +       queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
>> +       r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, &queue->userq_prop);
>> +       amdgpu_bo_unreserve(mqd->obj);
>> +       if (r) {
>> +               DRM_ERROR("Failed to init MQD for queue\n");
>> +               goto free_mqd;
>> +       }
>> +
>> +       DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>> +       return 0;
>> +
>> +free_mqd:
>> +       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>> +       return r;
>> +}
>> +
>> +static void
>> +gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
>> +{
>> +       struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>> +
>> +       amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>> +}
>> +
>> +const struct amdgpu_userq_funcs userq_gfx_v11_funcs = {
>> +       .mqd_create = gfx_v11_userq_mqd_create,
>> +       .mqd_destroy = gfx_v11_userq_mqd_destroy,
>> +};
> These functions and structures should start with gfx_v11_0_ for consistency.

Noted,

- Shashank

>
>> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> index 8d8f6b3bcda5..e7da27918bd2 100644
>> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> @@ -28,6 +28,12 @@
>>   #include "amdgpu.h"
>>   #define AMDGPU_MAX_USERQ 512
>>
>> +struct amdgpu_userq_ctx_space {
>> +       uint64_t         gpu_addr;
>> +       void             *cpu_ptr;
>> +       struct amdgpu_bo *obj;
>> +};
>> +
>>   struct amdgpu_usermode_queue {
>>          int                     queue_id;
>>          int                     queue_type;
>> @@ -36,6 +42,7 @@ struct amdgpu_usermode_queue {
>>          struct amdgpu_mqd_prop  userq_prop;
>>          struct amdgpu_userq_mgr *userq_mgr;
>>          struct amdgpu_vm        *vm;
>> +       struct amdgpu_userq_ctx_space mqd;
>>   };
>>
>>   struct amdgpu_userq_funcs {
>> --
>> 2.40.0
>>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue
  2023-05-19 21:21   ` Alex Deucher
@ 2023-05-22  9:05     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-05-22  9:05 UTC (permalink / raw)
  To: Alex Deucher
  Cc: pierre-eric.pelloux-prayer, arvind.yadav, amd-gfx, Alex Deucher,
	contactshashanksharma, Christian Koenig


On 19/05/2023 23:21, Alex Deucher wrote:
> On Mon, Apr 24, 2023 at 1:39 PM Shashank Sharma <shashank.sharma@amd.com> wrote:
>> The FW expects us to allocate at least one page as context
>> space to process gang, process, GDS and FW  related work.
>> This patch creates a joint object for the same, and calculates
>> GPU space offsets for each of these spaces.
>>
>> V1: Addressed review comments on RFC patch:
>>      Alex: Make this function IP specific
>>
>> V2: Addressed review comments from Christian
>>      - Allocate only one object for total FW space, and calculate
>>        offsets for each of these objects.
>>
>> V3: Integration with doorbell manager
>> V4: Review comments:
>>      - Remove shadow from FW space list from cover letter (Alex)
>>      - Alignment of macro (Luben)
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c        | 57 ++++++++++++++++++-
>>   .../gpu/drm/amd/include/amdgpu_userqueue.h    |  6 ++
>>   2 files changed, 61 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> index 9f7b14966ac8..f6b33faea86f 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> @@ -53,6 +53,11 @@
>>   #define GFX11_NUM_GFX_RINGS            1
>>   #define GFX11_MEC_HPD_SIZE     2048
>>
>> +#define AMDGPU_USERQ_PROC_CTX_SZ   PAGE_SIZE
>> +#define AMDGPU_USERQ_GANG_CTX_SZ   PAGE_SIZE
>> +#define AMDGPU_USERQ_FW_CTX_SZ     PAGE_SIZE
>> +#define AMDGPU_USERQ_GDS_CTX_SZ    PAGE_SIZE
>> +
>>   #define RLCG_UCODE_LOADING_START_ADDRESS       0x00002000L
>>   #define RLC_PG_DELAY_3_DEFAULT_GC_11_0_1       0x1388
>>
>> @@ -6406,6 +6411,44 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>>          .funcs = &gfx_v11_0_ip_funcs,
>>   };
>>
>> +static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
>> +                                         struct amdgpu_usermode_queue *queue)
>> +{
>> +       struct amdgpu_device *adev = uq_mgr->adev;
>> +       struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
>> +       int r, size;
>> +
>> +       /*
>> +        * The FW expects at least one page space allocated for
>> +        * process ctx, gang ctx, gds ctx, fw ctx each.
>> +        */
>> +       size = AMDGPU_USERQ_PROC_CTX_SZ + AMDGPU_USERQ_FW_CTX_SZ +
>> +              AMDGPU_USERQ_GANG_CTX_SZ + AMDGPU_USERQ_GDS_CTX_SZ;
>> +       r = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
>> +                                   AMDGPU_GEM_DOMAIN_GTT,
>> +                                   &ctx->obj,
>> +                                   &ctx->gpu_addr,
>> +                                   &ctx->cpu_ptr);
>> +       if (r) {
>> +               DRM_ERROR("Failed to allocate ctx space bo for userqueue, err:%d\n", r);
>> +               return r;
>> +       }
>> +
>> +       queue->proc_ctx_gpu_addr = ctx->gpu_addr;
>> +       queue->gang_ctx_gpu_addr = queue->proc_ctx_gpu_addr + AMDGPU_USERQ_PROC_CTX_SZ;
>> +       queue->fw_ctx_gpu_addr = queue->gang_ctx_gpu_addr + AMDGPU_USERQ_GANG_CTX_SZ;
>> +       queue->gds_ctx_gpu_addr = queue->fw_ctx_gpu_addr + AMDGPU_USERQ_FW_CTX_SZ;
>> +       return 0;
>> +}
> Please use gfx_v11_0_ naming for consistency.

Noted,

- Shashank

>
> Alex
>
>> +
>> +static void gfx_v11_userq_destroy_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
>> +                                           struct amdgpu_usermode_queue *queue)
>> +{
>> +       struct amdgpu_userq_ctx_space *ctx = &queue->fw_space;
>> +
>> +       amdgpu_bo_free_kernel(&ctx->obj, &ctx->gpu_addr, &ctx->cpu_ptr);
>> +}
>> +
>>   static int
>>   gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue)
>>   {
>> @@ -6426,10 +6469,16 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>>          }
>>
>>          memset(mqd->cpu_ptr, 0, size);
>> +       r = gfx_v11_userq_create_ctx_space(uq_mgr, queue);
>> +       if (r) {
>> +               DRM_ERROR("Failed to create CTX space for userqueue (%d)\n", r);
>> +               goto free_mqd;
>> +       }
>> +
>>          r = amdgpu_bo_reserve(mqd->obj, false);
>>          if (unlikely(r != 0)) {
>>                  DRM_ERROR("Failed to reserve mqd for userqueue (%d)", r);
>> -               goto free_mqd;
>> +               goto free_ctx;
>>          }
>>
>>          queue->userq_prop.use_doorbell = true;
>> @@ -6438,12 +6487,15 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>>          amdgpu_bo_unreserve(mqd->obj);
>>          if (r) {
>>                  DRM_ERROR("Failed to init MQD for queue\n");
>> -               goto free_mqd;
>> +               goto free_ctx;
>>          }
>>
>>          DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>>          return 0;
>>
>> +free_ctx:
>> +       gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>> +
>>   free_mqd:
>>          amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>          return r;
>> @@ -6454,6 +6506,7 @@ gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
>>   {
>>          struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>>
>> +       gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>>          amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>   }
>>
>> diff --git a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> index e7da27918bd2..11e8ad649f6e 100644
>> --- a/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> +++ b/drivers/gpu/drm/amd/include/amdgpu_userqueue.h
>> @@ -38,11 +38,17 @@ struct amdgpu_usermode_queue {
>>          int                     queue_id;
>>          int                     queue_type;
>>          uint64_t                doorbell_handle;
>> +       uint64_t                proc_ctx_gpu_addr;
>> +       uint64_t                gang_ctx_gpu_addr;
>> +       uint64_t                gds_ctx_gpu_addr;
>> +       uint64_t                fw_ctx_gpu_addr;
>> +       uint64_t                shadow_ctx_gpu_addr;
>>          uint64_t                flags;
>>          struct amdgpu_mqd_prop  userq_prop;
>>          struct amdgpu_userq_mgr *userq_mgr;
>>          struct amdgpu_vm        *vm;
>>          struct amdgpu_userq_ctx_space mqd;
>> +       struct amdgpu_userq_ctx_space fw_space;
>>   };
>>
>>   struct amdgpu_userq_funcs {
>> --
>> 2.40.0
>>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 06/10] drm/amdgpu: set FW parameters in v11_struct
  2023-05-19 21:22   ` Alex Deucher
@ 2023-05-22  9:06     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-05-22  9:06 UTC (permalink / raw)
  To: Alex Deucher
  Cc: pierre-eric.pelloux-prayer, arvind.yadav, amd-gfx, Alex Deucher,
	contactshashanksharma, Christian Koenig


On 19/05/2023 23:22, Alex Deucher wrote:
> On Mon, Apr 24, 2023 at 1:39 PM Shashank Sharma <shashank.sharma@amd.com> wrote:
>> From: Arvind Yadav <arvind.yadav@amd.com>
>>
>> This patch sets new parameters defined in v11_struct for
>> usermode queue with the respective allocated gpu context
>> space addresses.
>>
>> V4: Split the patch into two parts, keep only the set parameter
>>      part in this series (Alex).
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Cc: Shashank Sharma <shashank.sharma@amd.com>
>> Signed-off-by: Arvind Yadav <arvind.yadav@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 19 ++++++++++++++++++-
>>   1 file changed, 18 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> index f6b33faea86f..86de35292f69 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> @@ -6411,6 +6411,21 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>>          .funcs = &gfx_v11_0_ip_funcs,
>>   };
>>
>> +static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
>
> gfx_v11_0_ for consistency.
>
> Alex

Noted,

Shashank

>> +                                       struct amdgpu_usermode_queue *queue)
>> +{
>> +       struct v11_gfx_mqd *mqd = queue->mqd.cpu_ptr;
>> +
>> +       mqd->shadow_base_lo = queue->shadow_ctx_gpu_addr & 0xfffffffc;
>> +       mqd->shadow_base_hi = upper_32_bits(queue->shadow_ctx_gpu_addr);
>> +
>> +       mqd->gds_bkup_base_lo = queue->gds_ctx_gpu_addr & 0xfffffffc;
>> +       mqd->gds_bkup_base_hi = upper_32_bits(queue->gds_ctx_gpu_addr);
>> +
>> +       mqd->fw_work_area_base_lo = queue->fw_ctx_gpu_addr & 0xfffffffc;
>> +       mqd->fw_work_area_base_lo = upper_32_bits(queue->fw_ctx_gpu_addr);
>> +}
>> +
>>   static int gfx_v11_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
>>                                            struct amdgpu_usermode_queue *queue)
>>   {
>> @@ -6484,12 +6499,14 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>>          queue->userq_prop.use_doorbell = true;
>>          queue->userq_prop.mqd_gpu_addr = mqd->gpu_addr;
>>          r = gfx_v11_mqd->init_mqd(adev, (void *)mqd->cpu_ptr, &queue->userq_prop);
>> -       amdgpu_bo_unreserve(mqd->obj);
>>          if (r) {
>> +               amdgpu_bo_unreserve(mqd->obj);
>>                  DRM_ERROR("Failed to init MQD for queue\n");
>>                  goto free_ctx;
>>          }
>>
>> +       gfx_v11_userq_set_ctx_space(uq_mgr, queue);
>> +       amdgpu_bo_unreserve(mqd->obj);
>>          DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>>          return 0;
>>
>> --
>> 2.40.0
>>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES
  2023-05-19 21:22   ` Alex Deucher
@ 2023-05-22  9:06     ` Shashank Sharma
  0 siblings, 0 replies; 45+ messages in thread
From: Shashank Sharma @ 2023-05-22  9:06 UTC (permalink / raw)
  To: Alex Deucher
  Cc: pierre-eric.pelloux-prayer, arvind.yadav, amd-gfx, Alex Deucher,
	contactshashanksharma, Christian Koenig


On 19/05/2023 23:22, Alex Deucher wrote:
> On Mon, Apr 24, 2023 at 1:39 PM Shashank Sharma <shashank.sharma@amd.com> wrote:
>> This patch adds new functions to map/unmap a usermode queue into
>> the FW, using the MES ring. As soon as this mapping is done, the
>> queue would  be considered ready to accept the workload.
>>
>> V1: Addressed review comments from Alex on the RFC patch series
>>      - Map/Unmap should be IP specific.
>> V2:
>>      Addressed review comments from Christian:
>>      - Fix the wptr_mc_addr calculation (moved into another patch)
>>      Addressed review comments from Alex:
>>      - Do not add fptrs for map/unmap
>>
>> V3: Integration with doorbell manager
>> V4: Rebase
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 67 ++++++++++++++++++++++++++
>>   1 file changed, 67 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> index 86de35292f69..7a45d68091ec 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
>> @@ -31,6 +31,7 @@
>>   #include "amdgpu_smu.h"
>>   #include "amdgpu_atomfirmware.h"
>>   #include "amdgpu_userqueue.h"
>> +#include "amdgpu_mes.h"
>>   #include "imu_v11_0.h"
>>   #include "soc21.h"
>>   #include "nvd.h"
>> @@ -6411,6 +6412,64 @@ const struct amdgpu_ip_block_version gfx_v11_0_ip_block =
>>          .funcs = &gfx_v11_0_ip_funcs,
>>   };
>>
>> +static int gfx_v11_userq_map(struct amdgpu_userq_mgr *uq_mgr,
>> +                            struct amdgpu_usermode_queue *queue)
>> +{
>> +       struct amdgpu_device *adev = uq_mgr->adev;
>> +       struct mes_add_queue_input queue_input;
>> +       int r;
>> +
>> +       memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
>> +
>> +       queue_input.process_va_start = 0;
>> +       queue_input.process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT;
>> +       queue_input.process_quantum = 100000; /* 10ms */
>> +       queue_input.gang_quantum = 10000; /* 1ms */
>> +       queue_input.paging = false;
>> +
>> +       queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
>> +       queue_input.process_context_addr = queue->proc_ctx_gpu_addr;
>> +       queue_input.inprocess_gang_priority = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
>> +       queue_input.gang_global_priority_level = AMDGPU_MES_PRIORITY_LEVEL_NORMAL;
>> +
>> +       queue_input.process_id = queue->vm->pasid;
>> +       queue_input.queue_type = queue->queue_type;
>> +       queue_input.mqd_addr = queue->mqd.gpu_addr;
>> +       queue_input.wptr_addr = queue->userq_prop.wptr_gpu_addr;
>> +       queue_input.queue_size = queue->userq_prop.queue_size >> 2;
>> +       queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
>> +       queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(queue->vm->root.bo);
>> +
>> +       amdgpu_mes_lock(&adev->mes);
>> +       r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
>> +       amdgpu_mes_unlock(&adev->mes);
>> +       if (r) {
>> +               DRM_ERROR("Failed to map queue in HW, err (%d)\n", r);
>> +               return r;
>> +       }
>> +
>> +       DRM_DEBUG_DRIVER("Queue %d mapped successfully\n", queue->queue_id);
>> +       return 0;
>> +}
>> +
>> +static void gfx_v11_userq_unmap(struct amdgpu_userq_mgr *uq_mgr,
>> +                               struct amdgpu_usermode_queue *queue)
>> +{
>> +       struct amdgpu_device *adev = uq_mgr->adev;
>> +       struct mes_remove_queue_input queue_input;
>> +       int r;
>> +
>> +       memset(&queue_input, 0x0, sizeof(struct mes_remove_queue_input));
>> +       queue_input.doorbell_offset = queue->userq_prop.doorbell_index;
>> +       queue_input.gang_context_addr = queue->gang_ctx_gpu_addr;
>> +
>> +       amdgpu_mes_lock(&adev->mes);
>> +       r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
>> +       amdgpu_mes_unlock(&adev->mes);
>> +       if (r)
>> +               DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r);
>> +}
> gfx_v11_0_ for consistency.
>
> Alex

Noted,

Shashank

>> +
>>   static void gfx_v11_userq_set_ctx_space(struct amdgpu_userq_mgr *uq_mgr,
>>                                          struct amdgpu_usermode_queue *queue)
>>   {
>> @@ -6507,6 +6566,13 @@ gfx_v11_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode
>>
>>          gfx_v11_userq_set_ctx_space(uq_mgr, queue);
>>          amdgpu_bo_unreserve(mqd->obj);
>> +
>> +       /* Map the queue in HW using MES ring */
>> +       r = gfx_v11_userq_map(uq_mgr, queue);
>> +       if (r) {
>> +               DRM_ERROR("Failed to map userqueue (%d)\n", r);
>> +               goto free_ctx;
>> +       }
>>          DRM_DEBUG_DRIVER("MQD for queue %d created\n", queue->queue_id);
>>          return 0;
>>
>> @@ -6523,6 +6589,7 @@ gfx_v11_userq_mqd_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermod
>>   {
>>          struct amdgpu_userq_ctx_space *mqd = &queue->mqd;
>>
>> +       gfx_v11_userq_unmap(uq_mgr, queue);
>>          gfx_v11_userq_destroy_ctx_space(uq_mgr, queue);
>>          amdgpu_bo_free_kernel(&mqd->obj, &mqd->gpu_addr, &mqd->cpu_ptr);
>>   }
>> --
>> 2.40.0
>>

^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2023-05-22  9:07 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-24 17:38 [PATCH v4 00/10] AMDGPU usermode queues Shashank Sharma
2023-04-24 17:38 ` [PATCH v4 01/10] drm/amdgpu: UAPI for user queue management Shashank Sharma
2023-05-19 21:03   ` Alex Deucher
2023-05-22  8:54     ` Shashank Sharma
2023-04-24 17:38 ` [PATCH v4 02/10] drm/amdgpu: add usermode queue base code Shashank Sharma
2023-04-25 12:03   ` Christian König
2023-04-25 12:19     ` Shashank Sharma
2023-04-24 17:38 ` [PATCH v4 03/10] drm/amdgpu: add new IOCTL for usermode queue Shashank Sharma
2023-04-25 12:14   ` Christian König
2023-04-25 12:21     ` Shashank Sharma
2023-04-24 17:38 ` [PATCH v4 04/10] drm/amdgpu: create GFX-gen11 MQD for userqueue Shashank Sharma
2023-04-25 12:27   ` Christian König
2023-04-25 13:10     ` Shashank Sharma
2023-04-25 13:45       ` Christian König
2023-04-25 17:02         ` Shashank Sharma
2023-05-19 21:19   ` Alex Deucher
2023-05-22  9:05     ` Shashank Sharma
2023-04-24 17:38 ` [PATCH v4 05/10] drm/amdgpu: create context space for usermode queue Shashank Sharma
2023-04-25 12:30   ` Christian König
2023-04-25 13:13     ` Shashank Sharma
2023-04-25 17:38       ` Deucher, Alexander
2023-04-25 20:00         ` Sharma, Shashank
2023-05-19 21:21   ` Alex Deucher
2023-05-22  9:05     ` Shashank Sharma
2023-04-24 17:38 ` [PATCH v4 06/10] drm/amdgpu: set FW parameters in v11_struct Shashank Sharma
2023-04-25 12:32   ` Christian König
2023-04-25 13:27     ` Shashank Sharma
2023-05-19 21:22   ` Alex Deucher
2023-05-22  9:06     ` Shashank Sharma
2023-04-24 17:38 ` [PATCH v4 07/10] drm/amdgpu: map usermode queue into MES Shashank Sharma
2023-04-25 12:34   ` Christian König
2023-04-25 13:31     ` Shashank Sharma
2023-04-25 15:33       ` Christian König
2023-04-25 16:56         ` Shashank Sharma
2023-05-19 21:22   ` Alex Deucher
2023-05-22  9:06     ` Shashank Sharma
2023-04-24 17:38 ` [PATCH v4 08/10] drm/amdgpu: map wptr BO into GART Shashank Sharma
2023-04-25 12:36   ` Christian König
2023-04-25 13:33     ` Shashank Sharma
2023-04-24 17:38 ` [PATCH v4 09/10] drm/amdgpu: generate doorbell index for userqueue Shashank Sharma
2023-04-25 12:38   ` Christian König
2023-04-25 13:34     ` Shashank Sharma
2023-04-24 17:38 ` [PATCH v4 10/10] drm/amdgpu: cleanup leftover queues Shashank Sharma
2023-04-25 12:40   ` Christian König
2023-04-25 13:34     ` Shashank Sharma

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox