All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/16] AMDGPU Doorbell manager
@ 2023-03-29 15:47 Shashank Sharma
  2023-03-29 15:47 ` [PATCH 01/16] drm/amdgpu: rename num_doorbells Shashank Sharma
                   ` (16 more replies)
  0 siblings, 17 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig,
	Shashank Sharma

The doorbells in AMDGPU drivers are currently managed by different
users in a scattered way, across the driver. The existing clients are:
- AMDGPU graphics driver for kernel level doorbell writes.
- AMDGPU MES module for kernel level doorbell write (MES ring test).
- AMDGPU MES modules for kernel level aggregated doorbell writes.
- AMDGPU MES module for MES process doorbell writes.
- AMDKFD module for KFD/KIQ kernel doorbell writes.
- AMDKFD module for KFD process doorbell writes.
- AMDGPU usermode queues for usermode doorbell writes (upcoming).

This patch series introduces Doorbell-manager to keep the doorbell handling
at a central place. The fundamental changes are:

- Introduce and accommodate a new GEM domain for doorbells.
- Prepare the AMDGPU ttm backend for handling doorbell allocation.
- Introduce doorbell-manager functions to allocate, free and index
  doorbells in one unique way.
- Create doorbell BOs for kernel-level and process level doorbell
  opertations, and place it in existing structures.
- Modify the existing graphics, KFD and MES code to use the
  doorbell-manager functions.
- Remove the existing doorbell management code in KFD/MES.

PS: This series has been sanity tested with kfd_test_suit to ensure
    it is not introducing any regressions due to kfd doorbell changes.

The idea is that:
- a kernel client can call doorbell manager functions to allocate/free
  doorbell pages.
- a usermode app can directly allocate a page from the doorbell bar just
  like a GEM object and use it for different usermode queues.

Alex Deucher (2):
  drm/amdgpu: add UAPI for allocating doorbell memory
  drm/amdgpu: accommodate DOMAIN/PL_DOORBELL

Shashank Sharma (14):
  drm/amdgpu: rename num_doorbells
  drm/amdgpu: include protection for doobell.h
  drm/amdgpu: create a new file for doorbell manager
  drm/amdgpu: don't modify num_doorbells for mes
  drm/amdgpu: add helper to create doorbell pages
  drm/amdgpu: initialize ttm for doorbells
  drm/amdgpu: create kernel doorbell page
  drm/amdgpu: validate doorbell read/write
  drm/amdgpu: get absolute offset from doorbell index
  drm/amdgpu: use doorbell manager for kfd kernel doorbells
  drm/amdgpu: use doorbell manager for kfd process doorbells
  drm/amdgpu: remove ununsed functions and variables
  drm/amdgpu: use doorbell mgr for MES kernel doorbells
  drm/amdgpu: user doorbell mgr for MES process doorbells

 drivers/gpu/drm/amd/amdgpu/Makefile           |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c    |   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 164 ----------
 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h  | 102 +++++-
 .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 304 ++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c       | 165 +++++-----
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h       |  17 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c    |  11 +-
 .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h    |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  31 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h       |   1 +
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c      |  13 -
 drivers/gpu/drm/amd/amdkfd/kfd_device.c       |   4 +-
 .../drm/amd/amdkfd/kfd_device_queue_manager.c |  16 +-
 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c     | 198 ++++--------
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |  23 +-
 drivers/gpu/drm/amd/amdkfd/kfd_process.c      |  26 +-
 .../amd/amdkfd/kfd_process_queue_manager.c    |  16 +-
 include/uapi/drm/amdgpu_drm.h                 |   7 +-
 19 files changed, 636 insertions(+), 472 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c

-- 
2.40.0


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

* [PATCH 01/16] drm/amdgpu: rename num_doorbells
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 11:04   ` Christian König
                     ` (3 more replies)
  2023-03-29 15:47 ` [PATCH 02/16] drm/amdgpu: include protection for doobell.h Shashank Sharma
                   ` (15 subsequent siblings)
  16 siblings, 4 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Mukul Joshi, Shashank Sharma, Felix Kuehling, Alex Deucher,
	Shashank Sharma, Christian Koenig

From: Shashank Sharma <contactshashanksharma@gmail.com>

Rename doorbell.num_doorbells to doorbell.num_kernel_doorbells to
make it more readable.

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_amdkfd.c   |  6 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   | 22 ++++++++++----------
 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h |  4 +++-
 3 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
index f99d4873bf22..0385f7f69278 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -96,7 +96,7 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
 					 size_t *start_offset)
 {
 	/*
-	 * The first num_doorbells are used by amdgpu.
+	 * The first num_kernel_doorbells are used by amdgpu.
 	 * amdkfd takes whatever's left in the aperture.
 	 */
 	if (adev->enable_mes) {
@@ -109,11 +109,11 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
 		*aperture_base = adev->doorbell.base;
 		*aperture_size = 0;
 		*start_offset = 0;
-	} else if (adev->doorbell.size > adev->doorbell.num_doorbells *
+	} else if (adev->doorbell.size > adev->doorbell.num_kernel_doorbells *
 						sizeof(u32)) {
 		*aperture_base = adev->doorbell.base;
 		*aperture_size = adev->doorbell.size;
-		*start_offset = adev->doorbell.num_doorbells * sizeof(u32);
+		*start_offset = adev->doorbell.num_kernel_doorbells * sizeof(u32);
 	} else {
 		*aperture_base = 0;
 		*aperture_size = 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index afe6af9c0138..57ee1c4a81e9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -593,7 +593,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
 	if (amdgpu_device_skip_hw_access(adev))
 		return 0;
 
-	if (index < adev->doorbell.num_doorbells) {
+	if (index < adev->doorbell.num_kernel_doorbells) {
 		return readl(adev->doorbell.ptr + index);
 	} else {
 		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
@@ -616,7 +616,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
 	if (amdgpu_device_skip_hw_access(adev))
 		return;
 
-	if (index < adev->doorbell.num_doorbells) {
+	if (index < adev->doorbell.num_kernel_doorbells) {
 		writel(v, adev->doorbell.ptr + index);
 	} else {
 		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
@@ -637,7 +637,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
 	if (amdgpu_device_skip_hw_access(adev))
 		return 0;
 
-	if (index < adev->doorbell.num_doorbells) {
+	if (index < adev->doorbell.num_kernel_doorbells) {
 		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
 	} else {
 		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
@@ -660,7 +660,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
 	if (amdgpu_device_skip_hw_access(adev))
 		return;
 
-	if (index < adev->doorbell.num_doorbells) {
+	if (index < adev->doorbell.num_kernel_doorbells) {
 		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
 	} else {
 		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
@@ -1034,7 +1034,7 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
 	if (adev->asic_type < CHIP_BONAIRE) {
 		adev->doorbell.base = 0;
 		adev->doorbell.size = 0;
-		adev->doorbell.num_doorbells = 0;
+		adev->doorbell.num_kernel_doorbells = 0;
 		adev->doorbell.ptr = NULL;
 		return 0;
 	}
@@ -1049,27 +1049,27 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
 	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
 
 	if (adev->enable_mes) {
-		adev->doorbell.num_doorbells =
+		adev->doorbell.num_kernel_doorbells =
 			adev->doorbell.size / sizeof(u32);
 	} else {
-		adev->doorbell.num_doorbells =
+		adev->doorbell.num_kernel_doorbells =
 			min_t(u32, adev->doorbell.size / sizeof(u32),
 			      adev->doorbell_index.max_assignment+1);
-		if (adev->doorbell.num_doorbells == 0)
+		if (adev->doorbell.num_kernel_doorbells == 0)
 			return -EINVAL;
 
 		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
 		 * paging queue doorbell use the second page. The
 		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
 		 * doorbells are in the first page. So with paging queue enabled,
-		 * the max num_doorbells should + 1 page (0x400 in dword)
+		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
 		 */
 		if (adev->asic_type >= CHIP_VEGA10)
-			adev->doorbell.num_doorbells += 0x400;
+			adev->doorbell.num_kernel_doorbells += 0x400;
 	}
 
 	adev->doorbell.ptr = ioremap(adev->doorbell.base,
-				     adev->doorbell.num_doorbells *
+				     adev->doorbell.num_kernel_doorbells *
 				     sizeof(u32));
 	if (adev->doorbell.ptr == NULL)
 		return -ENOMEM;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
index 7199b6b0be81..12263986f889 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
@@ -29,7 +29,9 @@ struct amdgpu_doorbell {
 	resource_size_t		base;
 	resource_size_t		size;
 	u32 __iomem		*ptr;
-	u32			num_doorbells;	/* Number of doorbells actually reserved for amdgpu. */
+
+	/* Number of doorbells reserved for amdgpu kernel driver */
+	u32 num_kernel_doorbells;
 };
 
 /* Reserved doorbells for amdgpu (including multimedia).
-- 
2.40.0


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

* [PATCH 02/16] drm/amdgpu: include protection for doobell.h
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
  2023-03-29 15:47 ` [PATCH 01/16] drm/amdgpu: rename num_doorbells Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 11:05   ` Christian König
  2023-03-30 14:20   ` Alex Deucher
  2023-03-29 15:47 ` [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager Shashank Sharma
                   ` (14 subsequent siblings)
  16 siblings, 2 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Mukul Joshi, Shashank Sharma, Felix Kuehling, Alex Deucher,
	Shashank Sharma, Christian Koenig

From: Shashank Sharma <contactshashanksharma@gmail.com>

This patch adds double include protection for doorbell.h

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_doorbell.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
index 12263986f889..6064943a1b53 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
@@ -21,6 +21,9 @@
  *
  */
 
+#ifndef AMDGPU_DOORBELL_H
+#define AMDGPU_DOORBELL_H
+
 /*
  * GPU doorbell structures, functions & helpers
  */
@@ -308,3 +311,4 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
 #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
 #define WDOORBELL64(index, v) amdgpu_mm_wdoorbell64(adev, (index), (v))
 
+#endif
\ No newline at end of file
-- 
2.40.0


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

* [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
  2023-03-29 15:47 ` [PATCH 01/16] drm/amdgpu: rename num_doorbells Shashank Sharma
  2023-03-29 15:47 ` [PATCH 02/16] drm/amdgpu: include protection for doobell.h Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 11:09   ` Christian König
  2023-03-30 14:23   ` Alex Deucher
  2023-03-29 15:47 ` [PATCH 04/16] drm/amdgpu: don't modify num_doorbells for mes Shashank Sharma
                   ` (13 subsequent siblings)
  16 siblings, 2 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Mukul Joshi, Shashank Sharma, Felix Kuehling, Alex Deucher,
	Shashank Sharma, Christian Koenig

From: Shashank Sharma <contactshashanksharma@gmail.com>

This patch:
- creates a new file for doorbell management.
- moves doorbell code from amdgpu_device.c to this file.

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/Makefile           |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 164 ---------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h  |  22 +++
 .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 186 ++++++++++++++++++
 4 files changed, 209 insertions(+), 165 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c

diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index 798d0e9a60b7..204665f20319 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -41,7 +41,7 @@ ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
 amdgpu-y := amdgpu_drv.o
 
 # add KMS driver
-amdgpu-y += amdgpu_device.o amdgpu_kms.o \
+amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
 	amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
 	atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
 	amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 57ee1c4a81e9..7f8fcac4f18b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -579,94 +579,6 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
 	}
 }
 
-/**
- * amdgpu_mm_rdoorbell - read a doorbell dword
- *
- * @adev: amdgpu_device pointer
- * @index: doorbell index
- *
- * Returns the value in the doorbell aperture at the
- * requested doorbell index (CIK).
- */
-u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
-{
-	if (amdgpu_device_skip_hw_access(adev))
-		return 0;
-
-	if (index < adev->doorbell.num_kernel_doorbells) {
-		return readl(adev->doorbell.ptr + index);
-	} else {
-		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
-		return 0;
-	}
-}
-
-/**
- * amdgpu_mm_wdoorbell - write a doorbell dword
- *
- * @adev: amdgpu_device pointer
- * @index: doorbell index
- * @v: value to write
- *
- * Writes @v to the doorbell aperture at the
- * requested doorbell index (CIK).
- */
-void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
-{
-	if (amdgpu_device_skip_hw_access(adev))
-		return;
-
-	if (index < adev->doorbell.num_kernel_doorbells) {
-		writel(v, adev->doorbell.ptr + index);
-	} else {
-		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
-	}
-}
-
-/**
- * amdgpu_mm_rdoorbell64 - read a doorbell Qword
- *
- * @adev: amdgpu_device pointer
- * @index: doorbell index
- *
- * Returns the value in the doorbell aperture at the
- * requested doorbell index (VEGA10+).
- */
-u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
-{
-	if (amdgpu_device_skip_hw_access(adev))
-		return 0;
-
-	if (index < adev->doorbell.num_kernel_doorbells) {
-		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
-	} else {
-		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
-		return 0;
-	}
-}
-
-/**
- * amdgpu_mm_wdoorbell64 - write a doorbell Qword
- *
- * @adev: amdgpu_device pointer
- * @index: doorbell index
- * @v: value to write
- *
- * Writes @v to the doorbell aperture at the
- * requested doorbell index (VEGA10+).
- */
-void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
-{
-	if (amdgpu_device_skip_hw_access(adev))
-		return;
-
-	if (index < adev->doorbell.num_kernel_doorbells) {
-		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
-	} else {
-		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
-	}
-}
-
 /**
  * amdgpu_device_indirect_rreg - read an indirect register
  *
@@ -1016,82 +928,6 @@ int amdgpu_device_pci_reset(struct amdgpu_device *adev)
 	return pci_reset_function(adev->pdev);
 }
 
-/*
- * GPU doorbell aperture helpers function.
- */
-/**
- * amdgpu_device_doorbell_init - Init doorbell driver information.
- *
- * @adev: amdgpu_device pointer
- *
- * Init doorbell driver information (CIK)
- * Returns 0 on success, error on failure.
- */
-static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
-{
-
-	/* No doorbell on SI hardware generation */
-	if (adev->asic_type < CHIP_BONAIRE) {
-		adev->doorbell.base = 0;
-		adev->doorbell.size = 0;
-		adev->doorbell.num_kernel_doorbells = 0;
-		adev->doorbell.ptr = NULL;
-		return 0;
-	}
-
-	if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
-		return -EINVAL;
-
-	amdgpu_asic_init_doorbell_index(adev);
-
-	/* doorbell bar mapping */
-	adev->doorbell.base = pci_resource_start(adev->pdev, 2);
-	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
-
-	if (adev->enable_mes) {
-		adev->doorbell.num_kernel_doorbells =
-			adev->doorbell.size / sizeof(u32);
-	} else {
-		adev->doorbell.num_kernel_doorbells =
-			min_t(u32, adev->doorbell.size / sizeof(u32),
-			      adev->doorbell_index.max_assignment+1);
-		if (adev->doorbell.num_kernel_doorbells == 0)
-			return -EINVAL;
-
-		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
-		 * paging queue doorbell use the second page. The
-		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
-		 * doorbells are in the first page. So with paging queue enabled,
-		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
-		 */
-		if (adev->asic_type >= CHIP_VEGA10)
-			adev->doorbell.num_kernel_doorbells += 0x400;
-	}
-
-	adev->doorbell.ptr = ioremap(adev->doorbell.base,
-				     adev->doorbell.num_kernel_doorbells *
-				     sizeof(u32));
-	if (adev->doorbell.ptr == NULL)
-		return -ENOMEM;
-
-	return 0;
-}
-
-/**
- * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
- *
- * @adev: amdgpu_device pointer
- *
- * Tear down doorbell driver information (CIK)
- */
-static void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
-{
-	iounmap(adev->doorbell.ptr);
-	adev->doorbell.ptr = NULL;
-}
-
-
-
 /*
  * amdgpu_device_wb_*()
  * Writeback is the method by which the GPU updates special pages in memory
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
index 6064943a1b53..f9c3b77bf65d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
@@ -306,6 +306,28 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
 u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index);
 void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
 
+/*
+ * GPU doorbell aperture helpers function.
+ */
+/**
+ * amdgpu_device_doorbell_init - Init doorbell driver information.
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Init doorbell driver information (CIK)
+ * Returns 0 on success, error on failure.
+ */
+int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
+
+/**
+ * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Tear down doorbell driver information (CIK)
+ */
+void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
+
 #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
 #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
 #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
new file mode 100644
index 000000000000..2206926ba289
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
@@ -0,0 +1,186 @@
+/*
+ * 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"
+
+/**
+ * amdgpu_mm_rdoorbell - read a doorbell dword
+ *
+ * @adev: amdgpu_device pointer
+ * @index: doorbell index
+ *
+ * Returns the value in the doorbell aperture at the
+ * requested doorbell index (CIK).
+ */
+u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
+{
+	if (amdgpu_device_skip_hw_access(adev))
+		return 0;
+
+	if (index < adev->doorbell.num_kernel_doorbells) {
+		return readl(adev->doorbell.ptr + index);
+	} else {
+		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
+		return 0;
+	}
+}
+
+/**
+ * amdgpu_mm_wdoorbell - write a doorbell dword
+ *
+ * @adev: amdgpu_device pointer
+ * @index: doorbell index
+ * @v: value to write
+ *
+ * Writes @v to the doorbell aperture at the
+ * requested doorbell index (CIK).
+ */
+void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
+{
+	if (amdgpu_device_skip_hw_access(adev))
+		return;
+
+	if (index < adev->doorbell.num_kernel_doorbells) {
+		writel(v, adev->doorbell.ptr + index);
+	} else {
+		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
+	}
+}
+
+/**
+ * amdgpu_mm_rdoorbell64 - read a doorbell Qword
+ *
+ * @adev: amdgpu_device pointer
+ * @index: doorbell index
+ *
+ * Returns the value in the doorbell aperture at the
+ * requested doorbell index (VEGA10+).
+ */
+u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
+{
+	if (amdgpu_device_skip_hw_access(adev))
+		return 0;
+
+	if (index < adev->doorbell.num_kernel_doorbells) {
+		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
+	} else {
+		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
+		return 0;
+	}
+}
+
+/**
+ * amdgpu_mm_wdoorbell64 - write a doorbell Qword
+ *
+ * @adev: amdgpu_device pointer
+ * @index: doorbell index
+ * @v: value to write
+ *
+ * Writes @v to the doorbell aperture at the
+ * requested doorbell index (VEGA10+).
+ */
+void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
+{
+	if (amdgpu_device_skip_hw_access(adev))
+		return;
+
+	if (index < adev->doorbell.num_kernel_doorbells) {
+		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
+	} else {
+		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
+	}
+}
+
+/*
+ * GPU doorbell aperture helpers function.
+ */
+/**
+ * amdgpu_device_doorbell_init - Init doorbell driver information.
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Init doorbell driver information (CIK)
+ * Returns 0 on success, error on failure.
+ */
+int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
+{
+
+	/* No doorbell on SI hardware generation */
+	if (adev->asic_type < CHIP_BONAIRE) {
+		adev->doorbell.base = 0;
+		adev->doorbell.size = 0;
+		adev->doorbell.num_kernel_doorbells = 0;
+		adev->doorbell.ptr = NULL;
+		return 0;
+	}
+
+	if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
+		return -EINVAL;
+
+	amdgpu_asic_init_doorbell_index(adev);
+
+	/* doorbell bar mapping */
+	adev->doorbell.base = pci_resource_start(adev->pdev, 2);
+	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
+
+	if (adev->enable_mes) {
+		adev->doorbell.num_kernel_doorbells =
+			adev->doorbell.size / sizeof(u32);
+	} else {
+		adev->doorbell.num_kernel_doorbells =
+			min_t(u32, adev->doorbell.size / sizeof(u32),
+			      adev->doorbell_index.max_assignment+1);
+		if (adev->doorbell.num_kernel_doorbells == 0)
+			return -EINVAL;
+
+		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
+		 * paging queue doorbell use the second page. The
+		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
+		 * doorbells are in the first page. So with paging queue enabled,
+		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
+		 */
+		if (adev->asic_type >= CHIP_VEGA10)
+			adev->doorbell.num_kernel_doorbells += 0x400;
+	}
+
+	adev->doorbell.ptr = ioremap(adev->doorbell.base,
+				     adev->doorbell.num_kernel_doorbells *
+				     sizeof(u32));
+	if (adev->doorbell.ptr == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/**
+ * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Tear down doorbell driver information (CIK)
+ */
+void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
+{
+	iounmap(adev->doorbell.ptr);
+	adev->doorbell.ptr = NULL;
+}
-- 
2.40.0


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

* [PATCH 04/16] drm/amdgpu: don't modify num_doorbells for mes
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (2 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 11:10   ` Christian König
  2023-03-30 14:24   ` Alex Deucher
  2023-03-29 15:47 ` [PATCH 05/16] drm/amdgpu: add UAPI for allocating doorbell memory Shashank Sharma
                   ` (12 subsequent siblings)
  16 siblings, 2 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Mukul Joshi, Shashank Sharma, Felix Kuehling, Alex Deucher,
	Shashank Sharma, Christian Koenig

From: Shashank Sharma <contactshashanksharma@gmail.com>

This patch removes the check and change in num_kernel_doorbells
for MES, which is not being used anywhere by MES code.

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

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
index 2206926ba289..1aea92363fd3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
@@ -143,25 +143,21 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
 	adev->doorbell.base = pci_resource_start(adev->pdev, 2);
 	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
 
-	if (adev->enable_mes) {
-		adev->doorbell.num_kernel_doorbells =
-			adev->doorbell.size / sizeof(u32);
-	} else {
-		adev->doorbell.num_kernel_doorbells =
-			min_t(u32, adev->doorbell.size / sizeof(u32),
-			      adev->doorbell_index.max_assignment+1);
-		if (adev->doorbell.num_kernel_doorbells == 0)
-			return -EINVAL;
-
-		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
-		 * paging queue doorbell use the second page. The
-		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
-		 * doorbells are in the first page. So with paging queue enabled,
-		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
-		 */
-		if (adev->asic_type >= CHIP_VEGA10)
-			adev->doorbell.num_kernel_doorbells += 0x400;
-	}
+	adev->doorbell.num_kernel_doorbells =
+		min_t(u32, adev->doorbell.size / sizeof(u32),
+				adev->doorbell_index.max_assignment+1);
+	if (adev->doorbell.num_kernel_doorbells == 0)
+		return -EINVAL;
+
+	/*
+	 * For Vega, reserve and map two pages on doorbell BAR since SDMA
+	 * paging queue doorbell use the second page. The
+	 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
+	 * doorbells are in the first page. So with paging queue enabled,
+	 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
+	 */
+	if (adev->asic_type >= CHIP_VEGA10)
+		adev->doorbell.num_kernel_doorbells += 0x400;
 
 	adev->doorbell.ptr = ioremap(adev->doorbell.base,
 				     adev->doorbell.num_kernel_doorbells *
-- 
2.40.0


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

* [PATCH 05/16] drm/amdgpu: add UAPI for allocating doorbell memory
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (3 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 04/16] drm/amdgpu: don't modify num_doorbells for mes Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 11:11   ` Christian König
  2023-03-29 15:47 ` [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL Shashank Sharma
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx; +Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig

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

This patch adds flags for a new gem domain AMDGPU_GEM_DOMAIN_DOORBELL
in the UAPI layer.

V2: Drop 'memory' from description (Christian)

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 include/uapi/drm/amdgpu_drm.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 4038abe8505a..cc5d551abda5 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -94,6 +94,9 @@ extern "C" {
  *
  * %AMDGPU_GEM_DOMAIN_OA	Ordered append, used by 3D or Compute engines
  * for appending data.
+ *
+ * %AMDGPU_GEM_DOMAIN_DOORBELL	Doorbell. It is an MMIO region for
+ * signalling user mode queues.
  */
 #define AMDGPU_GEM_DOMAIN_CPU		0x1
 #define AMDGPU_GEM_DOMAIN_GTT		0x2
@@ -101,12 +104,14 @@ extern "C" {
 #define AMDGPU_GEM_DOMAIN_GDS		0x8
 #define AMDGPU_GEM_DOMAIN_GWS		0x10
 #define AMDGPU_GEM_DOMAIN_OA		0x20
+#define AMDGPU_GEM_DOMAIN_DOORBELL	0x40
 #define AMDGPU_GEM_DOMAIN_MASK		(AMDGPU_GEM_DOMAIN_CPU | \
 					 AMDGPU_GEM_DOMAIN_GTT | \
 					 AMDGPU_GEM_DOMAIN_VRAM | \
 					 AMDGPU_GEM_DOMAIN_GDS | \
 					 AMDGPU_GEM_DOMAIN_GWS | \
-					 AMDGPU_GEM_DOMAIN_OA)
+					 AMDGPU_GEM_DOMAIN_OA | \
+					 AMDGPU_GEM_DOMAIN_DOORBELL)
 
 /* Flag that CPU access will be required for the case of VRAM domain */
 #define AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED	(1 << 0)
-- 
2.40.0


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

* [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (4 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 05/16] drm/amdgpu: add UAPI for allocating doorbell memory Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 11:14   ` Christian König
  2023-03-30 19:59   ` Alex Deucher
  2023-03-29 15:47 ` [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages Shashank Sharma
                   ` (10 subsequent siblings)
  16 siblings, 2 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig,
	Shashank Sharma

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

This patch adds changes:
- to accommodate the new GEM domain DOORBELL
- to accommodate the new TTM PL DOORBELL

in order to manage doorbell pages as GEM object.

V2: Addressed reviwe comments from Christian
    - drop the doorbell changes for pinning/unpinning
    - drop the doorbell changes for dma-buf map
    - drop the doorbell changes for sgt
    - no need to handle TTM_PL_FLAG_CONTIGUOUS for doorbell
    - add caching type for doorbell

Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian Koenig <christian.koenig@amd.com>

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c     | 11 ++++++++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h |  2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c        | 16 +++++++++++++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h        |  1 +
 4 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 4e684c2afc70..0ec080e240ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -147,6 +147,14 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
 		c++;
 	}
 
+	if (domain & AMDGPU_GEM_DOMAIN_DOORBELL) {
+		places[c].fpfn = 0;
+		places[c].lpfn = 0;
+		places[c].mem_type = AMDGPU_PL_DOORBELL;
+		places[c].flags = 0;
+		c++;
+	}
+
 	if (domain & AMDGPU_GEM_DOMAIN_GTT) {
 		places[c].fpfn = 0;
 		places[c].lpfn = 0;
@@ -466,7 +474,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
 		goto fail;
 	}
 
-	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
+	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU,  AMDGPU_GEM_DOMAIN_DOORBELL */
 	return true;
 
 fail:
@@ -1013,6 +1021,7 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo)
 	} else if (bo->tbo.resource->mem_type == TTM_PL_TT) {
 		atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size);
 	}
+
 }
 
 static const char *amdgpu_vram_names[] = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
index 5c4f93ee0c57..3c988cc406e4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
@@ -90,6 +90,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
 		cur->node = block;
 		break;
 	case TTM_PL_TT:
+	case AMDGPU_PL_DOORBELL:
 		node = to_ttm_range_mgr_node(res)->mm_nodes;
 		while (start >= node->size << PAGE_SHIFT)
 			start -= node++->size << PAGE_SHIFT;
@@ -152,6 +153,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
 		cur->size = min(amdgpu_vram_mgr_block_size(block), cur->remaining);
 		break;
 	case TTM_PL_TT:
+	case AMDGPU_PL_DOORBELL:
 		node = cur->node;
 
 		cur->node = ++node;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 55e0284b2bdd..6f61491ef3dd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -128,6 +128,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
 	case AMDGPU_PL_GDS:
 	case AMDGPU_PL_GWS:
 	case AMDGPU_PL_OA:
+	case AMDGPU_PL_DOORBELL:
 		placement->num_placement = 0;
 		placement->num_busy_placement = 0;
 		return;
@@ -500,9 +501,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
 	if (old_mem->mem_type == AMDGPU_PL_GDS ||
 	    old_mem->mem_type == AMDGPU_PL_GWS ||
 	    old_mem->mem_type == AMDGPU_PL_OA ||
+	    old_mem->mem_type == AMDGPU_PL_DOORBELL ||
 	    new_mem->mem_type == AMDGPU_PL_GDS ||
 	    new_mem->mem_type == AMDGPU_PL_GWS ||
-	    new_mem->mem_type == AMDGPU_PL_OA) {
+	    new_mem->mem_type == AMDGPU_PL_OA ||
+	    new_mem->mem_type == AMDGPU_PL_DOORBELL) {
 		/* Nothing to save here */
 		ttm_bo_move_null(bo, new_mem);
 		goto out;
@@ -586,6 +589,12 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
 		mem->bus.offset += adev->gmc.aper_base;
 		mem->bus.is_iomem = true;
 		break;
+	case AMDGPU_PL_DOORBELL:
+		mem->bus.offset = mem->start << PAGE_SHIFT;
+		mem->bus.offset += adev->doorbell.base;
+		mem->bus.is_iomem = true;
+		mem->bus.caching = ttm_uncached;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -600,6 +609,10 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
 
 	amdgpu_res_first(bo->resource, (u64)page_offset << PAGE_SHIFT, 0,
 			 &cursor);
+
+	if (bo->resource->mem_type == AMDGPU_PL_DOORBELL)
+		return ((uint64_t)(adev->doorbell.base + cursor.start)) >> PAGE_SHIFT;
+
 	return (adev->gmc.aper_base + cursor.start) >> PAGE_SHIFT;
 }
 
@@ -1267,6 +1280,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem)
 		flags |= AMDGPU_PTE_VALID;
 
 	if (mem && (mem->mem_type == TTM_PL_TT ||
+		    mem->mem_type == AMDGPU_PL_DOORBELL ||
 		    mem->mem_type == AMDGPU_PL_PREEMPT)) {
 		flags |= AMDGPU_PTE_SYSTEM;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index e2cd5894afc9..761cd6b2b942 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -33,6 +33,7 @@
 #define AMDGPU_PL_GWS		(TTM_PL_PRIV + 1)
 #define AMDGPU_PL_OA		(TTM_PL_PRIV + 2)
 #define AMDGPU_PL_PREEMPT	(TTM_PL_PRIV + 3)
+#define AMDGPU_PL_DOORBELL	(TTM_PL_PRIV + 4)
 
 #define AMDGPU_GTT_MAX_TRANSFER_SIZE	512
 #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS	2
-- 
2.40.0


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

* [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (5 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 11:29   ` Christian König
                     ` (2 more replies)
  2023-03-29 15:47 ` [PATCH 08/16] drm/amdgpu: initialize ttm for doorbells Shashank Sharma
                   ` (9 subsequent siblings)
  16 siblings, 3 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Mukul Joshi, Shashank Sharma, Felix Kuehling, Alex Deucher,
	Shashank Sharma, Christian Koenig

From: Shashank Sharma <contactshashanksharma@gmail.com>

This patch adds helper functions to create and free doorbell
pages for kernel objects.

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_doorbell.h  | 41 ++++++++++++++++
 .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
 2 files changed, 90 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
index f9c3b77bf65d..6581b78fe438 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
@@ -27,6 +27,24 @@
 /*
  * GPU doorbell structures, functions & helpers
  */
+
+/* Structure to hold doorbell pages from PCI doorbell BAR */
+struct amdgpu_doorbell_obj {
+	struct amdgpu_bo *bo;
+	uint64_t gpu_addr;
+	uint32_t *cpu_addr;
+	uint32_t size;
+
+	/* First index in this object */
+	uint32_t start;
+
+	/* Last index in this object */
+	uint32_t end;
+
+	/* bitmap for dynamic doorbell allocation from this object */
+	unsigned long *doorbell_bitmap;
+};
+
 struct amdgpu_doorbell {
 	/* doorbell mmio */
 	resource_size_t		base;
@@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
  */
 void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
 
+/**
+ * amdgpu_doorbell_free_page - Free a doorbell page
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * @db_age: previously allocated doobell page details
+ *
+ */
+void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
+				struct amdgpu_doorbell_obj *db_obj);
+
+/**
+ * amdgpu_doorbell_alloc_page - create a page from doorbell pool
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * @db_age: doobell page structure to fill details with
+ *
+ * returns 0 on success, else error number
+ */
+int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
+				struct amdgpu_doorbell_obj *db_obj);
+
 #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
 #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
 #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
index 1aea92363fd3..8be15b82b545 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
@@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
 	}
 }
 
+/**
+ * amdgpu_doorbell_free_page - Free a doorbell page
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * @db_age: previously allocated doobell page details
+ *
+ */
+void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
+					struct amdgpu_doorbell_obj *db_obj)
+{
+	amdgpu_bo_free_kernel(&db_obj->bo,
+			      &db_obj->gpu_addr,
+			      (void **)&db_obj->cpu_addr);
+
+}
+
+/**
+ * amdgpu_doorbell_alloc_page - create a page from doorbell pool
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * @db_age: doobell page structure to fill details with
+ *
+ * returns 0 on success, else error number
+ */
+int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
+				struct amdgpu_doorbell_obj *db_obj)
+{
+	int r;
+
+	db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
+
+	r = amdgpu_bo_create_kernel(adev,
+				    db_obj->size,
+				    PAGE_SIZE,
+				    AMDGPU_GEM_DOMAIN_DOORBELL,
+				    &db_obj->bo,
+				    &db_obj->gpu_addr,
+				    (void **)&db_obj->cpu_addr);
+
+	if (r) {
+		DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
+		return r;
+	}
+
+	return 0;
+}
+
 /*
  * GPU doorbell aperture helpers function.
  */
-- 
2.40.0


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

* [PATCH 08/16] drm/amdgpu: initialize ttm for doorbells
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (6 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 11:22   ` Christian König
  2023-03-30 14:33   ` Alex Deucher
  2023-03-29 15:47 ` [PATCH 09/16] drm/amdgpu: create kernel doorbell page Shashank Sharma
                   ` (8 subsequent siblings)
  16 siblings, 2 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Mukul Joshi, Shashank Sharma, Felix Kuehling, Alex Deucher,
	Shashank Sharma, Christian Koenig

From: Shashank Sharma <contactshashanksharma@gmail.com>

This patch initialzes the ttm resource manager for doorbells.

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_ttm.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 6f61491ef3dd..203d77a20507 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1858,6 +1858,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
 	DRM_INFO("amdgpu: %uM of GTT memory ready.\n",
 		 (unsigned)(gtt_size / (1024 * 1024)));
 
+	/* Initiailize doorbell pool on PCI BAR */
+	r = amdgpu_ttm_init_on_chip(adev, AMDGPU_PL_DOORBELL,
+				    DIV_ROUND_UP(adev->doorbell.size, PAGE_SIZE));
+	if (r) {
+		DRM_ERROR("Failed initializing doorbell heap. \n");
+		return r;
+	}
+
 	/* Initialize preemptible memory pool */
 	r = amdgpu_preempt_mgr_init(adev);
 	if (r) {
-- 
2.40.0


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

* [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (7 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 08/16] drm/amdgpu: initialize ttm for doorbells Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 11:30   ` Christian König
  2023-03-30 14:24   ` Luben Tuikov
  2023-03-29 15:47 ` [PATCH 10/16] drm/amdgpu: validate doorbell read/write Shashank Sharma
                   ` (7 subsequent siblings)
  16 siblings, 2 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Mukul Joshi, Shashank Sharma, Felix Kuehling, Alex Deucher,
	Shashank Sharma, Christian Koenig

From: Shashank Sharma <contactshashanksharma@gmail.com>

This patch:
- creates a doorbell page for graphics driver usages.
- removes the adev->doorbell.ptr variable, replaces it with
  kernel-doorbell-bo's cpu address.

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_doorbell.h  | 16 ++++++-
 .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 +++++++++++++++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
 3 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
index 6581b78fe438..10a9bb10e974 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
@@ -49,10 +49,13 @@ struct amdgpu_doorbell {
 	/* doorbell mmio */
 	resource_size_t		base;
 	resource_size_t		size;
-	u32 __iomem		*ptr;
+	u32	__iomem		*ptr;
 
 	/* Number of doorbells reserved for amdgpu kernel driver */
 	u32 num_kernel_doorbells;
+
+	/* For kernel doorbell pages */
+	struct amdgpu_doorbell_obj kernel_doorbells;
 };
 
 /* Reserved doorbells for amdgpu (including multimedia).
@@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
 int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
 				struct amdgpu_doorbell_obj *db_obj);
 
+/**
+ * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells for graphics
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Creates doorbells for graphics driver
+ *
+ * returns 0 on success, error otherwise.
+ */
+int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev);
+
 #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
 #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
 #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
index 8be15b82b545..b46fe8b1378d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
@@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
 	return 0;
 }
 
+/**
+ * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells for graphics
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Creates doorbells for graphics driver
+ *
+ * returns 0 on success, error otherwise.
+ */
+int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev)
+{
+	int r;
+	struct amdgpu_doorbell_obj *kernel_doorbells = &adev->doorbell.kernel_doorbells;
+
+	kernel_doorbells->doorbell_bitmap = bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
+							  GFP_KERNEL);
+	if (!kernel_doorbells->doorbell_bitmap) {
+		DRM_ERROR("Failed to create kernel doorbell bitmap\n");
+		return -ENOMEM;
+	}
+
+	kernel_doorbells->size = adev->doorbell.num_kernel_doorbells * sizeof(u32);
+	r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
+	if (r) {
+		bitmap_free(kernel_doorbells->doorbell_bitmap);
+		DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", r);
+		return r;
+	}
+
+	return 0;
+}
+
 /*
  * GPU doorbell aperture helpers function.
  */
@@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
 		adev->doorbell.base = 0;
 		adev->doorbell.size = 0;
 		adev->doorbell.num_kernel_doorbells = 0;
-		adev->doorbell.ptr = NULL;
 		return 0;
 	}
 
@@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
 	if (adev->asic_type >= CHIP_VEGA10)
 		adev->doorbell.num_kernel_doorbells += 0x400;
 
-	adev->doorbell.ptr = ioremap(adev->doorbell.base,
-				     adev->doorbell.num_kernel_doorbells *
-				     sizeof(u32));
-	if (adev->doorbell.ptr == NULL)
-		return -ENOMEM;
-
+	adev->doorbell.ptr = ioremap(adev->doorbell.base, adev->doorbell.size);
 	return 0;
 }
 
@@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
  */
 void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
 {
-	iounmap(adev->doorbell.ptr);
-	adev->doorbell.ptr = NULL;
+	bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
+	amdgpu_doorbell_free_page(adev, &adev->doorbell.kernel_doorbells);
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 203d77a20507..75c6852845c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
 		return r;
 	}
 
+	/* Create a boorbell page for kernel usages */
+	r = amdgpu_doorbell_create_kernel_doorbells(adev);
+	if (r) {
+		DRM_ERROR("Failed to initialize kernel doorbells. \n");
+		return r;
+	}
+
 	/* Initialize preemptible memory pool */
 	r = amdgpu_preempt_mgr_init(adev);
 	if (r) {
-- 
2.40.0


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

* [PATCH 10/16] drm/amdgpu: validate doorbell read/write
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (8 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 09/16] drm/amdgpu: create kernel doorbell page Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 14:34   ` Luben Tuikov
  2023-03-29 15:47 ` [PATCH 11/16] drm/amdgpu: get absolute offset from doorbell index Shashank Sharma
                   ` (6 subsequent siblings)
  16 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Mukul Joshi, Shashank Sharma, Felix Kuehling,
	Arvind Yadav, Alex Deucher, Christian Koenig

This patch:
- updates start/end values for each of the doorbell object
  created.
- adds a function which validates that the kernel doorbell read/write
  is within this range.
- uses this function during doorbell writes from kernel.

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>
---
 .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 29 ++++++++++++++++---
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
index b46fe8b1378d..81713b2c28e1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
@@ -22,6 +22,25 @@
  */
 
 #include "amdgpu.h"
+#include "kfd_priv.h"
+
+static inline
+bool amdgpu_doorbell_valid(struct amdgpu_device *adev, u32 index)
+{
+	if (index >= adev->doorbell.kernel_doorbells.start &&
+	    index < adev->doorbell.kernel_doorbells.end)
+		return true;
+
+	if (index >= adev->mes.kernel_doorbells.start &&
+	    index < adev->mes.kernel_doorbells.end)
+		return true;
+
+	if (index >= adev->kfd.dev->kernel_doorbells.start &&
+	    index < adev->kfd.dev->kernel_doorbells.end)
+		return true;
+
+	return false;
+}
 
 /**
  * amdgpu_mm_rdoorbell - read a doorbell dword
@@ -37,7 +56,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
 	if (amdgpu_device_skip_hw_access(adev))
 		return 0;
 
-	if (index < adev->doorbell.num_kernel_doorbells) {
+	if (amdgpu_doorbell_valid(adev, index)) {
 		return readl(adev->doorbell.ptr + index);
 	} else {
 		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
@@ -60,7 +79,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
 	if (amdgpu_device_skip_hw_access(adev))
 		return;
 
-	if (index < adev->doorbell.num_kernel_doorbells) {
+	if (amdgpu_doorbell_valid(adev, index)) {
 		writel(v, adev->doorbell.ptr + index);
 	} else {
 		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
@@ -81,7 +100,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
 	if (amdgpu_device_skip_hw_access(adev))
 		return 0;
 
-	if (index < adev->doorbell.num_kernel_doorbells) {
+	if (amdgpu_doorbell_valid(adev, index)) {
 		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
 	} else {
 		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
@@ -104,7 +123,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
 	if (amdgpu_device_skip_hw_access(adev))
 		return;
 
-	if (index < adev->doorbell.num_kernel_doorbells) {
+	if (amdgpu_doorbell_valid(adev, index)) {
 		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
 	} else {
 		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
@@ -157,6 +176,8 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
 		return r;
 	}
 
+	db_obj->start = amdgpu_doorbell_index_on_bar(adev, db_obj->bo, 0);
+	db_obj->end = db_obj->start + db_obj->size / sizeof(u32);
 	return 0;
 }
 
-- 
2.40.0


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

* [PATCH 11/16] drm/amdgpu: get absolute offset from doorbell index
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (9 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 10/16] drm/amdgpu: validate doorbell read/write Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 17:18   ` Luben Tuikov
  2023-03-29 15:47 ` [PATCH 12/16] drm/amdgpu: use doorbell manager for kfd kernel doorbells Shashank Sharma
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig,
	Shashank Sharma

This patch adds a helper function which converts a doorbell's
relative index in a BO to an absolute doorbell offset in the
doorbell BAR.

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_doorbell.h  | 15 +++++++++++
 .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 26 +++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
index 10a9bb10e974..3481e9d83879 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
@@ -383,6 +383,21 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
  */
 int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev);
 
+/**
+ * amdgpu_doorbell_index_on_bar - Find doorbell's absolute offset in BAR
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * @db_bo: doorbell object's bo
+ *
+ * @db_index: doorbell relative index in this doorbell object
+ *
+ * returns doorbell's absolute index in BAR
+ */
+uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev,
+				       struct amdgpu_bo *db_bo,
+				       uint32_t doorbell_index);
+
 #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
 #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
 #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
index 81713b2c28e1..c263bae6b0c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
@@ -130,6 +130,32 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
 	}
 }
 
+/**
+ * amdgpu_doorbell_index_on_bar - Find doorbell's absolute offset in BAR
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * @db_bo: doorbell object's bo
+ *
+ * @db_index: doorbell relative index in this doorbell object
+ *
+ * returns doorbell's absolute index in BAR
+ */
+uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev,
+				       struct amdgpu_bo *db_bo,
+				       uint32_t doorbell_index)
+{
+	int db_bo_offset;
+
+	db_bo_offset = amdgpu_bo_gpu_offset_no_check(db_bo);
+
+	/*
+	 * doorbell index granularity is maintained at 32 bit
+	 * but doorbell's size is 64-bit, so index * 2
+	 */
+	return db_bo_offset / sizeof(u32) + doorbell_index * 2;
+}
+
 /**
  * amdgpu_doorbell_free_page - Free a doorbell page
  *
-- 
2.40.0


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

* [PATCH 12/16] drm/amdgpu: use doorbell manager for kfd kernel doorbells
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (10 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 11/16] drm/amdgpu: get absolute offset from doorbell index Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 20:46   ` Alex Deucher
  2023-03-29 15:47 ` [PATCH 13/16] drm/amdgpu: use doorbell manager for kfd process doorbells Shashank Sharma
                   ` (4 subsequent siblings)
  16 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig,
	Shashank Sharma

This patch:
- adds a doorbell manager structure in kfd device structure.
- plugs-in doorbell manager APIs for KFD kernel doorbell allocations
  an free functions.
- removes the doorbell bitmap, uses the one into the doorbell manager
  structure for all the allocations.
- updates the get_kernel_doorbell and free_kernel_doorbell functions
  accordingly

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/amdkfd/kfd_device.c   |   4 +-
 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | 109 ++++++----------------
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h     |   3 +
 3 files changed, 35 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index b8936340742b..a2e4cbddba26 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -435,8 +435,8 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
 	atomic_set(&kfd->compute_profile, 0);
 
 	mutex_init(&kfd->doorbell_mutex);
-	memset(&kfd->doorbell_available_index, 0,
-		sizeof(kfd->doorbell_available_index));
+	memset(kfd->kernel_doorbells.doorbell_bitmap, 0,
+	       kfd->kernel_doorbells.size / BITS_PER_LONG);
 
 	atomic_set(&kfd->sram_ecc_flag, 0);
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
index cd4e61bf0493..df259f2cc58a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -61,81 +61,37 @@ size_t kfd_doorbell_process_slice(struct kfd_dev *kfd)
 /* Doorbell calculations for device init. */
 int kfd_doorbell_init(struct kfd_dev *kfd)
 {
-	size_t doorbell_start_offset;
-	size_t doorbell_aperture_size;
-	size_t doorbell_process_limit;
+	int r;
+	struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
 
-	/*
-	 * With MES enabled, just set the doorbell base as it is needed
-	 * to calculate doorbell physical address.
-	 */
-	if (kfd->shared_resources.enable_mes) {
-		kfd->doorbell_base =
-			kfd->shared_resources.doorbell_physical_address;
-		return 0;
-	}
-
-	/*
-	 * We start with calculations in bytes because the input data might
-	 * only be byte-aligned.
-	 * Only after we have done the rounding can we assume any alignment.
-	 */
-
-	doorbell_start_offset =
-			roundup(kfd->shared_resources.doorbell_start_offset,
-					kfd_doorbell_process_slice(kfd));
-
-	doorbell_aperture_size =
-			rounddown(kfd->shared_resources.doorbell_aperture_size,
-					kfd_doorbell_process_slice(kfd));
-
-	if (doorbell_aperture_size > doorbell_start_offset)
-		doorbell_process_limit =
-			(doorbell_aperture_size - doorbell_start_offset) /
-						kfd_doorbell_process_slice(kfd);
-	else
-		return -ENOSPC;
-
-	if (!kfd->max_doorbell_slices ||
-	    doorbell_process_limit < kfd->max_doorbell_slices)
-		kfd->max_doorbell_slices = doorbell_process_limit;
-
-	kfd->doorbell_base = kfd->shared_resources.doorbell_physical_address +
-				doorbell_start_offset;
-
-	kfd->doorbell_base_dw_offset = doorbell_start_offset / sizeof(u32);
-
-	kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base,
-					   kfd_doorbell_process_slice(kfd));
-
-	if (!kfd->doorbell_kernel_ptr)
+	/* Bitmap to dynamically allocate doorbells from kernel page */
+	kernel_doorbells->doorbell_bitmap = bitmap_zalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!kernel_doorbells->doorbell_bitmap) {
+		DRM_ERROR("Failed to allocate kernel doorbell bitmap\n");
 		return -ENOMEM;
+	}
 
-	pr_debug("Doorbell initialization:\n");
-	pr_debug("doorbell base           == 0x%08lX\n",
-			(uintptr_t)kfd->doorbell_base);
-
-	pr_debug("doorbell_base_dw_offset      == 0x%08lX\n",
-			kfd->doorbell_base_dw_offset);
-
-	pr_debug("doorbell_process_limit  == 0x%08lX\n",
-			doorbell_process_limit);
-
-	pr_debug("doorbell_kernel_offset  == 0x%08lX\n",
-			(uintptr_t)kfd->doorbell_base);
-
-	pr_debug("doorbell aperture size  == 0x%08lX\n",
-			kfd->shared_resources.doorbell_aperture_size);
+	/* Alloc and reserve doorbells for KFD kernel usages */
+	kernel_doorbells->size = PAGE_SIZE;
+	r = amdgpu_doorbell_alloc_page(kfd->adev, kernel_doorbells);
+	if (r) {
+		pr_err("failed to allocate kernel doorbells\n");
+		bitmap_free(kernel_doorbells->doorbell_bitmap);
+		return r;
+	}
 
-	pr_debug("doorbell kernel address == %p\n", kfd->doorbell_kernel_ptr);
+	kfd->doorbell_kernel_ptr = kernel_doorbells->cpu_addr;
+	pr_debug("Doorbell kernel address == %p\n", kfd->doorbell_kernel_ptr);
 
 	return 0;
 }
 
 void kfd_doorbell_fini(struct kfd_dev *kfd)
 {
-	if (kfd->doorbell_kernel_ptr)
-		iounmap(kfd->doorbell_kernel_ptr);
+	struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
+
+	bitmap_free(kernel_doorbells->doorbell_bitmap);
+	amdgpu_doorbell_free_page(kfd->adev, kernel_doorbells);
 }
 
 int kfd_doorbell_mmap(struct kfd_dev *dev, struct kfd_process *process,
@@ -186,24 +142,19 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
 					unsigned int *doorbell_off)
 {
 	u32 inx;
+	struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
 
 	mutex_lock(&kfd->doorbell_mutex);
-	inx = find_first_zero_bit(kfd->doorbell_available_index,
-					KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
+	inx = find_first_zero_bit(kernel_doorbells->doorbell_bitmap,
+				  kernel_doorbells->size);
 
-	__set_bit(inx, kfd->doorbell_available_index);
+	__set_bit(inx, kernel_doorbells->doorbell_bitmap);
 	mutex_unlock(&kfd->doorbell_mutex);
 
 	if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
 		return NULL;
 
-	inx *= kfd->device_info.doorbell_size / sizeof(u32);
-
-	/*
-	 * Calculating the kernel doorbell offset using the first
-	 * doorbell page.
-	 */
-	*doorbell_off = kfd->doorbell_base_dw_offset + inx;
+	*doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev, kernel_doorbells->bo, inx);
 
 	pr_debug("Get kernel queue doorbell\n"
 			"     doorbell offset   == 0x%08X\n"
@@ -216,12 +167,12 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
 void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr)
 {
 	unsigned int inx;
+	struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
 
-	inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr)
-		* sizeof(u32) / kfd->device_info.doorbell_size;
+	inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr);
 
 	mutex_lock(&kfd->doorbell_mutex);
-	__clear_bit(inx, kfd->doorbell_available_index);
+	__clear_bit(inx, kernel_doorbells->doorbell_bitmap);
 	mutex_unlock(&kfd->doorbell_mutex);
 }
 
@@ -280,7 +231,7 @@ phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
 	if (!pdd->doorbell_index) {
 		int r = kfd_alloc_process_doorbells(pdd->dev,
 						    &pdd->doorbell_index);
-		if (r)
+		if (r < 0)
 			return 0;
 	}
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 552c3ac85a13..0ed33416c35f 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -346,6 +346,9 @@ struct kfd_dev {
 
 	/* HMM page migration MEMORY_DEVICE_PRIVATE mapping */
 	struct dev_pagemap pgmap;
+
+	/* Kernel doorbells for KFD device */
+	struct amdgpu_doorbell_obj kernel_doorbells;
 };
 
 enum kfd_mempool {
-- 
2.40.0


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

* [PATCH 13/16] drm/amdgpu: use doorbell manager for kfd process doorbells
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (11 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 12/16] drm/amdgpu: use doorbell manager for kfd kernel doorbells Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 20:54   ` Alex Deucher
  2023-03-29 15:47 ` [PATCH 14/16] drm/amdgpu: remove ununsed functions and variables Shashank Sharma
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig,
	Shashank Sharma

This patch:
- adds a new doorbell manager object in kfd pdd structure.
- allocates doorbells for a process while creating its pdd.
- frees the doorbells with pdd destroy.
- uses direct doorbell manager API for doorbell indexing.
- removes previous calls to allocate process doorbells as
  its not required anymore.

PS: This patch ensures that we don't break the existing KFD
    functionality, but now KFD userspace library must also
    move to creating doorbell pages as AMDGPU GEM objects
    using libdrm functions in userspace. The reference code
    for the same is available with AMDGPU Usermode queue
    libdrm MR. Once this is done, we will not need this
    patch.

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/amdkfd/kfd_chardev.c      | 13 ----
 .../drm/amd/amdkfd/kfd_device_queue_manager.c | 16 ++---
 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c     | 59 +++++++++----------
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |  8 +--
 drivers/gpu/drm/amd/amdkfd/kfd_process.c      | 26 ++++----
 .../amd/amdkfd/kfd_process_queue_manager.c    | 16 ++---
 6 files changed, 58 insertions(+), 80 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 6d291aa6386b..0e40756417e5 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -327,12 +327,6 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
 		goto err_bind_process;
 	}
 
-	if (!pdd->doorbell_index &&
-	    kfd_alloc_process_doorbells(dev, &pdd->doorbell_index) < 0) {
-		err = -ENOMEM;
-		goto err_alloc_doorbells;
-	}
-
 	/* Starting with GFX11, wptr BOs must be mapped to GART for MES to determine work
 	 * on unmapped queues for usermode queue oversubscription (no aggregated doorbell)
 	 */
@@ -410,7 +404,6 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
 	if (wptr_bo)
 		amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);
 err_wptr_map_gart:
-err_alloc_doorbells:
 err_bind_process:
 err_pdd:
 	mutex_unlock(&p->mutex);
@@ -2163,12 +2156,6 @@ static int criu_restore_devices(struct kfd_process *p,
 			ret = PTR_ERR(pdd);
 			goto exit;
 		}
-
-		if (!pdd->doorbell_index &&
-		    kfd_alloc_process_doorbells(pdd->dev, &pdd->doorbell_index) < 0) {
-			ret = -ENOMEM;
-			goto exit;
-		}
 	}
 
 	/*
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index ecb4c3abc629..5827db9b18a8 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -362,7 +362,7 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
 		/* For CP queues on SOC15 */
 		if (restore_id) {
 			/* make sure that ID is free  */
-			if (__test_and_set_bit(*restore_id, qpd->doorbell_bitmap))
+			if (__test_and_set_bit(*restore_id, qpd->proc_doorbells.doorbell_bitmap))
 				return -EINVAL;
 
 			q->doorbell_id = *restore_id;
@@ -370,20 +370,20 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
 			/* or reserve a free doorbell ID */
 			unsigned int found;
 
-			found = find_first_zero_bit(qpd->doorbell_bitmap,
-						KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
+			found = find_first_zero_bit(qpd->proc_doorbells.doorbell_bitmap,
+						    KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
 			if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
 				pr_debug("No doorbells available");
 				return -EBUSY;
 			}
-			set_bit(found, qpd->doorbell_bitmap);
+			set_bit(found, qpd->proc_doorbells.doorbell_bitmap);
 			q->doorbell_id = found;
 		}
 	}
 
-	q->properties.doorbell_off =
-		kfd_get_doorbell_dw_offset_in_bar(dev, qpd_to_pdd(qpd),
-					  q->doorbell_id);
+	q->properties.doorbell_off = amdgpu_doorbell_index_on_bar(dev->adev,
+								  qpd->proc_doorbells.bo,
+								  q->doorbell_id);
 	return 0;
 }
 
@@ -398,7 +398,7 @@ static void deallocate_doorbell(struct qcm_process_device *qpd,
 	    q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
 		return;
 
-	old = test_and_clear_bit(q->doorbell_id, qpd->doorbell_bitmap);
+	old = test_and_clear_bit(q->doorbell_id, qpd->proc_doorbells.doorbell_bitmap);
 	WARN_ON(!old);
 }
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
index df259f2cc58a..7d29653bff81 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -228,46 +228,41 @@ uint64_t kfd_get_number_elems(struct kfd_dev *kfd)
 
 phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
 {
-	if (!pdd->doorbell_index) {
-		int r = kfd_alloc_process_doorbells(pdd->dev,
-						    &pdd->doorbell_index);
-		if (r < 0)
-			return 0;
-	}
+	struct amdgpu_device *adev = pdd->dev->adev;
 
-	return pdd->dev->doorbell_base +
-		pdd->doorbell_index * kfd_doorbell_process_slice(pdd->dev);
+	/* Return base of the first doorbell of this process */
+	return adev->doorbell.base + pdd->qpd.proc_doorbells.start * sizeof(uint32_t);
 }
 
-int kfd_alloc_process_doorbells(struct kfd_dev *kfd, unsigned int *doorbell_index)
+int kfd_alloc_process_doorbells(struct kfd_dev *kfd, struct kfd_process_device *pdd)
 {
-	int r = 0;
-
-	if (!kfd->shared_resources.enable_mes)
-		r = ida_simple_get(&kfd->doorbell_ida, 1,
-				   kfd->max_doorbell_slices, GFP_KERNEL);
-	else
-		r = amdgpu_mes_alloc_process_doorbells(
-				(struct amdgpu_device *)kfd->adev,
-				doorbell_index);
-
-	if (r > 0)
-		*doorbell_index = r;
+	int r;
+	struct qcm_process_device *qpd = &pdd->qpd;
+	struct amdgpu_doorbell_obj *proc_doorbells = &qpd->proc_doorbells;
+
+	/* Allocate bitmap for dynamic doorbell allocation */
+	proc_doorbells->doorbell_bitmap = bitmap_zalloc(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
+							GFP_KERNEL);
+	if (!proc_doorbells->doorbell_bitmap) {
+		DRM_ERROR("Failed to allocate process doorbell bitmap\n");
+		return -ENOMEM;
+	}
 
-	if (r < 0)
-		pr_err("Failed to allocate process doorbells\n");
+	/* Allocate doorbells for this process from the PCI BAR */
+	proc_doorbells->size = kfd_doorbell_process_slice(kfd);
+	r = amdgpu_doorbell_alloc_page(kfd->adev, proc_doorbells);
+	if (r) {
+		DRM_ERROR("Failed to allocate process doorbells\n");
+		return r;
+	}
 
 	return r;
 }
 
-void kfd_free_process_doorbells(struct kfd_dev *kfd, unsigned int doorbell_index)
+void kfd_free_process_doorbells(struct kfd_dev *kfd, struct kfd_process_device *pdd)
 {
-	if (doorbell_index) {
-		if (!kfd->shared_resources.enable_mes)
-			ida_simple_remove(&kfd->doorbell_ida, doorbell_index);
-		else
-			amdgpu_mes_free_process_doorbells(
-					(struct amdgpu_device *)kfd->adev,
-					doorbell_index);
-	}
+	struct amdgpu_doorbell_obj *proc_doorbells = &pdd->qpd.proc_doorbells;
+
+	bitmap_free(proc_doorbells->doorbell_bitmap);
+	amdgpu_doorbell_free_page(kfd->adev, proc_doorbells);
 }
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 0ed33416c35f..c97ed8e7e02d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -658,8 +658,8 @@ struct qcm_process_device {
 	uint64_t ib_base;
 	void *ib_kaddr;
 
-	/* doorbell resources per process per device */
-	unsigned long *doorbell_bitmap;
+	/* physical doorbell pages */
+	struct amdgpu_doorbell_obj proc_doorbells;
 };
 
 /* KFD Memory Eviction */
@@ -1006,9 +1006,9 @@ unsigned int kfd_get_doorbell_dw_offset_in_bar(struct kfd_dev *kfd,
 					unsigned int doorbell_id);
 phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd);
 int kfd_alloc_process_doorbells(struct kfd_dev *kfd,
-				unsigned int *doorbell_index);
+				 struct kfd_process_device *pdd);
 void kfd_free_process_doorbells(struct kfd_dev *kfd,
-				unsigned int doorbell_index);
+				 struct kfd_process_device *pdd);
 /* GTT Sub-Allocator */
 
 int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index 51b1683ac5c1..68d0310c2d53 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -1037,10 +1037,9 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
 			free_pages((unsigned long)pdd->qpd.cwsr_kaddr,
 				get_order(KFD_CWSR_TBA_TMA_SIZE));
 
-		bitmap_free(pdd->qpd.doorbell_bitmap);
 		idr_destroy(&pdd->alloc_idr);
 
-		kfd_free_process_doorbells(pdd->dev, pdd->doorbell_index);
+		kfd_free_process_doorbells(pdd->dev, pdd);
 
 		if (pdd->dev->shared_resources.enable_mes)
 			amdgpu_amdkfd_free_gtt_mem(pdd->dev->adev,
@@ -1449,15 +1448,11 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd,
 	unsigned int i;
 	int range_start = dev->shared_resources.non_cp_doorbells_start;
 	int range_end = dev->shared_resources.non_cp_doorbells_end;
+	struct amdgpu_doorbell_obj *proc_doorbells = &qpd->proc_doorbells;
 
 	if (!KFD_IS_SOC15(dev))
 		return 0;
 
-	qpd->doorbell_bitmap = bitmap_zalloc(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
-					     GFP_KERNEL);
-	if (!qpd->doorbell_bitmap)
-		return -ENOMEM;
-
 	/* Mask out doorbells reserved for SDMA, IH, and VCN on SOC15. */
 	pr_debug("reserved doorbell 0x%03x - 0x%03x\n", range_start, range_end);
 	pr_debug("reserved doorbell 0x%03x - 0x%03x\n",
@@ -1466,9 +1461,9 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd,
 
 	for (i = 0; i < KFD_MAX_NUM_OF_QUEUES_PER_PROCESS / 2; i++) {
 		if (i >= range_start && i <= range_end) {
-			__set_bit(i, qpd->doorbell_bitmap);
+			__set_bit(i, proc_doorbells->doorbell_bitmap);
 			__set_bit(i + KFD_QUEUE_DOORBELL_MIRROR_OFFSET,
-				  qpd->doorbell_bitmap);
+				  proc_doorbells->doorbell_bitmap);
 		}
 	}
 
@@ -1499,9 +1494,15 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
 	if (!pdd)
 		return NULL;
 
+	retval = kfd_alloc_process_doorbells(dev, pdd);
+	if (retval) {
+		pr_err("failed to allocate process doorbells\n");
+		goto err_free_pdd;
+	}
+
 	if (init_doorbell_bitmap(&pdd->qpd, dev)) {
 		pr_err("Failed to init doorbell for process\n");
-		goto err_free_pdd;
+		goto err_free_db;
 	}
 
 	pdd->dev = dev;
@@ -1529,7 +1530,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
 						false);
 		if (retval) {
 			pr_err("failed to allocate process context bo\n");
-			goto err_free_pdd;
+			goto err_free_db;
 		}
 		memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
 	}
@@ -1541,6 +1542,9 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
 
 	return pdd;
 
+err_free_db:
+	kfd_free_process_doorbells(pdd->dev, pdd);
+
 err_free_pdd:
 	kfree(pdd);
 	return NULL;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 5137476ec18e..693688d789d3 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -348,13 +348,11 @@ int pqm_create_queue(struct process_queue_manager *pqm,
 		/* Return the doorbell offset within the doorbell page
 		 * to the caller so it can be passed up to user mode
 		 * (in bytes).
-		 * There are always 1024 doorbells per process, so in case
-		 * of 8-byte doorbells, there are two doorbell pages per
-		 * process.
+		 * relative doorbell index = Absolute doorbell index -
+		 * absolute index of first doorbell in the page.
 		 */
-		*p_doorbell_offset_in_process =
-			(q->properties.doorbell_off * sizeof(uint32_t)) &
-			(kfd_doorbell_process_slice(dev) - 1);
+		*p_doorbell_offset_in_process = (q->properties.doorbell_off
+						- pdd->qpd.proc_doorbells.start) * sizeof(uint32_t);
 
 	pr_debug("PQM After DQM create queue\n");
 
@@ -858,12 +856,6 @@ int kfd_criu_restore_queue(struct kfd_process *p,
 		goto exit;
 	}
 
-	if (!pdd->doorbell_index &&
-	    kfd_alloc_process_doorbells(pdd->dev, &pdd->doorbell_index) < 0) {
-		ret = -ENOMEM;
-		goto exit;
-	}
-
 	/* data stored in this order: mqd, ctl_stack */
 	mqd = q_extra_data;
 	ctl_stack = mqd + q_data->mqd_size;
-- 
2.40.0


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

* [PATCH 14/16] drm/amdgpu: remove ununsed functions and variables
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (12 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 13/16] drm/amdgpu: use doorbell manager for kfd process doorbells Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-29 15:47 ` [PATCH 15/16] drm/amdgpu: use doorbell mgr for MES kernel doorbells Shashank Sharma
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig,
	Shashank Sharma

This patch removes some variables and functions from KFD
doorbell handling code, which are no more required since
doorbell manager is handling doorbell calculations.

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/amdkfd/kfd_doorbell.c | 32 -----------------------
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h     | 12 ---------
 2 files changed, 44 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
index 7d29653bff81..fecf68976ac8 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -194,38 +194,6 @@ void write_kernel_doorbell64(void __iomem *db, u64 value)
 	}
 }
 
-unsigned int kfd_get_doorbell_dw_offset_in_bar(struct kfd_dev *kfd,
-					struct kfd_process_device *pdd,
-					unsigned int doorbell_id)
-{
-	/*
-	 * doorbell_base_dw_offset accounts for doorbells taken by KGD.
-	 * index * kfd_doorbell_process_slice/sizeof(u32) adjusts to
-	 * the process's doorbells. The offset returned is in dword
-	 * units regardless of the ASIC-dependent doorbell size.
-	 */
-	if (!kfd->shared_resources.enable_mes)
-		return kfd->doorbell_base_dw_offset +
-			pdd->doorbell_index
-			* kfd_doorbell_process_slice(kfd) / sizeof(u32) +
-			doorbell_id *
-			kfd->device_info.doorbell_size / sizeof(u32);
-	else
-		return amdgpu_mes_get_doorbell_dw_offset_in_bar(
-				(struct amdgpu_device *)kfd->adev,
-				pdd->doorbell_index, doorbell_id);
-}
-
-uint64_t kfd_get_number_elems(struct kfd_dev *kfd)
-{
-	uint64_t num_of_elems = (kfd->shared_resources.doorbell_aperture_size -
-				kfd->shared_resources.doorbell_start_offset) /
-					kfd_doorbell_process_slice(kfd) + 1;
-
-	return num_of_elems;
-
-}
-
 phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
 {
 	struct amdgpu_device *adev = pdd->dev->adev;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index c97ed8e7e02d..9c3b31c148b7 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -257,15 +257,6 @@ struct kfd_dev {
 
 	unsigned int id;		/* topology stub index */
 
-	phys_addr_t doorbell_base;	/* Start of actual doorbells used by
-					 * KFD. It is aligned for mapping
-					 * into user mode
-					 */
-	size_t doorbell_base_dw_offset;	/* Offset from the start of the PCI
-					 * doorbell BAR to the first KFD
-					 * doorbell in dwords. GFX reserves
-					 * the segment before this offset.
-					 */
 	u32 __iomem *doorbell_kernel_ptr; /* This is a pointer for a doorbells
 					   * page used by kernel queue
 					   */
@@ -276,8 +267,6 @@ struct kfd_dev {
 
 	const struct kfd2kgd_calls *kfd2kgd;
 	struct mutex doorbell_mutex;
-	DECLARE_BITMAP(doorbell_available_index,
-			KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
 
 	void *gtt_mem;
 	uint64_t gtt_start_gpu_addr;
@@ -748,7 +737,6 @@ struct kfd_process_device {
 	struct attribute attr_evict;
 
 	struct kobject *kobj_stats;
-	unsigned int doorbell_index;
 
 	/*
 	 * @cu_occupancy: Reports occupancy of Compute Units (CU) of a process
-- 
2.40.0


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

* [PATCH 15/16] drm/amdgpu: use doorbell mgr for MES kernel doorbells
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (13 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 14/16] drm/amdgpu: remove ununsed functions and variables Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 20:58   ` Alex Deucher
  2023-03-29 15:47 ` [PATCH 16/16] drm/amdgpu: user doorbell mgr for MES process doorbells Shashank Sharma
  2023-03-30 13:49 ` [PATCH 00/16] AMDGPU Doorbell manager Luben Tuikov
  16 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Mukul Joshi, Shashank Sharma, Felix Kuehling, Arvind Yadav,
	Alex Deucher, Christian Koenig

This patch:
- adds a doorbell object in MES structure, to manage the MES
  doorbell requirements in kernel.
- Removes the doorbell management code, and its variables from
  the doorbell_init function, it will be done in doorbell manager
  now.
- creates doorbell pages for MES kernel level needs (doorbells
  for MES self tests)
- current MES code was allocating MES doorbells in MES process context,
  but those were rung using kernel doorbell calls. This patch allocates
  MES kernel doorbells instead for this in add_hw_queue.

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_mes.c | 105 ++++++++++++------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h |   5 +-
 2 files changed, 56 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 0c546245793b..423cd642647c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -65,91 +65,89 @@ unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar(
 		doorbell_id * 2);
 }
 
-static int amdgpu_mes_queue_doorbell_get(struct amdgpu_device *adev,
+static int amdgpu_mes_kernel_doorbell_get(struct amdgpu_device *adev,
 					 struct amdgpu_mes_process *process,
 					 int ip_type, uint64_t *doorbell_index)
 {
 	unsigned int offset, found;
+	struct amdgpu_doorbell_obj *doorbells = &adev->mes.kernel_doorbells;
 
-	if (ip_type == AMDGPU_RING_TYPE_SDMA) {
+	if (ip_type == AMDGPU_RING_TYPE_SDMA)
 		offset = adev->doorbell_index.sdma_engine[0];
-		found = find_next_zero_bit(process->doorbell_bitmap,
-					   AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
-					   offset);
-	} else {
-		found = find_first_zero_bit(process->doorbell_bitmap,
-					    AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS);
-	}
+	else
+		offset = 0;
 
+	found = find_next_zero_bit(doorbells->doorbell_bitmap,
+				   AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
+				   offset);
 	if (found >= AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS) {
 		DRM_WARN("No doorbell available\n");
 		return -ENOSPC;
 	}
 
-	set_bit(found, process->doorbell_bitmap);
+	set_bit(found, doorbells->doorbell_bitmap);
 
-	*doorbell_index = amdgpu_mes_get_doorbell_dw_offset_in_bar(adev,
-				process->doorbell_index, found);
+	*doorbell_index = amdgpu_doorbell_index_on_bar(adev, doorbells->bo, found);
 
 	return 0;
 }
 
-static void amdgpu_mes_queue_doorbell_free(struct amdgpu_device *adev,
+static void amdgpu_mes_kernel_doorbell_free(struct amdgpu_device *adev,
 					   struct amdgpu_mes_process *process,
 					   uint32_t doorbell_index)
 {
 	unsigned int old, doorbell_id;
+	struct amdgpu_doorbell_obj *doorbells = &adev->mes.kernel_doorbells;
 
-	doorbell_id = doorbell_index -
-		(process->doorbell_index *
-		 amdgpu_mes_doorbell_process_slice(adev)) / sizeof(u32);
+	/* Find the relative index of the doorbell in this object */
+	doorbell_id = doorbell_index - doorbells->start;
 	doorbell_id /= 2;
 
-	old = test_and_clear_bit(doorbell_id, process->doorbell_bitmap);
+	old = test_and_clear_bit(doorbell_id, doorbells->doorbell_bitmap);
 	WARN_ON(!old);
 }
 
 static int amdgpu_mes_doorbell_init(struct amdgpu_device *adev)
 {
-	size_t doorbell_start_offset;
-	size_t doorbell_aperture_size;
-	size_t doorbell_process_limit;
-	size_t aggregated_doorbell_start;
-	int i;
-
-	aggregated_doorbell_start = (adev->doorbell_index.max_assignment + 1) * sizeof(u32);
-	aggregated_doorbell_start =
-		roundup(aggregated_doorbell_start, PAGE_SIZE);
-
-	doorbell_start_offset = aggregated_doorbell_start + PAGE_SIZE;
-	doorbell_start_offset =
-		roundup(doorbell_start_offset,
-			amdgpu_mes_doorbell_process_slice(adev));
-
-	doorbell_aperture_size = adev->doorbell.size;
-	doorbell_aperture_size =
-			rounddown(doorbell_aperture_size,
-				  amdgpu_mes_doorbell_process_slice(adev));
-
-	if (doorbell_aperture_size > doorbell_start_offset)
-		doorbell_process_limit =
-			(doorbell_aperture_size - doorbell_start_offset) /
-			amdgpu_mes_doorbell_process_slice(adev);
-	else
-		return -ENOSPC;
+	int i, r;
+	u32 agg_db_start_index, nbits;
+	struct amdgpu_doorbell_obj *mes_doorbells = &adev->mes.kernel_doorbells;
 
-	adev->mes.doorbell_id_offset = doorbell_start_offset / sizeof(u32);
-	adev->mes.max_doorbell_slices = doorbell_process_limit;
+		/* Allocated one page doorbells for MES kernel usages */
+	mes_doorbells->size = PAGE_SIZE;
 
-	/* allocate Qword range for aggregated doorbell */
-	for (i = 0; i < AMDGPU_MES_PRIORITY_NUM_LEVELS; i++)
-		adev->mes.aggregated_doorbells[i] =
-			aggregated_doorbell_start / sizeof(u32) + i * 2;
+	nbits = DIV_ROUND_UP(mes_doorbells->size, sizeof(u32));
+	mes_doorbells->doorbell_bitmap = bitmap_zalloc(nbits, GFP_KERNEL);
+	if (!mes_doorbells->doorbell_bitmap) {
+		DRM_ERROR("Failed to allocate MES doorbell bitmap\n");
+		return -ENOMEM;
+	}
+
+	r = amdgpu_doorbell_alloc_page(adev, mes_doorbells);
+	if (r) {
+		DRM_ERROR("Failed to create MES doorbell object\n, err=%d", r);
+		bitmap_free(mes_doorbells->doorbell_bitmap);
+		return r;
+	}
+
+	/* Get the absolute doorbell index for aggregated doobells */
+	agg_db_start_index = mes_doorbells->start;
+	for (i = 0; i < AMDGPU_MES_PRIORITY_NUM_LEVELS; i++) {
+		adev->mes.aggregated_doorbells[i] = agg_db_start_index + i;
+		set_bit(agg_db_start_index + i, mes_doorbells->doorbell_bitmap);
+	}
 
-	DRM_INFO("max_doorbell_slices=%zu\n", doorbell_process_limit);
 	return 0;
 }
 
+static void amdgpu_mes_doorbell_free(struct amdgpu_device *adev)
+{
+	struct amdgpu_doorbell_obj *mes_doorbells = &adev->mes.kernel_doorbells;
+
+	bitmap_free(mes_doorbells->doorbell_bitmap);
+	amdgpu_doorbell_free_page(adev, mes_doorbells);
+}
+
 int amdgpu_mes_init(struct amdgpu_device *adev)
 {
 	int i, r;
@@ -248,6 +246,7 @@ void amdgpu_mes_fini(struct amdgpu_device *adev)
 	amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);
 	amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs);
 	amdgpu_device_wb_free(adev, adev->mes.read_val_offs);
+	amdgpu_mes_doorbell_free(adev);
 
 	idr_destroy(&adev->mes.pasid_idr);
 	idr_destroy(&adev->mes.gang_id_idr);
@@ -677,7 +676,7 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id,
 	*queue_id = queue->queue_id = r;
 
 	/* allocate a doorbell index for the queue */
-	r = amdgpu_mes_queue_doorbell_get(adev, gang->process,
+	r = amdgpu_mes_kernel_doorbell_get(adev, gang->process,
 					  qprops->queue_type,
 					  &qprops->doorbell_off);
 	if (r)
@@ -735,7 +734,7 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id,
 	return 0;
 
 clean_up_doorbell:
-	amdgpu_mes_queue_doorbell_free(adev, gang->process,
+	amdgpu_mes_kernel_doorbell_free(adev, gang->process,
 				       qprops->doorbell_off);
 clean_up_queue_id:
 	spin_lock_irqsave(&adev->mes.queue_id_lock, flags);
@@ -790,7 +789,7 @@ int amdgpu_mes_remove_hw_queue(struct amdgpu_device *adev, int queue_id)
 			  queue_id);
 
 	list_del(&queue->list);
-	amdgpu_mes_queue_doorbell_free(adev, gang->process,
+	amdgpu_mes_kernel_doorbell_free(adev, gang->process,
 				       queue->doorbell_off);
 	amdgpu_mes_unlock(&adev->mes);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
index 97c05d08a551..e7e9dfe44c99 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
@@ -27,6 +27,7 @@
 #include "amdgpu_irq.h"
 #include "kgd_kfd_interface.h"
 #include "amdgpu_gfx.h"
+#include "amdgpu_doorbell.h"
 #include <linux/sched/mm.h>
 
 #define AMDGPU_MES_MAX_COMPUTE_PIPES        8
@@ -76,7 +77,6 @@ struct amdgpu_mes {
 	uint32_t			kiq_version;
 
 	uint32_t                        total_max_queue;
-	uint32_t                        doorbell_id_offset;
 	uint32_t                        max_doorbell_slices;
 
 	uint64_t                        default_process_quantum;
@@ -128,6 +128,9 @@ struct amdgpu_mes {
 	int                             (*kiq_hw_init)(struct amdgpu_device *adev);
 	int                             (*kiq_hw_fini)(struct amdgpu_device *adev);
 
+	/* MES Kernel doorbells */
+	struct amdgpu_doorbell_obj	kernel_doorbells;
+
 	/* ip specific functions */
 	const struct amdgpu_mes_funcs   *funcs;
 };
-- 
2.40.0


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

* [PATCH 16/16] drm/amdgpu: user doorbell mgr for MES process doorbells
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (14 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 15/16] drm/amdgpu: use doorbell mgr for MES kernel doorbells Shashank Sharma
@ 2023-03-29 15:47 ` Shashank Sharma
  2023-03-30 13:49 ` [PATCH 00/16] AMDGPU Doorbell manager Luben Tuikov
  16 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-29 15:47 UTC (permalink / raw)
  To: amd-gfx
  Cc: Mukul Joshi, Shashank Sharma, Felix Kuehling, Arvind Yadav,
	Alex Deucher, Christian Koenig

This patch:
- Adds a amdgpu_doorbell object in MES process.
- Allocs doorbell pages for MES process using doorbell manager.
- uses doorbell manager to get an absolute index of doorbells.
- removes a offset calculation function which is no more required.
- removes prototype of a few functions which are not required.

PS: This patch ensures that we don't break the existing KFD
    functionality, but now KFD userspace library must also
    move to creating doorbell pages as AMDGPU GEM objects
    using libdrm functions in userspace. The reference code
    for the same is available with AMDGPU Usermode queue
    libdrm MR.

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_mes.c | 60 ++++++++++++-------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h | 12 ++---
 2 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index 423cd642647c..7c6cf3d2c8ef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -36,33 +36,40 @@ int amdgpu_mes_doorbell_process_slice(struct amdgpu_device *adev)
 		       PAGE_SIZE);
 }
 
-int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev,
-				      unsigned int *doorbell_index)
+static int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev,
+					       struct amdgpu_mes_process *process)
 {
-	int r = ida_simple_get(&adev->mes.doorbell_ida, 2,
-			       adev->mes.max_doorbell_slices,
-			       GFP_KERNEL);
-	if (r > 0)
-		*doorbell_index = r;
+	int r;
+	struct amdgpu_doorbell_obj *proc_doorbells = &process->proc_doorbells;
+
+	/* Bitmap for dynamic allocation of doorbell */
+	proc_doorbells->doorbell_bitmap = bitmap_zalloc(
+					  AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
+					  GFP_KERNEL);
+	if (!proc_doorbells->doorbell_bitmap) {
+		DRM_ERROR("failed to allocate MES process doorbell bitmap\n");
+		return -ENOMEM;
+	}
+
+	/* Reserve actual doorbells from the BAR */
+	proc_doorbells->size = amdgpu_mes_doorbell_process_slice(adev);
+	r = amdgpu_doorbell_alloc_page(adev, proc_doorbells);
+	if (r) {
+		bitmap_free(proc_doorbells->doorbell_bitmap);
+		DRM_ERROR("failed to allocate MES process doorbells\n");
+		return r;
+	}
 
 	return r;
 }
 
 void amdgpu_mes_free_process_doorbells(struct amdgpu_device *adev,
-				      unsigned int doorbell_index)
+				       struct amdgpu_mes_process *process)
 {
-	if (doorbell_index)
-		ida_simple_remove(&adev->mes.doorbell_ida, doorbell_index);
-}
+	struct amdgpu_doorbell_obj *proc_doorbells = &process->proc_doorbells;
 
-unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar(
-					struct amdgpu_device *adev,
-					uint32_t doorbell_index,
-					unsigned int doorbell_id)
-{
-	return ((doorbell_index *
-		amdgpu_mes_doorbell_process_slice(adev)) / sizeof(u32) +
-		doorbell_id * 2);
+	bitmap_free(proc_doorbells->doorbell_bitmap);
+	amdgpu_doorbell_free_page(adev, proc_doorbells);
 }
 
 static int amdgpu_mes_kernel_doorbell_get(struct amdgpu_device *adev,
@@ -275,15 +282,6 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid,
 		return -ENOMEM;
 	}
 
-	process->doorbell_bitmap =
-		kzalloc(DIV_ROUND_UP(AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
-				     BITS_PER_BYTE), GFP_KERNEL);
-	if (!process->doorbell_bitmap) {
-		DRM_ERROR("failed to allocate doorbell bitmap\n");
-		kfree(process);
-		return -ENOMEM;
-	}
-
 	/* allocate the process context bo and map it */
 	r = amdgpu_bo_create_kernel(adev, AMDGPU_MES_PROC_CTX_SIZE, PAGE_SIZE,
 				    AMDGPU_GEM_DOMAIN_GTT,
@@ -311,7 +309,7 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid,
 	}
 
 	/* allocate the starting doorbell index of the process */
-	r = amdgpu_mes_alloc_process_doorbells(adev, &process->doorbell_index);
+	r = amdgpu_mes_alloc_process_doorbells(adev, process);
 	if (r < 0) {
 		DRM_ERROR("failed to allocate doorbell for process\n");
 		goto clean_up_pasid;
@@ -336,7 +334,6 @@ int amdgpu_mes_create_process(struct amdgpu_device *adev, int pasid,
 			      &process->proc_ctx_gpu_addr,
 			      &process->proc_ctx_cpu_ptr);
 clean_up_memory:
-	kfree(process->doorbell_bitmap);
 	kfree(process);
 	return r;
 }
@@ -382,7 +379,7 @@ void amdgpu_mes_destroy_process(struct amdgpu_device *adev, int pasid)
 		idr_remove(&adev->mes.gang_id_idr, gang->gang_id);
 	}
 
-	amdgpu_mes_free_process_doorbells(adev, process->doorbell_index);
+	amdgpu_mes_free_process_doorbells(adev, process);
 	idr_remove(&adev->mes.pasid_idr, pasid);
 	amdgpu_mes_unlock(&adev->mes);
 
@@ -404,7 +401,6 @@ void amdgpu_mes_destroy_process(struct amdgpu_device *adev, int pasid)
 	amdgpu_bo_free_kernel(&process->proc_ctx_bo,
 			      &process->proc_ctx_gpu_addr,
 			      &process->proc_ctx_cpu_ptr);
-	kfree(process->doorbell_bitmap);
 	kfree(process);
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
index e7e9dfe44c99..0c659ade527c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
@@ -145,8 +145,10 @@ struct amdgpu_mes_process {
 	uint64_t 		process_quantum;
 	struct 			list_head gang_list;
 	uint32_t 		doorbell_index;
-	unsigned long 		*doorbell_bitmap;
 	struct mutex		doorbell_lock;
+
+	/* process doorbells */
+	struct amdgpu_doorbell_obj proc_doorbells;
 };
 
 struct amdgpu_mes_gang {
@@ -364,14 +366,6 @@ int amdgpu_mes_ctx_unmap_meta_data(struct amdgpu_device *adev,
 
 int amdgpu_mes_self_test(struct amdgpu_device *adev);
 
-int amdgpu_mes_alloc_process_doorbells(struct amdgpu_device *adev,
-					unsigned int *doorbell_index);
-void amdgpu_mes_free_process_doorbells(struct amdgpu_device *adev,
-					unsigned int doorbell_index);
-unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar(
-					struct amdgpu_device *adev,
-					uint32_t doorbell_index,
-					unsigned int doorbell_id);
 int amdgpu_mes_doorbell_process_slice(struct amdgpu_device *adev);
 
 /*
-- 
2.40.0


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

* Re: [PATCH 01/16] drm/amdgpu: rename num_doorbells
  2023-03-29 15:47 ` [PATCH 01/16] drm/amdgpu: rename num_doorbells Shashank Sharma
@ 2023-03-30 11:04   ` Christian König
  2023-03-30 13:11   ` Luben Tuikov
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 87+ messages in thread
From: Christian König @ 2023-03-30 11:04 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma

Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> Rename doorbell.num_doorbells to doorbell.num_kernel_doorbells to
> make it more readable.
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>

Acked-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c   |  6 +++---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   | 22 ++++++++++----------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h |  4 +++-
>   3 files changed, 17 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> index f99d4873bf22..0385f7f69278 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> @@ -96,7 +96,7 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
>   					 size_t *start_offset)
>   {
>   	/*
> -	 * The first num_doorbells are used by amdgpu.
> +	 * The first num_kernel_doorbells are used by amdgpu.
>   	 * amdkfd takes whatever's left in the aperture.
>   	 */
>   	if (adev->enable_mes) {
> @@ -109,11 +109,11 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
>   		*aperture_base = adev->doorbell.base;
>   		*aperture_size = 0;
>   		*start_offset = 0;
> -	} else if (adev->doorbell.size > adev->doorbell.num_doorbells *
> +	} else if (adev->doorbell.size > adev->doorbell.num_kernel_doorbells *
>   						sizeof(u32)) {
>   		*aperture_base = adev->doorbell.base;
>   		*aperture_size = adev->doorbell.size;
> -		*start_offset = adev->doorbell.num_doorbells * sizeof(u32);
> +		*start_offset = adev->doorbell.num_kernel_doorbells * sizeof(u32);
>   	} else {
>   		*aperture_base = 0;
>   		*aperture_size = 0;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index afe6af9c0138..57ee1c4a81e9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -593,7 +593,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>   	if (amdgpu_device_skip_hw_access(adev))
>   		return 0;
>   
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>   		return readl(adev->doorbell.ptr + index);
>   	} else {
>   		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> @@ -616,7 +616,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>   	if (amdgpu_device_skip_hw_access(adev))
>   		return;
>   
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>   		writel(v, adev->doorbell.ptr + index);
>   	} else {
>   		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> @@ -637,7 +637,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>   	if (amdgpu_device_skip_hw_access(adev))
>   		return 0;
>   
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>   		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>   	} else {
>   		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> @@ -660,7 +660,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>   	if (amdgpu_device_skip_hw_access(adev))
>   		return;
>   
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>   		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>   	} else {
>   		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> @@ -1034,7 +1034,7 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>   	if (adev->asic_type < CHIP_BONAIRE) {
>   		adev->doorbell.base = 0;
>   		adev->doorbell.size = 0;
> -		adev->doorbell.num_doorbells = 0;
> +		adev->doorbell.num_kernel_doorbells = 0;
>   		adev->doorbell.ptr = NULL;
>   		return 0;
>   	}
> @@ -1049,27 +1049,27 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>   	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>   
>   	if (adev->enable_mes) {
> -		adev->doorbell.num_doorbells =
> +		adev->doorbell.num_kernel_doorbells =
>   			adev->doorbell.size / sizeof(u32);
>   	} else {
> -		adev->doorbell.num_doorbells =
> +		adev->doorbell.num_kernel_doorbells =
>   			min_t(u32, adev->doorbell.size / sizeof(u32),
>   			      adev->doorbell_index.max_assignment+1);
> -		if (adev->doorbell.num_doorbells == 0)
> +		if (adev->doorbell.num_kernel_doorbells == 0)
>   			return -EINVAL;
>   
>   		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
>   		 * paging queue doorbell use the second page. The
>   		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>   		 * doorbells are in the first page. So with paging queue enabled,
> -		 * the max num_doorbells should + 1 page (0x400 in dword)
> +		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>   		 */
>   		if (adev->asic_type >= CHIP_VEGA10)
> -			adev->doorbell.num_doorbells += 0x400;
> +			adev->doorbell.num_kernel_doorbells += 0x400;
>   	}
>   
>   	adev->doorbell.ptr = ioremap(adev->doorbell.base,
> -				     adev->doorbell.num_doorbells *
> +				     adev->doorbell.num_kernel_doorbells *
>   				     sizeof(u32));
>   	if (adev->doorbell.ptr == NULL)
>   		return -ENOMEM;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 7199b6b0be81..12263986f889 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -29,7 +29,9 @@ struct amdgpu_doorbell {
>   	resource_size_t		base;
>   	resource_size_t		size;
>   	u32 __iomem		*ptr;
> -	u32			num_doorbells;	/* Number of doorbells actually reserved for amdgpu. */
> +
> +	/* Number of doorbells reserved for amdgpu kernel driver */
> +	u32 num_kernel_doorbells;
>   };
>   
>   /* Reserved doorbells for amdgpu (including multimedia).


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

* Re: [PATCH 02/16] drm/amdgpu: include protection for doobell.h
  2023-03-29 15:47 ` [PATCH 02/16] drm/amdgpu: include protection for doobell.h Shashank Sharma
@ 2023-03-30 11:05   ` Christian König
  2023-03-30 11:07     ` Shashank Sharma
  2023-03-30 14:20   ` Alex Deucher
  1 sibling, 1 reply; 87+ messages in thread
From: Christian König @ 2023-03-30 11:05 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma

Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch adds double include protection for doorbell.h
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>

Reviewed-by: Christian König <christian.koenig@amd.com>

I suggest to get this pushed to amd-staging-drm-next ASAP together with 
patch #1.

Christian.

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h | 4 ++++
>   1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 12263986f889..6064943a1b53 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -21,6 +21,9 @@
>    *
>    */
>   
> +#ifndef AMDGPU_DOORBELL_H
> +#define AMDGPU_DOORBELL_H
> +
>   /*
>    * GPU doorbell structures, functions & helpers
>    */
> @@ -308,3 +311,4 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>   #define WDOORBELL64(index, v) amdgpu_mm_wdoorbell64(adev, (index), (v))
>   
> +#endif
> \ No newline at end of file


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

* Re: [PATCH 02/16] drm/amdgpu: include protection for doobell.h
  2023-03-30 11:05   ` Christian König
@ 2023-03-30 11:07     ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 11:07 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma

Hey Christian,

On 30/03/2023 13:05, Christian König wrote:
> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch adds double include protection for doorbell.h
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>
> Reviewed-by: Christian König <christian.koenig@amd.com>
>
> I suggest to get this pushed to amd-staging-drm-next ASAP together 
> with patch #1.
>
> Christian.

Noted,

- Shashank

>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index 12263986f889..6064943a1b53 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -21,6 +21,9 @@
>>    *
>>    */
>>   +#ifndef AMDGPU_DOORBELL_H
>> +#define AMDGPU_DOORBELL_H
>> +
>>   /*
>>    * GPU doorbell structures, functions & helpers
>>    */
>> @@ -308,3 +311,4 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device 
>> *adev, u32 index, u64 v);
>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>   #define WDOORBELL64(index, v) amdgpu_mm_wdoorbell64(adev, (index), 
>> (v))
>>   +#endif
>> \ No newline at end of file
>

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

* Re: [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager
  2023-03-29 15:47 ` [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager Shashank Sharma
@ 2023-03-30 11:09   ` Christian König
  2023-03-30 13:29     ` Luben Tuikov
  2023-03-30 14:23   ` Alex Deucher
  1 sibling, 1 reply; 87+ messages in thread
From: Christian König @ 2023-03-30 11:09 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma

Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch:
> - creates a new file for doorbell management.
> - moves doorbell code from amdgpu_device.c to this file.
>
> 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/Makefile           |   2 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 164 ---------------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h  |  22 +++
>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 186 ++++++++++++++++++
>   4 files changed, 209 insertions(+), 165 deletions(-)
>   create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
> index 798d0e9a60b7..204665f20319 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> @@ -41,7 +41,7 @@ ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
>   amdgpu-y := amdgpu_drv.o
>   
>   # add KMS driver
> -amdgpu-y += amdgpu_device.o amdgpu_kms.o \
> +amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
>   	amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
>   	atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
>   	amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 57ee1c4a81e9..7f8fcac4f18b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -579,94 +579,6 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
>   	}
>   }
>   
> -/**
> - * amdgpu_mm_rdoorbell - read a doorbell dword
> - *
> - * @adev: amdgpu_device pointer
> - * @index: doorbell index
> - *
> - * Returns the value in the doorbell aperture at the
> - * requested doorbell index (CIK).
> - */
> -u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
> -{
> -	if (amdgpu_device_skip_hw_access(adev))
> -		return 0;
> -
> -	if (index < adev->doorbell.num_kernel_doorbells) {
> -		return readl(adev->doorbell.ptr + index);
> -	} else {
> -		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> -		return 0;
> -	}
> -}
> -
> -/**
> - * amdgpu_mm_wdoorbell - write a doorbell dword
> - *
> - * @adev: amdgpu_device pointer
> - * @index: doorbell index
> - * @v: value to write
> - *
> - * Writes @v to the doorbell aperture at the
> - * requested doorbell index (CIK).
> - */
> -void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
> -{
> -	if (amdgpu_device_skip_hw_access(adev))
> -		return;
> -
> -	if (index < adev->doorbell.num_kernel_doorbells) {
> -		writel(v, adev->doorbell.ptr + index);
> -	} else {
> -		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> -	}
> -}
> -
> -/**
> - * amdgpu_mm_rdoorbell64 - read a doorbell Qword
> - *
> - * @adev: amdgpu_device pointer
> - * @index: doorbell index
> - *
> - * Returns the value in the doorbell aperture at the
> - * requested doorbell index (VEGA10+).
> - */
> -u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
> -{
> -	if (amdgpu_device_skip_hw_access(adev))
> -		return 0;
> -
> -	if (index < adev->doorbell.num_kernel_doorbells) {
> -		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
> -	} else {
> -		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> -		return 0;
> -	}
> -}
> -
> -/**
> - * amdgpu_mm_wdoorbell64 - write a doorbell Qword
> - *
> - * @adev: amdgpu_device pointer
> - * @index: doorbell index
> - * @v: value to write
> - *
> - * Writes @v to the doorbell aperture at the
> - * requested doorbell index (VEGA10+).
> - */
> -void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
> -{
> -	if (amdgpu_device_skip_hw_access(adev))
> -		return;
> -
> -	if (index < adev->doorbell.num_kernel_doorbells) {
> -		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
> -	} else {
> -		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> -	}
> -}
> -
>   /**
>    * amdgpu_device_indirect_rreg - read an indirect register
>    *
> @@ -1016,82 +928,6 @@ int amdgpu_device_pci_reset(struct amdgpu_device *adev)
>   	return pci_reset_function(adev->pdev);
>   }
>   
> -/*
> - * GPU doorbell aperture helpers function.
> - */
> -/**
> - * amdgpu_device_doorbell_init - Init doorbell driver information.
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Init doorbell driver information (CIK)
> - * Returns 0 on success, error on failure.
> - */
> -static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
> -{
> -
> -	/* No doorbell on SI hardware generation */
> -	if (adev->asic_type < CHIP_BONAIRE) {
> -		adev->doorbell.base = 0;
> -		adev->doorbell.size = 0;
> -		adev->doorbell.num_kernel_doorbells = 0;
> -		adev->doorbell.ptr = NULL;
> -		return 0;
> -	}
> -
> -	if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
> -		return -EINVAL;
> -
> -	amdgpu_asic_init_doorbell_index(adev);
> -
> -	/* doorbell bar mapping */
> -	adev->doorbell.base = pci_resource_start(adev->pdev, 2);
> -	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
> -
> -	if (adev->enable_mes) {
> -		adev->doorbell.num_kernel_doorbells =
> -			adev->doorbell.size / sizeof(u32);
> -	} else {
> -		adev->doorbell.num_kernel_doorbells =
> -			min_t(u32, adev->doorbell.size / sizeof(u32),
> -			      adev->doorbell_index.max_assignment+1);
> -		if (adev->doorbell.num_kernel_doorbells == 0)
> -			return -EINVAL;
> -
> -		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
> -		 * paging queue doorbell use the second page. The
> -		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
> -		 * doorbells are in the first page. So with paging queue enabled,
> -		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
> -		 */
> -		if (adev->asic_type >= CHIP_VEGA10)
> -			adev->doorbell.num_kernel_doorbells += 0x400;
> -	}
> -
> -	adev->doorbell.ptr = ioremap(adev->doorbell.base,
> -				     adev->doorbell.num_kernel_doorbells *
> -				     sizeof(u32));
> -	if (adev->doorbell.ptr == NULL)
> -		return -ENOMEM;
> -
> -	return 0;
> -}
> -
> -/**
> - * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Tear down doorbell driver information (CIK)
> - */
> -static void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
> -{
> -	iounmap(adev->doorbell.ptr);
> -	adev->doorbell.ptr = NULL;
> -}
> -
> -
> -
>   /*
>    * amdgpu_device_wb_*()
>    * Writeback is the method by which the GPU updates special pages in memory
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 6064943a1b53..f9c3b77bf65d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -306,6 +306,28 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
>   u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index);
>   void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
>   
> +/*
> + * GPU doorbell aperture helpers function.
> + */
> +/**
> + * amdgpu_device_doorbell_init - Init doorbell driver information.
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Init doorbell driver information (CIK)
> + * Returns 0 on success, error on failure.
> + */
> +int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
> +
> +/**
> + * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Tear down doorbell driver information (CIK)
> + */
> +void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);

I might be wrong, but having kerneldoc on both the declaration and the 
implementation is forbidden I think.

We usually have it on the implementation side only.

Christian.

> +
>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> new file mode 100644
> index 000000000000..2206926ba289
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -0,0 +1,186 @@
> +/*
> + * 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"
> +
> +/**
> + * amdgpu_mm_rdoorbell - read a doorbell dword
> + *
> + * @adev: amdgpu_device pointer
> + * @index: doorbell index
> + *
> + * Returns the value in the doorbell aperture at the
> + * requested doorbell index (CIK).
> + */
> +u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
> +{
> +	if (amdgpu_device_skip_hw_access(adev))
> +		return 0;
> +
> +	if (index < adev->doorbell.num_kernel_doorbells) {
> +		return readl(adev->doorbell.ptr + index);
> +	} else {
> +		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> +		return 0;
> +	}
> +}
> +
> +/**
> + * amdgpu_mm_wdoorbell - write a doorbell dword
> + *
> + * @adev: amdgpu_device pointer
> + * @index: doorbell index
> + * @v: value to write
> + *
> + * Writes @v to the doorbell aperture at the
> + * requested doorbell index (CIK).
> + */
> +void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
> +{
> +	if (amdgpu_device_skip_hw_access(adev))
> +		return;
> +
> +	if (index < adev->doorbell.num_kernel_doorbells) {
> +		writel(v, adev->doorbell.ptr + index);
> +	} else {
> +		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> +	}
> +}
> +
> +/**
> + * amdgpu_mm_rdoorbell64 - read a doorbell Qword
> + *
> + * @adev: amdgpu_device pointer
> + * @index: doorbell index
> + *
> + * Returns the value in the doorbell aperture at the
> + * requested doorbell index (VEGA10+).
> + */
> +u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
> +{
> +	if (amdgpu_device_skip_hw_access(adev))
> +		return 0;
> +
> +	if (index < adev->doorbell.num_kernel_doorbells) {
> +		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
> +	} else {
> +		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> +		return 0;
> +	}
> +}
> +
> +/**
> + * amdgpu_mm_wdoorbell64 - write a doorbell Qword
> + *
> + * @adev: amdgpu_device pointer
> + * @index: doorbell index
> + * @v: value to write
> + *
> + * Writes @v to the doorbell aperture at the
> + * requested doorbell index (VEGA10+).
> + */
> +void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
> +{
> +	if (amdgpu_device_skip_hw_access(adev))
> +		return;
> +
> +	if (index < adev->doorbell.num_kernel_doorbells) {
> +		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
> +	} else {
> +		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> +	}
> +}
> +
> +/*
> + * GPU doorbell aperture helpers function.
> + */
> +/**
> + * amdgpu_device_doorbell_init - Init doorbell driver information.
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Init doorbell driver information (CIK)
> + * Returns 0 on success, error on failure.
> + */
> +int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
> +{
> +
> +	/* No doorbell on SI hardware generation */
> +	if (adev->asic_type < CHIP_BONAIRE) {
> +		adev->doorbell.base = 0;
> +		adev->doorbell.size = 0;
> +		adev->doorbell.num_kernel_doorbells = 0;
> +		adev->doorbell.ptr = NULL;
> +		return 0;
> +	}
> +
> +	if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
> +		return -EINVAL;
> +
> +	amdgpu_asic_init_doorbell_index(adev);
> +
> +	/* doorbell bar mapping */
> +	adev->doorbell.base = pci_resource_start(adev->pdev, 2);
> +	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
> +
> +	if (adev->enable_mes) {
> +		adev->doorbell.num_kernel_doorbells =
> +			adev->doorbell.size / sizeof(u32);
> +	} else {
> +		adev->doorbell.num_kernel_doorbells =
> +			min_t(u32, adev->doorbell.size / sizeof(u32),
> +			      adev->doorbell_index.max_assignment+1);
> +		if (adev->doorbell.num_kernel_doorbells == 0)
> +			return -EINVAL;
> +
> +		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
> +		 * paging queue doorbell use the second page. The
> +		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
> +		 * doorbells are in the first page. So with paging queue enabled,
> +		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
> +		 */
> +		if (adev->asic_type >= CHIP_VEGA10)
> +			adev->doorbell.num_kernel_doorbells += 0x400;
> +	}
> +
> +	adev->doorbell.ptr = ioremap(adev->doorbell.base,
> +				     adev->doorbell.num_kernel_doorbells *
> +				     sizeof(u32));
> +	if (adev->doorbell.ptr == NULL)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +/**
> + * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Tear down doorbell driver information (CIK)
> + */
> +void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
> +{
> +	iounmap(adev->doorbell.ptr);
> +	adev->doorbell.ptr = NULL;
> +}


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

* Re: [PATCH 04/16] drm/amdgpu: don't modify num_doorbells for mes
  2023-03-29 15:47 ` [PATCH 04/16] drm/amdgpu: don't modify num_doorbells for mes Shashank Sharma
@ 2023-03-30 11:10   ` Christian König
  2023-03-30 14:24   ` Alex Deucher
  1 sibling, 0 replies; 87+ messages in thread
From: Christian König @ 2023-03-30 11:10 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch removes the check and change in num_kernel_doorbells
> for MES, which is not being used anywhere by MES code.
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 34 ++++++++-----------
>   1 file changed, 15 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> index 2206926ba289..1aea92363fd3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -143,25 +143,21 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>   	adev->doorbell.base = pci_resource_start(adev->pdev, 2);
>   	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>   
> -	if (adev->enable_mes) {
> -		adev->doorbell.num_kernel_doorbells =
> -			adev->doorbell.size / sizeof(u32);
> -	} else {
> -		adev->doorbell.num_kernel_doorbells =
> -			min_t(u32, adev->doorbell.size / sizeof(u32),
> -			      adev->doorbell_index.max_assignment+1);
> -		if (adev->doorbell.num_kernel_doorbells == 0)
> -			return -EINVAL;
> -
> -		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
> -		 * paging queue doorbell use the second page. The
> -		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
> -		 * doorbells are in the first page. So with paging queue enabled,
> -		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
> -		 */
> -		if (adev->asic_type >= CHIP_VEGA10)
> -			adev->doorbell.num_kernel_doorbells += 0x400;
> -	}
> +	adev->doorbell.num_kernel_doorbells =
> +		min_t(u32, adev->doorbell.size / sizeof(u32),
> +				adev->doorbell_index.max_assignment+1);
> +	if (adev->doorbell.num_kernel_doorbells == 0)
> +		return -EINVAL;
> +
> +	/*
> +	 * For Vega, reserve and map two pages on doorbell BAR since SDMA
> +	 * paging queue doorbell use the second page. The
> +	 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
> +	 * doorbells are in the first page. So with paging queue enabled,
> +	 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
> +	 */
> +	if (adev->asic_type >= CHIP_VEGA10)
> +		adev->doorbell.num_kernel_doorbells += 0x400;
>   
>   	adev->doorbell.ptr = ioremap(adev->doorbell.base,
>   				     adev->doorbell.num_kernel_doorbells *


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

* Re: [PATCH 05/16] drm/amdgpu: add UAPI for allocating doorbell memory
  2023-03-29 15:47 ` [PATCH 05/16] drm/amdgpu: add UAPI for allocating doorbell memory Shashank Sharma
@ 2023-03-30 11:11   ` Christian König
  0 siblings, 0 replies; 87+ messages in thread
From: Christian König @ 2023-03-30 11:11 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx; +Cc: Alex Deucher, Mukul Joshi, Felix Kuehling

Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> From: Alex Deucher <alexander.deucher@amd.com>
>
> This patch adds flags for a new gem domain AMDGPU_GEM_DOMAIN_DOORBELL
> in the UAPI layer.
>
> V2: Drop 'memory' from description (Christian)
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   include/uapi/drm/amdgpu_drm.h | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index 4038abe8505a..cc5d551abda5 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -94,6 +94,9 @@ extern "C" {
>    *
>    * %AMDGPU_GEM_DOMAIN_OA	Ordered append, used by 3D or Compute engines
>    * for appending data.
> + *
> + * %AMDGPU_GEM_DOMAIN_DOORBELL	Doorbell. It is an MMIO region for
> + * signalling user mode queues.
>    */
>   #define AMDGPU_GEM_DOMAIN_CPU		0x1
>   #define AMDGPU_GEM_DOMAIN_GTT		0x2
> @@ -101,12 +104,14 @@ extern "C" {
>   #define AMDGPU_GEM_DOMAIN_GDS		0x8
>   #define AMDGPU_GEM_DOMAIN_GWS		0x10
>   #define AMDGPU_GEM_DOMAIN_OA		0x20
> +#define AMDGPU_GEM_DOMAIN_DOORBELL	0x40
>   #define AMDGPU_GEM_DOMAIN_MASK		(AMDGPU_GEM_DOMAIN_CPU | \
>   					 AMDGPU_GEM_DOMAIN_GTT | \
>   					 AMDGPU_GEM_DOMAIN_VRAM | \
>   					 AMDGPU_GEM_DOMAIN_GDS | \
>   					 AMDGPU_GEM_DOMAIN_GWS | \
> -					 AMDGPU_GEM_DOMAIN_OA)
> +					 AMDGPU_GEM_DOMAIN_OA | \
> +					 AMDGPU_GEM_DOMAIN_DOORBELL)
>   
>   /* Flag that CPU access will be required for the case of VRAM domain */
>   #define AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED	(1 << 0)


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

* Re: [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
  2023-03-29 15:47 ` [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL Shashank Sharma
@ 2023-03-30 11:14   ` Christian König
  2023-03-30 13:33     ` Luben Tuikov
  2023-03-30 19:59   ` Alex Deucher
  1 sibling, 1 reply; 87+ messages in thread
From: Christian König @ 2023-03-30 11:14 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx; +Cc: Alex Deucher, Mukul Joshi, Felix Kuehling

Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> From: Alex Deucher <alexander.deucher@amd.com>
>
> This patch adds changes:
> - to accommodate the new GEM domain DOORBELL
> - to accommodate the new TTM PL DOORBELL
>
> in order to manage doorbell pages as GEM object.
>
> V2: Addressed reviwe comments from Christian
>      - drop the doorbell changes for pinning/unpinning
>      - drop the doorbell changes for dma-buf map
>      - drop the doorbell changes for sgt
>      - no need to handle TTM_PL_FLAG_CONTIGUOUS for doorbell
>      - add caching type for doorbell
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.c     | 11 ++++++++++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h |  2 ++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c        | 16 +++++++++++++++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h        |  1 +
>   4 files changed, 28 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index 4e684c2afc70..0ec080e240ad 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -147,6 +147,14 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
>   		c++;
>   	}
>   
> +	if (domain & AMDGPU_GEM_DOMAIN_DOORBELL) {
> +		places[c].fpfn = 0;
> +		places[c].lpfn = 0;
> +		places[c].mem_type = AMDGPU_PL_DOORBELL;
> +		places[c].flags = 0;
> +		c++;
> +	}
> +
>   	if (domain & AMDGPU_GEM_DOMAIN_GTT) {
>   		places[c].fpfn = 0;
>   		places[c].lpfn = 0;
> @@ -466,7 +474,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
>   		goto fail;
>   	}
>   
> -	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
> +	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU,  AMDGPU_GEM_DOMAIN_DOORBELL */
>   	return true;
>   
>   fail:
> @@ -1013,6 +1021,7 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo)
>   	} else if (bo->tbo.resource->mem_type == TTM_PL_TT) {
>   		atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size);
>   	}
> +

Unrelated newline, probably just a leftover.

Apart from that the patch is Reviewed-by: Christian König 
<christian.koenig@amd.com>

Regards,
Christian.

>   }
>   
>   static const char *amdgpu_vram_names[] = {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
> index 5c4f93ee0c57..3c988cc406e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
> @@ -90,6 +90,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
>   		cur->node = block;
>   		break;
>   	case TTM_PL_TT:
> +	case AMDGPU_PL_DOORBELL:
>   		node = to_ttm_range_mgr_node(res)->mm_nodes;
>   		while (start >= node->size << PAGE_SHIFT)
>   			start -= node++->size << PAGE_SHIFT;
> @@ -152,6 +153,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
>   		cur->size = min(amdgpu_vram_mgr_block_size(block), cur->remaining);
>   		break;
>   	case TTM_PL_TT:
> +	case AMDGPU_PL_DOORBELL:
>   		node = cur->node;
>   
>   		cur->node = ++node;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 55e0284b2bdd..6f61491ef3dd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -128,6 +128,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
>   	case AMDGPU_PL_GDS:
>   	case AMDGPU_PL_GWS:
>   	case AMDGPU_PL_OA:
> +	case AMDGPU_PL_DOORBELL:
>   		placement->num_placement = 0;
>   		placement->num_busy_placement = 0;
>   		return;
> @@ -500,9 +501,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
>   	if (old_mem->mem_type == AMDGPU_PL_GDS ||
>   	    old_mem->mem_type == AMDGPU_PL_GWS ||
>   	    old_mem->mem_type == AMDGPU_PL_OA ||
> +	    old_mem->mem_type == AMDGPU_PL_DOORBELL ||
>   	    new_mem->mem_type == AMDGPU_PL_GDS ||
>   	    new_mem->mem_type == AMDGPU_PL_GWS ||
> -	    new_mem->mem_type == AMDGPU_PL_OA) {
> +	    new_mem->mem_type == AMDGPU_PL_OA ||
> +	    new_mem->mem_type == AMDGPU_PL_DOORBELL) {
>   		/* Nothing to save here */
>   		ttm_bo_move_null(bo, new_mem);
>   		goto out;
> @@ -586,6 +589,12 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
>   		mem->bus.offset += adev->gmc.aper_base;
>   		mem->bus.is_iomem = true;
>   		break;
> +	case AMDGPU_PL_DOORBELL:
> +		mem->bus.offset = mem->start << PAGE_SHIFT;
> +		mem->bus.offset += adev->doorbell.base;
> +		mem->bus.is_iomem = true;
> +		mem->bus.caching = ttm_uncached;
> +		break;
>   	default:
>   		return -EINVAL;
>   	}
> @@ -600,6 +609,10 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
>   
>   	amdgpu_res_first(bo->resource, (u64)page_offset << PAGE_SHIFT, 0,
>   			 &cursor);
> +
> +	if (bo->resource->mem_type == AMDGPU_PL_DOORBELL)
> +		return ((uint64_t)(adev->doorbell.base + cursor.start)) >> PAGE_SHIFT;
> +
>   	return (adev->gmc.aper_base + cursor.start) >> PAGE_SHIFT;
>   }
>   
> @@ -1267,6 +1280,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem)
>   		flags |= AMDGPU_PTE_VALID;
>   
>   	if (mem && (mem->mem_type == TTM_PL_TT ||
> +		    mem->mem_type == AMDGPU_PL_DOORBELL ||
>   		    mem->mem_type == AMDGPU_PL_PREEMPT)) {
>   		flags |= AMDGPU_PTE_SYSTEM;
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> index e2cd5894afc9..761cd6b2b942 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> @@ -33,6 +33,7 @@
>   #define AMDGPU_PL_GWS		(TTM_PL_PRIV + 1)
>   #define AMDGPU_PL_OA		(TTM_PL_PRIV + 2)
>   #define AMDGPU_PL_PREEMPT	(TTM_PL_PRIV + 3)
> +#define AMDGPU_PL_DOORBELL	(TTM_PL_PRIV + 4)
>   
>   #define AMDGPU_GTT_MAX_TRANSFER_SIZE	512
>   #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS	2


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

* Re: [PATCH 08/16] drm/amdgpu: initialize ttm for doorbells
  2023-03-29 15:47 ` [PATCH 08/16] drm/amdgpu: initialize ttm for doorbells Shashank Sharma
@ 2023-03-30 11:22   ` Christian König
  2023-03-30 14:33   ` Alex Deucher
  1 sibling, 0 replies; 87+ messages in thread
From: Christian König @ 2023-03-30 11:22 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch initialzes the ttm resource manager for doorbells.
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 8 ++++++++
>   1 file changed, 8 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 6f61491ef3dd..203d77a20507 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1858,6 +1858,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>   	DRM_INFO("amdgpu: %uM of GTT memory ready.\n",
>   		 (unsigned)(gtt_size / (1024 * 1024)));
>   
> +	/* Initiailize doorbell pool on PCI BAR */
> +	r = amdgpu_ttm_init_on_chip(adev, AMDGPU_PL_DOORBELL,
> +				    DIV_ROUND_UP(adev->doorbell.size, PAGE_SIZE));
> +	if (r) {
> +		DRM_ERROR("Failed initializing doorbell heap. \n");
> +		return r;
> +	}
> +
>   	/* Initialize preemptible memory pool */
>   	r = amdgpu_preempt_mgr_init(adev);
>   	if (r) {


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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-29 15:47 ` [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages Shashank Sharma
@ 2023-03-30 11:29   ` Christian König
  2023-03-30 11:46     ` Shashank Sharma
  2023-03-30 13:42   ` Luben Tuikov
  2023-03-30 14:28   ` Alex Deucher
  2 siblings, 1 reply; 87+ messages in thread
From: Christian König @ 2023-03-30 11:29 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch adds helper functions to create and free doorbell
> pages for kernel objects.
>
> 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_doorbell.h  | 41 ++++++++++++++++
>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>   2 files changed, 90 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index f9c3b77bf65d..6581b78fe438 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -27,6 +27,24 @@
>   /*
>    * GPU doorbell structures, functions & helpers
>    */
> +
> +/* Structure to hold doorbell pages from PCI doorbell BAR */
> +struct amdgpu_doorbell_obj {
> +	struct amdgpu_bo *bo;
> +	uint64_t gpu_addr;

Do we need to map the doorbells into the GART for something?

On the other hand we probably don't have the check to not do it in 
amdgpu_bo_create_reserved yet.

> +	uint32_t *cpu_addr;
> +	uint32_t size;
> +
> +	/* First index in this object */
> +	uint32_t start;
> +
> +	/* Last index in this object */
> +	uint32_t end;
> +
> +	/* bitmap for dynamic doorbell allocation from this object */
> +	unsigned long *doorbell_bitmap;
> +};
> +

Do we really need a separate structure for all this? As far as I can see 
this is just part of the doorbell handling.

>   struct amdgpu_doorbell {
>   	/* doorbell mmio */
>   	resource_size_t		base;
> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>    */
>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>   
> +/**
> + * amdgpu_doorbell_free_page - Free a doorbell page
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: previously allocated doobell page details
> + *
> + */
> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
> +				struct amdgpu_doorbell_obj *db_obj);
> +
> +/**
> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: doobell page structure to fill details with
> + *
> + * returns 0 on success, else error number
> + */
> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> +				struct amdgpu_doorbell_obj *db_obj);
> +
>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> index 1aea92363fd3..8be15b82b545 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>   	}
>   }
>   
> +/**
> + * amdgpu_doorbell_free_page - Free a doorbell page
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: previously allocated doobell page details
> + *
> + */
> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
> +					struct amdgpu_doorbell_obj *db_obj)
> +{
> +	amdgpu_bo_free_kernel(&db_obj->bo,
> +			      &db_obj->gpu_addr,
> +			      (void **)&db_obj->cpu_addr);
> +
> +}
> +
> +/**
> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: doobell page structure to fill details with
> + *
> + * returns 0 on success, else error number
> + */
> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> +				struct amdgpu_doorbell_obj *db_obj)
> +{
> +	int r;
> +
> +	db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
> +
> +	r = amdgpu_bo_create_kernel(adev,
> +				    db_obj->size,
> +				    PAGE_SIZE,
> +				    AMDGPU_GEM_DOMAIN_DOORBELL,
> +				    &db_obj->bo,
> +				    &db_obj->gpu_addr,
> +				    (void **)&db_obj->cpu_addr);
> +
> +	if (r) {
> +		DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
> +		return r;
> +	}
> +
> +	return 0;
> +}
> +
>   /*
>    * GPU doorbell aperture helpers function.
>    */


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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-29 15:47 ` [PATCH 09/16] drm/amdgpu: create kernel doorbell page Shashank Sharma
@ 2023-03-30 11:30   ` Christian König
  2023-03-30 11:48     ` Shashank Sharma
  2023-03-30 14:24   ` Luben Tuikov
  1 sibling, 1 reply; 87+ messages in thread
From: Christian König @ 2023-03-30 11:30 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma



Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch:
> - creates a doorbell page for graphics driver usages.
> - removes the adev->doorbell.ptr variable, replaces it with
>    kernel-doorbell-bo's cpu address.
>
> 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_doorbell.h  | 16 ++++++-
>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 +++++++++++++++----
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>   3 files changed, 57 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 6581b78fe438..10a9bb10e974 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>   	/* doorbell mmio */
>   	resource_size_t		base;
>   	resource_size_t		size;
> -	u32 __iomem		*ptr;
> +	u32	__iomem		*ptr;

This one can probably go away if we use the pointer from 
amdgpu_bo_create_kernel().

>   
>   	/* Number of doorbells reserved for amdgpu kernel driver */
>   	u32 num_kernel_doorbells;
> +
> +	/* For kernel doorbell pages */
> +	struct amdgpu_doorbell_obj kernel_doorbells;
>   };
>   
>   /* Reserved doorbells for amdgpu (including multimedia).
> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>   int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>   				struct amdgpu_doorbell_obj *db_obj);
>   
> +/**
> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells for graphics
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Creates doorbells for graphics driver
> + *
> + * returns 0 on success, error otherwise.
> + */
> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev);
> +
>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> index 8be15b82b545..b46fe8b1378d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>   	return 0;
>   }
>   
> +/**
> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells for graphics
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Creates doorbells for graphics driver
> + *
> + * returns 0 on success, error otherwise.
> + */
> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev)
> +{
> +	int r;
> +	struct amdgpu_doorbell_obj *kernel_doorbells = &adev->doorbell.kernel_doorbells;
> +
> +	kernel_doorbells->doorbell_bitmap = bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
> +							  GFP_KERNEL);
> +	if (!kernel_doorbells->doorbell_bitmap) {
> +		DRM_ERROR("Failed to create kernel doorbell bitmap\n");
> +		return -ENOMEM;
> +	}
> +
> +	kernel_doorbells->size = adev->doorbell.num_kernel_doorbells * sizeof(u32);
> +	r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
> +	if (r) {
> +		bitmap_free(kernel_doorbells->doorbell_bitmap);
> +		DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", r);
> +		return r;
> +	}
> +
> +	return 0;
> +}
> +
>   /*
>    * GPU doorbell aperture helpers function.
>    */
> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>   		adev->doorbell.base = 0;
>   		adev->doorbell.size = 0;
>   		adev->doorbell.num_kernel_doorbells = 0;
> -		adev->doorbell.ptr = NULL;
>   		return 0;
>   	}
>   
> @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>   	if (adev->asic_type >= CHIP_VEGA10)
>   		adev->doorbell.num_kernel_doorbells += 0x400;
>   
> -	adev->doorbell.ptr = ioremap(adev->doorbell.base,
> -				     adev->doorbell.num_kernel_doorbells *
> -				     sizeof(u32));
> -	if (adev->doorbell.ptr == NULL)
> -		return -ENOMEM;
> -
> +	adev->doorbell.ptr = ioremap(adev->doorbell.base, adev->doorbell.size);
>   	return 0;
>   }
>   
> @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>    */
>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>   {
> -	iounmap(adev->doorbell.ptr);
> -	adev->doorbell.ptr = NULL;
> +	bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
> +	amdgpu_doorbell_free_page(adev, &adev->doorbell.kernel_doorbells);
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 203d77a20507..75c6852845c4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>   		return r;
>   	}
>   
> +	/* Create a boorbell page for kernel usages */
> +	r = amdgpu_doorbell_create_kernel_doorbells(adev);
> +	if (r) {
> +		DRM_ERROR("Failed to initialize kernel doorbells. \n");
> +		return r;
> +	}
> +
>   	/* Initialize preemptible memory pool */
>   	r = amdgpu_preempt_mgr_init(adev);
>   	if (r) {


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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 11:29   ` Christian König
@ 2023-03-30 11:46     ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 11:46 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig


On 30/03/2023 13:29, Christian König wrote:
> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch adds helper functions to create and free doorbell
>> pages for kernel objects.
>>
>> 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_doorbell.h  | 41 ++++++++++++++++
>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>>   2 files changed, 90 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index f9c3b77bf65d..6581b78fe438 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -27,6 +27,24 @@
>>   /*
>>    * GPU doorbell structures, functions & helpers
>>    */
>> +
>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>> +struct amdgpu_doorbell_obj {
>> +    struct amdgpu_bo *bo;
>> +    uint64_t gpu_addr;
>
> Do we need to map the doorbells into the GART for something?
>
> On the other hand we probably don't have the check to not do it in 
> amdgpu_bo_create_reserved yet.
We don't actually. I can remove this variable.
>
>> +    uint32_t *cpu_addr;
>> +    uint32_t size;
>> +
>> +    /* First index in this object */
>> +    uint32_t start;
>> +
>> +    /* Last index in this object */
>> +    uint32_t end;
>> +
>> +    /* bitmap for dynamic doorbell allocation from this object */
>> +    unsigned long *doorbell_bitmap;
>> +};
>> +
>
> Do we really need a separate structure for all this? As far as I can 
> see this is just part of the doorbell handling.
>
It makes it really convenient to have all of this in the same place, 
please check the patches where the doorbell

objects are used and stored, that might paint a better picture.

- Shashank

>>   struct amdgpu_doorbell {
>>       /* doorbell mmio */
>>       resource_size_t        base;
>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct 
>> amdgpu_device *adev);
>>    */
>>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>>   +/**
>> + * amdgpu_doorbell_free_page - Free a doorbell page
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: previously allocated doobell page details
>> + *
>> + */
>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>> +                struct amdgpu_doorbell_obj *db_obj);
>> +
>> +/**
>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: doobell page structure to fill details with
>> + *
>> + * returns 0 on success, else error number
>> + */
>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>> +                struct amdgpu_doorbell_obj *db_obj);
>> +
>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> index 1aea92363fd3..8be15b82b545 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device 
>> *adev, u32 index, u64 v)
>>       }
>>   }
>>   +/**
>> + * amdgpu_doorbell_free_page - Free a doorbell page
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: previously allocated doobell page details
>> + *
>> + */
>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>> +                    struct amdgpu_doorbell_obj *db_obj)
>> +{
>> +    amdgpu_bo_free_kernel(&db_obj->bo,
>> +                  &db_obj->gpu_addr,
>> +                  (void **)&db_obj->cpu_addr);
>> +
>> +}
>> +
>> +/**
>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: doobell page structure to fill details with
>> + *
>> + * returns 0 on success, else error number
>> + */
>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>> +                struct amdgpu_doorbell_obj *db_obj)
>> +{
>> +    int r;
>> +
>> +    db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
>> +
>> +    r = amdgpu_bo_create_kernel(adev,
>> +                    db_obj->size,
>> +                    PAGE_SIZE,
>> +                    AMDGPU_GEM_DOMAIN_DOORBELL,
>> +                    &db_obj->bo,
>> +                    &db_obj->gpu_addr,
>> +                    (void **)&db_obj->cpu_addr);
>> +
>> +    if (r) {
>> +        DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
>> +        return r;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   /*
>>    * GPU doorbell aperture helpers function.
>>    */
>

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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 11:30   ` Christian König
@ 2023-03-30 11:48     ` Shashank Sharma
  2023-03-30 14:39       ` Alex Deucher
  0 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 11:48 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma


On 30/03/2023 13:30, Christian König wrote:
>
>
> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch:
>> - creates a doorbell page for graphics driver usages.
>> - removes the adev->doorbell.ptr variable, replaces it with
>>    kernel-doorbell-bo's cpu address.
>>
>> 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_doorbell.h  | 16 ++++++-
>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 +++++++++++++++----
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>   3 files changed, 57 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index 6581b78fe438..10a9bb10e974 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>       /* doorbell mmio */
>>       resource_size_t        base;
>>       resource_size_t        size;
>> -    u32 __iomem        *ptr;
>> +    u32    __iomem        *ptr;
>
> This one can probably go away if we use the pointer from 
> amdgpu_bo_create_kernel().

We started like that, but later realized that the cpu_addr from 
create_kernel() will just limit us

to that object only, whereas we are keeping this ptr to ioremap the 
whole doorbell space in one shot.

- Shashank

>
>>         /* Number of doorbells reserved for amdgpu kernel driver */
>>       u32 num_kernel_doorbells;
>> +
>> +    /* For kernel doorbell pages */
>> +    struct amdgpu_doorbell_obj kernel_doorbells;
>>   };
>>     /* Reserved doorbells for amdgpu (including multimedia).
>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct 
>> amdgpu_device *adev,
>>   int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>                   struct amdgpu_doorbell_obj *db_obj);
>>   +/**
>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells 
>> for graphics
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Creates doorbells for graphics driver
>> + *
>> + * returns 0 on success, error otherwise.
>> + */
>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>> *adev);
>> +
>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> index 8be15b82b545..b46fe8b1378d 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct 
>> amdgpu_device *adev,
>>       return 0;
>>   }
>>   +/**
>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells 
>> for graphics
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Creates doorbells for graphics driver
>> + *
>> + * returns 0 on success, error otherwise.
>> + */
>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev)
>> +{
>> +    int r;
>> +    struct amdgpu_doorbell_obj *kernel_doorbells = 
>> &adev->doorbell.kernel_doorbells;
>> +
>> +    kernel_doorbells->doorbell_bitmap = 
>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>> +                              GFP_KERNEL);
>> +    if (!kernel_doorbells->doorbell_bitmap) {
>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>> +        return -ENOMEM;
>> +    }
>> +
>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells * 
>> sizeof(u32);
>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>> +    if (r) {
>> +        bitmap_free(kernel_doorbells->doorbell_bitmap);
>> +        DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", r);
>> +        return r;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   /*
>>    * GPU doorbell aperture helpers function.
>>    */
>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct 
>> amdgpu_device *adev)
>>           adev->doorbell.base = 0;
>>           adev->doorbell.size = 0;
>>           adev->doorbell.num_kernel_doorbells = 0;
>> -        adev->doorbell.ptr = NULL;
>>           return 0;
>>       }
>>   @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct 
>> amdgpu_device *adev)
>>       if (adev->asic_type >= CHIP_VEGA10)
>>           adev->doorbell.num_kernel_doorbells += 0x400;
>>   -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>> -                     adev->doorbell.num_kernel_doorbells *
>> -                     sizeof(u32));
>> -    if (adev->doorbell.ptr == NULL)
>> -        return -ENOMEM;
>> -
>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base, 
>> adev->doorbell.size);
>>       return 0;
>>   }
>>   @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct 
>> amdgpu_device *adev)
>>    */
>>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>   {
>> -    iounmap(adev->doorbell.ptr);
>> -    adev->doorbell.ptr = NULL;
>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>> +    amdgpu_doorbell_free_page(adev, &adev->doorbell.kernel_doorbells);
>>   }
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 203d77a20507..75c6852845c4 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>           return r;
>>       }
>>   +    /* Create a boorbell page for kernel usages */
>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
>> +    if (r) {
>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
>> +        return r;
>> +    }
>> +
>>       /* Initialize preemptible memory pool */
>>       r = amdgpu_preempt_mgr_init(adev);
>>       if (r) {
>

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

* Re: [PATCH 01/16] drm/amdgpu: rename num_doorbells
  2023-03-29 15:47 ` [PATCH 01/16] drm/amdgpu: rename num_doorbells Shashank Sharma
  2023-03-30 11:04   ` Christian König
@ 2023-03-30 13:11   ` Luben Tuikov
  2023-03-30 13:13     ` Shashank Sharma
  2023-03-30 14:19   ` Alex Deucher
  2023-04-04 16:13   ` Luben Tuikov
  3 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 13:11 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

Hi Shashank,

Inline:

On 2023-03-29 11:47, Shashank Sharma wrote:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
> 
> Rename doorbell.num_doorbells to doorbell.num_kernel_doorbells to
> make it more readable.
> 
> 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_amdkfd.c   |  6 +++---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   | 22 ++++++++++----------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h |  4 +++-
>  3 files changed, 17 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> index f99d4873bf22..0385f7f69278 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> @@ -96,7 +96,7 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
>  					 size_t *start_offset)
>  {
>  	/*
> -	 * The first num_doorbells are used by amdgpu.
> +	 * The first num_kernel_doorbells are used by amdgpu.
>  	 * amdkfd takes whatever's left in the aperture.
>  	 */
>  	if (adev->enable_mes) {
> @@ -109,11 +109,11 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
>  		*aperture_base = adev->doorbell.base;
>  		*aperture_size = 0;
>  		*start_offset = 0;
> -	} else if (adev->doorbell.size > adev->doorbell.num_doorbells *
> +	} else if (adev->doorbell.size > adev->doorbell.num_kernel_doorbells *
>  						sizeof(u32)) {
>  		*aperture_base = adev->doorbell.base;
>  		*aperture_size = adev->doorbell.size;
> -		*start_offset = adev->doorbell.num_doorbells * sizeof(u32);
> +		*start_offset = adev->doorbell.num_kernel_doorbells * sizeof(u32);
>  	} else {
>  		*aperture_base = 0;
>  		*aperture_size = 0;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index afe6af9c0138..57ee1c4a81e9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -593,7 +593,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return 0;
>  
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>  		return readl(adev->doorbell.ptr + index);
>  	} else {
>  		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> @@ -616,7 +616,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return;
>  
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>  		writel(v, adev->doorbell.ptr + index);
>  	} else {
>  		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> @@ -637,7 +637,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return 0;
>  
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>  		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>  	} else {
>  		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> @@ -660,7 +660,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return;
>  
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>  		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>  	} else {
>  		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> @@ -1034,7 +1034,7 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>  	if (adev->asic_type < CHIP_BONAIRE) {
>  		adev->doorbell.base = 0;
>  		adev->doorbell.size = 0;
> -		adev->doorbell.num_doorbells = 0;
> +		adev->doorbell.num_kernel_doorbells = 0;
>  		adev->doorbell.ptr = NULL;
>  		return 0;
>  	}
> @@ -1049,27 +1049,27 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>  	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>  
>  	if (adev->enable_mes) {
> -		adev->doorbell.num_doorbells =
> +		adev->doorbell.num_kernel_doorbells =
>  			adev->doorbell.size / sizeof(u32);
>  	} else {
> -		adev->doorbell.num_doorbells =
> +		adev->doorbell.num_kernel_doorbells =
>  			min_t(u32, adev->doorbell.size / sizeof(u32),
>  			      adev->doorbell_index.max_assignment+1);
> -		if (adev->doorbell.num_doorbells == 0)
> +		if (adev->doorbell.num_kernel_doorbells == 0)
>  			return -EINVAL;
>  
>  		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
>  		 * paging queue doorbell use the second page. The
>  		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>  		 * doorbells are in the first page. So with paging queue enabled,
> -		 * the max num_doorbells should + 1 page (0x400 in dword)
> +		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>  		 */
>  		if (adev->asic_type >= CHIP_VEGA10)
> -			adev->doorbell.num_doorbells += 0x400;
> +			adev->doorbell.num_kernel_doorbells += 0x400;
>  	}
>  
>  	adev->doorbell.ptr = ioremap(adev->doorbell.base,
> -				     adev->doorbell.num_doorbells *
> +				     adev->doorbell.num_kernel_doorbells *
>  				     sizeof(u32));
>  	if (adev->doorbell.ptr == NULL)
>  		return -ENOMEM;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 7199b6b0be81..12263986f889 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -29,7 +29,9 @@ struct amdgpu_doorbell {
>  	resource_size_t		base;
>  	resource_size_t		size;
>  	u32 __iomem		*ptr;
> -	u32			num_doorbells;	/* Number of doorbells actually reserved for amdgpu. */
> +
> +	/* Number of doorbells reserved for amdgpu kernel driver */
> +	u32 num_kernel_doorbells;

The variable name should be indented to the same column as the previous variables.
	u32                     num_kernel_doorbells;

With that change, this patch is
Acked-by: Luben Tuikov <luben.tuikov@amd.com>
-- 
Regards,
Luben

>  };
>  
>  /* Reserved doorbells for amdgpu (including multimedia).


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

* Re: [PATCH 01/16] drm/amdgpu: rename num_doorbells
  2023-03-30 13:11   ` Luben Tuikov
@ 2023-03-30 13:13     ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 13:13 UTC (permalink / raw)
  To: Luben Tuikov, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

Hello Luben,

Thanks for the review, comments inline.


On 30/03/2023 15:11, Luben Tuikov wrote:
> Hi Shashank,
>
> Inline:
>
> On 2023-03-29 11:47, Shashank Sharma wrote:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> Rename doorbell.num_doorbells to doorbell.num_kernel_doorbells to
>> make it more readable.
>>
>> 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_amdkfd.c   |  6 +++---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   | 22 ++++++++++----------
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h |  4 +++-
>>   3 files changed, 17 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
>> index f99d4873bf22..0385f7f69278 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
>> @@ -96,7 +96,7 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
>>   					 size_t *start_offset)
>>   {
>>   	/*
>> -	 * The first num_doorbells are used by amdgpu.
>> +	 * The first num_kernel_doorbells are used by amdgpu.
>>   	 * amdkfd takes whatever's left in the aperture.
>>   	 */
>>   	if (adev->enable_mes) {
>> @@ -109,11 +109,11 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
>>   		*aperture_base = adev->doorbell.base;
>>   		*aperture_size = 0;
>>   		*start_offset = 0;
>> -	} else if (adev->doorbell.size > adev->doorbell.num_doorbells *
>> +	} else if (adev->doorbell.size > adev->doorbell.num_kernel_doorbells *
>>   						sizeof(u32)) {
>>   		*aperture_base = adev->doorbell.base;
>>   		*aperture_size = adev->doorbell.size;
>> -		*start_offset = adev->doorbell.num_doorbells * sizeof(u32);
>> +		*start_offset = adev->doorbell.num_kernel_doorbells * sizeof(u32);
>>   	} else {
>>   		*aperture_base = 0;
>>   		*aperture_size = 0;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> index afe6af9c0138..57ee1c4a81e9 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -593,7 +593,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>>   	if (amdgpu_device_skip_hw_access(adev))
>>   		return 0;
>>   
>> -	if (index < adev->doorbell.num_doorbells) {
>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>>   		return readl(adev->doorbell.ptr + index);
>>   	} else {
>>   		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> @@ -616,7 +616,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>>   	if (amdgpu_device_skip_hw_access(adev))
>>   		return;
>>   
>> -	if (index < adev->doorbell.num_doorbells) {
>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>>   		writel(v, adev->doorbell.ptr + index);
>>   	} else {
>>   		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> @@ -637,7 +637,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>>   	if (amdgpu_device_skip_hw_access(adev))
>>   		return 0;
>>   
>> -	if (index < adev->doorbell.num_doorbells) {
>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>>   		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>>   	} else {
>>   		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> @@ -660,7 +660,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>   	if (amdgpu_device_skip_hw_access(adev))
>>   		return;
>>   
>> -	if (index < adev->doorbell.num_doorbells) {
>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>>   		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>>   	} else {
>>   		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> @@ -1034,7 +1034,7 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>>   	if (adev->asic_type < CHIP_BONAIRE) {
>>   		adev->doorbell.base = 0;
>>   		adev->doorbell.size = 0;
>> -		adev->doorbell.num_doorbells = 0;
>> +		adev->doorbell.num_kernel_doorbells = 0;
>>   		adev->doorbell.ptr = NULL;
>>   		return 0;
>>   	}
>> @@ -1049,27 +1049,27 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>>   	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>>   
>>   	if (adev->enable_mes) {
>> -		adev->doorbell.num_doorbells =
>> +		adev->doorbell.num_kernel_doorbells =
>>   			adev->doorbell.size / sizeof(u32);
>>   	} else {
>> -		adev->doorbell.num_doorbells =
>> +		adev->doorbell.num_kernel_doorbells =
>>   			min_t(u32, adev->doorbell.size / sizeof(u32),
>>   			      adev->doorbell_index.max_assignment+1);
>> -		if (adev->doorbell.num_doorbells == 0)
>> +		if (adev->doorbell.num_kernel_doorbells == 0)
>>   			return -EINVAL;
>>   
>>   		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
>>   		 * paging queue doorbell use the second page. The
>>   		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>>   		 * doorbells are in the first page. So with paging queue enabled,
>> -		 * the max num_doorbells should + 1 page (0x400 in dword)
>> +		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>>   		 */
>>   		if (adev->asic_type >= CHIP_VEGA10)
>> -			adev->doorbell.num_doorbells += 0x400;
>> +			adev->doorbell.num_kernel_doorbells += 0x400;
>>   	}
>>   
>>   	adev->doorbell.ptr = ioremap(adev->doorbell.base,
>> -				     adev->doorbell.num_doorbells *
>> +				     adev->doorbell.num_kernel_doorbells *
>>   				     sizeof(u32));
>>   	if (adev->doorbell.ptr == NULL)
>>   		return -ENOMEM;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index 7199b6b0be81..12263986f889 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -29,7 +29,9 @@ struct amdgpu_doorbell {
>>   	resource_size_t		base;
>>   	resource_size_t		size;
>>   	u32 __iomem		*ptr;
>> -	u32			num_doorbells;	/* Number of doorbells actually reserved for amdgpu. */
>> +
>> +	/* Number of doorbells reserved for amdgpu kernel driver */
>> +	u32 num_kernel_doorbells;
> The variable name should be indented to the same column as the previous variables.
> 	u32                     num_kernel_doorbells;

Noted,

-Shashank

> With that change, this patch is
> Acked-by: Luben Tuikov <luben.tuikov@amd.com>

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

* Re: [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager
  2023-03-30 11:09   ` Christian König
@ 2023-03-30 13:29     ` Luben Tuikov
  2023-03-30 13:42       ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 13:29 UTC (permalink / raw)
  To: Christian König, Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma

Hi Shashank,

Inline:

On 2023-03-30 07:09, Christian König wrote:
> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch:
>> - creates a new file for doorbell management.
>> - moves doorbell code from amdgpu_device.c to this file.
>>
>> 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/Makefile           |   2 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 164 ---------------
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h  |  22 +++
>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 186 ++++++++++++++++++
>>   4 files changed, 209 insertions(+), 165 deletions(-)
>>   create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
>> index 798d0e9a60b7..204665f20319 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
>> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
>> @@ -41,7 +41,7 @@ ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
>>   amdgpu-y := amdgpu_drv.o
>>   
>>   # add KMS driver
>> -amdgpu-y += amdgpu_device.o amdgpu_kms.o \
>> +amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
>>   	amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
>>   	atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
>>   	amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> index 57ee1c4a81e9..7f8fcac4f18b 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -579,94 +579,6 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
>>   	}
>>   }
>>   
>> -/**
>> - * amdgpu_mm_rdoorbell - read a doorbell dword
>> - *
>> - * @adev: amdgpu_device pointer
>> - * @index: doorbell index
>> - *
>> - * Returns the value in the doorbell aperture at the
>> - * requested doorbell index (CIK).
>> - */
>> -u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>> -{
>> -	if (amdgpu_device_skip_hw_access(adev))
>> -		return 0;
>> -
>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>> -		return readl(adev->doorbell.ptr + index);
>> -	} else {
>> -		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> -		return 0;
>> -	}
>> -}
>> -
>> -/**
>> - * amdgpu_mm_wdoorbell - write a doorbell dword
>> - *
>> - * @adev: amdgpu_device pointer
>> - * @index: doorbell index
>> - * @v: value to write
>> - *
>> - * Writes @v to the doorbell aperture at the
>> - * requested doorbell index (CIK).
>> - */
>> -void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>> -{
>> -	if (amdgpu_device_skip_hw_access(adev))
>> -		return;
>> -
>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>> -		writel(v, adev->doorbell.ptr + index);
>> -	} else {
>> -		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> -	}
>> -}
>> -
>> -/**
>> - * amdgpu_mm_rdoorbell64 - read a doorbell Qword
>> - *
>> - * @adev: amdgpu_device pointer
>> - * @index: doorbell index
>> - *
>> - * Returns the value in the doorbell aperture at the
>> - * requested doorbell index (VEGA10+).
>> - */
>> -u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>> -{
>> -	if (amdgpu_device_skip_hw_access(adev))
>> -		return 0;
>> -
>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>> -		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>> -	} else {
>> -		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> -		return 0;
>> -	}
>> -}
>> -
>> -/**
>> - * amdgpu_mm_wdoorbell64 - write a doorbell Qword
>> - *
>> - * @adev: amdgpu_device pointer
>> - * @index: doorbell index
>> - * @v: value to write
>> - *
>> - * Writes @v to the doorbell aperture at the
>> - * requested doorbell index (VEGA10+).
>> - */
>> -void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>> -{
>> -	if (amdgpu_device_skip_hw_access(adev))
>> -		return;
>> -
>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>> -		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>> -	} else {
>> -		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> -	}
>> -}
>> -
>>   /**
>>    * amdgpu_device_indirect_rreg - read an indirect register
>>    *
>> @@ -1016,82 +928,6 @@ int amdgpu_device_pci_reset(struct amdgpu_device *adev)
>>   	return pci_reset_function(adev->pdev);
>>   }
>>   
>> -/*
>> - * GPU doorbell aperture helpers function.
>> - */
>> -/**
>> - * amdgpu_device_doorbell_init - Init doorbell driver information.
>> - *
>> - * @adev: amdgpu_device pointer
>> - *
>> - * Init doorbell driver information (CIK)
>> - * Returns 0 on success, error on failure.
>> - */
>> -static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>> -{
>> -
>> -	/* No doorbell on SI hardware generation */
>> -	if (adev->asic_type < CHIP_BONAIRE) {
>> -		adev->doorbell.base = 0;
>> -		adev->doorbell.size = 0;
>> -		adev->doorbell.num_kernel_doorbells = 0;
>> -		adev->doorbell.ptr = NULL;
>> -		return 0;
>> -	}
>> -
>> -	if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
>> -		return -EINVAL;
>> -
>> -	amdgpu_asic_init_doorbell_index(adev);
>> -
>> -	/* doorbell bar mapping */
>> -	adev->doorbell.base = pci_resource_start(adev->pdev, 2);
>> -	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>> -
>> -	if (adev->enable_mes) {
>> -		adev->doorbell.num_kernel_doorbells =
>> -			adev->doorbell.size / sizeof(u32);
>> -	} else {
>> -		adev->doorbell.num_kernel_doorbells =
>> -			min_t(u32, adev->doorbell.size / sizeof(u32),
>> -			      adev->doorbell_index.max_assignment+1);
>> -		if (adev->doorbell.num_kernel_doorbells == 0)
>> -			return -EINVAL;
>> -
>> -		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
>> -		 * paging queue doorbell use the second page. The
>> -		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>> -		 * doorbells are in the first page. So with paging queue enabled,
>> -		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>> -		 */
>> -		if (adev->asic_type >= CHIP_VEGA10)
>> -			adev->doorbell.num_kernel_doorbells += 0x400;
>> -	}
>> -
>> -	adev->doorbell.ptr = ioremap(adev->doorbell.base,
>> -				     adev->doorbell.num_kernel_doorbells *
>> -				     sizeof(u32));
>> -	if (adev->doorbell.ptr == NULL)
>> -		return -ENOMEM;
>> -
>> -	return 0;
>> -}
>> -
>> -/**
>> - * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
>> - *
>> - * @adev: amdgpu_device pointer
>> - *
>> - * Tear down doorbell driver information (CIK)
>> - */
>> -static void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>> -{
>> -	iounmap(adev->doorbell.ptr);
>> -	adev->doorbell.ptr = NULL;
>> -}
>> -
>> -
>> -
>>   /*
>>    * amdgpu_device_wb_*()
>>    * Writeback is the method by which the GPU updates special pages in memory
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index 6064943a1b53..f9c3b77bf65d 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -306,6 +306,28 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
>>   u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index);
>>   void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
>>   
>> +/*
>> + * GPU doorbell aperture helpers function.
>> + */
>> +/**
>> + * amdgpu_device_doorbell_init - Init doorbell driver information.
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Init doorbell driver information (CIK)
>> + * Returns 0 on success, error on failure.
>> + */
>> +int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>> +
>> +/**
>> + * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Tear down doorbell driver information (CIK)
>> + */
>> +void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
> 
> I might be wrong, but having kerneldoc on both the declaration and the 
> implementation is forbidden I think.
> 
> We usually have it on the implementation side only.

Yes, that is correct--implementation side only as that's where
the actual code can be found.

> 
> Christian.
> 
>> +
>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> new file mode 100644
>> index 000000000000..2206926ba289
>> --- /dev/null
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> @@ -0,0 +1,186 @@
>> +/*

Add an SPDX licence identifier as the very first line:
//SPDX-License-Identifier: <value>

with some appropriate value, maybe "GPL-2.0-or-later" (no quotes when added).

Regards,
Luben

>> + * 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"
>> +
>> +/**
>> + * amdgpu_mm_rdoorbell - read a doorbell dword
>> + *
>> + * @adev: amdgpu_device pointer
>> + * @index: doorbell index
>> + *
>> + * Returns the value in the doorbell aperture at the
>> + * requested doorbell index (CIK).
>> + */
>> +u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>> +{
>> +	if (amdgpu_device_skip_hw_access(adev))
>> +		return 0;
>> +
>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>> +		return readl(adev->doorbell.ptr + index);
>> +	} else {
>> +		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> +		return 0;
>> +	}
>> +}
>> +
>> +/**
>> + * amdgpu_mm_wdoorbell - write a doorbell dword
>> + *
>> + * @adev: amdgpu_device pointer
>> + * @index: doorbell index
>> + * @v: value to write
>> + *
>> + * Writes @v to the doorbell aperture at the
>> + * requested doorbell index (CIK).
>> + */
>> +void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>> +{
>> +	if (amdgpu_device_skip_hw_access(adev))
>> +		return;
>> +
>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>> +		writel(v, adev->doorbell.ptr + index);
>> +	} else {
>> +		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> +	}
>> +}
>> +
>> +/**
>> + * amdgpu_mm_rdoorbell64 - read a doorbell Qword
>> + *
>> + * @adev: amdgpu_device pointer
>> + * @index: doorbell index
>> + *
>> + * Returns the value in the doorbell aperture at the
>> + * requested doorbell index (VEGA10+).
>> + */
>> +u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>> +{
>> +	if (amdgpu_device_skip_hw_access(adev))
>> +		return 0;
>> +
>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>> +		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>> +	} else {
>> +		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> +		return 0;
>> +	}
>> +}
>> +
>> +/**
>> + * amdgpu_mm_wdoorbell64 - write a doorbell Qword
>> + *
>> + * @adev: amdgpu_device pointer
>> + * @index: doorbell index
>> + * @v: value to write
>> + *
>> + * Writes @v to the doorbell aperture at the
>> + * requested doorbell index (VEGA10+).
>> + */
>> +void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>> +{
>> +	if (amdgpu_device_skip_hw_access(adev))
>> +		return;
>> +
>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>> +		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>> +	} else {
>> +		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> +	}
>> +}
>> +
>> +/*
>> + * GPU doorbell aperture helpers function.
>> + */
>> +/**
>> + * amdgpu_device_doorbell_init - Init doorbell driver information.
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Init doorbell driver information (CIK)
>> + * Returns 0 on success, error on failure.
>> + */
>> +int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>> +{
>> +
>> +	/* No doorbell on SI hardware generation */
>> +	if (adev->asic_type < CHIP_BONAIRE) {
>> +		adev->doorbell.base = 0;
>> +		adev->doorbell.size = 0;
>> +		adev->doorbell.num_kernel_doorbells = 0;
>> +		adev->doorbell.ptr = NULL;
>> +		return 0;
>> +	}
>> +
>> +	if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
>> +		return -EINVAL;
>> +
>> +	amdgpu_asic_init_doorbell_index(adev);
>> +
>> +	/* doorbell bar mapping */
>> +	adev->doorbell.base = pci_resource_start(adev->pdev, 2);
>> +	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>> +
>> +	if (adev->enable_mes) {
>> +		adev->doorbell.num_kernel_doorbells =
>> +			adev->doorbell.size / sizeof(u32);
>> +	} else {
>> +		adev->doorbell.num_kernel_doorbells =
>> +			min_t(u32, adev->doorbell.size / sizeof(u32),
>> +			      adev->doorbell_index.max_assignment+1);
>> +		if (adev->doorbell.num_kernel_doorbells == 0)
>> +			return -EINVAL;
>> +
>> +		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
>> +		 * paging queue doorbell use the second page. The
>> +		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>> +		 * doorbells are in the first page. So with paging queue enabled,
>> +		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>> +		 */
>> +		if (adev->asic_type >= CHIP_VEGA10)
>> +			adev->doorbell.num_kernel_doorbells += 0x400;
>> +	}
>> +
>> +	adev->doorbell.ptr = ioremap(adev->doorbell.base,
>> +				     adev->doorbell.num_kernel_doorbells *
>> +				     sizeof(u32));
>> +	if (adev->doorbell.ptr == NULL)
>> +		return -ENOMEM;
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Tear down doorbell driver information (CIK)
>> + */
>> +void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>> +{
>> +	iounmap(adev->doorbell.ptr);
>> +	adev->doorbell.ptr = NULL;
>> +}
> 


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

* Re: [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
  2023-03-30 11:14   ` Christian König
@ 2023-03-30 13:33     ` Luben Tuikov
  2023-03-30 13:43       ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 13:33 UTC (permalink / raw)
  To: Christian König, Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling

On 2023-03-30 07:14, Christian König wrote:
> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>> From: Alex Deucher <alexander.deucher@amd.com>
>>
>> This patch adds changes:
>> - to accommodate the new GEM domain DOORBELL
>> - to accommodate the new TTM PL DOORBELL
>>
>> in order to manage doorbell pages as GEM object.
>>
>> V2: Addressed reviwe comments from Christian
>>      - drop the doorbell changes for pinning/unpinning
>>      - drop the doorbell changes for dma-buf map
>>      - drop the doorbell changes for sgt
>>      - no need to handle TTM_PL_FLAG_CONTIGUOUS for doorbell
>>      - add caching type for doorbell
>>
>> Cc: Alex Deucher <alexander.deucher@amd.com>
>> Cc: Christian Koenig <christian.koenig@amd.com>
>>
>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>

Generally there are no empty lines in the tag list. Perhaps remove it?

Regards,
Luben

>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_object.c     | 11 ++++++++++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h |  2 ++
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c        | 16 +++++++++++++++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h        |  1 +
>>   4 files changed, 28 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> index 4e684c2afc70..0ec080e240ad 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>> @@ -147,6 +147,14 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
>>   		c++;
>>   	}
>>   
>> +	if (domain & AMDGPU_GEM_DOMAIN_DOORBELL) {
>> +		places[c].fpfn = 0;
>> +		places[c].lpfn = 0;
>> +		places[c].mem_type = AMDGPU_PL_DOORBELL;
>> +		places[c].flags = 0;
>> +		c++;
>> +	}
>> +
>>   	if (domain & AMDGPU_GEM_DOMAIN_GTT) {
>>   		places[c].fpfn = 0;
>>   		places[c].lpfn = 0;
>> @@ -466,7 +474,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
>>   		goto fail;
>>   	}
>>   
>> -	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
>> +	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU,  AMDGPU_GEM_DOMAIN_DOORBELL */
>>   	return true;
>>   
>>   fail:
>> @@ -1013,6 +1021,7 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo)
>>   	} else if (bo->tbo.resource->mem_type == TTM_PL_TT) {
>>   		atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size);
>>   	}
>> +
> 
> Unrelated newline, probably just a leftover.
> 
> Apart from that the patch is Reviewed-by: Christian König 
> <christian.koenig@amd.com>
> 
> Regards,
> Christian.
> 
>>   }
>>   
>>   static const char *amdgpu_vram_names[] = {
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>> index 5c4f93ee0c57..3c988cc406e4 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>> @@ -90,6 +90,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
>>   		cur->node = block;
>>   		break;
>>   	case TTM_PL_TT:
>> +	case AMDGPU_PL_DOORBELL:
>>   		node = to_ttm_range_mgr_node(res)->mm_nodes;
>>   		while (start >= node->size << PAGE_SHIFT)
>>   			start -= node++->size << PAGE_SHIFT;
>> @@ -152,6 +153,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
>>   		cur->size = min(amdgpu_vram_mgr_block_size(block), cur->remaining);
>>   		break;
>>   	case TTM_PL_TT:
>> +	case AMDGPU_PL_DOORBELL:
>>   		node = cur->node;
>>   
>>   		cur->node = ++node;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 55e0284b2bdd..6f61491ef3dd 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -128,6 +128,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
>>   	case AMDGPU_PL_GDS:
>>   	case AMDGPU_PL_GWS:
>>   	case AMDGPU_PL_OA:
>> +	case AMDGPU_PL_DOORBELL:
>>   		placement->num_placement = 0;
>>   		placement->num_busy_placement = 0;
>>   		return;
>> @@ -500,9 +501,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
>>   	if (old_mem->mem_type == AMDGPU_PL_GDS ||
>>   	    old_mem->mem_type == AMDGPU_PL_GWS ||
>>   	    old_mem->mem_type == AMDGPU_PL_OA ||
>> +	    old_mem->mem_type == AMDGPU_PL_DOORBELL ||
>>   	    new_mem->mem_type == AMDGPU_PL_GDS ||
>>   	    new_mem->mem_type == AMDGPU_PL_GWS ||
>> -	    new_mem->mem_type == AMDGPU_PL_OA) {
>> +	    new_mem->mem_type == AMDGPU_PL_OA ||
>> +	    new_mem->mem_type == AMDGPU_PL_DOORBELL) {
>>   		/* Nothing to save here */
>>   		ttm_bo_move_null(bo, new_mem);
>>   		goto out;
>> @@ -586,6 +589,12 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
>>   		mem->bus.offset += adev->gmc.aper_base;
>>   		mem->bus.is_iomem = true;
>>   		break;
>> +	case AMDGPU_PL_DOORBELL:
>> +		mem->bus.offset = mem->start << PAGE_SHIFT;
>> +		mem->bus.offset += adev->doorbell.base;
>> +		mem->bus.is_iomem = true;
>> +		mem->bus.caching = ttm_uncached;
>> +		break;
>>   	default:
>>   		return -EINVAL;
>>   	}
>> @@ -600,6 +609,10 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
>>   
>>   	amdgpu_res_first(bo->resource, (u64)page_offset << PAGE_SHIFT, 0,
>>   			 &cursor);
>> +
>> +	if (bo->resource->mem_type == AMDGPU_PL_DOORBELL)
>> +		return ((uint64_t)(adev->doorbell.base + cursor.start)) >> PAGE_SHIFT;
>> +
>>   	return (adev->gmc.aper_base + cursor.start) >> PAGE_SHIFT;
>>   }
>>   
>> @@ -1267,6 +1280,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem)
>>   		flags |= AMDGPU_PTE_VALID;
>>   
>>   	if (mem && (mem->mem_type == TTM_PL_TT ||
>> +		    mem->mem_type == AMDGPU_PL_DOORBELL ||
>>   		    mem->mem_type == AMDGPU_PL_PREEMPT)) {
>>   		flags |= AMDGPU_PTE_SYSTEM;
>>   
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> index e2cd5894afc9..761cd6b2b942 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>> @@ -33,6 +33,7 @@
>>   #define AMDGPU_PL_GWS		(TTM_PL_PRIV + 1)
>>   #define AMDGPU_PL_OA		(TTM_PL_PRIV + 2)
>>   #define AMDGPU_PL_PREEMPT	(TTM_PL_PRIV + 3)
>> +#define AMDGPU_PL_DOORBELL	(TTM_PL_PRIV + 4)
>>   
>>   #define AMDGPU_GTT_MAX_TRANSFER_SIZE	512
>>   #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS	2
> 


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

* Re: [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager
  2023-03-30 13:29     ` Luben Tuikov
@ 2023-03-30 13:42       ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 13:42 UTC (permalink / raw)
  To: Luben Tuikov, Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma


On 30/03/2023 15:29, Luben Tuikov wrote:
> Hi Shashank,
>
> Inline:
>
> On 2023-03-30 07:09, Christian König wrote:
>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>
>>> This patch:
>>> - creates a new file for doorbell management.
>>> - moves doorbell code from amdgpu_device.c to this file.
>>>
>>> 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/Makefile           |   2 +-
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 164 ---------------
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h  |  22 +++
>>>    .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 186 ++++++++++++++++++
>>>    4 files changed, 209 insertions(+), 165 deletions(-)
>>>    create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
>>> index 798d0e9a60b7..204665f20319 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
>>> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
>>> @@ -41,7 +41,7 @@ ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
>>>    amdgpu-y := amdgpu_drv.o
>>>    
>>>    # add KMS driver
>>> -amdgpu-y += amdgpu_device.o amdgpu_kms.o \
>>> +amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
>>>    	amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
>>>    	atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
>>>    	amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>> index 57ee1c4a81e9..7f8fcac4f18b 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>>> @@ -579,94 +579,6 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
>>>    	}
>>>    }
>>>    
>>> -/**
>>> - * amdgpu_mm_rdoorbell - read a doorbell dword
>>> - *
>>> - * @adev: amdgpu_device pointer
>>> - * @index: doorbell index
>>> - *
>>> - * Returns the value in the doorbell aperture at the
>>> - * requested doorbell index (CIK).
>>> - */
>>> -u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>>> -{
>>> -	if (amdgpu_device_skip_hw_access(adev))
>>> -		return 0;
>>> -
>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>> -		return readl(adev->doorbell.ptr + index);
>>> -	} else {
>>> -		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>>> -		return 0;
>>> -	}
>>> -}
>>> -
>>> -/**
>>> - * amdgpu_mm_wdoorbell - write a doorbell dword
>>> - *
>>> - * @adev: amdgpu_device pointer
>>> - * @index: doorbell index
>>> - * @v: value to write
>>> - *
>>> - * Writes @v to the doorbell aperture at the
>>> - * requested doorbell index (CIK).
>>> - */
>>> -void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>>> -{
>>> -	if (amdgpu_device_skip_hw_access(adev))
>>> -		return;
>>> -
>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>> -		writel(v, adev->doorbell.ptr + index);
>>> -	} else {
>>> -		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>>> -	}
>>> -}
>>> -
>>> -/**
>>> - * amdgpu_mm_rdoorbell64 - read a doorbell Qword
>>> - *
>>> - * @adev: amdgpu_device pointer
>>> - * @index: doorbell index
>>> - *
>>> - * Returns the value in the doorbell aperture at the
>>> - * requested doorbell index (VEGA10+).
>>> - */
>>> -u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>>> -{
>>> -	if (amdgpu_device_skip_hw_access(adev))
>>> -		return 0;
>>> -
>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>> -		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>>> -	} else {
>>> -		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>>> -		return 0;
>>> -	}
>>> -}
>>> -
>>> -/**
>>> - * amdgpu_mm_wdoorbell64 - write a doorbell Qword
>>> - *
>>> - * @adev: amdgpu_device pointer
>>> - * @index: doorbell index
>>> - * @v: value to write
>>> - *
>>> - * Writes @v to the doorbell aperture at the
>>> - * requested doorbell index (VEGA10+).
>>> - */
>>> -void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>> -{
>>> -	if (amdgpu_device_skip_hw_access(adev))
>>> -		return;
>>> -
>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>> -		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>>> -	} else {
>>> -		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>>> -	}
>>> -}
>>> -
>>>    /**
>>>     * amdgpu_device_indirect_rreg - read an indirect register
>>>     *
>>> @@ -1016,82 +928,6 @@ int amdgpu_device_pci_reset(struct amdgpu_device *adev)
>>>    	return pci_reset_function(adev->pdev);
>>>    }
>>>    
>>> -/*
>>> - * GPU doorbell aperture helpers function.
>>> - */
>>> -/**
>>> - * amdgpu_device_doorbell_init - Init doorbell driver information.
>>> - *
>>> - * @adev: amdgpu_device pointer
>>> - *
>>> - * Init doorbell driver information (CIK)
>>> - * Returns 0 on success, error on failure.
>>> - */
>>> -static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>>> -{
>>> -
>>> -	/* No doorbell on SI hardware generation */
>>> -	if (adev->asic_type < CHIP_BONAIRE) {
>>> -		adev->doorbell.base = 0;
>>> -		adev->doorbell.size = 0;
>>> -		adev->doorbell.num_kernel_doorbells = 0;
>>> -		adev->doorbell.ptr = NULL;
>>> -		return 0;
>>> -	}
>>> -
>>> -	if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
>>> -		return -EINVAL;
>>> -
>>> -	amdgpu_asic_init_doorbell_index(adev);
>>> -
>>> -	/* doorbell bar mapping */
>>> -	adev->doorbell.base = pci_resource_start(adev->pdev, 2);
>>> -	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>>> -
>>> -	if (adev->enable_mes) {
>>> -		adev->doorbell.num_kernel_doorbells =
>>> -			adev->doorbell.size / sizeof(u32);
>>> -	} else {
>>> -		adev->doorbell.num_kernel_doorbells =
>>> -			min_t(u32, adev->doorbell.size / sizeof(u32),
>>> -			      adev->doorbell_index.max_assignment+1);
>>> -		if (adev->doorbell.num_kernel_doorbells == 0)
>>> -			return -EINVAL;
>>> -
>>> -		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
>>> -		 * paging queue doorbell use the second page. The
>>> -		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>>> -		 * doorbells are in the first page. So with paging queue enabled,
>>> -		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>>> -		 */
>>> -		if (adev->asic_type >= CHIP_VEGA10)
>>> -			adev->doorbell.num_kernel_doorbells += 0x400;
>>> -	}
>>> -
>>> -	adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>> -				     adev->doorbell.num_kernel_doorbells *
>>> -				     sizeof(u32));
>>> -	if (adev->doorbell.ptr == NULL)
>>> -		return -ENOMEM;
>>> -
>>> -	return 0;
>>> -}
>>> -
>>> -/**
>>> - * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
>>> - *
>>> - * @adev: amdgpu_device pointer
>>> - *
>>> - * Tear down doorbell driver information (CIK)
>>> - */
>>> -static void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>> -{
>>> -	iounmap(adev->doorbell.ptr);
>>> -	adev->doorbell.ptr = NULL;
>>> -}
>>> -
>>> -
>>> -
>>>    /*
>>>     * amdgpu_device_wb_*()
>>>     * Writeback is the method by which the GPU updates special pages in memory
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>> index 6064943a1b53..f9c3b77bf65d 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>> @@ -306,6 +306,28 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
>>>    u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index);
>>>    void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
>>>    
>>> +/*
>>> + * GPU doorbell aperture helpers function.
>>> + */
>>> +/**
>>> + * amdgpu_device_doorbell_init - Init doorbell driver information.
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + *
>>> + * Init doorbell driver information (CIK)
>>> + * Returns 0 on success, error on failure.
>>> + */
>>> +int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>>> +
>>> +/**
>>> + * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + *
>>> + * Tear down doorbell driver information (CIK)
>>> + */
>>> +void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>> I might be wrong, but having kerneldoc on both the declaration and the
>> implementation is forbidden I think.
>>
>> We usually have it on the implementation side only.
> Yes, that is correct--implementation side only as that's where
> the actual code can be found.

Noted, I will remove the extra doc.

- Shashank

>> Christian.
>>
>>> +
>>>    #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>    #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>>    #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> new file mode 100644
>>> index 000000000000..2206926ba289
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> @@ -0,0 +1,186 @@
>>> +/*
> Add an SPDX licence identifier as the very first line:
> //SPDX-License-Identifier: <value>
>
> with some appropriate value, maybe "GPL-2.0-or-later" (no quotes when added).
>
> Regards,
> Luben
>
>>> + * 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"
>>> +
>>> +/**
>>> + * amdgpu_mm_rdoorbell - read a doorbell dword
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + * @index: doorbell index
>>> + *
>>> + * Returns the value in the doorbell aperture at the
>>> + * requested doorbell index (CIK).
>>> + */
>>> +u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>>> +{
>>> +	if (amdgpu_device_skip_hw_access(adev))
>>> +		return 0;
>>> +
>>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>>> +		return readl(adev->doorbell.ptr + index);
>>> +	} else {
>>> +		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>>> +		return 0;
>>> +	}
>>> +}
>>> +
>>> +/**
>>> + * amdgpu_mm_wdoorbell - write a doorbell dword
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + * @index: doorbell index
>>> + * @v: value to write
>>> + *
>>> + * Writes @v to the doorbell aperture at the
>>> + * requested doorbell index (CIK).
>>> + */
>>> +void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>>> +{
>>> +	if (amdgpu_device_skip_hw_access(adev))
>>> +		return;
>>> +
>>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>>> +		writel(v, adev->doorbell.ptr + index);
>>> +	} else {
>>> +		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>>> +	}
>>> +}
>>> +
>>> +/**
>>> + * amdgpu_mm_rdoorbell64 - read a doorbell Qword
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + * @index: doorbell index
>>> + *
>>> + * Returns the value in the doorbell aperture at the
>>> + * requested doorbell index (VEGA10+).
>>> + */
>>> +u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>>> +{
>>> +	if (amdgpu_device_skip_hw_access(adev))
>>> +		return 0;
>>> +
>>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>>> +		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>>> +	} else {
>>> +		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>>> +		return 0;
>>> +	}
>>> +}
>>> +
>>> +/**
>>> + * amdgpu_mm_wdoorbell64 - write a doorbell Qword
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + * @index: doorbell index
>>> + * @v: value to write
>>> + *
>>> + * Writes @v to the doorbell aperture at the
>>> + * requested doorbell index (VEGA10+).
>>> + */
>>> +void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>> +{
>>> +	if (amdgpu_device_skip_hw_access(adev))
>>> +		return;
>>> +
>>> +	if (index < adev->doorbell.num_kernel_doorbells) {
>>> +		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>>> +	} else {
>>> +		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>>> +	}
>>> +}
>>> +
>>> +/*
>>> + * GPU doorbell aperture helpers function.
>>> + */
>>> +/**
>>> + * amdgpu_device_doorbell_init - Init doorbell driver information.
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + *
>>> + * Init doorbell driver information (CIK)
>>> + * Returns 0 on success, error on failure.
>>> + */
>>> +int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>>> +{
>>> +
>>> +	/* No doorbell on SI hardware generation */
>>> +	if (adev->asic_type < CHIP_BONAIRE) {
>>> +		adev->doorbell.base = 0;
>>> +		adev->doorbell.size = 0;
>>> +		adev->doorbell.num_kernel_doorbells = 0;
>>> +		adev->doorbell.ptr = NULL;
>>> +		return 0;
>>> +	}
>>> +
>>> +	if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
>>> +		return -EINVAL;
>>> +
>>> +	amdgpu_asic_init_doorbell_index(adev);
>>> +
>>> +	/* doorbell bar mapping */
>>> +	adev->doorbell.base = pci_resource_start(adev->pdev, 2);
>>> +	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>>> +
>>> +	if (adev->enable_mes) {
>>> +		adev->doorbell.num_kernel_doorbells =
>>> +			adev->doorbell.size / sizeof(u32);
>>> +	} else {
>>> +		adev->doorbell.num_kernel_doorbells =
>>> +			min_t(u32, adev->doorbell.size / sizeof(u32),
>>> +			      adev->doorbell_index.max_assignment+1);
>>> +		if (adev->doorbell.num_kernel_doorbells == 0)
>>> +			return -EINVAL;
>>> +
>>> +		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
>>> +		 * paging queue doorbell use the second page. The
>>> +		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>>> +		 * doorbells are in the first page. So with paging queue enabled,
>>> +		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>>> +		 */
>>> +		if (adev->asic_type >= CHIP_VEGA10)
>>> +			adev->doorbell.num_kernel_doorbells += 0x400;
>>> +	}
>>> +
>>> +	adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>> +				     adev->doorbell.num_kernel_doorbells *
>>> +				     sizeof(u32));
>>> +	if (adev->doorbell.ptr == NULL)
>>> +		return -ENOMEM;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +/**
>>> + * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + *
>>> + * Tear down doorbell driver information (CIK)
>>> + */
>>> +void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>> +{
>>> +	iounmap(adev->doorbell.ptr);
>>> +	adev->doorbell.ptr = NULL;
>>> +}

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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-29 15:47 ` [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages Shashank Sharma
  2023-03-30 11:29   ` Christian König
@ 2023-03-30 13:42   ` Luben Tuikov
  2023-03-30 13:44     ` Luben Tuikov
  2023-03-30 14:04     ` Shashank Sharma
  2023-03-30 14:28   ` Alex Deucher
  2 siblings, 2 replies; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 13:42 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

On 2023-03-29 11:47, Shashank Sharma wrote:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
> 
> This patch adds helper functions to create and free doorbell
> pages for kernel objects.
> 
> 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_doorbell.h  | 41 ++++++++++++++++
>  .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>  2 files changed, 90 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index f9c3b77bf65d..6581b78fe438 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -27,6 +27,24 @@
>  /*
>   * GPU doorbell structures, functions & helpers
>   */
> +
> +/* Structure to hold doorbell pages from PCI doorbell BAR */
> +struct amdgpu_doorbell_obj {

In the comment you say "Structure to hold ...";
it is a C structure, but then in the name of a function we see "obj".
(Object is something which is defined like in memory, i.e. it exists, not
something which is only declared.)
This is just a declaration of a structure, not an object per se.
I'd call it "struct amdgpu_doorbell_struct" or just "struct amdgpu_doorbell".

Then in the definition, you can call it an object/objects, if you'd like,
like "struct amdgpu_doorbell *doorb_object[];" then you can say
"db = doorb_object[i]";

Regards,
Luben

> +	struct amdgpu_bo *bo;
> +	uint64_t gpu_addr;
> +	uint32_t *cpu_addr;
> +	uint32_t size;
> +
> +	/* First index in this object */
> +	uint32_t start;
> +
> +	/* Last index in this object */
> +	uint32_t end;
> +
> +	/* bitmap for dynamic doorbell allocation from this object */
> +	unsigned long *doorbell_bitmap;
> +};
> +
>  struct amdgpu_doorbell {
>  	/* doorbell mmio */
>  	resource_size_t		base;
> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>   */
>  void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>  
> +/**
> + * amdgpu_doorbell_free_page - Free a doorbell page
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: previously allocated doobell page details
> + *
> + */
> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
> +				struct amdgpu_doorbell_obj *db_obj);
> +
> +/**
> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: doobell page structure to fill details with
> + *
> + * returns 0 on success, else error number
> + */
> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> +				struct amdgpu_doorbell_obj *db_obj);
> +
>  #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>  #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>  #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> index 1aea92363fd3..8be15b82b545 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>  	}
>  }
>  
> +/**
> + * amdgpu_doorbell_free_page - Free a doorbell page
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: previously allocated doobell page details
> + *
> + */
> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
> +					struct amdgpu_doorbell_obj *db_obj)
> +{
> +	amdgpu_bo_free_kernel(&db_obj->bo,
> +			      &db_obj->gpu_addr,
> +			      (void **)&db_obj->cpu_addr);
> +
> +}
> +
> +/**
> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: doobell page structure to fill details with
> + *
> + * returns 0 on success, else error number
> + */
> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> +				struct amdgpu_doorbell_obj *db_obj)
> +{
> +	int r;
> +
> +	db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
> +
> +	r = amdgpu_bo_create_kernel(adev,
> +				    db_obj->size,
> +				    PAGE_SIZE,
> +				    AMDGPU_GEM_DOMAIN_DOORBELL,
> +				    &db_obj->bo,
> +				    &db_obj->gpu_addr,
> +				    (void **)&db_obj->cpu_addr);
> +
> +	if (r) {
> +		DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
> +		return r;
> +	}
> +
> +	return 0;
> +}
> +
>  /*
>   * GPU doorbell aperture helpers function.
>   */


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

* Re: [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
  2023-03-30 13:33     ` Luben Tuikov
@ 2023-03-30 13:43       ` Shashank Sharma
  2023-03-30 13:45         ` Luben Tuikov
  0 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 13:43 UTC (permalink / raw)
  To: Luben Tuikov, Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling


On 30/03/2023 15:33, Luben Tuikov wrote:
> On 2023-03-30 07:14, Christian König wrote:
>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>>> From: Alex Deucher <alexander.deucher@amd.com>
>>>
>>> This patch adds changes:
>>> - to accommodate the new GEM domain DOORBELL
>>> - to accommodate the new TTM PL DOORBELL
>>>
>>> in order to manage doorbell pages as GEM object.
>>>
>>> V2: Addressed reviwe comments from Christian
>>>       - drop the doorbell changes for pinning/unpinning
>>>       - drop the doorbell changes for dma-buf map
>>>       - drop the doorbell changes for sgt
>>>       - no need to handle TTM_PL_FLAG_CONTIGUOUS for doorbell
>>>       - add caching type for doorbell
>>>
>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>> Cc: Christian Koenig <christian.koenig@amd.com>
>>>
>>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> Generally there are no empty lines in the tag list. Perhaps remove it?

I would prefer to keep it, to highlight the CC parts.

- Shashank

> Regards,
> Luben
>
>>> ---
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_object.c     | 11 ++++++++++-
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h |  2 ++
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c        | 16 +++++++++++++++-
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h        |  1 +
>>>    4 files changed, 28 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>> index 4e684c2afc70..0ec080e240ad 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>> @@ -147,6 +147,14 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
>>>    		c++;
>>>    	}
>>>    
>>> +	if (domain & AMDGPU_GEM_DOMAIN_DOORBELL) {
>>> +		places[c].fpfn = 0;
>>> +		places[c].lpfn = 0;
>>> +		places[c].mem_type = AMDGPU_PL_DOORBELL;
>>> +		places[c].flags = 0;
>>> +		c++;
>>> +	}
>>> +
>>>    	if (domain & AMDGPU_GEM_DOMAIN_GTT) {
>>>    		places[c].fpfn = 0;
>>>    		places[c].lpfn = 0;
>>> @@ -466,7 +474,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
>>>    		goto fail;
>>>    	}
>>>    
>>> -	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
>>> +	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU,  AMDGPU_GEM_DOMAIN_DOORBELL */
>>>    	return true;
>>>    
>>>    fail:
>>> @@ -1013,6 +1021,7 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo)
>>>    	} else if (bo->tbo.resource->mem_type == TTM_PL_TT) {
>>>    		atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size);
>>>    	}
>>> +
>> Unrelated newline, probably just a leftover.
>>
>> Apart from that the patch is Reviewed-by: Christian König
>> <christian.koenig@amd.com>
>>
>> Regards,
>> Christian.
>>
>>>    }
>>>    
>>>    static const char *amdgpu_vram_names[] = {
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>> index 5c4f93ee0c57..3c988cc406e4 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>> @@ -90,6 +90,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
>>>    		cur->node = block;
>>>    		break;
>>>    	case TTM_PL_TT:
>>> +	case AMDGPU_PL_DOORBELL:
>>>    		node = to_ttm_range_mgr_node(res)->mm_nodes;
>>>    		while (start >= node->size << PAGE_SHIFT)
>>>    			start -= node++->size << PAGE_SHIFT;
>>> @@ -152,6 +153,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
>>>    		cur->size = min(amdgpu_vram_mgr_block_size(block), cur->remaining);
>>>    		break;
>>>    	case TTM_PL_TT:
>>> +	case AMDGPU_PL_DOORBELL:
>>>    		node = cur->node;
>>>    
>>>    		cur->node = ++node;
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> index 55e0284b2bdd..6f61491ef3dd 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> @@ -128,6 +128,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
>>>    	case AMDGPU_PL_GDS:
>>>    	case AMDGPU_PL_GWS:
>>>    	case AMDGPU_PL_OA:
>>> +	case AMDGPU_PL_DOORBELL:
>>>    		placement->num_placement = 0;
>>>    		placement->num_busy_placement = 0;
>>>    		return;
>>> @@ -500,9 +501,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
>>>    	if (old_mem->mem_type == AMDGPU_PL_GDS ||
>>>    	    old_mem->mem_type == AMDGPU_PL_GWS ||
>>>    	    old_mem->mem_type == AMDGPU_PL_OA ||
>>> +	    old_mem->mem_type == AMDGPU_PL_DOORBELL ||
>>>    	    new_mem->mem_type == AMDGPU_PL_GDS ||
>>>    	    new_mem->mem_type == AMDGPU_PL_GWS ||
>>> -	    new_mem->mem_type == AMDGPU_PL_OA) {
>>> +	    new_mem->mem_type == AMDGPU_PL_OA ||
>>> +	    new_mem->mem_type == AMDGPU_PL_DOORBELL) {
>>>    		/* Nothing to save here */
>>>    		ttm_bo_move_null(bo, new_mem);
>>>    		goto out;
>>> @@ -586,6 +589,12 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
>>>    		mem->bus.offset += adev->gmc.aper_base;
>>>    		mem->bus.is_iomem = true;
>>>    		break;
>>> +	case AMDGPU_PL_DOORBELL:
>>> +		mem->bus.offset = mem->start << PAGE_SHIFT;
>>> +		mem->bus.offset += adev->doorbell.base;
>>> +		mem->bus.is_iomem = true;
>>> +		mem->bus.caching = ttm_uncached;
>>> +		break;
>>>    	default:
>>>    		return -EINVAL;
>>>    	}
>>> @@ -600,6 +609,10 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
>>>    
>>>    	amdgpu_res_first(bo->resource, (u64)page_offset << PAGE_SHIFT, 0,
>>>    			 &cursor);
>>> +
>>> +	if (bo->resource->mem_type == AMDGPU_PL_DOORBELL)
>>> +		return ((uint64_t)(adev->doorbell.base + cursor.start)) >> PAGE_SHIFT;
>>> +
>>>    	return (adev->gmc.aper_base + cursor.start) >> PAGE_SHIFT;
>>>    }
>>>    
>>> @@ -1267,6 +1280,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem)
>>>    		flags |= AMDGPU_PTE_VALID;
>>>    
>>>    	if (mem && (mem->mem_type == TTM_PL_TT ||
>>> +		    mem->mem_type == AMDGPU_PL_DOORBELL ||
>>>    		    mem->mem_type == AMDGPU_PL_PREEMPT)) {
>>>    		flags |= AMDGPU_PTE_SYSTEM;
>>>    
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>> index e2cd5894afc9..761cd6b2b942 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>> @@ -33,6 +33,7 @@
>>>    #define AMDGPU_PL_GWS		(TTM_PL_PRIV + 1)
>>>    #define AMDGPU_PL_OA		(TTM_PL_PRIV + 2)
>>>    #define AMDGPU_PL_PREEMPT	(TTM_PL_PRIV + 3)
>>> +#define AMDGPU_PL_DOORBELL	(TTM_PL_PRIV + 4)
>>>    
>>>    #define AMDGPU_GTT_MAX_TRANSFER_SIZE	512
>>>    #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS	2

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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 13:42   ` Luben Tuikov
@ 2023-03-30 13:44     ` Luben Tuikov
  2023-03-30 14:04     ` Shashank Sharma
  1 sibling, 0 replies; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 13:44 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

On 2023-03-30 09:42, Luben Tuikov wrote:
> On 2023-03-29 11:47, Shashank Sharma wrote:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch adds helper functions to create and free doorbell
>> pages for kernel objects.
>>
>> 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_doorbell.h  | 41 ++++++++++++++++
>>  .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>>  2 files changed, 90 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index f9c3b77bf65d..6581b78fe438 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -27,6 +27,24 @@
>>  /*
>>   * GPU doorbell structures, functions & helpers
>>   */
>> +
>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>> +struct amdgpu_doorbell_obj {
> 
> In the comment you say "Structure to hold ...";
> it is a C structure, but then in the name of a function we see "obj".

I mean here " in the name of the structure we see ..."

Regards,
Luben

> (Object is something which is defined like in memory, i.e. it exists, not
> something which is only declared.)
> This is just a declaration of a structure, not an object per se.
> I'd call it "struct amdgpu_doorbell_struct" or just "struct amdgpu_doorbell".
> 
> Then in the definition, you can call it an object/objects, if you'd like,
> like "struct amdgpu_doorbell *doorb_object[];" then you can say
> "db = doorb_object[i]";
> 
> Regards,
> Luben
> 
>> +	struct amdgpu_bo *bo;
>> +	uint64_t gpu_addr;
>> +	uint32_t *cpu_addr;
>> +	uint32_t size;
>> +
>> +	/* First index in this object */
>> +	uint32_t start;
>> +
>> +	/* Last index in this object */
>> +	uint32_t end;
>> +
>> +	/* bitmap for dynamic doorbell allocation from this object */
>> +	unsigned long *doorbell_bitmap;
>> +};
>> +
>>  struct amdgpu_doorbell {
>>  	/* doorbell mmio */
>>  	resource_size_t		base;
>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>>   */
>>  void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>>  
>> +/**
>> + * amdgpu_doorbell_free_page - Free a doorbell page
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: previously allocated doobell page details
>> + *
>> + */
>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>> +				struct amdgpu_doorbell_obj *db_obj);
>> +
>> +/**
>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: doobell page structure to fill details with
>> + *
>> + * returns 0 on success, else error number
>> + */
>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>> +				struct amdgpu_doorbell_obj *db_obj);
>> +
>>  #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>  #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>  #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> index 1aea92363fd3..8be15b82b545 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>  	}
>>  }
>>  
>> +/**
>> + * amdgpu_doorbell_free_page - Free a doorbell page
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: previously allocated doobell page details
>> + *
>> + */
>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>> +					struct amdgpu_doorbell_obj *db_obj)
>> +{
>> +	amdgpu_bo_free_kernel(&db_obj->bo,
>> +			      &db_obj->gpu_addr,
>> +			      (void **)&db_obj->cpu_addr);
>> +
>> +}
>> +
>> +/**
>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: doobell page structure to fill details with
>> + *
>> + * returns 0 on success, else error number
>> + */
>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>> +				struct amdgpu_doorbell_obj *db_obj)
>> +{
>> +	int r;
>> +
>> +	db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
>> +
>> +	r = amdgpu_bo_create_kernel(adev,
>> +				    db_obj->size,
>> +				    PAGE_SIZE,
>> +				    AMDGPU_GEM_DOMAIN_DOORBELL,
>> +				    &db_obj->bo,
>> +				    &db_obj->gpu_addr,
>> +				    (void **)&db_obj->cpu_addr);
>> +
>> +	if (r) {
>> +		DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
>> +		return r;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  /*
>>   * GPU doorbell aperture helpers function.
>>   */
> 


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

* Re: [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
  2023-03-30 13:43       ` Shashank Sharma
@ 2023-03-30 13:45         ` Luben Tuikov
  2023-03-30 13:48           ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 13:45 UTC (permalink / raw)
  To: Shashank Sharma, Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling

On 2023-03-30 09:43, Shashank Sharma wrote:
> 
> On 30/03/2023 15:33, Luben Tuikov wrote:
>> On 2023-03-30 07:14, Christian König wrote:
>>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>>>> From: Alex Deucher <alexander.deucher@amd.com>
>>>>
>>>> This patch adds changes:
>>>> - to accommodate the new GEM domain DOORBELL
>>>> - to accommodate the new TTM PL DOORBELL
>>>>
>>>> in order to manage doorbell pages as GEM object.
>>>>
>>>> V2: Addressed reviwe comments from Christian
>>>>       - drop the doorbell changes for pinning/unpinning
>>>>       - drop the doorbell changes for dma-buf map
>>>>       - drop the doorbell changes for sgt
>>>>       - no need to handle TTM_PL_FLAG_CONTIGUOUS for doorbell
>>>>       - add caching type for doorbell
>>>>
>>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>>> Cc: Christian Koenig <christian.koenig@amd.com>
>>>>
>>>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>>>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>> Generally there are no empty lines in the tag list. Perhaps remove it?
> 
> I would prefer to keep it, to highlight the CC parts.

I've never seen a commit with them separated. Perhaps follow Linux custom?

Regards,
Luben

> 
> - Shashank
> 
>> Regards,
>> Luben
>>
>>>> ---
>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_object.c     | 11 ++++++++++-
>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h |  2 ++
>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c        | 16 +++++++++++++++-
>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h        |  1 +
>>>>    4 files changed, 28 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>> index 4e684c2afc70..0ec080e240ad 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>> @@ -147,6 +147,14 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
>>>>    		c++;
>>>>    	}
>>>>    
>>>> +	if (domain & AMDGPU_GEM_DOMAIN_DOORBELL) {
>>>> +		places[c].fpfn = 0;
>>>> +		places[c].lpfn = 0;
>>>> +		places[c].mem_type = AMDGPU_PL_DOORBELL;
>>>> +		places[c].flags = 0;
>>>> +		c++;
>>>> +	}
>>>> +
>>>>    	if (domain & AMDGPU_GEM_DOMAIN_GTT) {
>>>>    		places[c].fpfn = 0;
>>>>    		places[c].lpfn = 0;
>>>> @@ -466,7 +474,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
>>>>    		goto fail;
>>>>    	}
>>>>    
>>>> -	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
>>>> +	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU,  AMDGPU_GEM_DOMAIN_DOORBELL */
>>>>    	return true;
>>>>    
>>>>    fail:
>>>> @@ -1013,6 +1021,7 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo)
>>>>    	} else if (bo->tbo.resource->mem_type == TTM_PL_TT) {
>>>>    		atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size);
>>>>    	}
>>>> +
>>> Unrelated newline, probably just a leftover.
>>>
>>> Apart from that the patch is Reviewed-by: Christian König
>>> <christian.koenig@amd.com>
>>>
>>> Regards,
>>> Christian.
>>>
>>>>    }
>>>>    
>>>>    static const char *amdgpu_vram_names[] = {
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>> index 5c4f93ee0c57..3c988cc406e4 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>> @@ -90,6 +90,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
>>>>    		cur->node = block;
>>>>    		break;
>>>>    	case TTM_PL_TT:
>>>> +	case AMDGPU_PL_DOORBELL:
>>>>    		node = to_ttm_range_mgr_node(res)->mm_nodes;
>>>>    		while (start >= node->size << PAGE_SHIFT)
>>>>    			start -= node++->size << PAGE_SHIFT;
>>>> @@ -152,6 +153,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
>>>>    		cur->size = min(amdgpu_vram_mgr_block_size(block), cur->remaining);
>>>>    		break;
>>>>    	case TTM_PL_TT:
>>>> +	case AMDGPU_PL_DOORBELL:
>>>>    		node = cur->node;
>>>>    
>>>>    		cur->node = ++node;
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> index 55e0284b2bdd..6f61491ef3dd 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> @@ -128,6 +128,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
>>>>    	case AMDGPU_PL_GDS:
>>>>    	case AMDGPU_PL_GWS:
>>>>    	case AMDGPU_PL_OA:
>>>> +	case AMDGPU_PL_DOORBELL:
>>>>    		placement->num_placement = 0;
>>>>    		placement->num_busy_placement = 0;
>>>>    		return;
>>>> @@ -500,9 +501,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
>>>>    	if (old_mem->mem_type == AMDGPU_PL_GDS ||
>>>>    	    old_mem->mem_type == AMDGPU_PL_GWS ||
>>>>    	    old_mem->mem_type == AMDGPU_PL_OA ||
>>>> +	    old_mem->mem_type == AMDGPU_PL_DOORBELL ||
>>>>    	    new_mem->mem_type == AMDGPU_PL_GDS ||
>>>>    	    new_mem->mem_type == AMDGPU_PL_GWS ||
>>>> -	    new_mem->mem_type == AMDGPU_PL_OA) {
>>>> +	    new_mem->mem_type == AMDGPU_PL_OA ||
>>>> +	    new_mem->mem_type == AMDGPU_PL_DOORBELL) {
>>>>    		/* Nothing to save here */
>>>>    		ttm_bo_move_null(bo, new_mem);
>>>>    		goto out;
>>>> @@ -586,6 +589,12 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
>>>>    		mem->bus.offset += adev->gmc.aper_base;
>>>>    		mem->bus.is_iomem = true;
>>>>    		break;
>>>> +	case AMDGPU_PL_DOORBELL:
>>>> +		mem->bus.offset = mem->start << PAGE_SHIFT;
>>>> +		mem->bus.offset += adev->doorbell.base;
>>>> +		mem->bus.is_iomem = true;
>>>> +		mem->bus.caching = ttm_uncached;
>>>> +		break;
>>>>    	default:
>>>>    		return -EINVAL;
>>>>    	}
>>>> @@ -600,6 +609,10 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
>>>>    
>>>>    	amdgpu_res_first(bo->resource, (u64)page_offset << PAGE_SHIFT, 0,
>>>>    			 &cursor);
>>>> +
>>>> +	if (bo->resource->mem_type == AMDGPU_PL_DOORBELL)
>>>> +		return ((uint64_t)(adev->doorbell.base + cursor.start)) >> PAGE_SHIFT;
>>>> +
>>>>    	return (adev->gmc.aper_base + cursor.start) >> PAGE_SHIFT;
>>>>    }
>>>>    
>>>> @@ -1267,6 +1280,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem)
>>>>    		flags |= AMDGPU_PTE_VALID;
>>>>    
>>>>    	if (mem && (mem->mem_type == TTM_PL_TT ||
>>>> +		    mem->mem_type == AMDGPU_PL_DOORBELL ||
>>>>    		    mem->mem_type == AMDGPU_PL_PREEMPT)) {
>>>>    		flags |= AMDGPU_PTE_SYSTEM;
>>>>    
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>> index e2cd5894afc9..761cd6b2b942 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>> @@ -33,6 +33,7 @@
>>>>    #define AMDGPU_PL_GWS		(TTM_PL_PRIV + 1)
>>>>    #define AMDGPU_PL_OA		(TTM_PL_PRIV + 2)
>>>>    #define AMDGPU_PL_PREEMPT	(TTM_PL_PRIV + 3)
>>>> +#define AMDGPU_PL_DOORBELL	(TTM_PL_PRIV + 4)
>>>>    
>>>>    #define AMDGPU_GTT_MAX_TRANSFER_SIZE	512
>>>>    #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS	2


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

* Re: [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
  2023-03-30 13:45         ` Luben Tuikov
@ 2023-03-30 13:48           ` Shashank Sharma
  2023-03-30 14:12             ` Luben Tuikov
  0 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 13:48 UTC (permalink / raw)
  To: Luben Tuikov, Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling


On 30/03/2023 15:45, Luben Tuikov wrote:
> On 2023-03-30 09:43, Shashank Sharma wrote:
>> On 30/03/2023 15:33, Luben Tuikov wrote:
>>> On 2023-03-30 07:14, Christian König wrote:
>>>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>>>>> From: Alex Deucher <alexander.deucher@amd.com>
>>>>>
>>>>> This patch adds changes:
>>>>> - to accommodate the new GEM domain DOORBELL
>>>>> - to accommodate the new TTM PL DOORBELL
>>>>>
>>>>> in order to manage doorbell pages as GEM object.
>>>>>
>>>>> V2: Addressed reviwe comments from Christian
>>>>>        - drop the doorbell changes for pinning/unpinning
>>>>>        - drop the doorbell changes for dma-buf map
>>>>>        - drop the doorbell changes for sgt
>>>>>        - no need to handle TTM_PL_FLAG_CONTIGUOUS for doorbell
>>>>>        - add caching type for doorbell
>>>>>
>>>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>>>> Cc: Christian Koenig <christian.koenig@amd.com>
>>>>>
>>>>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>>>>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>>> Generally there are no empty lines in the tag list. Perhaps remove it?
>> I would prefer to keep it, to highlight the CC parts.
> I've never seen a commit with them separated. Perhaps follow Linux custom?

IIRC This is not against Linux patch formatting/message body guidelines.

- Shashank

> Regards,
> Luben
>
>> - Shashank
>>
>>> Regards,
>>> Luben
>>>
>>>>> ---
>>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_object.c     | 11 ++++++++++-
>>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h |  2 ++
>>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c        | 16 +++++++++++++++-
>>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h        |  1 +
>>>>>     4 files changed, 28 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>>> index 4e684c2afc70..0ec080e240ad 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>>> @@ -147,6 +147,14 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
>>>>>     		c++;
>>>>>     	}
>>>>>     
>>>>> +	if (domain & AMDGPU_GEM_DOMAIN_DOORBELL) {
>>>>> +		places[c].fpfn = 0;
>>>>> +		places[c].lpfn = 0;
>>>>> +		places[c].mem_type = AMDGPU_PL_DOORBELL;
>>>>> +		places[c].flags = 0;
>>>>> +		c++;
>>>>> +	}
>>>>> +
>>>>>     	if (domain & AMDGPU_GEM_DOMAIN_GTT) {
>>>>>     		places[c].fpfn = 0;
>>>>>     		places[c].lpfn = 0;
>>>>> @@ -466,7 +474,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
>>>>>     		goto fail;
>>>>>     	}
>>>>>     
>>>>> -	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
>>>>> +	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU,  AMDGPU_GEM_DOMAIN_DOORBELL */
>>>>>     	return true;
>>>>>     
>>>>>     fail:
>>>>> @@ -1013,6 +1021,7 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo)
>>>>>     	} else if (bo->tbo.resource->mem_type == TTM_PL_TT) {
>>>>>     		atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size);
>>>>>     	}
>>>>> +
>>>> Unrelated newline, probably just a leftover.
>>>>
>>>> Apart from that the patch is Reviewed-by: Christian König
>>>> <christian.koenig@amd.com>
>>>>
>>>> Regards,
>>>> Christian.
>>>>
>>>>>     }
>>>>>     
>>>>>     static const char *amdgpu_vram_names[] = {
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>>> index 5c4f93ee0c57..3c988cc406e4 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>>> @@ -90,6 +90,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
>>>>>     		cur->node = block;
>>>>>     		break;
>>>>>     	case TTM_PL_TT:
>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>     		node = to_ttm_range_mgr_node(res)->mm_nodes;
>>>>>     		while (start >= node->size << PAGE_SHIFT)
>>>>>     			start -= node++->size << PAGE_SHIFT;
>>>>> @@ -152,6 +153,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
>>>>>     		cur->size = min(amdgpu_vram_mgr_block_size(block), cur->remaining);
>>>>>     		break;
>>>>>     	case TTM_PL_TT:
>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>     		node = cur->node;
>>>>>     
>>>>>     		cur->node = ++node;
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>> index 55e0284b2bdd..6f61491ef3dd 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>> @@ -128,6 +128,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
>>>>>     	case AMDGPU_PL_GDS:
>>>>>     	case AMDGPU_PL_GWS:
>>>>>     	case AMDGPU_PL_OA:
>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>     		placement->num_placement = 0;
>>>>>     		placement->num_busy_placement = 0;
>>>>>     		return;
>>>>> @@ -500,9 +501,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
>>>>>     	if (old_mem->mem_type == AMDGPU_PL_GDS ||
>>>>>     	    old_mem->mem_type == AMDGPU_PL_GWS ||
>>>>>     	    old_mem->mem_type == AMDGPU_PL_OA ||
>>>>> +	    old_mem->mem_type == AMDGPU_PL_DOORBELL ||
>>>>>     	    new_mem->mem_type == AMDGPU_PL_GDS ||
>>>>>     	    new_mem->mem_type == AMDGPU_PL_GWS ||
>>>>> -	    new_mem->mem_type == AMDGPU_PL_OA) {
>>>>> +	    new_mem->mem_type == AMDGPU_PL_OA ||
>>>>> +	    new_mem->mem_type == AMDGPU_PL_DOORBELL) {
>>>>>     		/* Nothing to save here */
>>>>>     		ttm_bo_move_null(bo, new_mem);
>>>>>     		goto out;
>>>>> @@ -586,6 +589,12 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
>>>>>     		mem->bus.offset += adev->gmc.aper_base;
>>>>>     		mem->bus.is_iomem = true;
>>>>>     		break;
>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>> +		mem->bus.offset = mem->start << PAGE_SHIFT;
>>>>> +		mem->bus.offset += adev->doorbell.base;
>>>>> +		mem->bus.is_iomem = true;
>>>>> +		mem->bus.caching = ttm_uncached;
>>>>> +		break;
>>>>>     	default:
>>>>>     		return -EINVAL;
>>>>>     	}
>>>>> @@ -600,6 +609,10 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
>>>>>     
>>>>>     	amdgpu_res_first(bo->resource, (u64)page_offset << PAGE_SHIFT, 0,
>>>>>     			 &cursor);
>>>>> +
>>>>> +	if (bo->resource->mem_type == AMDGPU_PL_DOORBELL)
>>>>> +		return ((uint64_t)(adev->doorbell.base + cursor.start)) >> PAGE_SHIFT;
>>>>> +
>>>>>     	return (adev->gmc.aper_base + cursor.start) >> PAGE_SHIFT;
>>>>>     }
>>>>>     
>>>>> @@ -1267,6 +1280,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem)
>>>>>     		flags |= AMDGPU_PTE_VALID;
>>>>>     
>>>>>     	if (mem && (mem->mem_type == TTM_PL_TT ||
>>>>> +		    mem->mem_type == AMDGPU_PL_DOORBELL ||
>>>>>     		    mem->mem_type == AMDGPU_PL_PREEMPT)) {
>>>>>     		flags |= AMDGPU_PTE_SYSTEM;
>>>>>     
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>>> index e2cd5894afc9..761cd6b2b942 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>>> @@ -33,6 +33,7 @@
>>>>>     #define AMDGPU_PL_GWS		(TTM_PL_PRIV + 1)
>>>>>     #define AMDGPU_PL_OA		(TTM_PL_PRIV + 2)
>>>>>     #define AMDGPU_PL_PREEMPT	(TTM_PL_PRIV + 3)
>>>>> +#define AMDGPU_PL_DOORBELL	(TTM_PL_PRIV + 4)
>>>>>     
>>>>>     #define AMDGPU_GTT_MAX_TRANSFER_SIZE	512
>>>>>     #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS	2

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

* Re: [PATCH 00/16] AMDGPU Doorbell manager
  2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
                   ` (15 preceding siblings ...)
  2023-03-29 15:47 ` [PATCH 16/16] drm/amdgpu: user doorbell mgr for MES process doorbells Shashank Sharma
@ 2023-03-30 13:49 ` Luben Tuikov
  2023-03-30 13:56   ` Sharma, Shashank
  16 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 13:49 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig

As I'm reviewing this, it is obvious that this patchset hasn't gone
though scripts/checkpatch.pl.

It's good practice to run one's patches through scripts/checkpatch.pl,
to see deviations on common Linux practices, and correct them.

Regards,
Luben

On 2023-03-29 11:47, Shashank Sharma wrote:
> The doorbells in AMDGPU drivers are currently managed by different
> users in a scattered way, across the driver. The existing clients are:
> - AMDGPU graphics driver for kernel level doorbell writes.
> - AMDGPU MES module for kernel level doorbell write (MES ring test).
> - AMDGPU MES modules for kernel level aggregated doorbell writes.
> - AMDGPU MES module for MES process doorbell writes.
> - AMDKFD module for KFD/KIQ kernel doorbell writes.
> - AMDKFD module for KFD process doorbell writes.
> - AMDGPU usermode queues for usermode doorbell writes (upcoming).
> 
> This patch series introduces Doorbell-manager to keep the doorbell handling
> at a central place. The fundamental changes are:
> 
> - Introduce and accommodate a new GEM domain for doorbells.
> - Prepare the AMDGPU ttm backend for handling doorbell allocation.
> - Introduce doorbell-manager functions to allocate, free and index
>   doorbells in one unique way.
> - Create doorbell BOs for kernel-level and process level doorbell
>   opertations, and place it in existing structures.
> - Modify the existing graphics, KFD and MES code to use the
>   doorbell-manager functions.
> - Remove the existing doorbell management code in KFD/MES.
> 
> PS: This series has been sanity tested with kfd_test_suit to ensure
>     it is not introducing any regressions due to kfd doorbell changes.
> 
> The idea is that:
> - a kernel client can call doorbell manager functions to allocate/free
>   doorbell pages.
> - a usermode app can directly allocate a page from the doorbell bar just
>   like a GEM object and use it for different usermode queues.
> 
> Alex Deucher (2):
>   drm/amdgpu: add UAPI for allocating doorbell memory
>   drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
> 
> Shashank Sharma (14):
>   drm/amdgpu: rename num_doorbells
>   drm/amdgpu: include protection for doobell.h
>   drm/amdgpu: create a new file for doorbell manager
>   drm/amdgpu: don't modify num_doorbells for mes
>   drm/amdgpu: add helper to create doorbell pages
>   drm/amdgpu: initialize ttm for doorbells
>   drm/amdgpu: create kernel doorbell page
>   drm/amdgpu: validate doorbell read/write
>   drm/amdgpu: get absolute offset from doorbell index
>   drm/amdgpu: use doorbell manager for kfd kernel doorbells
>   drm/amdgpu: use doorbell manager for kfd process doorbells
>   drm/amdgpu: remove ununsed functions and variables
>   drm/amdgpu: use doorbell mgr for MES kernel doorbells
>   drm/amdgpu: user doorbell mgr for MES process doorbells
> 
>  drivers/gpu/drm/amd/amdgpu/Makefile           |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c    |   6 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 164 ----------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h  | 102 +++++-
>  .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 304 ++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c       | 165 +++++-----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h       |  17 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c    |  11 +-
>  .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h    |   2 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  31 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h       |   1 +
>  drivers/gpu/drm/amd/amdkfd/kfd_chardev.c      |  13 -
>  drivers/gpu/drm/amd/amdkfd/kfd_device.c       |   4 +-
>  .../drm/amd/amdkfd/kfd_device_queue_manager.c |  16 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c     | 198 ++++--------
>  drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |  23 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_process.c      |  26 +-
>  .../amd/amdkfd/kfd_process_queue_manager.c    |  16 +-
>  include/uapi/drm/amdgpu_drm.h                 |   7 +-
>  19 files changed, 636 insertions(+), 472 deletions(-)
>  create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> 


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

* RE: [PATCH 00/16] AMDGPU Doorbell manager
  2023-03-30 13:49 ` [PATCH 00/16] AMDGPU Doorbell manager Luben Tuikov
@ 2023-03-30 13:56   ` Sharma, Shashank
  0 siblings, 0 replies; 87+ messages in thread
From: Sharma, Shashank @ 2023-03-30 13:56 UTC (permalink / raw)
  To: Tuikov, Luben, amd-gfx
  Cc: Deucher, Alexander, Joshi, Mukul, Kuehling, Felix, Koenig, Christian

[AMD Official Use Only - General]

Hey Luben, 

Agree and noted.
I have configured my editor to write the code according to the alignment conventions, but probably something missed the mark. 

- Shashank

-----Original Message-----
From: Tuikov, Luben <Luben.Tuikov@amd.com> 
Sent: 30 March 2023 15:50
To: Sharma, Shashank <Shashank.Sharma@amd.com>; amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Joshi, Mukul <Mukul.Joshi@amd.com>; Kuehling, Felix <Felix.Kuehling@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>
Subject: Re: [PATCH 00/16] AMDGPU Doorbell manager

As I'm reviewing this, it is obvious that this patchset hasn't gone though scripts/checkpatch.pl.

It's good practice to run one's patches through scripts/checkpatch.pl, to see deviations on common Linux practices, and correct them.

Regards,
Luben

On 2023-03-29 11:47, Shashank Sharma wrote:
> The doorbells in AMDGPU drivers are currently managed by different 
> users in a scattered way, across the driver. The existing clients are:
> - AMDGPU graphics driver for kernel level doorbell writes.
> - AMDGPU MES module for kernel level doorbell write (MES ring test).
> - AMDGPU MES modules for kernel level aggregated doorbell writes.
> - AMDGPU MES module for MES process doorbell writes.
> - AMDKFD module for KFD/KIQ kernel doorbell writes.
> - AMDKFD module for KFD process doorbell writes.
> - AMDGPU usermode queues for usermode doorbell writes (upcoming).
> 
> This patch series introduces Doorbell-manager to keep the doorbell 
> handling at a central place. The fundamental changes are:
> 
> - Introduce and accommodate a new GEM domain for doorbells.
> - Prepare the AMDGPU ttm backend for handling doorbell allocation.
> - Introduce doorbell-manager functions to allocate, free and index
>   doorbells in one unique way.
> - Create doorbell BOs for kernel-level and process level doorbell
>   opertations, and place it in existing structures.
> - Modify the existing graphics, KFD and MES code to use the
>   doorbell-manager functions.
> - Remove the existing doorbell management code in KFD/MES.
> 
> PS: This series has been sanity tested with kfd_test_suit to ensure
>     it is not introducing any regressions due to kfd doorbell changes.
> 
> The idea is that:
> - a kernel client can call doorbell manager functions to allocate/free
>   doorbell pages.
> - a usermode app can directly allocate a page from the doorbell bar just
>   like a GEM object and use it for different usermode queues.
> 
> Alex Deucher (2):
>   drm/amdgpu: add UAPI for allocating doorbell memory
>   drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
> 
> Shashank Sharma (14):
>   drm/amdgpu: rename num_doorbells
>   drm/amdgpu: include protection for doobell.h
>   drm/amdgpu: create a new file for doorbell manager
>   drm/amdgpu: don't modify num_doorbells for mes
>   drm/amdgpu: add helper to create doorbell pages
>   drm/amdgpu: initialize ttm for doorbells
>   drm/amdgpu: create kernel doorbell page
>   drm/amdgpu: validate doorbell read/write
>   drm/amdgpu: get absolute offset from doorbell index
>   drm/amdgpu: use doorbell manager for kfd kernel doorbells
>   drm/amdgpu: use doorbell manager for kfd process doorbells
>   drm/amdgpu: remove ununsed functions and variables
>   drm/amdgpu: use doorbell mgr for MES kernel doorbells
>   drm/amdgpu: user doorbell mgr for MES process doorbells
> 
>  drivers/gpu/drm/amd/amdgpu/Makefile           |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c    |   6 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 164 ----------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h  | 102 +++++-  
> .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 304 ++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c       | 165 +++++-----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h       |  17 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c    |  11 +-
>  .../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h    |   2 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  31 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h       |   1 +
>  drivers/gpu/drm/amd/amdkfd/kfd_chardev.c      |  13 -
>  drivers/gpu/drm/amd/amdkfd/kfd_device.c       |   4 +-
>  .../drm/amd/amdkfd/kfd_device_queue_manager.c |  16 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c     | 198 ++++--------
>  drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |  23 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_process.c      |  26 +-
>  .../amd/amdkfd/kfd_process_queue_manager.c    |  16 +-
>  include/uapi/drm/amdgpu_drm.h                 |   7 +-
>  19 files changed, 636 insertions(+), 472 deletions(-)  create mode 
> 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> 

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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 13:42   ` Luben Tuikov
  2023-03-30 13:44     ` Luben Tuikov
@ 2023-03-30 14:04     ` Shashank Sharma
  2023-03-30 14:15       ` Luben Tuikov
  1 sibling, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 14:04 UTC (permalink / raw)
  To: Luben Tuikov, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig


On 30/03/2023 15:42, Luben Tuikov wrote:
> On 2023-03-29 11:47, Shashank Sharma wrote:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch adds helper functions to create and free doorbell
>> pages for kernel objects.
>>
>> 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_doorbell.h  | 41 ++++++++++++++++
>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>>   2 files changed, 90 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index f9c3b77bf65d..6581b78fe438 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -27,6 +27,24 @@
>>   /*
>>    * GPU doorbell structures, functions & helpers
>>    */
>> +
>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>> +struct amdgpu_doorbell_obj {
> In the comment you say "Structure to hold ...";
> it is a C structure, but then in the name of a function we see "obj".
> (Object is something which is defined like in memory, i.e. it exists, not
> something which is only declared.)
> This is just a declaration of a structure, not an object per se.
> I'd call it "struct amdgpu_doorbell_struct" or just "struct amdgpu_doorbell".

It is similar to struct amdgpu buffer object (struct amdgpu_bo), and 
many more existing structure.

- Shashank

> Then in the definition, you can call it an object/objects, if you'd like,
> like "struct amdgpu_doorbell *doorb_object[];" then you can say
> "db = doorb_object[i]";
>
> Regards,
> Luben
>
>> +	struct amdgpu_bo *bo;
>> +	uint64_t gpu_addr;
>> +	uint32_t *cpu_addr;
>> +	uint32_t size;
>> +
>> +	/* First index in this object */
>> +	uint32_t start;
>> +
>> +	/* Last index in this object */
>> +	uint32_t end;
>> +
>> +	/* bitmap for dynamic doorbell allocation from this object */
>> +	unsigned long *doorbell_bitmap;
>> +};
>> +
>>   struct amdgpu_doorbell {
>>   	/* doorbell mmio */
>>   	resource_size_t		base;
>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>>    */
>>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>>   
>> +/**
>> + * amdgpu_doorbell_free_page - Free a doorbell page
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: previously allocated doobell page details
>> + *
>> + */
>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>> +				struct amdgpu_doorbell_obj *db_obj);
>> +
>> +/**
>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: doobell page structure to fill details with
>> + *
>> + * returns 0 on success, else error number
>> + */
>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>> +				struct amdgpu_doorbell_obj *db_obj);
>> +
>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> index 1aea92363fd3..8be15b82b545 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>   	}
>>   }
>>   
>> +/**
>> + * amdgpu_doorbell_free_page - Free a doorbell page
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: previously allocated doobell page details
>> + *
>> + */
>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>> +					struct amdgpu_doorbell_obj *db_obj)
>> +{
>> +	amdgpu_bo_free_kernel(&db_obj->bo,
>> +			      &db_obj->gpu_addr,
>> +			      (void **)&db_obj->cpu_addr);
>> +
>> +}
>> +
>> +/**
>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: doobell page structure to fill details with
>> + *
>> + * returns 0 on success, else error number
>> + */
>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>> +				struct amdgpu_doorbell_obj *db_obj)
>> +{
>> +	int r;
>> +
>> +	db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
>> +
>> +	r = amdgpu_bo_create_kernel(adev,
>> +				    db_obj->size,
>> +				    PAGE_SIZE,
>> +				    AMDGPU_GEM_DOMAIN_DOORBELL,
>> +				    &db_obj->bo,
>> +				    &db_obj->gpu_addr,
>> +				    (void **)&db_obj->cpu_addr);
>> +
>> +	if (r) {
>> +		DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
>> +		return r;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>   /*
>>    * GPU doorbell aperture helpers function.
>>    */

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

* Re: [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
  2023-03-30 13:48           ` Shashank Sharma
@ 2023-03-30 14:12             ` Luben Tuikov
  2023-03-30 15:32               ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 14:12 UTC (permalink / raw)
  To: Shashank Sharma, Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling

On 2023-03-30 09:48, Shashank Sharma wrote:
> 
> On 30/03/2023 15:45, Luben Tuikov wrote:
>> On 2023-03-30 09:43, Shashank Sharma wrote:
>>> On 30/03/2023 15:33, Luben Tuikov wrote:
>>>> On 2023-03-30 07:14, Christian König wrote:
>>>>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>>>>>> From: Alex Deucher <alexander.deucher@amd.com>
>>>>>>
>>>>>> This patch adds changes:
>>>>>> - to accommodate the new GEM domain DOORBELL
>>>>>> - to accommodate the new TTM PL DOORBELL
>>>>>>
>>>>>> in order to manage doorbell pages as GEM object.
>>>>>>
>>>>>> V2: Addressed reviwe comments from Christian
>>>>>>        - drop the doorbell changes for pinning/unpinning
>>>>>>        - drop the doorbell changes for dma-buf map
>>>>>>        - drop the doorbell changes for sgt
>>>>>>        - no need to handle TTM_PL_FLAG_CONTIGUOUS for doorbell
>>>>>>        - add caching type for doorbell
>>>>>>
>>>>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>>>>> Cc: Christian Koenig <christian.koenig@amd.com>
>>>>>>
>>>>>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>>>>>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>>>> Generally there are no empty lines in the tag list. Perhaps remove it?
>>> I would prefer to keep it, to highlight the CC parts.
>> I've never seen a commit with them separated. Perhaps follow Linux custom?
> 
> IIRC This is not against Linux patch formatting/message body guidelines.

The tag list forms a block, a paragraph, which is easy to scan and separate out
of the description of the patch, which in itself can have many paragraphs separated
by white lines: subject line, paragraph 1, paragraph 2, ..., paragraph of tags.
Furthermore these tags are added/appended by automated scripts/tools which wouldn't
add an empty line.

Check out the following resources:
https://www.kernel.org/doc/html/v4.12/process/5.Posting.html#patch-formatting-and-changelogs
https://www.kernel.org/doc/html/v4.12/process/submitting-patches.html#the-canonical-patch-format

"git log -- drivers/gpu/drm/." is also a very helpful reference to see some good patch formatting.

Please remove the empty line between the Cc and Sob lines, so it forms a tag paragraph.

Regards,
Luben


> 
> - Shashank
> 
>> Regards,
>> Luben
>>
>>> - Shashank
>>>
>>>> Regards,
>>>> Luben
>>>>
>>>>>> ---
>>>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_object.c     | 11 ++++++++++-
>>>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h |  2 ++
>>>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c        | 16 +++++++++++++++-
>>>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h        |  1 +
>>>>>>     4 files changed, 28 insertions(+), 2 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>>>> index 4e684c2afc70..0ec080e240ad 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>>>> @@ -147,6 +147,14 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
>>>>>>     		c++;
>>>>>>     	}
>>>>>>     
>>>>>> +	if (domain & AMDGPU_GEM_DOMAIN_DOORBELL) {
>>>>>> +		places[c].fpfn = 0;
>>>>>> +		places[c].lpfn = 0;
>>>>>> +		places[c].mem_type = AMDGPU_PL_DOORBELL;
>>>>>> +		places[c].flags = 0;
>>>>>> +		c++;
>>>>>> +	}
>>>>>> +
>>>>>>     	if (domain & AMDGPU_GEM_DOMAIN_GTT) {
>>>>>>     		places[c].fpfn = 0;
>>>>>>     		places[c].lpfn = 0;
>>>>>> @@ -466,7 +474,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
>>>>>>     		goto fail;
>>>>>>     	}
>>>>>>     
>>>>>> -	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
>>>>>> +	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU,  AMDGPU_GEM_DOMAIN_DOORBELL */
>>>>>>     	return true;
>>>>>>     
>>>>>>     fail:
>>>>>> @@ -1013,6 +1021,7 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo)
>>>>>>     	} else if (bo->tbo.resource->mem_type == TTM_PL_TT) {
>>>>>>     		atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size);
>>>>>>     	}
>>>>>> +
>>>>> Unrelated newline, probably just a leftover.
>>>>>
>>>>> Apart from that the patch is Reviewed-by: Christian König
>>>>> <christian.koenig@amd.com>
>>>>>
>>>>> Regards,
>>>>> Christian.
>>>>>
>>>>>>     }
>>>>>>     
>>>>>>     static const char *amdgpu_vram_names[] = {
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>>>> index 5c4f93ee0c57..3c988cc406e4 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>>>> @@ -90,6 +90,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
>>>>>>     		cur->node = block;
>>>>>>     		break;
>>>>>>     	case TTM_PL_TT:
>>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>>     		node = to_ttm_range_mgr_node(res)->mm_nodes;
>>>>>>     		while (start >= node->size << PAGE_SHIFT)
>>>>>>     			start -= node++->size << PAGE_SHIFT;
>>>>>> @@ -152,6 +153,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
>>>>>>     		cur->size = min(amdgpu_vram_mgr_block_size(block), cur->remaining);
>>>>>>     		break;
>>>>>>     	case TTM_PL_TT:
>>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>>     		node = cur->node;
>>>>>>     
>>>>>>     		cur->node = ++node;
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> index 55e0284b2bdd..6f61491ef3dd 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> @@ -128,6 +128,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
>>>>>>     	case AMDGPU_PL_GDS:
>>>>>>     	case AMDGPU_PL_GWS:
>>>>>>     	case AMDGPU_PL_OA:
>>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>>     		placement->num_placement = 0;
>>>>>>     		placement->num_busy_placement = 0;
>>>>>>     		return;
>>>>>> @@ -500,9 +501,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
>>>>>>     	if (old_mem->mem_type == AMDGPU_PL_GDS ||
>>>>>>     	    old_mem->mem_type == AMDGPU_PL_GWS ||
>>>>>>     	    old_mem->mem_type == AMDGPU_PL_OA ||
>>>>>> +	    old_mem->mem_type == AMDGPU_PL_DOORBELL ||
>>>>>>     	    new_mem->mem_type == AMDGPU_PL_GDS ||
>>>>>>     	    new_mem->mem_type == AMDGPU_PL_GWS ||
>>>>>> -	    new_mem->mem_type == AMDGPU_PL_OA) {
>>>>>> +	    new_mem->mem_type == AMDGPU_PL_OA ||
>>>>>> +	    new_mem->mem_type == AMDGPU_PL_DOORBELL) {
>>>>>>     		/* Nothing to save here */
>>>>>>     		ttm_bo_move_null(bo, new_mem);
>>>>>>     		goto out;
>>>>>> @@ -586,6 +589,12 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
>>>>>>     		mem->bus.offset += adev->gmc.aper_base;
>>>>>>     		mem->bus.is_iomem = true;
>>>>>>     		break;
>>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>> +		mem->bus.offset = mem->start << PAGE_SHIFT;
>>>>>> +		mem->bus.offset += adev->doorbell.base;
>>>>>> +		mem->bus.is_iomem = true;
>>>>>> +		mem->bus.caching = ttm_uncached;
>>>>>> +		break;
>>>>>>     	default:
>>>>>>     		return -EINVAL;
>>>>>>     	}
>>>>>> @@ -600,6 +609,10 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
>>>>>>     
>>>>>>     	amdgpu_res_first(bo->resource, (u64)page_offset << PAGE_SHIFT, 0,
>>>>>>     			 &cursor);
>>>>>> +
>>>>>> +	if (bo->resource->mem_type == AMDGPU_PL_DOORBELL)
>>>>>> +		return ((uint64_t)(adev->doorbell.base + cursor.start)) >> PAGE_SHIFT;
>>>>>> +
>>>>>>     	return (adev->gmc.aper_base + cursor.start) >> PAGE_SHIFT;
>>>>>>     }
>>>>>>     
>>>>>> @@ -1267,6 +1280,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem)
>>>>>>     		flags |= AMDGPU_PTE_VALID;
>>>>>>     
>>>>>>     	if (mem && (mem->mem_type == TTM_PL_TT ||
>>>>>> +		    mem->mem_type == AMDGPU_PL_DOORBELL ||
>>>>>>     		    mem->mem_type == AMDGPU_PL_PREEMPT)) {
>>>>>>     		flags |= AMDGPU_PTE_SYSTEM;
>>>>>>     
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>>>> index e2cd5894afc9..761cd6b2b942 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>>>> @@ -33,6 +33,7 @@
>>>>>>     #define AMDGPU_PL_GWS		(TTM_PL_PRIV + 1)
>>>>>>     #define AMDGPU_PL_OA		(TTM_PL_PRIV + 2)
>>>>>>     #define AMDGPU_PL_PREEMPT	(TTM_PL_PRIV + 3)
>>>>>> +#define AMDGPU_PL_DOORBELL	(TTM_PL_PRIV + 4)
>>>>>>     
>>>>>>     #define AMDGPU_GTT_MAX_TRANSFER_SIZE	512
>>>>>>     #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS	2


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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 14:04     ` Shashank Sharma
@ 2023-03-30 14:15       ` Luben Tuikov
  2023-03-30 14:34         ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 14:15 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

On 2023-03-30 10:04, Shashank Sharma wrote:
> 
> On 30/03/2023 15:42, Luben Tuikov wrote:
>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>
>>> This patch adds helper functions to create and free doorbell
>>> pages for kernel objects.
>>>
>>> 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_doorbell.h  | 41 ++++++++++++++++
>>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>>>   2 files changed, 90 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>> index f9c3b77bf65d..6581b78fe438 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>> @@ -27,6 +27,24 @@
>>>   /*
>>>    * GPU doorbell structures, functions & helpers
>>>    */
>>> +
>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>>> +struct amdgpu_doorbell_obj {
>> In the comment you say "Structure to hold ...";
>> it is a C structure, but then in the name of a function we see "obj".
>> (Object is something which is defined like in memory, i.e. it exists, not
>> something which is only declared.)
>> This is just a declaration of a structure, not an object per se.
>> I'd call it "struct amdgpu_doorbell_struct" or just "struct amdgpu_doorbell".
> 
> It is similar to struct amdgpu buffer object (struct amdgpu_bo), and 
> many more existing structure.

The amdpgu_bo is very different than a structure describing a doorbell.
The doorbell description isn't really "an object". I understand
the enthusiasm, but it is really not "an object". It's just a doorbell
description. :-)

Regards,
Luben

> 
> - Shashank
> 
>> Then in the definition, you can call it an object/objects, if you'd like,
>> like "struct amdgpu_doorbell *doorb_object[];" then you can say
>> "db = doorb_object[i]";
>>
>> Regards,
>> Luben
>>
>>> +	struct amdgpu_bo *bo;
>>> +	uint64_t gpu_addr;
>>> +	uint32_t *cpu_addr;
>>> +	uint32_t size;
>>> +
>>> +	/* First index in this object */
>>> +	uint32_t start;
>>> +
>>> +	/* Last index in this object */
>>> +	uint32_t end;
>>> +
>>> +	/* bitmap for dynamic doorbell allocation from this object */
>>> +	unsigned long *doorbell_bitmap;
>>> +};
>>> +
>>>   struct amdgpu_doorbell {
>>>   	/* doorbell mmio */
>>>   	resource_size_t		base;
>>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>>>    */
>>>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>>>   
>>> +/**
>>> + * amdgpu_doorbell_free_page - Free a doorbell page
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + *
>>> + * @db_age: previously allocated doobell page details
>>> + *
>>> + */
>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>> +				struct amdgpu_doorbell_obj *db_obj);
>>> +
>>> +/**
>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + *
>>> + * @db_age: doobell page structure to fill details with
>>> + *
>>> + * returns 0 on success, else error number
>>> + */
>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>> +				struct amdgpu_doorbell_obj *db_obj);
>>> +
>>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> index 1aea92363fd3..8be15b82b545 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>>   	}
>>>   }
>>>   
>>> +/**
>>> + * amdgpu_doorbell_free_page - Free a doorbell page
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + *
>>> + * @db_age: previously allocated doobell page details
>>> + *
>>> + */
>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>> +					struct amdgpu_doorbell_obj *db_obj)
>>> +{
>>> +	amdgpu_bo_free_kernel(&db_obj->bo,
>>> +			      &db_obj->gpu_addr,
>>> +			      (void **)&db_obj->cpu_addr);
>>> +
>>> +}
>>> +
>>> +/**
>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + *
>>> + * @db_age: doobell page structure to fill details with
>>> + *
>>> + * returns 0 on success, else error number
>>> + */
>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>> +				struct amdgpu_doorbell_obj *db_obj)
>>> +{
>>> +	int r;
>>> +
>>> +	db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
>>> +
>>> +	r = amdgpu_bo_create_kernel(adev,
>>> +				    db_obj->size,
>>> +				    PAGE_SIZE,
>>> +				    AMDGPU_GEM_DOMAIN_DOORBELL,
>>> +				    &db_obj->bo,
>>> +				    &db_obj->gpu_addr,
>>> +				    (void **)&db_obj->cpu_addr);
>>> +
>>> +	if (r) {
>>> +		DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
>>> +		return r;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>>   /*
>>>    * GPU doorbell aperture helpers function.
>>>    */


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

* Re: [PATCH 01/16] drm/amdgpu: rename num_doorbells
  2023-03-29 15:47 ` [PATCH 01/16] drm/amdgpu: rename num_doorbells Shashank Sharma
  2023-03-30 11:04   ` Christian König
  2023-03-30 13:11   ` Luben Tuikov
@ 2023-03-30 14:19   ` Alex Deucher
  2023-04-04 16:13   ` Luben Tuikov
  3 siblings, 0 replies; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 14:19 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian Koenig

On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> Rename doorbell.num_doorbells to doorbell.num_kernel_doorbells to
> make it more readable.
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c   |  6 +++---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   | 22 ++++++++++----------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h |  4 +++-
>  3 files changed, 17 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> index f99d4873bf22..0385f7f69278 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> @@ -96,7 +96,7 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
>                                          size_t *start_offset)
>  {
>         /*
> -        * The first num_doorbells are used by amdgpu.
> +        * The first num_kernel_doorbells are used by amdgpu.
>          * amdkfd takes whatever's left in the aperture.
>          */
>         if (adev->enable_mes) {
> @@ -109,11 +109,11 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
>                 *aperture_base = adev->doorbell.base;
>                 *aperture_size = 0;
>                 *start_offset = 0;
> -       } else if (adev->doorbell.size > adev->doorbell.num_doorbells *
> +       } else if (adev->doorbell.size > adev->doorbell.num_kernel_doorbells *
>                                                 sizeof(u32)) {
>                 *aperture_base = adev->doorbell.base;
>                 *aperture_size = adev->doorbell.size;
> -               *start_offset = adev->doorbell.num_doorbells * sizeof(u32);
> +               *start_offset = adev->doorbell.num_kernel_doorbells * sizeof(u32);
>         } else {
>                 *aperture_base = 0;
>                 *aperture_size = 0;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index afe6af9c0138..57ee1c4a81e9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -593,7 +593,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>         if (amdgpu_device_skip_hw_access(adev))
>                 return 0;
>
> -       if (index < adev->doorbell.num_doorbells) {
> +       if (index < adev->doorbell.num_kernel_doorbells) {
>                 return readl(adev->doorbell.ptr + index);
>         } else {
>                 DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> @@ -616,7 +616,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>         if (amdgpu_device_skip_hw_access(adev))
>                 return;
>
> -       if (index < adev->doorbell.num_doorbells) {
> +       if (index < adev->doorbell.num_kernel_doorbells) {
>                 writel(v, adev->doorbell.ptr + index);
>         } else {
>                 DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> @@ -637,7 +637,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>         if (amdgpu_device_skip_hw_access(adev))
>                 return 0;
>
> -       if (index < adev->doorbell.num_doorbells) {
> +       if (index < adev->doorbell.num_kernel_doorbells) {
>                 return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>         } else {
>                 DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> @@ -660,7 +660,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>         if (amdgpu_device_skip_hw_access(adev))
>                 return;
>
> -       if (index < adev->doorbell.num_doorbells) {
> +       if (index < adev->doorbell.num_kernel_doorbells) {
>                 atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>         } else {
>                 DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> @@ -1034,7 +1034,7 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>         if (adev->asic_type < CHIP_BONAIRE) {
>                 adev->doorbell.base = 0;
>                 adev->doorbell.size = 0;
> -               adev->doorbell.num_doorbells = 0;
> +               adev->doorbell.num_kernel_doorbells = 0;
>                 adev->doorbell.ptr = NULL;
>                 return 0;
>         }
> @@ -1049,27 +1049,27 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>         adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>
>         if (adev->enable_mes) {
> -               adev->doorbell.num_doorbells =
> +               adev->doorbell.num_kernel_doorbells =
>                         adev->doorbell.size / sizeof(u32);
>         } else {
> -               adev->doorbell.num_doorbells =
> +               adev->doorbell.num_kernel_doorbells =
>                         min_t(u32, adev->doorbell.size / sizeof(u32),
>                               adev->doorbell_index.max_assignment+1);
> -               if (adev->doorbell.num_doorbells == 0)
> +               if (adev->doorbell.num_kernel_doorbells == 0)
>                         return -EINVAL;
>
>                 /* For Vega, reserve and map two pages on doorbell BAR since SDMA
>                  * paging queue doorbell use the second page. The
>                  * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>                  * doorbells are in the first page. So with paging queue enabled,
> -                * the max num_doorbells should + 1 page (0x400 in dword)
> +                * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>                  */
>                 if (adev->asic_type >= CHIP_VEGA10)
> -                       adev->doorbell.num_doorbells += 0x400;
> +                       adev->doorbell.num_kernel_doorbells += 0x400;
>         }
>
>         adev->doorbell.ptr = ioremap(adev->doorbell.base,
> -                                    adev->doorbell.num_doorbells *
> +                                    adev->doorbell.num_kernel_doorbells *
>                                      sizeof(u32));
>         if (adev->doorbell.ptr == NULL)
>                 return -ENOMEM;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 7199b6b0be81..12263986f889 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -29,7 +29,9 @@ struct amdgpu_doorbell {
>         resource_size_t         base;
>         resource_size_t         size;
>         u32 __iomem             *ptr;
> -       u32                     num_doorbells;  /* Number of doorbells actually reserved for amdgpu. */
> +
> +       /* Number of doorbells reserved for amdgpu kernel driver */
> +       u32 num_kernel_doorbells;
>  };
>
>  /* Reserved doorbells for amdgpu (including multimedia).
> --
> 2.40.0
>

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

* Re: [PATCH 02/16] drm/amdgpu: include protection for doobell.h
  2023-03-29 15:47 ` [PATCH 02/16] drm/amdgpu: include protection for doobell.h Shashank Sharma
  2023-03-30 11:05   ` Christian König
@ 2023-03-30 14:20   ` Alex Deucher
  1 sibling, 0 replies; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 14:20 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian Koenig

On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch adds double include protection for doorbell.h
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 12263986f889..6064943a1b53 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -21,6 +21,9 @@
>   *
>   */
>
> +#ifndef AMDGPU_DOORBELL_H
> +#define AMDGPU_DOORBELL_H
> +
>  /*
>   * GPU doorbell structures, functions & helpers
>   */
> @@ -308,3 +311,4 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
>  #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>  #define WDOORBELL64(index, v) amdgpu_mm_wdoorbell64(adev, (index), (v))
>
> +#endif
> \ No newline at end of file
> --
> 2.40.0
>

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

* Re: [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager
  2023-03-29 15:47 ` [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager Shashank Sharma
  2023-03-30 11:09   ` Christian König
@ 2023-03-30 14:23   ` Alex Deucher
  2023-03-30 14:49     ` Shashank Sharma
  1 sibling, 1 reply; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 14:23 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian Koenig

On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch:
> - creates a new file for doorbell management.
> - moves doorbell code from amdgpu_device.c to this file.
>
> 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/Makefile           |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 164 ---------------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h  |  22 +++
>  .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 186 ++++++++++++++++++
>  4 files changed, 209 insertions(+), 165 deletions(-)
>  create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
> index 798d0e9a60b7..204665f20319 100644
> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
> @@ -41,7 +41,7 @@ ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
>  amdgpu-y := amdgpu_drv.o
>
>  # add KMS driver
> -amdgpu-y += amdgpu_device.o amdgpu_kms.o \
> +amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
>         amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
>         atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
>         amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 57ee1c4a81e9..7f8fcac4f18b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -579,94 +579,6 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
>         }
>  }
>
> -/**
> - * amdgpu_mm_rdoorbell - read a doorbell dword
> - *
> - * @adev: amdgpu_device pointer
> - * @index: doorbell index
> - *
> - * Returns the value in the doorbell aperture at the
> - * requested doorbell index (CIK).
> - */
> -u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
> -{
> -       if (amdgpu_device_skip_hw_access(adev))
> -               return 0;
> -
> -       if (index < adev->doorbell.num_kernel_doorbells) {
> -               return readl(adev->doorbell.ptr + index);
> -       } else {
> -               DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> -               return 0;
> -       }
> -}
> -
> -/**
> - * amdgpu_mm_wdoorbell - write a doorbell dword
> - *
> - * @adev: amdgpu_device pointer
> - * @index: doorbell index
> - * @v: value to write
> - *
> - * Writes @v to the doorbell aperture at the
> - * requested doorbell index (CIK).
> - */
> -void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
> -{
> -       if (amdgpu_device_skip_hw_access(adev))
> -               return;
> -
> -       if (index < adev->doorbell.num_kernel_doorbells) {
> -               writel(v, adev->doorbell.ptr + index);
> -       } else {
> -               DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> -       }
> -}
> -
> -/**
> - * amdgpu_mm_rdoorbell64 - read a doorbell Qword
> - *
> - * @adev: amdgpu_device pointer
> - * @index: doorbell index
> - *
> - * Returns the value in the doorbell aperture at the
> - * requested doorbell index (VEGA10+).
> - */
> -u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
> -{
> -       if (amdgpu_device_skip_hw_access(adev))
> -               return 0;
> -
> -       if (index < adev->doorbell.num_kernel_doorbells) {
> -               return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
> -       } else {
> -               DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> -               return 0;
> -       }
> -}
> -
> -/**
> - * amdgpu_mm_wdoorbell64 - write a doorbell Qword
> - *
> - * @adev: amdgpu_device pointer
> - * @index: doorbell index
> - * @v: value to write
> - *
> - * Writes @v to the doorbell aperture at the
> - * requested doorbell index (VEGA10+).
> - */
> -void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
> -{
> -       if (amdgpu_device_skip_hw_access(adev))
> -               return;
> -
> -       if (index < adev->doorbell.num_kernel_doorbells) {
> -               atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
> -       } else {
> -               DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> -       }
> -}
> -
>  /**
>   * amdgpu_device_indirect_rreg - read an indirect register
>   *
> @@ -1016,82 +928,6 @@ int amdgpu_device_pci_reset(struct amdgpu_device *adev)
>         return pci_reset_function(adev->pdev);
>  }
>
> -/*
> - * GPU doorbell aperture helpers function.
> - */
> -/**
> - * amdgpu_device_doorbell_init - Init doorbell driver information.
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Init doorbell driver information (CIK)
> - * Returns 0 on success, error on failure.
> - */
> -static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
> -{
> -
> -       /* No doorbell on SI hardware generation */
> -       if (adev->asic_type < CHIP_BONAIRE) {
> -               adev->doorbell.base = 0;
> -               adev->doorbell.size = 0;
> -               adev->doorbell.num_kernel_doorbells = 0;
> -               adev->doorbell.ptr = NULL;
> -               return 0;
> -       }
> -
> -       if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
> -               return -EINVAL;
> -
> -       amdgpu_asic_init_doorbell_index(adev);
> -
> -       /* doorbell bar mapping */
> -       adev->doorbell.base = pci_resource_start(adev->pdev, 2);
> -       adev->doorbell.size = pci_resource_len(adev->pdev, 2);
> -
> -       if (adev->enable_mes) {
> -               adev->doorbell.num_kernel_doorbells =
> -                       adev->doorbell.size / sizeof(u32);
> -       } else {
> -               adev->doorbell.num_kernel_doorbells =
> -                       min_t(u32, adev->doorbell.size / sizeof(u32),
> -                             adev->doorbell_index.max_assignment+1);
> -               if (adev->doorbell.num_kernel_doorbells == 0)
> -                       return -EINVAL;
> -
> -               /* For Vega, reserve and map two pages on doorbell BAR since SDMA
> -                * paging queue doorbell use the second page. The
> -                * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
> -                * doorbells are in the first page. So with paging queue enabled,
> -                * the max num_kernel_doorbells should + 1 page (0x400 in dword)
> -                */
> -               if (adev->asic_type >= CHIP_VEGA10)
> -                       adev->doorbell.num_kernel_doorbells += 0x400;
> -       }
> -
> -       adev->doorbell.ptr = ioremap(adev->doorbell.base,
> -                                    adev->doorbell.num_kernel_doorbells *
> -                                    sizeof(u32));
> -       if (adev->doorbell.ptr == NULL)
> -               return -ENOMEM;
> -
> -       return 0;
> -}
> -
> -/**
> - * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
> - *
> - * @adev: amdgpu_device pointer
> - *
> - * Tear down doorbell driver information (CIK)
> - */
> -static void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
> -{
> -       iounmap(adev->doorbell.ptr);
> -       adev->doorbell.ptr = NULL;
> -}
> -
> -
> -
>  /*
>   * amdgpu_device_wb_*()
>   * Writeback is the method by which the GPU updates special pages in memory
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 6064943a1b53..f9c3b77bf65d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -306,6 +306,28 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
>  u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index);
>  void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
>
> +/*
> + * GPU doorbell aperture helpers function.
> + */
> +/**
> + * amdgpu_device_doorbell_init - Init doorbell driver information.
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Init doorbell driver information (CIK)
> + * Returns 0 on success, error on failure.
> + */
> +int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
> +
> +/**
> + * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Tear down doorbell driver information (CIK)
> + */
> +void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
> +
>  #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>  #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>  #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> new file mode 100644
> index 000000000000..2206926ba289
> --- /dev/null
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -0,0 +1,186 @@
> +/*
> + * 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"
> +
> +/**
> + * amdgpu_mm_rdoorbell - read a doorbell dword
> + *
> + * @adev: amdgpu_device pointer
> + * @index: doorbell index
> + *
> + * Returns the value in the doorbell aperture at the
> + * requested doorbell index (CIK).
> + */
> +u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
> +{
> +       if (amdgpu_device_skip_hw_access(adev))
> +               return 0;
> +
> +       if (index < adev->doorbell.num_kernel_doorbells) {
> +               return readl(adev->doorbell.ptr + index);
> +       } else {
> +               DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> +               return 0;
> +       }
> +}
> +
> +/**
> + * amdgpu_mm_wdoorbell - write a doorbell dword
> + *
> + * @adev: amdgpu_device pointer
> + * @index: doorbell index
> + * @v: value to write
> + *
> + * Writes @v to the doorbell aperture at the
> + * requested doorbell index (CIK).
> + */
> +void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
> +{
> +       if (amdgpu_device_skip_hw_access(adev))
> +               return;
> +
> +       if (index < adev->doorbell.num_kernel_doorbells) {
> +               writel(v, adev->doorbell.ptr + index);
> +       } else {
> +               DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> +       }
> +}
> +
> +/**
> + * amdgpu_mm_rdoorbell64 - read a doorbell Qword
> + *
> + * @adev: amdgpu_device pointer
> + * @index: doorbell index
> + *
> + * Returns the value in the doorbell aperture at the
> + * requested doorbell index (VEGA10+).
> + */
> +u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
> +{
> +       if (amdgpu_device_skip_hw_access(adev))
> +               return 0;
> +
> +       if (index < adev->doorbell.num_kernel_doorbells) {
> +               return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
> +       } else {
> +               DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> +               return 0;
> +       }
> +}
> +
> +/**
> + * amdgpu_mm_wdoorbell64 - write a doorbell Qword
> + *
> + * @adev: amdgpu_device pointer
> + * @index: doorbell index
> + * @v: value to write
> + *
> + * Writes @v to the doorbell aperture at the
> + * requested doorbell index (VEGA10+).
> + */
> +void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
> +{
> +       if (amdgpu_device_skip_hw_access(adev))
> +               return;
> +
> +       if (index < adev->doorbell.num_kernel_doorbells) {
> +               atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
> +       } else {
> +               DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> +       }
> +}
> +
> +/*
> + * GPU doorbell aperture helpers function.
> + */
> +/**
> + * amdgpu_device_doorbell_init - Init doorbell driver information.
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Init doorbell driver information (CIK)
> + * Returns 0 on success, error on failure.
> + */
> +int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
> +{
> +
> +       /* No doorbell on SI hardware generation */
> +       if (adev->asic_type < CHIP_BONAIRE) {
> +               adev->doorbell.base = 0;
> +               adev->doorbell.size = 0;
> +               adev->doorbell.num_kernel_doorbells = 0;
> +               adev->doorbell.ptr = NULL;
> +               return 0;
> +       }
> +
> +       if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
> +               return -EINVAL;
> +
> +       amdgpu_asic_init_doorbell_index(adev);
> +
> +       /* doorbell bar mapping */
> +       adev->doorbell.base = pci_resource_start(adev->pdev, 2);
> +       adev->doorbell.size = pci_resource_len(adev->pdev, 2);
> +
> +       if (adev->enable_mes) {
> +               adev->doorbell.num_kernel_doorbells =
> +                       adev->doorbell.size / sizeof(u32);
> +       } else {
> +               adev->doorbell.num_kernel_doorbells =
> +                       min_t(u32, adev->doorbell.size / sizeof(u32),
> +                             adev->doorbell_index.max_assignment+1);
> +               if (adev->doorbell.num_kernel_doorbells == 0)
> +                       return -EINVAL;
> +
> +               /* For Vega, reserve and map two pages on doorbell BAR since SDMA
> +                * paging queue doorbell use the second page. The
> +                * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
> +                * doorbells are in the first page. So with paging queue enabled,
> +                * the max num_kernel_doorbells should + 1 page (0x400 in dword)
> +                */
> +               if (adev->asic_type >= CHIP_VEGA10)
> +                       adev->doorbell.num_kernel_doorbells += 0x400;
> +       }
> +
> +       adev->doorbell.ptr = ioremap(adev->doorbell.base,
> +                                    adev->doorbell.num_kernel_doorbells *
> +                                    sizeof(u32));
> +       if (adev->doorbell.ptr == NULL)
> +               return -ENOMEM;
> +
> +       return 0;
> +}
> +
> +/**
> + * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Tear down doorbell driver information (CIK)
> + */
> +void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
> +{
> +       iounmap(adev->doorbell.ptr);
> +       adev->doorbell.ptr = NULL;
> +}

I would suggest renaming these functions to begin with
amdgpu_doorbell_ to be consistent with the naming conventions in the
driver.

Alex

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

* Re: [PATCH 04/16] drm/amdgpu: don't modify num_doorbells for mes
  2023-03-29 15:47 ` [PATCH 04/16] drm/amdgpu: don't modify num_doorbells for mes Shashank Sharma
  2023-03-30 11:10   ` Christian König
@ 2023-03-30 14:24   ` Alex Deucher
  1 sibling, 0 replies; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 14:24 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian Koenig

On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch removes the check and change in num_kernel_doorbells
> for MES, which is not being used anywhere by MES code.
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>

Acked-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 34 ++++++++-----------
>  1 file changed, 15 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> index 2206926ba289..1aea92363fd3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -143,25 +143,21 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>         adev->doorbell.base = pci_resource_start(adev->pdev, 2);
>         adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>
> -       if (adev->enable_mes) {
> -               adev->doorbell.num_kernel_doorbells =
> -                       adev->doorbell.size / sizeof(u32);
> -       } else {
> -               adev->doorbell.num_kernel_doorbells =
> -                       min_t(u32, adev->doorbell.size / sizeof(u32),
> -                             adev->doorbell_index.max_assignment+1);
> -               if (adev->doorbell.num_kernel_doorbells == 0)
> -                       return -EINVAL;
> -
> -               /* For Vega, reserve and map two pages on doorbell BAR since SDMA
> -                * paging queue doorbell use the second page. The
> -                * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
> -                * doorbells are in the first page. So with paging queue enabled,
> -                * the max num_kernel_doorbells should + 1 page (0x400 in dword)
> -                */
> -               if (adev->asic_type >= CHIP_VEGA10)
> -                       adev->doorbell.num_kernel_doorbells += 0x400;
> -       }
> +       adev->doorbell.num_kernel_doorbells =
> +               min_t(u32, adev->doorbell.size / sizeof(u32),
> +                               adev->doorbell_index.max_assignment+1);
> +       if (adev->doorbell.num_kernel_doorbells == 0)
> +               return -EINVAL;
> +
> +       /*
> +        * For Vega, reserve and map two pages on doorbell BAR since SDMA
> +        * paging queue doorbell use the second page. The
> +        * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
> +        * doorbells are in the first page. So with paging queue enabled,
> +        * the max num_kernel_doorbells should + 1 page (0x400 in dword)
> +        */
> +       if (adev->asic_type >= CHIP_VEGA10)
> +               adev->doorbell.num_kernel_doorbells += 0x400;
>
>         adev->doorbell.ptr = ioremap(adev->doorbell.base,
>                                      adev->doorbell.num_kernel_doorbells *
> --
> 2.40.0
>

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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-29 15:47 ` [PATCH 09/16] drm/amdgpu: create kernel doorbell page Shashank Sharma
  2023-03-30 11:30   ` Christian König
@ 2023-03-30 14:24   ` Luben Tuikov
  2023-03-30 14:40     ` Shashank Sharma
  1 sibling, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 14:24 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

On 2023-03-29 11:47, Shashank Sharma wrote:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
> 
> This patch:
> - creates a doorbell page for graphics driver usages.
> - removes the adev->doorbell.ptr variable, replaces it with
>   kernel-doorbell-bo's cpu address.
> 
> 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_doorbell.h  | 16 ++++++-
>  .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 +++++++++++++++----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>  3 files changed, 57 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 6581b78fe438..10a9bb10e974 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>  	/* doorbell mmio */
>  	resource_size_t		base;
>  	resource_size_t		size;
> -	u32 __iomem		*ptr;
> +	u32	__iomem		*ptr;
>  
>  	/* Number of doorbells reserved for amdgpu kernel driver */
>  	u32 num_kernel_doorbells;
> +
> +	/* For kernel doorbell pages */
> +	struct amdgpu_doorbell_obj kernel_doorbells;
>  };

Here's an example where it could be confusing what the difference is
between "struct amdgpu_doorbell" and "struct amdgpu_doobell_obj".
As the comment to the struct doorbell_obj declarations says
in patch 7,

> +/* Structure to hold doorbell pages from PCI doorbell BAR */
> +struct amdgpu_doorbell_obj {

Perhaps we should call it "struct amdgpu_doorbell_bo", since
it does contain amdgpu_bo's, which are doorbell's bos.

Regards,
Luben

>  
>  /* Reserved doorbells for amdgpu (including multimedia).
> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>  int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>  				struct amdgpu_doorbell_obj *db_obj);
>  
> +/**
> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells for graphics
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Creates doorbells for graphics driver
> + *
> + * returns 0 on success, error otherwise.
> + */
> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev);
> +
>  #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>  #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>  #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> index 8be15b82b545..b46fe8b1378d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>  	return 0;
>  }
>  
> +/**
> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells for graphics
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * Creates doorbells for graphics driver
> + *
> + * returns 0 on success, error otherwise.
> + */
> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev)
> +{
> +	int r;
> +	struct amdgpu_doorbell_obj *kernel_doorbells = &adev->doorbell.kernel_doorbells;
> +
> +	kernel_doorbells->doorbell_bitmap = bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
> +							  GFP_KERNEL);
> +	if (!kernel_doorbells->doorbell_bitmap) {
> +		DRM_ERROR("Failed to create kernel doorbell bitmap\n");
> +		return -ENOMEM;
> +	}
> +
> +	kernel_doorbells->size = adev->doorbell.num_kernel_doorbells * sizeof(u32);
> +	r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
> +	if (r) {
> +		bitmap_free(kernel_doorbells->doorbell_bitmap);
> +		DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", r);
> +		return r;
> +	}
> +
> +	return 0;
> +}
> +
>  /*
>   * GPU doorbell aperture helpers function.
>   */
> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>  		adev->doorbell.base = 0;
>  		adev->doorbell.size = 0;
>  		adev->doorbell.num_kernel_doorbells = 0;
> -		adev->doorbell.ptr = NULL;
>  		return 0;
>  	}
>  
> @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>  	if (adev->asic_type >= CHIP_VEGA10)
>  		adev->doorbell.num_kernel_doorbells += 0x400;
>  
> -	adev->doorbell.ptr = ioremap(adev->doorbell.base,
> -				     adev->doorbell.num_kernel_doorbells *
> -				     sizeof(u32));
> -	if (adev->doorbell.ptr == NULL)
> -		return -ENOMEM;
> -
> +	adev->doorbell.ptr = ioremap(adev->doorbell.base, adev->doorbell.size);
>  	return 0;
>  }
>  
> @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>   */
>  void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>  {
> -	iounmap(adev->doorbell.ptr);
> -	adev->doorbell.ptr = NULL;
> +	bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
> +	amdgpu_doorbell_free_page(adev, &adev->doorbell.kernel_doorbells);
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 203d77a20507..75c6852845c4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>  		return r;
>  	}
>  
> +	/* Create a boorbell page for kernel usages */
> +	r = amdgpu_doorbell_create_kernel_doorbells(adev);
> +	if (r) {
> +		DRM_ERROR("Failed to initialize kernel doorbells. \n");
> +		return r;
> +	}
> +
>  	/* Initialize preemptible memory pool */
>  	r = amdgpu_preempt_mgr_init(adev);
>  	if (r) {


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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-29 15:47 ` [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages Shashank Sharma
  2023-03-30 11:29   ` Christian König
  2023-03-30 13:42   ` Luben Tuikov
@ 2023-03-30 14:28   ` Alex Deucher
  2023-03-30 14:38     ` Luben Tuikov
  2 siblings, 1 reply; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 14:28 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian Koenig

On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch adds helper functions to create and free doorbell
> pages for kernel objects.

I think we can probably drop this patch.  I think it would be simpler
to just use standard amdgpu_bos to represent them and then maybe a
helper function to calculate the BAR offset from a doorbell bo object.

Alex

>
> 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_doorbell.h  | 41 ++++++++++++++++
>  .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>  2 files changed, 90 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index f9c3b77bf65d..6581b78fe438 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -27,6 +27,24 @@
>  /*
>   * GPU doorbell structures, functions & helpers
>   */
> +
> +/* Structure to hold doorbell pages from PCI doorbell BAR */
> +struct amdgpu_doorbell_obj {
> +       struct amdgpu_bo *bo;
> +       uint64_t gpu_addr;
> +       uint32_t *cpu_addr;
> +       uint32_t size;
> +
> +       /* First index in this object */
> +       uint32_t start;
> +
> +       /* Last index in this object */
> +       uint32_t end;
> +
> +       /* bitmap for dynamic doorbell allocation from this object */
> +       unsigned long *doorbell_bitmap;
> +};
> +
>  struct amdgpu_doorbell {
>         /* doorbell mmio */
>         resource_size_t         base;
> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>   */
>  void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>
> +/**
> + * amdgpu_doorbell_free_page - Free a doorbell page
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: previously allocated doobell page details
> + *
> + */
> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
> +                               struct amdgpu_doorbell_obj *db_obj);
> +
> +/**
> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: doobell page structure to fill details with
> + *
> + * returns 0 on success, else error number
> + */
> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> +                               struct amdgpu_doorbell_obj *db_obj);
> +
>  #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>  #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>  #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> index 1aea92363fd3..8be15b82b545 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>         }
>  }
>
> +/**
> + * amdgpu_doorbell_free_page - Free a doorbell page
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: previously allocated doobell page details
> + *
> + */
> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
> +                                       struct amdgpu_doorbell_obj *db_obj)
> +{
> +       amdgpu_bo_free_kernel(&db_obj->bo,
> +                             &db_obj->gpu_addr,
> +                             (void **)&db_obj->cpu_addr);
> +
> +}
> +
> +/**
> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_age: doobell page structure to fill details with
> + *
> + * returns 0 on success, else error number
> + */
> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> +                               struct amdgpu_doorbell_obj *db_obj)
> +{
> +       int r;
> +
> +       db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
> +
> +       r = amdgpu_bo_create_kernel(adev,
> +                                   db_obj->size,
> +                                   PAGE_SIZE,
> +                                   AMDGPU_GEM_DOMAIN_DOORBELL,
> +                                   &db_obj->bo,
> +                                   &db_obj->gpu_addr,
> +                                   (void **)&db_obj->cpu_addr);
> +
> +       if (r) {
> +               DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
> +               return r;
> +       }
> +
> +       return 0;
> +}
> +
>  /*
>   * GPU doorbell aperture helpers function.
>   */
> --
> 2.40.0
>

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

* Re: [PATCH 08/16] drm/amdgpu: initialize ttm for doorbells
  2023-03-29 15:47 ` [PATCH 08/16] drm/amdgpu: initialize ttm for doorbells Shashank Sharma
  2023-03-30 11:22   ` Christian König
@ 2023-03-30 14:33   ` Alex Deucher
  2023-03-30 14:54     ` Shashank Sharma
  1 sibling, 1 reply; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 14:33 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian Koenig

On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
> From: Shashank Sharma <contactshashanksharma@gmail.com>
>
> This patch initialzes the ttm resource manager for doorbells.
>
> 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_ttm.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 6f61491ef3dd..203d77a20507 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1858,6 +1858,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>         DRM_INFO("amdgpu: %uM of GTT memory ready.\n",
>                  (unsigned)(gtt_size / (1024 * 1024)));
>
> +       /* Initiailize doorbell pool on PCI BAR */
> +       r = amdgpu_ttm_init_on_chip(adev, AMDGPU_PL_DOORBELL,
> +                                   DIV_ROUND_UP(adev->doorbell.size, PAGE_SIZE));

In practice this would never be an issue since the PCI BAR is always
at least 2M, but I think we probably don't want to round up here?  I
guess large pages would be a problem, but so would going beyond the
BAR.

Alex

> +       if (r) {
> +               DRM_ERROR("Failed initializing doorbell heap. \n");
> +               return r;
> +       }
> +
>         /* Initialize preemptible memory pool */
>         r = amdgpu_preempt_mgr_init(adev);
>         if (r) {
> --
> 2.40.0
>

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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 14:15       ` Luben Tuikov
@ 2023-03-30 14:34         ` Shashank Sharma
  2023-03-30 14:37           ` Luben Tuikov
  2023-03-30 14:55           ` Alex Deucher
  0 siblings, 2 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 14:34 UTC (permalink / raw)
  To: Luben Tuikov, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig


On 30/03/2023 16:15, Luben Tuikov wrote:
> On 2023-03-30 10:04, Shashank Sharma wrote:
>> On 30/03/2023 15:42, Luben Tuikov wrote:
>>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>
>>>> This patch adds helper functions to create and free doorbell
>>>> pages for kernel objects.
>>>>
>>>> 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_doorbell.h  | 41 ++++++++++++++++
>>>>    .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>>>>    2 files changed, 90 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> index f9c3b77bf65d..6581b78fe438 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> @@ -27,6 +27,24 @@
>>>>    /*
>>>>     * GPU doorbell structures, functions & helpers
>>>>     */
>>>> +
>>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>>>> +struct amdgpu_doorbell_obj {
>>> In the comment you say "Structure to hold ...";
>>> it is a C structure, but then in the name of a function we see "obj".
>>> (Object is something which is defined like in memory, i.e. it exists, not
>>> something which is only declared.)
>>> This is just a declaration of a structure, not an object per se.
>>> I'd call it "struct amdgpu_doorbell_struct" or just "struct amdgpu_doorbell".
>> It is similar to struct amdgpu buffer object (struct amdgpu_bo), and
>> many more existing structure.
> The amdpgu_bo is very different than a structure describing a doorbell.
> The doorbell description isn't really "an object". I understand
> the enthusiasm, but it is really not "an object". It's just a doorbell
> description. :-)

amdgpu_bo is page of ttm_memory with additional information,

amdgpu_doorbell_obj is a page of ttm_doorbells with additional information

(it is not just one doorbell description)

I don't see a problem here.

- Shashank

>
> Regards,
> Luben
>
>> - Shashank
>>
>>> Then in the definition, you can call it an object/objects, if you'd like,
>>> like "struct amdgpu_doorbell *doorb_object[];" then you can say
>>> "db = doorb_object[i]";
>>>
>>> Regards,
>>> Luben
>>>
>>>> +	struct amdgpu_bo *bo;
>>>> +	uint64_t gpu_addr;
>>>> +	uint32_t *cpu_addr;
>>>> +	uint32_t size;
>>>> +
>>>> +	/* First index in this object */
>>>> +	uint32_t start;
>>>> +
>>>> +	/* Last index in this object */
>>>> +	uint32_t end;
>>>> +
>>>> +	/* bitmap for dynamic doorbell allocation from this object */
>>>> +	unsigned long *doorbell_bitmap;
>>>> +};
>>>> +
>>>>    struct amdgpu_doorbell {
>>>>    	/* doorbell mmio */
>>>>    	resource_size_t		base;
>>>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>>>>     */
>>>>    void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>>>>    
>>>> +/**
>>>> + * amdgpu_doorbell_free_page - Free a doorbell page
>>>> + *
>>>> + * @adev: amdgpu_device pointer
>>>> + *
>>>> + * @db_age: previously allocated doobell page details
>>>> + *
>>>> + */
>>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>>> +				struct amdgpu_doorbell_obj *db_obj);
>>>> +
>>>> +/**
>>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>>>> + *
>>>> + * @adev: amdgpu_device pointer
>>>> + *
>>>> + * @db_age: doobell page structure to fill details with
>>>> + *
>>>> + * returns 0 on success, else error number
>>>> + */
>>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>> +				struct amdgpu_doorbell_obj *db_obj);
>>>> +
>>>>    #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>    #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>>>    #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> index 1aea92363fd3..8be15b82b545 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>>>    	}
>>>>    }
>>>>    
>>>> +/**
>>>> + * amdgpu_doorbell_free_page - Free a doorbell page
>>>> + *
>>>> + * @adev: amdgpu_device pointer
>>>> + *
>>>> + * @db_age: previously allocated doobell page details
>>>> + *
>>>> + */
>>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>>> +					struct amdgpu_doorbell_obj *db_obj)
>>>> +{
>>>> +	amdgpu_bo_free_kernel(&db_obj->bo,
>>>> +			      &db_obj->gpu_addr,
>>>> +			      (void **)&db_obj->cpu_addr);
>>>> +
>>>> +}
>>>> +
>>>> +/**
>>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>>>> + *
>>>> + * @adev: amdgpu_device pointer
>>>> + *
>>>> + * @db_age: doobell page structure to fill details with
>>>> + *
>>>> + * returns 0 on success, else error number
>>>> + */
>>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>> +				struct amdgpu_doorbell_obj *db_obj)
>>>> +{
>>>> +	int r;
>>>> +
>>>> +	db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
>>>> +
>>>> +	r = amdgpu_bo_create_kernel(adev,
>>>> +				    db_obj->size,
>>>> +				    PAGE_SIZE,
>>>> +				    AMDGPU_GEM_DOMAIN_DOORBELL,
>>>> +				    &db_obj->bo,
>>>> +				    &db_obj->gpu_addr,
>>>> +				    (void **)&db_obj->cpu_addr);
>>>> +
>>>> +	if (r) {
>>>> +		DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
>>>> +		return r;
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>>    /*
>>>>     * GPU doorbell aperture helpers function.
>>>>     */

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

* Re: [PATCH 10/16] drm/amdgpu: validate doorbell read/write
  2023-03-29 15:47 ` [PATCH 10/16] drm/amdgpu: validate doorbell read/write Shashank Sharma
@ 2023-03-30 14:34   ` Luben Tuikov
  2023-03-30 14:37     ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 14:34 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig,
	Arvind Yadav

On 2023-03-29 11:47, Shashank Sharma wrote:
> This patch:
> - updates start/end values for each of the doorbell object
>   created.
> - adds a function which validates that the kernel doorbell read/write
>   is within this range.
> - uses this function during doorbell writes from kernel.
> 
> 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>
> ---
>  .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 29 ++++++++++++++++---
>  1 file changed, 25 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> index b46fe8b1378d..81713b2c28e1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -22,6 +22,25 @@
>   */
>  
>  #include "amdgpu.h"
> +#include "kfd_priv.h"
> +
> +static inline
> +bool amdgpu_doorbell_valid(struct amdgpu_device *adev, u32 index)
> +{
> +	if (index >= adev->doorbell.kernel_doorbells.start &&
> +	    index < adev->doorbell.kernel_doorbells.end)
> +		return true;
> +
> +	if (index >= adev->mes.kernel_doorbells.start &&
> +	    index < adev->mes.kernel_doorbells.end)
> +		return true;
> +
> +	if (index >= adev->kfd.dev->kernel_doorbells.start &&
> +	    index < adev->kfd.dev->kernel_doorbells.end)
> +		return true;
> +
> +	return false;
> +}

Here you're excluding "end".

In patch 7 we see this:
> +	/* Last index in this object */
> +	uint32_t end;

Which implies that "end" is included, but in this patch, the code excludes it.
Perhaps you intended to use "index <= ...end" here?

Since this isn't RTL, wouldn't it be better to describe the doorbell instance,
with a "start" and "size"? This is traditionally used in memory management,
and it makes comparisons and checks easy.

Regards,
Luben


>  
>  /**
>   * amdgpu_mm_rdoorbell - read a doorbell dword
> @@ -37,7 +56,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return 0;
>  
> -	if (index < adev->doorbell.num_kernel_doorbells) {
> +	if (amdgpu_doorbell_valid(adev, index)) {
>  		return readl(adev->doorbell.ptr + index);
>  	} else {
>  		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> @@ -60,7 +79,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return;
>  
> -	if (index < adev->doorbell.num_kernel_doorbells) {
> +	if (amdgpu_doorbell_valid(adev, index)) {
>  		writel(v, adev->doorbell.ptr + index);
>  	} else {
>  		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> @@ -81,7 +100,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return 0;
>  
> -	if (index < adev->doorbell.num_kernel_doorbells) {
> +	if (amdgpu_doorbell_valid(adev, index)) {
>  		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>  	} else {
>  		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> @@ -104,7 +123,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return;
>  
> -	if (index < adev->doorbell.num_kernel_doorbells) {
> +	if (amdgpu_doorbell_valid(adev, index)) {
>  		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>  	} else {
>  		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> @@ -157,6 +176,8 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>  		return r;
>  	}
>  
> +	db_obj->start = amdgpu_doorbell_index_on_bar(adev, db_obj->bo, 0);
> +	db_obj->end = db_obj->start + db_obj->size / sizeof(u32);
>  	return 0;
>  }
>  


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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 14:34         ` Shashank Sharma
@ 2023-03-30 14:37           ` Luben Tuikov
  2023-03-30 14:55           ` Alex Deucher
  1 sibling, 0 replies; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 14:37 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

On 2023-03-30 10:34, Shashank Sharma wrote:
> 
> On 30/03/2023 16:15, Luben Tuikov wrote:
>> On 2023-03-30 10:04, Shashank Sharma wrote:
>>> On 30/03/2023 15:42, Luben Tuikov wrote:
>>>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>>
>>>>> This patch adds helper functions to create and free doorbell
>>>>> pages for kernel objects.
>>>>>
>>>>> 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_doorbell.h  | 41 ++++++++++++++++
>>>>>    .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>>>>>    2 files changed, 90 insertions(+)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>> index f9c3b77bf65d..6581b78fe438 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>> @@ -27,6 +27,24 @@
>>>>>    /*
>>>>>     * GPU doorbell structures, functions & helpers
>>>>>     */
>>>>> +
>>>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>>>>> +struct amdgpu_doorbell_obj {
>>>> In the comment you say "Structure to hold ...";
>>>> it is a C structure, but then in the name of a function we see "obj".
>>>> (Object is something which is defined like in memory, i.e. it exists, not
>>>> something which is only declared.)
>>>> This is just a declaration of a structure, not an object per se.
>>>> I'd call it "struct amdgpu_doorbell_struct" or just "struct amdgpu_doorbell".
>>> It is similar to struct amdgpu buffer object (struct amdgpu_bo), and
>>> many more existing structure.
>> The amdpgu_bo is very different than a structure describing a doorbell.
>> The doorbell description isn't really "an object". I understand
>> the enthusiasm, but it is really not "an object". It's just a doorbell
>> description. :-)
> 
> amdgpu_bo is page of ttm_memory with additional information,
> 
> amdgpu_doorbell_obj is a page of ttm_doorbells with additional information
> 
> (it is not just one doorbell description)
> 
> I don't see a problem here.

There is no problem, it just descriptively may be confusing to future
maintainers and readers.

If amdgpu_doobell_obj stores a page/pages maybe "amdgpu_doorbell_bo"
would be more descriptive.

I'm merely trying to find the closest descriptive name, since
this not being C++, using "obj" is confusing.

Regards,
Luben

> 
> - Shashank
> 
>>
>> Regards,
>> Luben
>>
>>> - Shashank
>>>
>>>> Then in the definition, you can call it an object/objects, if you'd like,
>>>> like "struct amdgpu_doorbell *doorb_object[];" then you can say
>>>> "db = doorb_object[i]";
>>>>
>>>> Regards,
>>>> Luben
>>>>
>>>>> +	struct amdgpu_bo *bo;
>>>>> +	uint64_t gpu_addr;
>>>>> +	uint32_t *cpu_addr;
>>>>> +	uint32_t size;
>>>>> +
>>>>> +	/* First index in this object */
>>>>> +	uint32_t start;
>>>>> +
>>>>> +	/* Last index in this object */
>>>>> +	uint32_t end;
>>>>> +
>>>>> +	/* bitmap for dynamic doorbell allocation from this object */
>>>>> +	unsigned long *doorbell_bitmap;
>>>>> +};
>>>>> +
>>>>>    struct amdgpu_doorbell {
>>>>>    	/* doorbell mmio */
>>>>>    	resource_size_t		base;
>>>>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>>>>>     */
>>>>>    void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>>>>>    
>>>>> +/**
>>>>> + * amdgpu_doorbell_free_page - Free a doorbell page
>>>>> + *
>>>>> + * @adev: amdgpu_device pointer
>>>>> + *
>>>>> + * @db_age: previously allocated doobell page details
>>>>> + *
>>>>> + */
>>>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>>>> +				struct amdgpu_doorbell_obj *db_obj);
>>>>> +
>>>>> +/**
>>>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>>>>> + *
>>>>> + * @adev: amdgpu_device pointer
>>>>> + *
>>>>> + * @db_age: doobell page structure to fill details with
>>>>> + *
>>>>> + * returns 0 on success, else error number
>>>>> + */
>>>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>> +				struct amdgpu_doorbell_obj *db_obj);
>>>>> +
>>>>>    #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>>    #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>>>>    #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>> index 1aea92363fd3..8be15b82b545 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>>>>    	}
>>>>>    }
>>>>>    
>>>>> +/**
>>>>> + * amdgpu_doorbell_free_page - Free a doorbell page
>>>>> + *
>>>>> + * @adev: amdgpu_device pointer
>>>>> + *
>>>>> + * @db_age: previously allocated doobell page details
>>>>> + *
>>>>> + */
>>>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>>>> +					struct amdgpu_doorbell_obj *db_obj)
>>>>> +{
>>>>> +	amdgpu_bo_free_kernel(&db_obj->bo,
>>>>> +			      &db_obj->gpu_addr,
>>>>> +			      (void **)&db_obj->cpu_addr);
>>>>> +
>>>>> +}
>>>>> +
>>>>> +/**
>>>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>>>>> + *
>>>>> + * @adev: amdgpu_device pointer
>>>>> + *
>>>>> + * @db_age: doobell page structure to fill details with
>>>>> + *
>>>>> + * returns 0 on success, else error number
>>>>> + */
>>>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>> +				struct amdgpu_doorbell_obj *db_obj)
>>>>> +{
>>>>> +	int r;
>>>>> +
>>>>> +	db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
>>>>> +
>>>>> +	r = amdgpu_bo_create_kernel(adev,
>>>>> +				    db_obj->size,
>>>>> +				    PAGE_SIZE,
>>>>> +				    AMDGPU_GEM_DOMAIN_DOORBELL,
>>>>> +				    &db_obj->bo,
>>>>> +				    &db_obj->gpu_addr,
>>>>> +				    (void **)&db_obj->cpu_addr);
>>>>> +
>>>>> +	if (r) {
>>>>> +		DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
>>>>> +		return r;
>>>>> +	}
>>>>> +
>>>>> +	return 0;
>>>>> +}
>>>>> +
>>>>>    /*
>>>>>     * GPU doorbell aperture helpers function.
>>>>>     */


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

* Re: [PATCH 10/16] drm/amdgpu: validate doorbell read/write
  2023-03-30 14:34   ` Luben Tuikov
@ 2023-03-30 14:37     ` Shashank Sharma
  2023-03-30 14:49       ` Luben Tuikov
  0 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 14:37 UTC (permalink / raw)
  To: Luben Tuikov, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig,
	Arvind Yadav


On 30/03/2023 16:34, Luben Tuikov wrote:
> On 2023-03-29 11:47, Shashank Sharma wrote:
>> This patch:
>> - updates start/end values for each of the doorbell object
>>    created.
>> - adds a function which validates that the kernel doorbell read/write
>>    is within this range.
>> - uses this function during doorbell writes from kernel.
>>
>> 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>
>> ---
>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 29 ++++++++++++++++---
>>   1 file changed, 25 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> index b46fe8b1378d..81713b2c28e1 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> @@ -22,6 +22,25 @@
>>    */
>>   
>>   #include "amdgpu.h"
>> +#include "kfd_priv.h"
>> +
>> +static inline
>> +bool amdgpu_doorbell_valid(struct amdgpu_device *adev, u32 index)
>> +{
>> +	if (index >= adev->doorbell.kernel_doorbells.start &&
>> +	    index < adev->doorbell.kernel_doorbells.end)
>> +		return true;
>> +
>> +	if (index >= adev->mes.kernel_doorbells.start &&
>> +	    index < adev->mes.kernel_doorbells.end)
>> +		return true;
>> +
>> +	if (index >= adev->kfd.dev->kernel_doorbells.start &&
>> +	    index < adev->kfd.dev->kernel_doorbells.end)
>> +		return true;
>> +
>> +	return false;
>> +}
> Here you're excluding "end".
>
> In patch 7 we see this:
>> +	/* Last index in this object */
>> +	uint32_t end;
> Which implies that "end" is included, but in this patch, the code excludes it.
> Perhaps you intended to use "index <= ...end" here?

No, this is intended, same as array object calculation.

end = start + size;

max = start + size - 1

so (< end) not (<= end)

end says last index in this doorbell range;

- Shashank

>
> Since this isn't RTL, wouldn't it be better to describe the doorbell instance,
> with a "start" and "size"? This is traditionally used in memory management,
> and it makes comparisons and checks easy.
>
> Regards,
> Luben
>
>
>>   
>>   /**
>>    * amdgpu_mm_rdoorbell - read a doorbell dword
>> @@ -37,7 +56,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>>   	if (amdgpu_device_skip_hw_access(adev))
>>   		return 0;
>>   
>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>   		return readl(adev->doorbell.ptr + index);
>>   	} else {
>>   		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> @@ -60,7 +79,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>>   	if (amdgpu_device_skip_hw_access(adev))
>>   		return;
>>   
>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>   		writel(v, adev->doorbell.ptr + index);
>>   	} else {
>>   		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> @@ -81,7 +100,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>>   	if (amdgpu_device_skip_hw_access(adev))
>>   		return 0;
>>   
>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>   		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>>   	} else {
>>   		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> @@ -104,7 +123,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>   	if (amdgpu_device_skip_hw_access(adev))
>>   		return;
>>   
>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>   		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>>   	} else {
>>   		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> @@ -157,6 +176,8 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>   		return r;
>>   	}
>>   
>> +	db_obj->start = amdgpu_doorbell_index_on_bar(adev, db_obj->bo, 0);
>> +	db_obj->end = db_obj->start + db_obj->size / sizeof(u32);
>>   	return 0;
>>   }
>>   

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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 14:28   ` Alex Deucher
@ 2023-03-30 14:38     ` Luben Tuikov
  0 siblings, 0 replies; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 14:38 UTC (permalink / raw)
  To: Alex Deucher, Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian Koenig

On 2023-03-30 10:28, Alex Deucher wrote:
> On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
> <shashank.sharma@amd.com> wrote:
>>
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch adds helper functions to create and free doorbell
>> pages for kernel objects.
> 
> I think we can probably drop this patch.  I think it would be simpler
> to just use standard amdgpu_bos to represent them and then maybe a
> helper function to calculate the BAR offset from a doorbell bo object.

I agree.

Regards,
Luben

> 
> Alex
> 
>>
>> 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_doorbell.h  | 41 ++++++++++++++++
>>  .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>>  2 files changed, 90 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index f9c3b77bf65d..6581b78fe438 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -27,6 +27,24 @@
>>  /*
>>   * GPU doorbell structures, functions & helpers
>>   */
>> +
>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>> +struct amdgpu_doorbell_obj {
>> +       struct amdgpu_bo *bo;
>> +       uint64_t gpu_addr;
>> +       uint32_t *cpu_addr;
>> +       uint32_t size;
>> +
>> +       /* First index in this object */
>> +       uint32_t start;
>> +
>> +       /* Last index in this object */
>> +       uint32_t end;
>> +
>> +       /* bitmap for dynamic doorbell allocation from this object */
>> +       unsigned long *doorbell_bitmap;
>> +};
>> +
>>  struct amdgpu_doorbell {
>>         /* doorbell mmio */
>>         resource_size_t         base;
>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>>   */
>>  void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>>
>> +/**
>> + * amdgpu_doorbell_free_page - Free a doorbell page
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: previously allocated doobell page details
>> + *
>> + */
>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>> +                               struct amdgpu_doorbell_obj *db_obj);
>> +
>> +/**
>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: doobell page structure to fill details with
>> + *
>> + * returns 0 on success, else error number
>> + */
>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>> +                               struct amdgpu_doorbell_obj *db_obj);
>> +
>>  #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>  #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>  #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> index 1aea92363fd3..8be15b82b545 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>         }
>>  }
>>
>> +/**
>> + * amdgpu_doorbell_free_page - Free a doorbell page
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: previously allocated doobell page details
>> + *
>> + */
>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>> +                                       struct amdgpu_doorbell_obj *db_obj)
>> +{
>> +       amdgpu_bo_free_kernel(&db_obj->bo,
>> +                             &db_obj->gpu_addr,
>> +                             (void **)&db_obj->cpu_addr);
>> +
>> +}
>> +
>> +/**
>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_age: doobell page structure to fill details with
>> + *
>> + * returns 0 on success, else error number
>> + */
>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>> +                               struct amdgpu_doorbell_obj *db_obj)
>> +{
>> +       int r;
>> +
>> +       db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
>> +
>> +       r = amdgpu_bo_create_kernel(adev,
>> +                                   db_obj->size,
>> +                                   PAGE_SIZE,
>> +                                   AMDGPU_GEM_DOMAIN_DOORBELL,
>> +                                   &db_obj->bo,
>> +                                   &db_obj->gpu_addr,
>> +                                   (void **)&db_obj->cpu_addr);
>> +
>> +       if (r) {
>> +               DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
>> +               return r;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>>  /*
>>   * GPU doorbell aperture helpers function.
>>   */
>> --
>> 2.40.0
>>


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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 11:48     ` Shashank Sharma
@ 2023-03-30 14:39       ` Alex Deucher
  2023-03-30 14:42         ` Christian König
  0 siblings, 1 reply; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 14:39 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian König

On Thu, Mar 30, 2023 at 7:49 AM Shashank Sharma <shashank.sharma@amd.com> wrote:
>
>
> On 30/03/2023 13:30, Christian König wrote:
> >
> >
> > Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> >> From: Shashank Sharma <contactshashanksharma@gmail.com>
> >>
> >> This patch:
> >> - creates a doorbell page for graphics driver usages.
> >> - removes the adev->doorbell.ptr variable, replaces it with
> >>    kernel-doorbell-bo's cpu address.
> >>
> >> 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_doorbell.h  | 16 ++++++-
> >>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 +++++++++++++++----
> >>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
> >>   3 files changed, 57 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >> index 6581b78fe438..10a9bb10e974 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
> >>       /* doorbell mmio */
> >>       resource_size_t        base;
> >>       resource_size_t        size;
> >> -    u32 __iomem        *ptr;
> >> +    u32    __iomem        *ptr;
> >
> > This one can probably go away if we use the pointer from
> > amdgpu_bo_create_kernel().
>
> We started like that, but later realized that the cpu_addr from
> create_kernel() will just limit us
>
> to that object only, whereas we are keeping this ptr to ioremap the
> whole doorbell space in one shot.

Why do we need that?  For the kernel driver, we'd only need to mmap
the page used for kernel doorbells.  Then each user app would mmap its
doorbell page.

Alex

>
> - Shashank
>
> >
> >>         /* Number of doorbells reserved for amdgpu kernel driver */
> >>       u32 num_kernel_doorbells;
> >> +
> >> +    /* For kernel doorbell pages */
> >> +    struct amdgpu_doorbell_obj kernel_doorbells;
> >>   };
> >>     /* Reserved doorbells for amdgpu (including multimedia).
> >> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct
> >> amdgpu_device *adev,
> >>   int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> >>                   struct amdgpu_doorbell_obj *db_obj);
> >>   +/**
> >> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells
> >> for graphics
> >> + *
> >> + * @adev: amdgpu_device pointer
> >> + *
> >> + * Creates doorbells for graphics driver
> >> + *
> >> + * returns 0 on success, error otherwise.
> >> + */
> >> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device
> >> *adev);
> >> +
> >>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
> >>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
> >>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >> index 8be15b82b545..b46fe8b1378d 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct
> >> amdgpu_device *adev,
> >>       return 0;
> >>   }
> >>   +/**
> >> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells
> >> for graphics
> >> + *
> >> + * @adev: amdgpu_device pointer
> >> + *
> >> + * Creates doorbells for graphics driver
> >> + *
> >> + * returns 0 on success, error otherwise.
> >> + */
> >> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev)
> >> +{
> >> +    int r;
> >> +    struct amdgpu_doorbell_obj *kernel_doorbells =
> >> &adev->doorbell.kernel_doorbells;
> >> +
> >> +    kernel_doorbells->doorbell_bitmap =
> >> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
> >> +                              GFP_KERNEL);
> >> +    if (!kernel_doorbells->doorbell_bitmap) {
> >> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
> >> +        return -ENOMEM;
> >> +    }
> >> +
> >> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells *
> >> sizeof(u32);
> >> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
> >> +    if (r) {
> >> +        bitmap_free(kernel_doorbells->doorbell_bitmap);
> >> +        DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", r);
> >> +        return r;
> >> +    }
> >> +
> >> +    return 0;
> >> +}
> >> +
> >>   /*
> >>    * GPU doorbell aperture helpers function.
> >>    */
> >> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct
> >> amdgpu_device *adev)
> >>           adev->doorbell.base = 0;
> >>           adev->doorbell.size = 0;
> >>           adev->doorbell.num_kernel_doorbells = 0;
> >> -        adev->doorbell.ptr = NULL;
> >>           return 0;
> >>       }
> >>   @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct
> >> amdgpu_device *adev)
> >>       if (adev->asic_type >= CHIP_VEGA10)
> >>           adev->doorbell.num_kernel_doorbells += 0x400;
> >>   -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
> >> -                     adev->doorbell.num_kernel_doorbells *
> >> -                     sizeof(u32));
> >> -    if (adev->doorbell.ptr == NULL)
> >> -        return -ENOMEM;
> >> -
> >> +    adev->doorbell.ptr = ioremap(adev->doorbell.base,
> >> adev->doorbell.size);
> >>       return 0;
> >>   }
> >>   @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct
> >> amdgpu_device *adev)
> >>    */
> >>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
> >>   {
> >> -    iounmap(adev->doorbell.ptr);
> >> -    adev->doorbell.ptr = NULL;
> >> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
> >> +    amdgpu_doorbell_free_page(adev, &adev->doorbell.kernel_doorbells);
> >>   }
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> >> index 203d77a20507..75c6852845c4 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> >> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
> >>           return r;
> >>       }
> >>   +    /* Create a boorbell page for kernel usages */
> >> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
> >> +    if (r) {
> >> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
> >> +        return r;
> >> +    }
> >> +
> >>       /* Initialize preemptible memory pool */
> >>       r = amdgpu_preempt_mgr_init(adev);
> >>       if (r) {
> >

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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 14:24   ` Luben Tuikov
@ 2023-03-30 14:40     ` Shashank Sharma
  2023-03-30 14:49       ` Christian König
  0 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 14:40 UTC (permalink / raw)
  To: Luben Tuikov, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig


On 30/03/2023 16:24, Luben Tuikov wrote:
> On 2023-03-29 11:47, Shashank Sharma wrote:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch:
>> - creates a doorbell page for graphics driver usages.
>> - removes the adev->doorbell.ptr variable, replaces it with
>>    kernel-doorbell-bo's cpu address.
>>
>> 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_doorbell.h  | 16 ++++++-
>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 +++++++++++++++----
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>   3 files changed, 57 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index 6581b78fe438..10a9bb10e974 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>   	/* doorbell mmio */
>>   	resource_size_t		base;
>>   	resource_size_t		size;
>> -	u32 __iomem		*ptr;
>> +	u32	__iomem		*ptr;
>>   
>>   	/* Number of doorbells reserved for amdgpu kernel driver */
>>   	u32 num_kernel_doorbells;
>> +
>> +	/* For kernel doorbell pages */
>> +	struct amdgpu_doorbell_obj kernel_doorbells;
>>   };
> Here's an example where it could be confusing what the difference is
> between "struct amdgpu_doorbell" and "struct amdgpu_doobell_obj".
> As the comment to the struct doorbell_obj declarations says
> in patch 7,
>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>> +struct amdgpu_doorbell_obj {

What is the confusion ? This is the object which is holding doorbell 
page. There could be 2 type of

doorbell pages, kernel and process, this is a kernel one.

> Perhaps we should call it "struct amdgpu_doorbell_bo", since
> it does contain amdgpu_bo's, which are doorbell's bos.

This is not a buffer object (memory), this is doorbell object, so 
calling it bo would be wrong.

- Shashank

>
> Regards,
> Luben
>
>>   
>>   /* Reserved doorbells for amdgpu (including multimedia).
>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>   int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>   				struct amdgpu_doorbell_obj *db_obj);
>>   
>> +/**
>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells for graphics
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Creates doorbells for graphics driver
>> + *
>> + * returns 0 on success, error otherwise.
>> + */
>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev);
>> +
>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> index 8be15b82b545..b46fe8b1378d 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>   	return 0;
>>   }
>>   
>> +/**
>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells for graphics
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Creates doorbells for graphics driver
>> + *
>> + * returns 0 on success, error otherwise.
>> + */
>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev)
>> +{
>> +	int r;
>> +	struct amdgpu_doorbell_obj *kernel_doorbells = &adev->doorbell.kernel_doorbells;
>> +
>> +	kernel_doorbells->doorbell_bitmap = bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>> +							  GFP_KERNEL);
>> +	if (!kernel_doorbells->doorbell_bitmap) {
>> +		DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	kernel_doorbells->size = adev->doorbell.num_kernel_doorbells * sizeof(u32);
>> +	r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>> +	if (r) {
>> +		bitmap_free(kernel_doorbells->doorbell_bitmap);
>> +		DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", r);
>> +		return r;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>   /*
>>    * GPU doorbell aperture helpers function.
>>    */
>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>>   		adev->doorbell.base = 0;
>>   		adev->doorbell.size = 0;
>>   		adev->doorbell.num_kernel_doorbells = 0;
>> -		adev->doorbell.ptr = NULL;
>>   		return 0;
>>   	}
>>   
>> @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>>   	if (adev->asic_type >= CHIP_VEGA10)
>>   		adev->doorbell.num_kernel_doorbells += 0x400;
>>   
>> -	adev->doorbell.ptr = ioremap(adev->doorbell.base,
>> -				     adev->doorbell.num_kernel_doorbells *
>> -				     sizeof(u32));
>> -	if (adev->doorbell.ptr == NULL)
>> -		return -ENOMEM;
>> -
>> +	adev->doorbell.ptr = ioremap(adev->doorbell.base, adev->doorbell.size);
>>   	return 0;
>>   }
>>   
>> @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>>    */
>>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>   {
>> -	iounmap(adev->doorbell.ptr);
>> -	adev->doorbell.ptr = NULL;
>> +	bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>> +	amdgpu_doorbell_free_page(adev, &adev->doorbell.kernel_doorbells);
>>   }
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 203d77a20507..75c6852845c4 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>   		return r;
>>   	}
>>   
>> +	/* Create a boorbell page for kernel usages */
>> +	r = amdgpu_doorbell_create_kernel_doorbells(adev);
>> +	if (r) {
>> +		DRM_ERROR("Failed to initialize kernel doorbells. \n");
>> +		return r;
>> +	}
>> +
>>   	/* Initialize preemptible memory pool */
>>   	r = amdgpu_preempt_mgr_init(adev);
>>   	if (r) {

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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 14:39       ` Alex Deucher
@ 2023-03-30 14:42         ` Christian König
  2023-03-30 14:48           ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Christian König @ 2023-03-30 14:42 UTC (permalink / raw)
  To: Alex Deucher, Shashank Sharma
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma, amd-gfx

Am 30.03.23 um 16:39 schrieb Alex Deucher:
> On Thu, Mar 30, 2023 at 7:49 AM Shashank Sharma <shashank.sharma@amd.com> wrote:
>>
>> On 30/03/2023 13:30, Christian König wrote:
>>>
>>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>
>>>> This patch:
>>>> - creates a doorbell page for graphics driver usages.
>>>> - removes the adev->doorbell.ptr variable, replaces it with
>>>>     kernel-doorbell-bo's cpu address.
>>>>
>>>> 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_doorbell.h  | 16 ++++++-
>>>>    .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 +++++++++++++++----
>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>>>    3 files changed, 57 insertions(+), 10 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> index 6581b78fe438..10a9bb10e974 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>>>        /* doorbell mmio */
>>>>        resource_size_t        base;
>>>>        resource_size_t        size;
>>>> -    u32 __iomem        *ptr;
>>>> +    u32    __iomem        *ptr;
>>> This one can probably go away if we use the pointer from
>>> amdgpu_bo_create_kernel().
>> We started like that, but later realized that the cpu_addr from
>> create_kernel() will just limit us
>>
>> to that object only, whereas we are keeping this ptr to ioremap the
>> whole doorbell space in one shot.
> Why do we need that?  For the kernel driver, we'd only need to mmap
> the page used for kernel doorbells.  Then each user app would mmap its
> doorbell page.

Yes, that is exactly my concern as well.

The kernel needs a fixed number of doorbells allocated for its internal 
use. Everything else should probably use the normal BO API.

For KFD we can use the BO API internal in the kernel, but that is 
certainly completely different to the kernel allocations.

Christian.

>
> Alex
>
>> - Shashank
>>
>>>>          /* Number of doorbells reserved for amdgpu kernel driver */
>>>>        u32 num_kernel_doorbells;
>>>> +
>>>> +    /* For kernel doorbell pages */
>>>> +    struct amdgpu_doorbell_obj kernel_doorbells;
>>>>    };
>>>>      /* Reserved doorbells for amdgpu (including multimedia).
>>>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct
>>>> amdgpu_device *adev,
>>>>    int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>                    struct amdgpu_doorbell_obj *db_obj);
>>>>    +/**
>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells
>>>> for graphics
>>>> + *
>>>> + * @adev: amdgpu_device pointer
>>>> + *
>>>> + * Creates doorbells for graphics driver
>>>> + *
>>>> + * returns 0 on success, error otherwise.
>>>> + */
>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device
>>>> *adev);
>>>> +
>>>>    #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>    #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>>>    #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> index 8be15b82b545..b46fe8b1378d 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct
>>>> amdgpu_device *adev,
>>>>        return 0;
>>>>    }
>>>>    +/**
>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells
>>>> for graphics
>>>> + *
>>>> + * @adev: amdgpu_device pointer
>>>> + *
>>>> + * Creates doorbells for graphics driver
>>>> + *
>>>> + * returns 0 on success, error otherwise.
>>>> + */
>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev)
>>>> +{
>>>> +    int r;
>>>> +    struct amdgpu_doorbell_obj *kernel_doorbells =
>>>> &adev->doorbell.kernel_doorbells;
>>>> +
>>>> +    kernel_doorbells->doorbell_bitmap =
>>>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>>>> +                              GFP_KERNEL);
>>>> +    if (!kernel_doorbells->doorbell_bitmap) {
>>>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>>>> +        return -ENOMEM;
>>>> +    }
>>>> +
>>>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells *
>>>> sizeof(u32);
>>>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>>>> +    if (r) {
>>>> +        bitmap_free(kernel_doorbells->doorbell_bitmap);
>>>> +        DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", r);
>>>> +        return r;
>>>> +    }
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>>    /*
>>>>     * GPU doorbell aperture helpers function.
>>>>     */
>>>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct
>>>> amdgpu_device *adev)
>>>>            adev->doorbell.base = 0;
>>>>            adev->doorbell.size = 0;
>>>>            adev->doorbell.num_kernel_doorbells = 0;
>>>> -        adev->doorbell.ptr = NULL;
>>>>            return 0;
>>>>        }
>>>>    @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct
>>>> amdgpu_device *adev)
>>>>        if (adev->asic_type >= CHIP_VEGA10)
>>>>            adev->doorbell.num_kernel_doorbells += 0x400;
>>>>    -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>> -                     adev->doorbell.num_kernel_doorbells *
>>>> -                     sizeof(u32));
>>>> -    if (adev->doorbell.ptr == NULL)
>>>> -        return -ENOMEM;
>>>> -
>>>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>> adev->doorbell.size);
>>>>        return 0;
>>>>    }
>>>>    @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct
>>>> amdgpu_device *adev)
>>>>     */
>>>>    void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>>>    {
>>>> -    iounmap(adev->doorbell.ptr);
>>>> -    adev->doorbell.ptr = NULL;
>>>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>>>> +    amdgpu_doorbell_free_page(adev, &adev->doorbell.kernel_doorbells);
>>>>    }
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> index 203d77a20507..75c6852845c4 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>>>            return r;
>>>>        }
>>>>    +    /* Create a boorbell page for kernel usages */
>>>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
>>>> +    if (r) {
>>>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
>>>> +        return r;
>>>> +    }
>>>> +
>>>>        /* Initialize preemptible memory pool */
>>>>        r = amdgpu_preempt_mgr_init(adev);
>>>>        if (r) {


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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 14:42         ` Christian König
@ 2023-03-30 14:48           ` Shashank Sharma
  2023-03-30 14:53             ` Christian König
  2023-03-30 15:04             ` Alex Deucher
  0 siblings, 2 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 14:48 UTC (permalink / raw)
  To: Christian König, Alex Deucher
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma, amd-gfx


On 30/03/2023 16:42, Christian König wrote:
> Am 30.03.23 um 16:39 schrieb Alex Deucher:
>> On Thu, Mar 30, 2023 at 7:49 AM Shashank Sharma 
>> <shashank.sharma@amd.com> wrote:
>>>
>>> On 30/03/2023 13:30, Christian König wrote:
>>>>
>>>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>>
>>>>> This patch:
>>>>> - creates a doorbell page for graphics driver usages.
>>>>> - removes the adev->doorbell.ptr variable, replaces it with
>>>>>     kernel-doorbell-bo's cpu address.
>>>>>
>>>>> 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_doorbell.h  | 16 ++++++-
>>>>>    .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 
>>>>> +++++++++++++++----
>>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>>>>    3 files changed, 57 insertions(+), 10 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>> index 6581b78fe438..10a9bb10e974 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>>>>        /* doorbell mmio */
>>>>>        resource_size_t        base;
>>>>>        resource_size_t        size;
>>>>> -    u32 __iomem        *ptr;
>>>>> +    u32    __iomem        *ptr;
>>>> This one can probably go away if we use the pointer from
>>>> amdgpu_bo_create_kernel().
>>> We started like that, but later realized that the cpu_addr from
>>> create_kernel() will just limit us
>>>
>>> to that object only, whereas we are keeping this ptr to ioremap the
>>> whole doorbell space in one shot.
>> Why do we need that?  For the kernel driver, we'd only need to mmap
>> the page used for kernel doorbells.  Then each user app would mmap its
>> doorbell page.
>
> Yes, that is exactly my concern as well.
>
> The kernel needs a fixed number of doorbells allocated for its 
> internal use. Everything else should probably use the normal BO API.
>
> For KFD we can use the BO API internal in the kernel, but that is 
> certainly completely different to the kernel allocations.
>
There are 3 different kernel doorbell clients here:

- graphics driver

- mes (for aggregated doorbells and kernel ring test)

- kfd (for kernel ring test and KIQ)


The fix num_doorbells are just for kernel graphics driver, but We are 
allocating doorbell pages for each of those, and they all need to be 
mapped.

Please see patch 12-16 for these details.

- Shashank

> Christian.
>
>>
>> Alex
>>
>>> - Shashank
>>>
>>>>>          /* Number of doorbells reserved for amdgpu kernel driver */
>>>>>        u32 num_kernel_doorbells;
>>>>> +
>>>>> +    /* For kernel doorbell pages */
>>>>> +    struct amdgpu_doorbell_obj kernel_doorbells;
>>>>>    };
>>>>>      /* Reserved doorbells for amdgpu (including multimedia).
>>>>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct
>>>>> amdgpu_device *adev,
>>>>>    int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>>                    struct amdgpu_doorbell_obj *db_obj);
>>>>>    +/**
>>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells
>>>>> for graphics
>>>>> + *
>>>>> + * @adev: amdgpu_device pointer
>>>>> + *
>>>>> + * Creates doorbells for graphics driver
>>>>> + *
>>>>> + * returns 0 on success, error otherwise.
>>>>> + */
>>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device
>>>>> *adev);
>>>>> +
>>>>>    #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>>    #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, 
>>>>> (index), (v))
>>>>>    #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>> index 8be15b82b545..b46fe8b1378d 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct
>>>>> amdgpu_device *adev,
>>>>>        return 0;
>>>>>    }
>>>>>    +/**
>>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells
>>>>> for graphics
>>>>> + *
>>>>> + * @adev: amdgpu_device pointer
>>>>> + *
>>>>> + * Creates doorbells for graphics driver
>>>>> + *
>>>>> + * returns 0 on success, error otherwise.
>>>>> + */
>>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>>>>> *adev)
>>>>> +{
>>>>> +    int r;
>>>>> +    struct amdgpu_doorbell_obj *kernel_doorbells =
>>>>> &adev->doorbell.kernel_doorbells;
>>>>> +
>>>>> +    kernel_doorbells->doorbell_bitmap =
>>>>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>>>>> +                              GFP_KERNEL);
>>>>> +    if (!kernel_doorbells->doorbell_bitmap) {
>>>>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>>>>> +        return -ENOMEM;
>>>>> +    }
>>>>> +
>>>>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells *
>>>>> sizeof(u32);
>>>>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>>>>> +    if (r) {
>>>>> + bitmap_free(kernel_doorbells->doorbell_bitmap);
>>>>> +        DRM_ERROR("Failed to allocate kernel doorbells, 
>>>>> err=%d\n", r);
>>>>> +        return r;
>>>>> +    }
>>>>> +
>>>>> +    return 0;
>>>>> +}
>>>>> +
>>>>>    /*
>>>>>     * GPU doorbell aperture helpers function.
>>>>>     */
>>>>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct
>>>>> amdgpu_device *adev)
>>>>>            adev->doorbell.base = 0;
>>>>>            adev->doorbell.size = 0;
>>>>>            adev->doorbell.num_kernel_doorbells = 0;
>>>>> -        adev->doorbell.ptr = NULL;
>>>>>            return 0;
>>>>>        }
>>>>>    @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct
>>>>> amdgpu_device *adev)
>>>>>        if (adev->asic_type >= CHIP_VEGA10)
>>>>>            adev->doorbell.num_kernel_doorbells += 0x400;
>>>>>    -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>>> - adev->doorbell.num_kernel_doorbells *
>>>>> -                     sizeof(u32));
>>>>> -    if (adev->doorbell.ptr == NULL)
>>>>> -        return -ENOMEM;
>>>>> -
>>>>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>>> adev->doorbell.size);
>>>>>        return 0;
>>>>>    }
>>>>>    @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct
>>>>> amdgpu_device *adev)
>>>>>     */
>>>>>    void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>>>>    {
>>>>> -    iounmap(adev->doorbell.ptr);
>>>>> -    adev->doorbell.ptr = NULL;
>>>>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>>>>> +    amdgpu_doorbell_free_page(adev, 
>>>>> &adev->doorbell.kernel_doorbells);
>>>>>    }
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>> index 203d77a20507..75c6852845c4 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device 
>>>>> *adev)
>>>>>            return r;
>>>>>        }
>>>>>    +    /* Create a boorbell page for kernel usages */
>>>>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
>>>>> +    if (r) {
>>>>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
>>>>> +        return r;
>>>>> +    }
>>>>> +
>>>>>        /* Initialize preemptible memory pool */
>>>>>        r = amdgpu_preempt_mgr_init(adev);
>>>>>        if (r) {
>

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

* Re: [PATCH 10/16] drm/amdgpu: validate doorbell read/write
  2023-03-30 14:37     ` Shashank Sharma
@ 2023-03-30 14:49       ` Luben Tuikov
  2023-03-30 15:02         ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 14:49 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig,
	Arvind Yadav

On 2023-03-30 10:37, Shashank Sharma wrote:
> 
> On 30/03/2023 16:34, Luben Tuikov wrote:
>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>> This patch:
>>> - updates start/end values for each of the doorbell object
>>>    created.
>>> - adds a function which validates that the kernel doorbell read/write
>>>    is within this range.
>>> - uses this function during doorbell writes from kernel.
>>>
>>> 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>
>>> ---
>>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 29 ++++++++++++++++---
>>>   1 file changed, 25 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> index b46fe8b1378d..81713b2c28e1 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> @@ -22,6 +22,25 @@
>>>    */
>>>   
>>>   #include "amdgpu.h"
>>> +#include "kfd_priv.h"
>>> +
>>> +static inline
>>> +bool amdgpu_doorbell_valid(struct amdgpu_device *adev, u32 index)
>>> +{
>>> +	if (index >= adev->doorbell.kernel_doorbells.start &&
>>> +	    index < adev->doorbell.kernel_doorbells.end)
>>> +		return true;
>>> +
>>> +	if (index >= adev->mes.kernel_doorbells.start &&
>>> +	    index < adev->mes.kernel_doorbells.end)
>>> +		return true;
>>> +
>>> +	if (index >= adev->kfd.dev->kernel_doorbells.start &&
>>> +	    index < adev->kfd.dev->kernel_doorbells.end)
>>> +		return true;
>>> +
>>> +	return false;
>>> +}
>> Here you're excluding "end".
>>
>> In patch 7 we see this:
>>> +	/* Last index in this object */
>>> +	uint32_t end;
>> Which implies that "end" is included, but in this patch, the code excludes it.
>> Perhaps you intended to use "index <= ...end" here?
> 
> No, this is intended, same as array object calculation.
> 
> end = start + size;
> 
> max = start + size - 1

This I understand, but "end" is NEVER "start + size" in all
code written since 1969. "end" is outside the bounds and thus
never used like that.

"start" and "end" usage comes from RTL and is always inclusive,
and "end" always fits in the same sized register as that of "start".
But if you use "size" and add, it may overflow. So, enough history.

"end" is inclusive. If this is not the case in your implementation,
then please use "size".

> 
> so (< end) not (<= end)
> 
> end says last index in this doorbell range;

This I don't understand.

This isn't how "start" and "end" are being used.
Their usage comes from RTL, and is always inclusive.

Either use "start" and "size" or make "end" be inclusive.

I'd prefer using "start" and "size" as this is traditionally
what is done in memory management in software (not RTL).

However using "end" in software makes it tricky to calculate
size, and one always does "end-start+1", and this could lead
to bugs and errors.

Please use "start" and "size", then.

Regards,
Luben


> 
> - Shashank
> 
>>
>> Since this isn't RTL, wouldn't it be better to describe the doorbell instance,
>> with a "start" and "size"? This is traditionally used in memory management,
>> and it makes comparisons and checks easy.
>>
>> Regards,
>> Luben
>>
>>
>>>   
>>>   /**
>>>    * amdgpu_mm_rdoorbell - read a doorbell dword
>>> @@ -37,7 +56,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>>>   	if (amdgpu_device_skip_hw_access(adev))
>>>   		return 0;
>>>   
>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>>   		return readl(adev->doorbell.ptr + index);
>>>   	} else {
>>>   		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>>> @@ -60,7 +79,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>>>   	if (amdgpu_device_skip_hw_access(adev))
>>>   		return;
>>>   
>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>>   		writel(v, adev->doorbell.ptr + index);
>>>   	} else {
>>>   		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>>> @@ -81,7 +100,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>>>   	if (amdgpu_device_skip_hw_access(adev))
>>>   		return 0;
>>>   
>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>>   		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>>>   	} else {
>>>   		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>>> @@ -104,7 +123,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>>   	if (amdgpu_device_skip_hw_access(adev))
>>>   		return;
>>>   
>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>>   		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>>>   	} else {
>>>   		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>>> @@ -157,6 +176,8 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>   		return r;
>>>   	}
>>>   
>>> +	db_obj->start = amdgpu_doorbell_index_on_bar(adev, db_obj->bo, 0);
>>> +	db_obj->end = db_obj->start + db_obj->size / sizeof(u32);
>>>   	return 0;
>>>   }
>>>   


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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 14:40     ` Shashank Sharma
@ 2023-03-30 14:49       ` Christian König
  2023-03-30 14:52         ` Luben Tuikov
  2023-03-30 14:53         ` Shashank Sharma
  0 siblings, 2 replies; 87+ messages in thread
From: Christian König @ 2023-03-30 14:49 UTC (permalink / raw)
  To: Shashank Sharma, Luben Tuikov, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma

Am 30.03.23 um 16:40 schrieb Shashank Sharma:
>
> On 30/03/2023 16:24, Luben Tuikov wrote:
>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>
>>> This patch:
>>> - creates a doorbell page for graphics driver usages.
>>> - removes the adev->doorbell.ptr variable, replaces it with
>>>    kernel-doorbell-bo's cpu address.
>>>
>>> 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_doorbell.h  | 16 ++++++-
>>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 
>>> +++++++++++++++----
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>>   3 files changed, 57 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>> index 6581b78fe438..10a9bb10e974 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>>       /* doorbell mmio */
>>>       resource_size_t        base;
>>>       resource_size_t        size;
>>> -    u32 __iomem        *ptr;
>>> +    u32    __iomem        *ptr;
>>>         /* Number of doorbells reserved for amdgpu kernel driver */
>>>       u32 num_kernel_doorbells;
>>> +
>>> +    /* For kernel doorbell pages */
>>> +    struct amdgpu_doorbell_obj kernel_doorbells;
>>>   };
>> Here's an example where it could be confusing what the difference is
>> between "struct amdgpu_doorbell" and "struct amdgpu_doobell_obj".
>> As the comment to the struct doorbell_obj declarations says
>> in patch 7,
>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>>> +struct amdgpu_doorbell_obj {
>
> What is the confusion ? This is the object which is holding doorbell 
> page. There could be 2 type of
>
> doorbell pages, kernel and process, this is a kernel one.
>
>> Perhaps we should call it "struct amdgpu_doorbell_bo", since
>> it does contain amdgpu_bo's, which are doorbell's bos.
>
> This is not a buffer object (memory), this is doorbell object, so 
> calling it bo would be wrong.

I think what Luben means is that in object orient programming this here 
would be the class. The object is then the actual instantiation of that.

But I have some real doubts that this is the right approach in the first 
place.

Regards,
Christian.

>
> - Shashank
>
>>
>> Regards,
>> Luben
>>
>>>     /* Reserved doorbells for amdgpu (including multimedia).
>>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct 
>>> amdgpu_device *adev,
>>>   int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>                   struct amdgpu_doorbell_obj *db_obj);
>>>   +/**
>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel 
>>> doorbells for graphics
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + *
>>> + * Creates doorbells for graphics driver
>>> + *
>>> + * returns 0 on success, error otherwise.
>>> + */
>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>>> *adev);
>>> +
>>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> index 8be15b82b545..b46fe8b1378d 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct 
>>> amdgpu_device *adev,
>>>       return 0;
>>>   }
>>>   +/**
>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel 
>>> doorbells for graphics
>>> + *
>>> + * @adev: amdgpu_device pointer
>>> + *
>>> + * Creates doorbells for graphics driver
>>> + *
>>> + * returns 0 on success, error otherwise.
>>> + */
>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>>> *adev)
>>> +{
>>> +    int r;
>>> +    struct amdgpu_doorbell_obj *kernel_doorbells = 
>>> &adev->doorbell.kernel_doorbells;
>>> +
>>> +    kernel_doorbells->doorbell_bitmap = 
>>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>>> +                              GFP_KERNEL);
>>> +    if (!kernel_doorbells->doorbell_bitmap) {
>>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>>> +        return -ENOMEM;
>>> +    }
>>> +
>>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells * 
>>> sizeof(u32);
>>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>>> +    if (r) {
>>> +        bitmap_free(kernel_doorbells->doorbell_bitmap);
>>> +        DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", r);
>>> +        return r;
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>>   /*
>>>    * GPU doorbell aperture helpers function.
>>>    */
>>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct 
>>> amdgpu_device *adev)
>>>           adev->doorbell.base = 0;
>>>           adev->doorbell.size = 0;
>>>           adev->doorbell.num_kernel_doorbells = 0;
>>> -        adev->doorbell.ptr = NULL;
>>>           return 0;
>>>       }
>>>   @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct 
>>> amdgpu_device *adev)
>>>       if (adev->asic_type >= CHIP_VEGA10)
>>>           adev->doorbell.num_kernel_doorbells += 0x400;
>>>   -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>> -                     adev->doorbell.num_kernel_doorbells *
>>> -                     sizeof(u32));
>>> -    if (adev->doorbell.ptr == NULL)
>>> -        return -ENOMEM;
>>> -
>>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base, 
>>> adev->doorbell.size);
>>>       return 0;
>>>   }
>>>   @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct 
>>> amdgpu_device *adev)
>>>    */
>>>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>>   {
>>> -    iounmap(adev->doorbell.ptr);
>>> -    adev->doorbell.ptr = NULL;
>>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>>> +    amdgpu_doorbell_free_page(adev, &adev->doorbell.kernel_doorbells);
>>>   }
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> index 203d77a20507..75c6852845c4 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>>           return r;
>>>       }
>>>   +    /* Create a boorbell page for kernel usages */
>>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
>>> +    if (r) {
>>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
>>> +        return r;
>>> +    }
>>> +
>>>       /* Initialize preemptible memory pool */
>>>       r = amdgpu_preempt_mgr_init(adev);
>>>       if (r) {


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

* Re: [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager
  2023-03-30 14:23   ` Alex Deucher
@ 2023-03-30 14:49     ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 14:49 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian Koenig


On 30/03/2023 16:23, Alex Deucher wrote:
> On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
> <shashank.sharma@amd.com> wrote:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch:
>> - creates a new file for doorbell management.
>> - moves doorbell code from amdgpu_device.c to this file.
>>
>> 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/Makefile           |   2 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 164 ---------------
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h  |  22 +++
>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 186 ++++++++++++++++++
>>   4 files changed, 209 insertions(+), 165 deletions(-)
>>   create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
>> index 798d0e9a60b7..204665f20319 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
>> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
>> @@ -41,7 +41,7 @@ ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
>>   amdgpu-y := amdgpu_drv.o
>>
>>   # add KMS driver
>> -amdgpu-y += amdgpu_device.o amdgpu_kms.o \
>> +amdgpu-y += amdgpu_device.o amdgpu_doorbell_mgr.o amdgpu_kms.o \
>>          amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \
>>          atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \
>>          amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> index 57ee1c4a81e9..7f8fcac4f18b 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -579,94 +579,6 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev,
>>          }
>>   }
>>
>> -/**
>> - * amdgpu_mm_rdoorbell - read a doorbell dword
>> - *
>> - * @adev: amdgpu_device pointer
>> - * @index: doorbell index
>> - *
>> - * Returns the value in the doorbell aperture at the
>> - * requested doorbell index (CIK).
>> - */
>> -u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>> -{
>> -       if (amdgpu_device_skip_hw_access(adev))
>> -               return 0;
>> -
>> -       if (index < adev->doorbell.num_kernel_doorbells) {
>> -               return readl(adev->doorbell.ptr + index);
>> -       } else {
>> -               DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> -               return 0;
>> -       }
>> -}
>> -
>> -/**
>> - * amdgpu_mm_wdoorbell - write a doorbell dword
>> - *
>> - * @adev: amdgpu_device pointer
>> - * @index: doorbell index
>> - * @v: value to write
>> - *
>> - * Writes @v to the doorbell aperture at the
>> - * requested doorbell index (CIK).
>> - */
>> -void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>> -{
>> -       if (amdgpu_device_skip_hw_access(adev))
>> -               return;
>> -
>> -       if (index < adev->doorbell.num_kernel_doorbells) {
>> -               writel(v, adev->doorbell.ptr + index);
>> -       } else {
>> -               DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> -       }
>> -}
>> -
>> -/**
>> - * amdgpu_mm_rdoorbell64 - read a doorbell Qword
>> - *
>> - * @adev: amdgpu_device pointer
>> - * @index: doorbell index
>> - *
>> - * Returns the value in the doorbell aperture at the
>> - * requested doorbell index (VEGA10+).
>> - */
>> -u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>> -{
>> -       if (amdgpu_device_skip_hw_access(adev))
>> -               return 0;
>> -
>> -       if (index < adev->doorbell.num_kernel_doorbells) {
>> -               return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>> -       } else {
>> -               DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> -               return 0;
>> -       }
>> -}
>> -
>> -/**
>> - * amdgpu_mm_wdoorbell64 - write a doorbell Qword
>> - *
>> - * @adev: amdgpu_device pointer
>> - * @index: doorbell index
>> - * @v: value to write
>> - *
>> - * Writes @v to the doorbell aperture at the
>> - * requested doorbell index (VEGA10+).
>> - */
>> -void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>> -{
>> -       if (amdgpu_device_skip_hw_access(adev))
>> -               return;
>> -
>> -       if (index < adev->doorbell.num_kernel_doorbells) {
>> -               atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>> -       } else {
>> -               DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> -       }
>> -}
>> -
>>   /**
>>    * amdgpu_device_indirect_rreg - read an indirect register
>>    *
>> @@ -1016,82 +928,6 @@ int amdgpu_device_pci_reset(struct amdgpu_device *adev)
>>          return pci_reset_function(adev->pdev);
>>   }
>>
>> -/*
>> - * GPU doorbell aperture helpers function.
>> - */
>> -/**
>> - * amdgpu_device_doorbell_init - Init doorbell driver information.
>> - *
>> - * @adev: amdgpu_device pointer
>> - *
>> - * Init doorbell driver information (CIK)
>> - * Returns 0 on success, error on failure.
>> - */
>> -static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>> -{
>> -
>> -       /* No doorbell on SI hardware generation */
>> -       if (adev->asic_type < CHIP_BONAIRE) {
>> -               adev->doorbell.base = 0;
>> -               adev->doorbell.size = 0;
>> -               adev->doorbell.num_kernel_doorbells = 0;
>> -               adev->doorbell.ptr = NULL;
>> -               return 0;
>> -       }
>> -
>> -       if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
>> -               return -EINVAL;
>> -
>> -       amdgpu_asic_init_doorbell_index(adev);
>> -
>> -       /* doorbell bar mapping */
>> -       adev->doorbell.base = pci_resource_start(adev->pdev, 2);
>> -       adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>> -
>> -       if (adev->enable_mes) {
>> -               adev->doorbell.num_kernel_doorbells =
>> -                       adev->doorbell.size / sizeof(u32);
>> -       } else {
>> -               adev->doorbell.num_kernel_doorbells =
>> -                       min_t(u32, adev->doorbell.size / sizeof(u32),
>> -                             adev->doorbell_index.max_assignment+1);
>> -               if (adev->doorbell.num_kernel_doorbells == 0)
>> -                       return -EINVAL;
>> -
>> -               /* For Vega, reserve and map two pages on doorbell BAR since SDMA
>> -                * paging queue doorbell use the second page. The
>> -                * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>> -                * doorbells are in the first page. So with paging queue enabled,
>> -                * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>> -                */
>> -               if (adev->asic_type >= CHIP_VEGA10)
>> -                       adev->doorbell.num_kernel_doorbells += 0x400;
>> -       }
>> -
>> -       adev->doorbell.ptr = ioremap(adev->doorbell.base,
>> -                                    adev->doorbell.num_kernel_doorbells *
>> -                                    sizeof(u32));
>> -       if (adev->doorbell.ptr == NULL)
>> -               return -ENOMEM;
>> -
>> -       return 0;
>> -}
>> -
>> -/**
>> - * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
>> - *
>> - * @adev: amdgpu_device pointer
>> - *
>> - * Tear down doorbell driver information (CIK)
>> - */
>> -static void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>> -{
>> -       iounmap(adev->doorbell.ptr);
>> -       adev->doorbell.ptr = NULL;
>> -}
>> -
>> -
>> -
>>   /*
>>    * amdgpu_device_wb_*()
>>    * Writeback is the method by which the GPU updates special pages in memory
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index 6064943a1b53..f9c3b77bf65d 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -306,6 +306,28 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v);
>>   u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index);
>>   void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
>>
>> +/*
>> + * GPU doorbell aperture helpers function.
>> + */
>> +/**
>> + * amdgpu_device_doorbell_init - Init doorbell driver information.
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Init doorbell driver information (CIK)
>> + * Returns 0 on success, error on failure.
>> + */
>> +int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>> +
>> +/**
>> + * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Tear down doorbell driver information (CIK)
>> + */
>> +void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>> +
>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> new file mode 100644
>> index 000000000000..2206926ba289
>> --- /dev/null
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> @@ -0,0 +1,186 @@
>> +/*
>> + * 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"
>> +
>> +/**
>> + * amdgpu_mm_rdoorbell - read a doorbell dword
>> + *
>> + * @adev: amdgpu_device pointer
>> + * @index: doorbell index
>> + *
>> + * Returns the value in the doorbell aperture at the
>> + * requested doorbell index (CIK).
>> + */
>> +u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>> +{
>> +       if (amdgpu_device_skip_hw_access(adev))
>> +               return 0;
>> +
>> +       if (index < adev->doorbell.num_kernel_doorbells) {
>> +               return readl(adev->doorbell.ptr + index);
>> +       } else {
>> +               DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> +               return 0;
>> +       }
>> +}
>> +
>> +/**
>> + * amdgpu_mm_wdoorbell - write a doorbell dword
>> + *
>> + * @adev: amdgpu_device pointer
>> + * @index: doorbell index
>> + * @v: value to write
>> + *
>> + * Writes @v to the doorbell aperture at the
>> + * requested doorbell index (CIK).
>> + */
>> +void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>> +{
>> +       if (amdgpu_device_skip_hw_access(adev))
>> +               return;
>> +
>> +       if (index < adev->doorbell.num_kernel_doorbells) {
>> +               writel(v, adev->doorbell.ptr + index);
>> +       } else {
>> +               DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> +       }
>> +}
>> +
>> +/**
>> + * amdgpu_mm_rdoorbell64 - read a doorbell Qword
>> + *
>> + * @adev: amdgpu_device pointer
>> + * @index: doorbell index
>> + *
>> + * Returns the value in the doorbell aperture at the
>> + * requested doorbell index (VEGA10+).
>> + */
>> +u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>> +{
>> +       if (amdgpu_device_skip_hw_access(adev))
>> +               return 0;
>> +
>> +       if (index < adev->doorbell.num_kernel_doorbells) {
>> +               return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>> +       } else {
>> +               DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>> +               return 0;
>> +       }
>> +}
>> +
>> +/**
>> + * amdgpu_mm_wdoorbell64 - write a doorbell Qword
>> + *
>> + * @adev: amdgpu_device pointer
>> + * @index: doorbell index
>> + * @v: value to write
>> + *
>> + * Writes @v to the doorbell aperture at the
>> + * requested doorbell index (VEGA10+).
>> + */
>> +void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>> +{
>> +       if (amdgpu_device_skip_hw_access(adev))
>> +               return;
>> +
>> +       if (index < adev->doorbell.num_kernel_doorbells) {
>> +               atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>> +       } else {
>> +               DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>> +       }
>> +}
>> +
>> +/*
>> + * GPU doorbell aperture helpers function.
>> + */
>> +/**
>> + * amdgpu_device_doorbell_init - Init doorbell driver information.
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Init doorbell driver information (CIK)
>> + * Returns 0 on success, error on failure.
>> + */
>> +int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>> +{
>> +
>> +       /* No doorbell on SI hardware generation */
>> +       if (adev->asic_type < CHIP_BONAIRE) {
>> +               adev->doorbell.base = 0;
>> +               adev->doorbell.size = 0;
>> +               adev->doorbell.num_kernel_doorbells = 0;
>> +               adev->doorbell.ptr = NULL;
>> +               return 0;
>> +       }
>> +
>> +       if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
>> +               return -EINVAL;
>> +
>> +       amdgpu_asic_init_doorbell_index(adev);
>> +
>> +       /* doorbell bar mapping */
>> +       adev->doorbell.base = pci_resource_start(adev->pdev, 2);
>> +       adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>> +
>> +       if (adev->enable_mes) {
>> +               adev->doorbell.num_kernel_doorbells =
>> +                       adev->doorbell.size / sizeof(u32);
>> +       } else {
>> +               adev->doorbell.num_kernel_doorbells =
>> +                       min_t(u32, adev->doorbell.size / sizeof(u32),
>> +                             adev->doorbell_index.max_assignment+1);
>> +               if (adev->doorbell.num_kernel_doorbells == 0)
>> +                       return -EINVAL;
>> +
>> +               /* For Vega, reserve and map two pages on doorbell BAR since SDMA
>> +                * paging queue doorbell use the second page. The
>> +                * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>> +                * doorbells are in the first page. So with paging queue enabled,
>> +                * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>> +                */
>> +               if (adev->asic_type >= CHIP_VEGA10)
>> +                       adev->doorbell.num_kernel_doorbells += 0x400;
>> +       }
>> +
>> +       adev->doorbell.ptr = ioremap(adev->doorbell.base,
>> +                                    adev->doorbell.num_kernel_doorbells *
>> +                                    sizeof(u32));
>> +       if (adev->doorbell.ptr == NULL)
>> +               return -ENOMEM;
>> +
>> +       return 0;
>> +}
>> +
>> +/**
>> + * amdgpu_device_doorbell_fini - Tear down doorbell driver information.
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * Tear down doorbell driver information (CIK)
>> + */
>> +void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>> +{
>> +       iounmap(adev->doorbell.ptr);
>> +       adev->doorbell.ptr = NULL;
>> +}
> I would suggest renaming these functions to begin with
> amdgpu_doorbell_ to be consistent with the naming conventions in the
> driver.

Noted, agree.

- Shashank

> Alex

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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 14:49       ` Christian König
@ 2023-03-30 14:52         ` Luben Tuikov
  2023-03-30 14:53         ` Shashank Sharma
  1 sibling, 0 replies; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 14:52 UTC (permalink / raw)
  To: Christian König, Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma

On 2023-03-30 10:49, Christian König wrote:
> Am 30.03.23 um 16:40 schrieb Shashank Sharma:
>>
>> On 30/03/2023 16:24, Luben Tuikov wrote:
>>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>
>>>> This patch:
>>>> - creates a doorbell page for graphics driver usages.
>>>> - removes the adev->doorbell.ptr variable, replaces it with
>>>>    kernel-doorbell-bo's cpu address.
>>>>
>>>> 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_doorbell.h  | 16 ++++++-
>>>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 
>>>> +++++++++++++++----
>>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>>>   3 files changed, 57 insertions(+), 10 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h 
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> index 6581b78fe438..10a9bb10e974 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>>>       /* doorbell mmio */
>>>>       resource_size_t        base;
>>>>       resource_size_t        size;
>>>> -    u32 __iomem        *ptr;
>>>> +    u32    __iomem        *ptr;
>>>>         /* Number of doorbells reserved for amdgpu kernel driver */
>>>>       u32 num_kernel_doorbells;
>>>> +
>>>> +    /* For kernel doorbell pages */
>>>> +    struct amdgpu_doorbell_obj kernel_doorbells;
>>>>   };
>>> Here's an example where it could be confusing what the difference is
>>> between "struct amdgpu_doorbell" and "struct amdgpu_doobell_obj".
>>> As the comment to the struct doorbell_obj declarations says
>>> in patch 7,
>>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>>>> +struct amdgpu_doorbell_obj {
>>
>> What is the confusion ? This is the object which is holding doorbell 
>> page. There could be 2 type of
>>
>> doorbell pages, kernel and process, this is a kernel one.
>>
>>> Perhaps we should call it "struct amdgpu_doorbell_bo", since
>>> it does contain amdgpu_bo's, which are doorbell's bos.
>>
>> This is not a buffer object (memory), this is doorbell object, so 
>> calling it bo would be wrong.
> 
> I think what Luben means is that in object orient programming this here 
> would be the class. The object is then the actual instantiation of that.

Yes, absolutely exactly what Christian said.

Regards,
Luben

> 
> But I have some real doubts that this is the right approach in the first 
> place.
> 
> Regards,
> Christian.
> 
>>
>> - Shashank
>>
>>>
>>> Regards,
>>> Luben
>>>
>>>>     /* Reserved doorbells for amdgpu (including multimedia).
>>>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct 
>>>> amdgpu_device *adev,
>>>>   int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>                   struct amdgpu_doorbell_obj *db_obj);
>>>>   +/**
>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel 
>>>> doorbells for graphics
>>>> + *
>>>> + * @adev: amdgpu_device pointer
>>>> + *
>>>> + * Creates doorbells for graphics driver
>>>> + *
>>>> + * returns 0 on success, error otherwise.
>>>> + */
>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>>>> *adev);
>>>> +
>>>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c 
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> index 8be15b82b545..b46fe8b1378d 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct 
>>>> amdgpu_device *adev,
>>>>       return 0;
>>>>   }
>>>>   +/**
>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel 
>>>> doorbells for graphics
>>>> + *
>>>> + * @adev: amdgpu_device pointer
>>>> + *
>>>> + * Creates doorbells for graphics driver
>>>> + *
>>>> + * returns 0 on success, error otherwise.
>>>> + */
>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>>>> *adev)
>>>> +{
>>>> +    int r;
>>>> +    struct amdgpu_doorbell_obj *kernel_doorbells = 
>>>> &adev->doorbell.kernel_doorbells;
>>>> +
>>>> +    kernel_doorbells->doorbell_bitmap = 
>>>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>>>> +                              GFP_KERNEL);
>>>> +    if (!kernel_doorbells->doorbell_bitmap) {
>>>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>>>> +        return -ENOMEM;
>>>> +    }
>>>> +
>>>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells * 
>>>> sizeof(u32);
>>>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>>>> +    if (r) {
>>>> +        bitmap_free(kernel_doorbells->doorbell_bitmap);
>>>> +        DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", r);
>>>> +        return r;
>>>> +    }
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>>   /*
>>>>    * GPU doorbell aperture helpers function.
>>>>    */
>>>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct 
>>>> amdgpu_device *adev)
>>>>           adev->doorbell.base = 0;
>>>>           adev->doorbell.size = 0;
>>>>           adev->doorbell.num_kernel_doorbells = 0;
>>>> -        adev->doorbell.ptr = NULL;
>>>>           return 0;
>>>>       }
>>>>   @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct 
>>>> amdgpu_device *adev)
>>>>       if (adev->asic_type >= CHIP_VEGA10)
>>>>           adev->doorbell.num_kernel_doorbells += 0x400;
>>>>   -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>> -                     adev->doorbell.num_kernel_doorbells *
>>>> -                     sizeof(u32));
>>>> -    if (adev->doorbell.ptr == NULL)
>>>> -        return -ENOMEM;
>>>> -
>>>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base, 
>>>> adev->doorbell.size);
>>>>       return 0;
>>>>   }
>>>>   @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct 
>>>> amdgpu_device *adev)
>>>>    */
>>>>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>>>   {
>>>> -    iounmap(adev->doorbell.ptr);
>>>> -    adev->doorbell.ptr = NULL;
>>>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>>>> +    amdgpu_doorbell_free_page(adev, &adev->doorbell.kernel_doorbells);
>>>>   }
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> index 203d77a20507..75c6852845c4 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>>>           return r;
>>>>       }
>>>>   +    /* Create a boorbell page for kernel usages */
>>>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
>>>> +    if (r) {
>>>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
>>>> +        return r;
>>>> +    }
>>>> +
>>>>       /* Initialize preemptible memory pool */
>>>>       r = amdgpu_preempt_mgr_init(adev);
>>>>       if (r) {
> 


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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 14:48           ` Shashank Sharma
@ 2023-03-30 14:53             ` Christian König
  2023-03-30 15:04             ` Alex Deucher
  1 sibling, 0 replies; 87+ messages in thread
From: Christian König @ 2023-03-30 14:53 UTC (permalink / raw)
  To: Shashank Sharma, Alex Deucher
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma, amd-gfx

Am 30.03.23 um 16:48 schrieb Shashank Sharma:
>
> On 30/03/2023 16:42, Christian König wrote:
>> Am 30.03.23 um 16:39 schrieb Alex Deucher:
>>> On Thu, Mar 30, 2023 at 7:49 AM Shashank Sharma 
>>> <shashank.sharma@amd.com> wrote:
>>>>
>>>> On 30/03/2023 13:30, Christian König wrote:
>>>>>
>>>>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>>>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>>>
>>>>>> This patch:
>>>>>> - creates a doorbell page for graphics driver usages.
>>>>>> - removes the adev->doorbell.ptr variable, replaces it with
>>>>>>     kernel-doorbell-bo's cpu address.
>>>>>>
>>>>>> 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_doorbell.h  | 16 ++++++-
>>>>>>    .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 
>>>>>> +++++++++++++++----
>>>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>>>>>    3 files changed, 57 insertions(+), 10 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> index 6581b78fe438..10a9bb10e974 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>>>>>        /* doorbell mmio */
>>>>>>        resource_size_t        base;
>>>>>>        resource_size_t        size;
>>>>>> -    u32 __iomem        *ptr;
>>>>>> +    u32    __iomem        *ptr;
>>>>> This one can probably go away if we use the pointer from
>>>>> amdgpu_bo_create_kernel().
>>>> We started like that, but later realized that the cpu_addr from
>>>> create_kernel() will just limit us
>>>>
>>>> to that object only, whereas we are keeping this ptr to ioremap the
>>>> whole doorbell space in one shot.
>>> Why do we need that?  For the kernel driver, we'd only need to mmap
>>> the page used for kernel doorbells.  Then each user app would mmap its
>>> doorbell page.
>>
>> Yes, that is exactly my concern as well.
>>
>> The kernel needs a fixed number of doorbells allocated for its 
>> internal use. Everything else should probably use the normal BO API.
>>
>> For KFD we can use the BO API internal in the kernel, but that is 
>> certainly completely different to the kernel allocations.
>>
> There are 3 different kernel doorbell clients here:
>
> - graphics driver
>
> - mes (for aggregated doorbells and kernel ring test)
>
> - kfd (for kernel ring test and KIQ)
>
>
> The fix num_doorbells are just for kernel graphics driver, but We are 
> allocating doorbell pages for each of those, and they all need to be 
> mapped.

Yeah and exactly that doesn't sound like a good idea to me. In general 
we should only distinct between static and dynamic allocations and *not* 
different use cases of those.

What do you mean exactly with graphics driver and aggregated doorbells?

For the MES in kernel test we should probably just allocate a single 
doorbell page and use it statically like userspace would do. E.g. with 
fixed indexes etc...

Regards,
Christian.

>
> Please see patch 12-16 for these details.
>
> - Shashank
>
>> Christian.
>>
>>>
>>> Alex
>>>
>>>> - Shashank
>>>>
>>>>>>          /* Number of doorbells reserved for amdgpu kernel driver */
>>>>>>        u32 num_kernel_doorbells;
>>>>>> +
>>>>>> +    /* For kernel doorbell pages */
>>>>>> +    struct amdgpu_doorbell_obj kernel_doorbells;
>>>>>>    };
>>>>>>      /* Reserved doorbells for amdgpu (including multimedia).
>>>>>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct
>>>>>> amdgpu_device *adev,
>>>>>>    int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>>>                    struct amdgpu_doorbell_obj *db_obj);
>>>>>>    +/**
>>>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel 
>>>>>> doorbells
>>>>>> for graphics
>>>>>> + *
>>>>>> + * @adev: amdgpu_device pointer
>>>>>> + *
>>>>>> + * Creates doorbells for graphics driver
>>>>>> + *
>>>>>> + * returns 0 on success, error otherwise.
>>>>>> + */
>>>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device
>>>>>> *adev);
>>>>>> +
>>>>>>    #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>>>    #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, 
>>>>>> (index), (v))
>>>>>>    #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> index 8be15b82b545..b46fe8b1378d 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct
>>>>>> amdgpu_device *adev,
>>>>>>        return 0;
>>>>>>    }
>>>>>>    +/**
>>>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel 
>>>>>> doorbells
>>>>>> for graphics
>>>>>> + *
>>>>>> + * @adev: amdgpu_device pointer
>>>>>> + *
>>>>>> + * Creates doorbells for graphics driver
>>>>>> + *
>>>>>> + * returns 0 on success, error otherwise.
>>>>>> + */
>>>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>>>>>> *adev)
>>>>>> +{
>>>>>> +    int r;
>>>>>> +    struct amdgpu_doorbell_obj *kernel_doorbells =
>>>>>> &adev->doorbell.kernel_doorbells;
>>>>>> +
>>>>>> +    kernel_doorbells->doorbell_bitmap =
>>>>>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>>>>>> +                              GFP_KERNEL);
>>>>>> +    if (!kernel_doorbells->doorbell_bitmap) {
>>>>>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>>>>>> +        return -ENOMEM;
>>>>>> +    }
>>>>>> +
>>>>>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells *
>>>>>> sizeof(u32);
>>>>>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>>>>>> +    if (r) {
>>>>>> + bitmap_free(kernel_doorbells->doorbell_bitmap);
>>>>>> +        DRM_ERROR("Failed to allocate kernel doorbells, 
>>>>>> err=%d\n", r);
>>>>>> +        return r;
>>>>>> +    }
>>>>>> +
>>>>>> +    return 0;
>>>>>> +}
>>>>>> +
>>>>>>    /*
>>>>>>     * GPU doorbell aperture helpers function.
>>>>>>     */
>>>>>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct
>>>>>> amdgpu_device *adev)
>>>>>>            adev->doorbell.base = 0;
>>>>>>            adev->doorbell.size = 0;
>>>>>>            adev->doorbell.num_kernel_doorbells = 0;
>>>>>> -        adev->doorbell.ptr = NULL;
>>>>>>            return 0;
>>>>>>        }
>>>>>>    @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct
>>>>>> amdgpu_device *adev)
>>>>>>        if (adev->asic_type >= CHIP_VEGA10)
>>>>>>            adev->doorbell.num_kernel_doorbells += 0x400;
>>>>>>    -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>>>> - adev->doorbell.num_kernel_doorbells *
>>>>>> -                     sizeof(u32));
>>>>>> -    if (adev->doorbell.ptr == NULL)
>>>>>> -        return -ENOMEM;
>>>>>> -
>>>>>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>>>> adev->doorbell.size);
>>>>>>        return 0;
>>>>>>    }
>>>>>>    @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct
>>>>>> amdgpu_device *adev)
>>>>>>     */
>>>>>>    void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>>>>>    {
>>>>>> -    iounmap(adev->doorbell.ptr);
>>>>>> -    adev->doorbell.ptr = NULL;
>>>>>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>>>>>> +    amdgpu_doorbell_free_page(adev, 
>>>>>> &adev->doorbell.kernel_doorbells);
>>>>>>    }
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> index 203d77a20507..75c6852845c4 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device 
>>>>>> *adev)
>>>>>>            return r;
>>>>>>        }
>>>>>>    +    /* Create a boorbell page for kernel usages */
>>>>>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
>>>>>> +    if (r) {
>>>>>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
>>>>>> +        return r;
>>>>>> +    }
>>>>>> +
>>>>>>        /* Initialize preemptible memory pool */
>>>>>>        r = amdgpu_preempt_mgr_init(adev);
>>>>>>        if (r) {
>>


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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 14:49       ` Christian König
  2023-03-30 14:52         ` Luben Tuikov
@ 2023-03-30 14:53         ` Shashank Sharma
  2023-03-30 14:59           ` Luben Tuikov
  1 sibling, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 14:53 UTC (permalink / raw)
  To: Christian König, Luben Tuikov, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma


On 30/03/2023 16:49, Christian König wrote:
> Am 30.03.23 um 16:40 schrieb Shashank Sharma:
>>
>> On 30/03/2023 16:24, Luben Tuikov wrote:
>>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>
>>>> This patch:
>>>> - creates a doorbell page for graphics driver usages.
>>>> - removes the adev->doorbell.ptr variable, replaces it with
>>>>    kernel-doorbell-bo's cpu address.
>>>>
>>>> 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_doorbell.h  | 16 ++++++-
>>>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 
>>>> +++++++++++++++----
>>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>>>   3 files changed, 57 insertions(+), 10 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h 
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> index 6581b78fe438..10a9bb10e974 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>>>       /* doorbell mmio */
>>>>       resource_size_t        base;
>>>>       resource_size_t        size;
>>>> -    u32 __iomem        *ptr;
>>>> +    u32    __iomem        *ptr;
>>>>         /* Number of doorbells reserved for amdgpu kernel driver */
>>>>       u32 num_kernel_doorbells;
>>>> +
>>>> +    /* For kernel doorbell pages */
>>>> +    struct amdgpu_doorbell_obj kernel_doorbells;
>>>>   };
>>> Here's an example where it could be confusing what the difference is
>>> between "struct amdgpu_doorbell" and "struct amdgpu_doobell_obj".
>>> As the comment to the struct doorbell_obj declarations says
>>> in patch 7,
>>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>>>> +struct amdgpu_doorbell_obj {
>>
>> What is the confusion ? This is the object which is holding doorbell 
>> page. There could be 2 type of
>>
>> doorbell pages, kernel and process, this is a kernel one.
>>
>>> Perhaps we should call it "struct amdgpu_doorbell_bo", since
>>> it does contain amdgpu_bo's, which are doorbell's bos.
>>
>> This is not a buffer object (memory), this is doorbell object, so 
>> calling it bo would be wrong.
>
> I think what Luben means is that in object orient programming this 
> here would be the class. The object is then the actual instantiation 
> of that.
>
Why should we even bother about OOPs terminology in kernel C code ? I 
think we are spending too much time in something not worth.


> But I have some real doubts that this is the right approach in the 
> first place.


I would like to discuss and understand more on this technical aspect. 
Can you please have a look at the whole series and check how we have

handled the existing doorbell clients (KFD, MES), and if you feel the 
same, we should talk more on this ?

- Shashank

>
> Regards,
> Christian.
>
>>
>> - Shashank
>>
>>>
>>> Regards,
>>> Luben
>>>
>>>>     /* Reserved doorbells for amdgpu (including multimedia).
>>>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct 
>>>> amdgpu_device *adev,
>>>>   int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>                   struct amdgpu_doorbell_obj *db_obj);
>>>>   +/**
>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel 
>>>> doorbells for graphics
>>>> + *
>>>> + * @adev: amdgpu_device pointer
>>>> + *
>>>> + * Creates doorbells for graphics driver
>>>> + *
>>>> + * returns 0 on success, error otherwise.
>>>> + */
>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>>>> *adev);
>>>> +
>>>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), 
>>>> (v))
>>>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c 
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> index 8be15b82b545..b46fe8b1378d 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct 
>>>> amdgpu_device *adev,
>>>>       return 0;
>>>>   }
>>>>   +/**
>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel 
>>>> doorbells for graphics
>>>> + *
>>>> + * @adev: amdgpu_device pointer
>>>> + *
>>>> + * Creates doorbells for graphics driver
>>>> + *
>>>> + * returns 0 on success, error otherwise.
>>>> + */
>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>>>> *adev)
>>>> +{
>>>> +    int r;
>>>> +    struct amdgpu_doorbell_obj *kernel_doorbells = 
>>>> &adev->doorbell.kernel_doorbells;
>>>> +
>>>> +    kernel_doorbells->doorbell_bitmap = 
>>>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>>>> +                              GFP_KERNEL);
>>>> +    if (!kernel_doorbells->doorbell_bitmap) {
>>>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>>>> +        return -ENOMEM;
>>>> +    }
>>>> +
>>>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells * 
>>>> sizeof(u32);
>>>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>>>> +    if (r) {
>>>> +        bitmap_free(kernel_doorbells->doorbell_bitmap);
>>>> +        DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", 
>>>> r);
>>>> +        return r;
>>>> +    }
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>>   /*
>>>>    * GPU doorbell aperture helpers function.
>>>>    */
>>>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct 
>>>> amdgpu_device *adev)
>>>>           adev->doorbell.base = 0;
>>>>           adev->doorbell.size = 0;
>>>>           adev->doorbell.num_kernel_doorbells = 0;
>>>> -        adev->doorbell.ptr = NULL;
>>>>           return 0;
>>>>       }
>>>>   @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct 
>>>> amdgpu_device *adev)
>>>>       if (adev->asic_type >= CHIP_VEGA10)
>>>>           adev->doorbell.num_kernel_doorbells += 0x400;
>>>>   -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>> -                     adev->doorbell.num_kernel_doorbells *
>>>> -                     sizeof(u32));
>>>> -    if (adev->doorbell.ptr == NULL)
>>>> -        return -ENOMEM;
>>>> -
>>>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base, 
>>>> adev->doorbell.size);
>>>>       return 0;
>>>>   }
>>>>   @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct 
>>>> amdgpu_device *adev)
>>>>    */
>>>>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>>>   {
>>>> -    iounmap(adev->doorbell.ptr);
>>>> -    adev->doorbell.ptr = NULL;
>>>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>>>> +    amdgpu_doorbell_free_page(adev, 
>>>> &adev->doorbell.kernel_doorbells);
>>>>   }
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> index 203d77a20507..75c6852845c4 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>>>           return r;
>>>>       }
>>>>   +    /* Create a boorbell page for kernel usages */
>>>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
>>>> +    if (r) {
>>>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
>>>> +        return r;
>>>> +    }
>>>> +
>>>>       /* Initialize preemptible memory pool */
>>>>       r = amdgpu_preempt_mgr_init(adev);
>>>>       if (r) {
>

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

* Re: [PATCH 08/16] drm/amdgpu: initialize ttm for doorbells
  2023-03-30 14:33   ` Alex Deucher
@ 2023-03-30 14:54     ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 14:54 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian Koenig


On 30/03/2023 16:33, Alex Deucher wrote:
> On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
> <shashank.sharma@amd.com> wrote:
>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>
>> This patch initialzes the ttm resource manager for doorbells.
>>
>> 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_ttm.c | 8 ++++++++
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 6f61491ef3dd..203d77a20507 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -1858,6 +1858,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>          DRM_INFO("amdgpu: %uM of GTT memory ready.\n",
>>                   (unsigned)(gtt_size / (1024 * 1024)));
>>
>> +       /* Initiailize doorbell pool on PCI BAR */
>> +       r = amdgpu_ttm_init_on_chip(adev, AMDGPU_PL_DOORBELL,
>> +                                   DIV_ROUND_UP(adev->doorbell.size, PAGE_SIZE));
> In practice this would never be an issue since the PCI BAR is always
> at least 2M, but I think we probably don't want to round up here?  I
> guess large pages would be a problem, but so would going beyond the
> BAR.

Agree, will take care of this.

- Shashank

>
> Alex
>
>> +       if (r) {
>> +               DRM_ERROR("Failed initializing doorbell heap. \n");
>> +               return r;
>> +       }
>> +
>>          /* Initialize preemptible memory pool */
>>          r = amdgpu_preempt_mgr_init(adev);
>>          if (r) {
>> --
>> 2.40.0
>>

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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 14:34         ` Shashank Sharma
  2023-03-30 14:37           ` Luben Tuikov
@ 2023-03-30 14:55           ` Alex Deucher
  2023-03-30 15:21             ` Shashank Sharma
  1 sibling, 1 reply; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 14:55 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Luben Tuikov, Alex Deucher,
	Shashank Sharma, Christian Koenig

On Thu, Mar 30, 2023 at 10:34 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
>
> On 30/03/2023 16:15, Luben Tuikov wrote:
> > On 2023-03-30 10:04, Shashank Sharma wrote:
> >> On 30/03/2023 15:42, Luben Tuikov wrote:
> >>> On 2023-03-29 11:47, Shashank Sharma wrote:
> >>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
> >>>>
> >>>> This patch adds helper functions to create and free doorbell
> >>>> pages for kernel objects.
> >>>>
> >>>> 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_doorbell.h  | 41 ++++++++++++++++
> >>>>    .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
> >>>>    2 files changed, 90 insertions(+)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >>>> index f9c3b77bf65d..6581b78fe438 100644
> >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >>>> @@ -27,6 +27,24 @@
> >>>>    /*
> >>>>     * GPU doorbell structures, functions & helpers
> >>>>     */
> >>>> +
> >>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
> >>>> +struct amdgpu_doorbell_obj {
> >>> In the comment you say "Structure to hold ...";
> >>> it is a C structure, but then in the name of a function we see "obj".
> >>> (Object is something which is defined like in memory, i.e. it exists, not
> >>> something which is only declared.)
> >>> This is just a declaration of a structure, not an object per se.
> >>> I'd call it "struct amdgpu_doorbell_struct" or just "struct amdgpu_doorbell".
> >> It is similar to struct amdgpu buffer object (struct amdgpu_bo), and
> >> many more existing structure.
> > The amdpgu_bo is very different than a structure describing a doorbell.
> > The doorbell description isn't really "an object". I understand
> > the enthusiasm, but it is really not "an object". It's just a doorbell
> > description. :-)
>
> amdgpu_bo is page of ttm_memory with additional information,
>
> amdgpu_doorbell_obj is a page of ttm_doorbells with additional information
>
> (it is not just one doorbell description)
>
> I don't see a problem here.

I find the new API confusing.  I would expect to see
amdgpu_bo_create_kernel(...DOORBELL...), amdgpu_bo_reserve(),
amdgpu_bo_kmap(), etc.  That makes it consistent with the other
resource pools that we manage in ttm.

Alex

>
> - Shashank
>
> >
> > Regards,
> > Luben
> >
> >> - Shashank
> >>
> >>> Then in the definition, you can call it an object/objects, if you'd like,
> >>> like "struct amdgpu_doorbell *doorb_object[];" then you can say
> >>> "db = doorb_object[i]";
> >>>
> >>> Regards,
> >>> Luben
> >>>
> >>>> +  struct amdgpu_bo *bo;
> >>>> +  uint64_t gpu_addr;
> >>>> +  uint32_t *cpu_addr;
> >>>> +  uint32_t size;
> >>>> +
> >>>> +  /* First index in this object */
> >>>> +  uint32_t start;
> >>>> +
> >>>> +  /* Last index in this object */
> >>>> +  uint32_t end;
> >>>> +
> >>>> +  /* bitmap for dynamic doorbell allocation from this object */
> >>>> +  unsigned long *doorbell_bitmap;
> >>>> +};
> >>>> +
> >>>>    struct amdgpu_doorbell {
> >>>>            /* doorbell mmio */
> >>>>            resource_size_t         base;
> >>>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
> >>>>     */
> >>>>    void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
> >>>>
> >>>> +/**
> >>>> + * amdgpu_doorbell_free_page - Free a doorbell page
> >>>> + *
> >>>> + * @adev: amdgpu_device pointer
> >>>> + *
> >>>> + * @db_age: previously allocated doobell page details
> >>>> + *
> >>>> + */
> >>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
> >>>> +                          struct amdgpu_doorbell_obj *db_obj);
> >>>> +
> >>>> +/**
> >>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
> >>>> + *
> >>>> + * @adev: amdgpu_device pointer
> >>>> + *
> >>>> + * @db_age: doobell page structure to fill details with
> >>>> + *
> >>>> + * returns 0 on success, else error number
> >>>> + */
> >>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> >>>> +                          struct amdgpu_doorbell_obj *db_obj);
> >>>> +
> >>>>    #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
> >>>>    #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
> >>>>    #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >>>> index 1aea92363fd3..8be15b82b545 100644
> >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >>>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
> >>>>            }
> >>>>    }
> >>>>
> >>>> +/**
> >>>> + * amdgpu_doorbell_free_page - Free a doorbell page
> >>>> + *
> >>>> + * @adev: amdgpu_device pointer
> >>>> + *
> >>>> + * @db_age: previously allocated doobell page details
> >>>> + *
> >>>> + */
> >>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
> >>>> +                                  struct amdgpu_doorbell_obj *db_obj)
> >>>> +{
> >>>> +  amdgpu_bo_free_kernel(&db_obj->bo,
> >>>> +                        &db_obj->gpu_addr,
> >>>> +                        (void **)&db_obj->cpu_addr);
> >>>> +
> >>>> +}
> >>>> +
> >>>> +/**
> >>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
> >>>> + *
> >>>> + * @adev: amdgpu_device pointer
> >>>> + *
> >>>> + * @db_age: doobell page structure to fill details with
> >>>> + *
> >>>> + * returns 0 on success, else error number
> >>>> + */
> >>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> >>>> +                          struct amdgpu_doorbell_obj *db_obj)
> >>>> +{
> >>>> +  int r;
> >>>> +
> >>>> +  db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
> >>>> +
> >>>> +  r = amdgpu_bo_create_kernel(adev,
> >>>> +                              db_obj->size,
> >>>> +                              PAGE_SIZE,
> >>>> +                              AMDGPU_GEM_DOMAIN_DOORBELL,
> >>>> +                              &db_obj->bo,
> >>>> +                              &db_obj->gpu_addr,
> >>>> +                              (void **)&db_obj->cpu_addr);
> >>>> +
> >>>> +  if (r) {
> >>>> +          DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
> >>>> +          return r;
> >>>> +  }
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>>    /*
> >>>>     * GPU doorbell aperture helpers function.
> >>>>     */

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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 14:53         ` Shashank Sharma
@ 2023-03-30 14:59           ` Luben Tuikov
  2023-03-30 15:09             ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 14:59 UTC (permalink / raw)
  To: Shashank Sharma, Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma

On 2023-03-30 10:53, Shashank Sharma wrote:
> 
> On 30/03/2023 16:49, Christian König wrote:
>> Am 30.03.23 um 16:40 schrieb Shashank Sharma:
>>>
>>> On 30/03/2023 16:24, Luben Tuikov wrote:
>>>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>>
>>>>> This patch:
>>>>> - creates a doorbell page for graphics driver usages.
>>>>> - removes the adev->doorbell.ptr variable, replaces it with
>>>>>    kernel-doorbell-bo's cpu address.
>>>>>
>>>>> 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_doorbell.h  | 16 ++++++-
>>>>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44 
>>>>> +++++++++++++++----
>>>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>>>>   3 files changed, 57 insertions(+), 10 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h 
>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>> index 6581b78fe438..10a9bb10e974 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>>>>       /* doorbell mmio */
>>>>>       resource_size_t        base;
>>>>>       resource_size_t        size;
>>>>> -    u32 __iomem        *ptr;
>>>>> +    u32    __iomem        *ptr;
>>>>>         /* Number of doorbells reserved for amdgpu kernel driver */
>>>>>       u32 num_kernel_doorbells;
>>>>> +
>>>>> +    /* For kernel doorbell pages */
>>>>> +    struct amdgpu_doorbell_obj kernel_doorbells;
>>>>>   };
>>>> Here's an example where it could be confusing what the difference is
>>>> between "struct amdgpu_doorbell" and "struct amdgpu_doobell_obj".
>>>> As the comment to the struct doorbell_obj declarations says
>>>> in patch 7,
>>>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>>>>> +struct amdgpu_doorbell_obj {
>>>
>>> What is the confusion ? This is the object which is holding doorbell 
>>> page. There could be 2 type of
>>>
>>> doorbell pages, kernel and process, this is a kernel one.
>>>
>>>> Perhaps we should call it "struct amdgpu_doorbell_bo", since
>>>> it does contain amdgpu_bo's, which are doorbell's bos.
>>>
>>> This is not a buffer object (memory), this is doorbell object, so 
>>> calling it bo would be wrong.
>>
>> I think what Luben means is that in object orient programming this 
>> here would be the class. The object is then the actual instantiation 
>> of that.
>>
> Why should we even bother about OOPs terminology in kernel C code ? I 
> think we are spending too much time in something not worth.

Because you're using "object" incorrectly. Especially for people with
vast programming experience, this creates confusion. Please don't use
"obj" in the name of a structure. Perhaps use "bo" or "page" or something
which it really _is_. But don't mix OOP terminology in non-OOP code. We
have people who program both sides of the isle and this creates confusion.

Let's use structure names which really describe what something is. This would
help very much new people reading the code in the future, to form mental
concepts and better understand the code.

Regards,
Luben

> 
> 
>> But I have some real doubts that this is the right approach in the 
>> first place.
> 
> 
> I would like to discuss and understand more on this technical aspect. 
> Can you please have a look at the whole series and check how we have
> 
> handled the existing doorbell clients (KFD, MES), and if you feel the 
> same, we should talk more on this ?
> 
> - Shashank
> 
>>
>> Regards,
>> Christian.
>>
>>>
>>> - Shashank
>>>
>>>>
>>>> Regards,
>>>> Luben
>>>>
>>>>>     /* Reserved doorbells for amdgpu (including multimedia).
>>>>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct 
>>>>> amdgpu_device *adev,
>>>>>   int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>>                   struct amdgpu_doorbell_obj *db_obj);
>>>>>   +/**
>>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel 
>>>>> doorbells for graphics
>>>>> + *
>>>>> + * @adev: amdgpu_device pointer
>>>>> + *
>>>>> + * Creates doorbells for graphics driver
>>>>> + *
>>>>> + * returns 0 on success, error otherwise.
>>>>> + */
>>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>>>>> *adev);
>>>>> +
>>>>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), 
>>>>> (v))
>>>>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c 
>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>> index 8be15b82b545..b46fe8b1378d 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct 
>>>>> amdgpu_device *adev,
>>>>>       return 0;
>>>>>   }
>>>>>   +/**
>>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel 
>>>>> doorbells for graphics
>>>>> + *
>>>>> + * @adev: amdgpu_device pointer
>>>>> + *
>>>>> + * Creates doorbells for graphics driver
>>>>> + *
>>>>> + * returns 0 on success, error otherwise.
>>>>> + */
>>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device 
>>>>> *adev)
>>>>> +{
>>>>> +    int r;
>>>>> +    struct amdgpu_doorbell_obj *kernel_doorbells = 
>>>>> &adev->doorbell.kernel_doorbells;
>>>>> +
>>>>> +    kernel_doorbells->doorbell_bitmap = 
>>>>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>>>>> +                              GFP_KERNEL);
>>>>> +    if (!kernel_doorbells->doorbell_bitmap) {
>>>>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>>>>> +        return -ENOMEM;
>>>>> +    }
>>>>> +
>>>>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells * 
>>>>> sizeof(u32);
>>>>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>>>>> +    if (r) {
>>>>> +        bitmap_free(kernel_doorbells->doorbell_bitmap);
>>>>> +        DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n", 
>>>>> r);
>>>>> +        return r;
>>>>> +    }
>>>>> +
>>>>> +    return 0;
>>>>> +}
>>>>> +
>>>>>   /*
>>>>>    * GPU doorbell aperture helpers function.
>>>>>    */
>>>>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct 
>>>>> amdgpu_device *adev)
>>>>>           adev->doorbell.base = 0;
>>>>>           adev->doorbell.size = 0;
>>>>>           adev->doorbell.num_kernel_doorbells = 0;
>>>>> -        adev->doorbell.ptr = NULL;
>>>>>           return 0;
>>>>>       }
>>>>>   @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct 
>>>>> amdgpu_device *adev)
>>>>>       if (adev->asic_type >= CHIP_VEGA10)
>>>>>           adev->doorbell.num_kernel_doorbells += 0x400;
>>>>>   -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>>> -                     adev->doorbell.num_kernel_doorbells *
>>>>> -                     sizeof(u32));
>>>>> -    if (adev->doorbell.ptr == NULL)
>>>>> -        return -ENOMEM;
>>>>> -
>>>>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base, 
>>>>> adev->doorbell.size);
>>>>>       return 0;
>>>>>   }
>>>>>   @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct 
>>>>> amdgpu_device *adev)
>>>>>    */
>>>>>   void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>>>>   {
>>>>> -    iounmap(adev->doorbell.ptr);
>>>>> -    adev->doorbell.ptr = NULL;
>>>>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>>>>> +    amdgpu_doorbell_free_page(adev, 
>>>>> &adev->doorbell.kernel_doorbells);
>>>>>   }
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>> index 203d77a20507..75c6852845c4 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>>>>           return r;
>>>>>       }
>>>>>   +    /* Create a boorbell page for kernel usages */
>>>>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
>>>>> +    if (r) {
>>>>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
>>>>> +        return r;
>>>>> +    }
>>>>> +
>>>>>       /* Initialize preemptible memory pool */
>>>>>       r = amdgpu_preempt_mgr_init(adev);
>>>>>       if (r) {
>>


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

* Re: [PATCH 10/16] drm/amdgpu: validate doorbell read/write
  2023-03-30 14:49       ` Luben Tuikov
@ 2023-03-30 15:02         ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 15:02 UTC (permalink / raw)
  To: Luben Tuikov, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig,
	Arvind Yadav


On 30/03/2023 16:49, Luben Tuikov wrote:
> On 2023-03-30 10:37, Shashank Sharma wrote:
>> On 30/03/2023 16:34, Luben Tuikov wrote:
>>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>>> This patch:
>>>> - updates start/end values for each of the doorbell object
>>>>     created.
>>>> - adds a function which validates that the kernel doorbell read/write
>>>>     is within this range.
>>>> - uses this function during doorbell writes from kernel.
>>>>
>>>> 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>
>>>> ---
>>>>    .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 29 ++++++++++++++++---
>>>>    1 file changed, 25 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> index b46fe8b1378d..81713b2c28e1 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>> @@ -22,6 +22,25 @@
>>>>     */
>>>>    
>>>>    #include "amdgpu.h"
>>>> +#include "kfd_priv.h"
>>>> +
>>>> +static inline
>>>> +bool amdgpu_doorbell_valid(struct amdgpu_device *adev, u32 index)
>>>> +{
>>>> +	if (index >= adev->doorbell.kernel_doorbells.start &&
>>>> +	    index < adev->doorbell.kernel_doorbells.end)
>>>> +		return true;
>>>> +
>>>> +	if (index >= adev->mes.kernel_doorbells.start &&
>>>> +	    index < adev->mes.kernel_doorbells.end)
>>>> +		return true;
>>>> +
>>>> +	if (index >= adev->kfd.dev->kernel_doorbells.start &&
>>>> +	    index < adev->kfd.dev->kernel_doorbells.end)
>>>> +		return true;
>>>> +
>>>> +	return false;
>>>> +}
>>> Here you're excluding "end".
>>>
>>> In patch 7 we see this:
>>>> +	/* Last index in this object */
>>>> +	uint32_t end;
>>> Which implies that "end" is included, but in this patch, the code excludes it.
>>> Perhaps you intended to use "index <= ...end" here?
>> No, this is intended, same as array object calculation.
>>
>> end = start + size;
>>
>> max = start + size - 1
> This I understand, but "end" is NEVER "start + size" in all
> code written since 1969. "end" is outside the bounds and thus
> never used like that.
> "start" and "end" usage comes from RTL and is always inclusive,
> and "end" always fits in the same sized register as that of "start".
> But if you use "size" and add, it may overflow. So, enough history.
>
> "end" is inclusive. If this is not the case in your implementation,
> then please use "size".
>
>> so (< end) not (<= end)
>>
>> end says last index in this doorbell range;
> This I don't understand.
>
> This isn't how "start" and "end" are being used.
> Their usage comes from RTL, and is always inclusive.
>
> Either use "start" and "size" or make "end" be inclusive.
>
> I'd prefer using "start" and "size" as this is traditionally
> what is done in memory management in software (not RTL).
>
> However using "end" in software makes it tricky to calculate
> size, and one always does "end-start+1", and this could lead
> to bugs and errors.
>
> Please use "start" and "size", then.

I think I am getting your point here, it should be end inclusive in this 
case, noted.

- Shashank


>
> Regards,
> Luben
>
>
>> - Shashank
>>
>>> Since this isn't RTL, wouldn't it be better to describe the doorbell instance,
>>> with a "start" and "size"? This is traditionally used in memory management,
>>> and it makes comparisons and checks easy.
>>>
>>> Regards,
>>> Luben
>>>
>>>
>>>>    
>>>>    /**
>>>>     * amdgpu_mm_rdoorbell - read a doorbell dword
>>>> @@ -37,7 +56,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>>>>    	if (amdgpu_device_skip_hw_access(adev))
>>>>    		return 0;
>>>>    
>>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>>>    		return readl(adev->doorbell.ptr + index);
>>>>    	} else {
>>>>    		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>>>> @@ -60,7 +79,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>>>>    	if (amdgpu_device_skip_hw_access(adev))
>>>>    		return;
>>>>    
>>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>>>    		writel(v, adev->doorbell.ptr + index);
>>>>    	} else {
>>>>    		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>>>> @@ -81,7 +100,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>>>>    	if (amdgpu_device_skip_hw_access(adev))
>>>>    		return 0;
>>>>    
>>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>>>    		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>>>>    	} else {
>>>>    		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
>>>> @@ -104,7 +123,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>>>    	if (amdgpu_device_skip_hw_access(adev))
>>>>    		return;
>>>>    
>>>> -	if (index < adev->doorbell.num_kernel_doorbells) {
>>>> +	if (amdgpu_doorbell_valid(adev, index)) {
>>>>    		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>>>>    	} else {
>>>>    		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
>>>> @@ -157,6 +176,8 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>    		return r;
>>>>    	}
>>>>    
>>>> +	db_obj->start = amdgpu_doorbell_index_on_bar(adev, db_obj->bo, 0);
>>>> +	db_obj->end = db_obj->start + db_obj->size / sizeof(u32);
>>>>    	return 0;
>>>>    }
>>>>    

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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 14:48           ` Shashank Sharma
  2023-03-30 14:53             ` Christian König
@ 2023-03-30 15:04             ` Alex Deucher
  2023-03-31  8:25               ` Shashank Sharma
  1 sibling, 1 reply; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 15:04 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian König

On Thu, Mar 30, 2023 at 10:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
>
> On 30/03/2023 16:42, Christian König wrote:
> > Am 30.03.23 um 16:39 schrieb Alex Deucher:
> >> On Thu, Mar 30, 2023 at 7:49 AM Shashank Sharma
> >> <shashank.sharma@amd.com> wrote:
> >>>
> >>> On 30/03/2023 13:30, Christian König wrote:
> >>>>
> >>>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
> >>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
> >>>>>
> >>>>> This patch:
> >>>>> - creates a doorbell page for graphics driver usages.
> >>>>> - removes the adev->doorbell.ptr variable, replaces it with
> >>>>>     kernel-doorbell-bo's cpu address.
> >>>>>
> >>>>> 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_doorbell.h  | 16 ++++++-
> >>>>>    .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44
> >>>>> +++++++++++++++----
> >>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
> >>>>>    3 files changed, 57 insertions(+), 10 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >>>>> index 6581b78fe438..10a9bb10e974 100644
> >>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >>>>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
> >>>>>        /* doorbell mmio */
> >>>>>        resource_size_t        base;
> >>>>>        resource_size_t        size;
> >>>>> -    u32 __iomem        *ptr;
> >>>>> +    u32    __iomem        *ptr;
> >>>> This one can probably go away if we use the pointer from
> >>>> amdgpu_bo_create_kernel().
> >>> We started like that, but later realized that the cpu_addr from
> >>> create_kernel() will just limit us
> >>>
> >>> to that object only, whereas we are keeping this ptr to ioremap the
> >>> whole doorbell space in one shot.
> >> Why do we need that?  For the kernel driver, we'd only need to mmap
> >> the page used for kernel doorbells.  Then each user app would mmap its
> >> doorbell page.
> >
> > Yes, that is exactly my concern as well.
> >
> > The kernel needs a fixed number of doorbells allocated for its
> > internal use. Everything else should probably use the normal BO API.
> >
> > For KFD we can use the BO API internal in the kernel, but that is
> > certainly completely different to the kernel allocations.
> >
> There are 3 different kernel doorbell clients here:
>
> - graphics driver
>
> - mes (for aggregated doorbells and kernel ring test)
>
> - kfd (for kernel ring test and KIQ)
>
>
> The fix num_doorbells are just for kernel graphics driver, but We are
> allocating doorbell pages for each of those, and they all need to be
> mapped.
>
> Please see patch 12-16 for these details.

To me, it's clearer that resources managed by ttm are consistently
dealt with.  Regardless of whether we are talking about VRAM or OA or
GDS or GTT or doorbells.  When the kernel driver needs a page of vram
resources, it calls amdgpu_bo_create_kernel(), then if it needs a CPU
mmap, it calls amdgpu_bo_kmp().  Doorbells should be the same.  In
this case, the KGD would call amdgpu_bo_create_kernel(...DOORBELL..),
then create a mmap with amdgpu_bo_kmap() and then use that pointer for
its use.  KFD would do the same.  User mode doorbell allocations would
be consistent as well.

Alex


>
> - Shashank
>
> > Christian.
> >
> >>
> >> Alex
> >>
> >>> - Shashank
> >>>
> >>>>>          /* Number of doorbells reserved for amdgpu kernel driver */
> >>>>>        u32 num_kernel_doorbells;
> >>>>> +
> >>>>> +    /* For kernel doorbell pages */
> >>>>> +    struct amdgpu_doorbell_obj kernel_doorbells;
> >>>>>    };
> >>>>>      /* Reserved doorbells for amdgpu (including multimedia).
> >>>>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct
> >>>>> amdgpu_device *adev,
> >>>>>    int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> >>>>>                    struct amdgpu_doorbell_obj *db_obj);
> >>>>>    +/**
> >>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells
> >>>>> for graphics
> >>>>> + *
> >>>>> + * @adev: amdgpu_device pointer
> >>>>> + *
> >>>>> + * Creates doorbells for graphics driver
> >>>>> + *
> >>>>> + * returns 0 on success, error otherwise.
> >>>>> + */
> >>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device
> >>>>> *adev);
> >>>>> +
> >>>>>    #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
> >>>>>    #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev,
> >>>>> (index), (v))
> >>>>>    #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> >>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >>>>> index 8be15b82b545..b46fe8b1378d 100644
> >>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >>>>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct
> >>>>> amdgpu_device *adev,
> >>>>>        return 0;
> >>>>>    }
> >>>>>    +/**
> >>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells
> >>>>> for graphics
> >>>>> + *
> >>>>> + * @adev: amdgpu_device pointer
> >>>>> + *
> >>>>> + * Creates doorbells for graphics driver
> >>>>> + *
> >>>>> + * returns 0 on success, error otherwise.
> >>>>> + */
> >>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device
> >>>>> *adev)
> >>>>> +{
> >>>>> +    int r;
> >>>>> +    struct amdgpu_doorbell_obj *kernel_doorbells =
> >>>>> &adev->doorbell.kernel_doorbells;
> >>>>> +
> >>>>> +    kernel_doorbells->doorbell_bitmap =
> >>>>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
> >>>>> +                              GFP_KERNEL);
> >>>>> +    if (!kernel_doorbells->doorbell_bitmap) {
> >>>>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
> >>>>> +        return -ENOMEM;
> >>>>> +    }
> >>>>> +
> >>>>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells *
> >>>>> sizeof(u32);
> >>>>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
> >>>>> +    if (r) {
> >>>>> + bitmap_free(kernel_doorbells->doorbell_bitmap);
> >>>>> +        DRM_ERROR("Failed to allocate kernel doorbells,
> >>>>> err=%d\n", r);
> >>>>> +        return r;
> >>>>> +    }
> >>>>> +
> >>>>> +    return 0;
> >>>>> +}
> >>>>> +
> >>>>>    /*
> >>>>>     * GPU doorbell aperture helpers function.
> >>>>>     */
> >>>>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct
> >>>>> amdgpu_device *adev)
> >>>>>            adev->doorbell.base = 0;
> >>>>>            adev->doorbell.size = 0;
> >>>>>            adev->doorbell.num_kernel_doorbells = 0;
> >>>>> -        adev->doorbell.ptr = NULL;
> >>>>>            return 0;
> >>>>>        }
> >>>>>    @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct
> >>>>> amdgpu_device *adev)
> >>>>>        if (adev->asic_type >= CHIP_VEGA10)
> >>>>>            adev->doorbell.num_kernel_doorbells += 0x400;
> >>>>>    -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
> >>>>> - adev->doorbell.num_kernel_doorbells *
> >>>>> -                     sizeof(u32));
> >>>>> -    if (adev->doorbell.ptr == NULL)
> >>>>> -        return -ENOMEM;
> >>>>> -
> >>>>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base,
> >>>>> adev->doorbell.size);
> >>>>>        return 0;
> >>>>>    }
> >>>>>    @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct
> >>>>> amdgpu_device *adev)
> >>>>>     */
> >>>>>    void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
> >>>>>    {
> >>>>> -    iounmap(adev->doorbell.ptr);
> >>>>> -    adev->doorbell.ptr = NULL;
> >>>>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
> >>>>> +    amdgpu_doorbell_free_page(adev,
> >>>>> &adev->doorbell.kernel_doorbells);
> >>>>>    }
> >>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> >>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> >>>>> index 203d77a20507..75c6852845c4 100644
> >>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> >>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> >>>>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device
> >>>>> *adev)
> >>>>>            return r;
> >>>>>        }
> >>>>>    +    /* Create a boorbell page for kernel usages */
> >>>>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
> >>>>> +    if (r) {
> >>>>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
> >>>>> +        return r;
> >>>>> +    }
> >>>>> +
> >>>>>        /* Initialize preemptible memory pool */
> >>>>>        r = amdgpu_preempt_mgr_init(adev);
> >>>>>        if (r) {
> >

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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 14:59           ` Luben Tuikov
@ 2023-03-30 15:09             ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 15:09 UTC (permalink / raw)
  To: Luben Tuikov, Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma


On 30/03/2023 16:59, Luben Tuikov wrote:
> On 2023-03-30 10:53, Shashank Sharma wrote:
>> On 30/03/2023 16:49, Christian König wrote:
>>> Am 30.03.23 um 16:40 schrieb Shashank Sharma:
>>>> On 30/03/2023 16:24, Luben Tuikov wrote:
>>>>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>>>
>>>>>> This patch:
>>>>>> - creates a doorbell page for graphics driver usages.
>>>>>> - removes the adev->doorbell.ptr variable, replaces it with
>>>>>>     kernel-doorbell-bo's cpu address.
>>>>>>
>>>>>> 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_doorbell.h  | 16 ++++++-
>>>>>>    .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44
>>>>>> +++++++++++++++----
>>>>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>>>>>    3 files changed, 57 insertions(+), 10 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> index 6581b78fe438..10a9bb10e974 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>>>>>        /* doorbell mmio */
>>>>>>        resource_size_t        base;
>>>>>>        resource_size_t        size;
>>>>>> -    u32 __iomem        *ptr;
>>>>>> +    u32    __iomem        *ptr;
>>>>>>          /* Number of doorbells reserved for amdgpu kernel driver */
>>>>>>        u32 num_kernel_doorbells;
>>>>>> +
>>>>>> +    /* For kernel doorbell pages */
>>>>>> +    struct amdgpu_doorbell_obj kernel_doorbells;
>>>>>>    };
>>>>> Here's an example where it could be confusing what the difference is
>>>>> between "struct amdgpu_doorbell" and "struct amdgpu_doobell_obj".
>>>>> As the comment to the struct doorbell_obj declarations says
>>>>> in patch 7,
>>>>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>>>>>> +struct amdgpu_doorbell_obj {
>>>> What is the confusion ? This is the object which is holding doorbell
>>>> page. There could be 2 type of
>>>>
>>>> doorbell pages, kernel and process, this is a kernel one.
>>>>
>>>>> Perhaps we should call it "struct amdgpu_doorbell_bo", since
>>>>> it does contain amdgpu_bo's, which are doorbell's bos.
>>>> This is not a buffer object (memory), this is doorbell object, so
>>>> calling it bo would be wrong.
>>> I think what Luben means is that in object orient programming this
>>> here would be the class. The object is then the actual instantiation
>>> of that.
>>>
>> Why should we even bother about OOPs terminology in kernel C code ? I
>> think we are spending too much time in something not worth.
> Because you're using "object" incorrectly. Especially for people with
> vast programming experience, this creates confusion. Please don't use
> "obj" in the name of a structure. Perhaps use "bo" or "page" or something
> which it really _is_. But don't mix OOP terminology in non-OOP code. We
> have people who program both sides of the isle and this creates confusion.

The correct usage of object is valid only in context of OOP, not in C 
code.  As I have mentioned,

object or obj has been used in the existing AMDGPU code at multiple 
places, and it did not create

confusion so far, so it should be good now as well. I certainly don't 
find it a reason to change the

name of the structure.

- Shashank

> Let's use structure names which really describe what something is. This would
> help very much new people reading the code in the future, to form mental
> concepts and better understand the code.
> Regards,
> Luben
>
>>
>>> But I have some real doubts that this is the right approach in the
>>> first place.
>>
>> I would like to discuss and understand more on this technical aspect.
>> Can you please have a look at the whole series and check how we have
>>
>> handled the existing doorbell clients (KFD, MES), and if you feel the
>> same, we should talk more on this ?
>>
>> - Shashank
>>
>>> Regards,
>>> Christian.
>>>
>>>> - Shashank
>>>>
>>>>> Regards,
>>>>> Luben
>>>>>
>>>>>>      /* Reserved doorbells for amdgpu (including multimedia).
>>>>>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct
>>>>>> amdgpu_device *adev,
>>>>>>    int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>>>                    struct amdgpu_doorbell_obj *db_obj);
>>>>>>    +/**
>>>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel
>>>>>> doorbells for graphics
>>>>>> + *
>>>>>> + * @adev: amdgpu_device pointer
>>>>>> + *
>>>>>> + * Creates doorbells for graphics driver
>>>>>> + *
>>>>>> + * returns 0 on success, error otherwise.
>>>>>> + */
>>>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device
>>>>>> *adev);
>>>>>> +
>>>>>>    #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>>>    #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index),
>>>>>> (v))
>>>>>>    #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> index 8be15b82b545..b46fe8b1378d 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct
>>>>>> amdgpu_device *adev,
>>>>>>        return 0;
>>>>>>    }
>>>>>>    +/**
>>>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel
>>>>>> doorbells for graphics
>>>>>> + *
>>>>>> + * @adev: amdgpu_device pointer
>>>>>> + *
>>>>>> + * Creates doorbells for graphics driver
>>>>>> + *
>>>>>> + * returns 0 on success, error otherwise.
>>>>>> + */
>>>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device
>>>>>> *adev)
>>>>>> +{
>>>>>> +    int r;
>>>>>> +    struct amdgpu_doorbell_obj *kernel_doorbells =
>>>>>> &adev->doorbell.kernel_doorbells;
>>>>>> +
>>>>>> +    kernel_doorbells->doorbell_bitmap =
>>>>>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>>>>>> +                              GFP_KERNEL);
>>>>>> +    if (!kernel_doorbells->doorbell_bitmap) {
>>>>>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>>>>>> +        return -ENOMEM;
>>>>>> +    }
>>>>>> +
>>>>>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells *
>>>>>> sizeof(u32);
>>>>>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>>>>>> +    if (r) {
>>>>>> +        bitmap_free(kernel_doorbells->doorbell_bitmap);
>>>>>> +        DRM_ERROR("Failed to allocate kernel doorbells, err=%d\n",
>>>>>> r);
>>>>>> +        return r;
>>>>>> +    }
>>>>>> +
>>>>>> +    return 0;
>>>>>> +}
>>>>>> +
>>>>>>    /*
>>>>>>     * GPU doorbell aperture helpers function.
>>>>>>     */
>>>>>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct
>>>>>> amdgpu_device *adev)
>>>>>>            adev->doorbell.base = 0;
>>>>>>            adev->doorbell.size = 0;
>>>>>>            adev->doorbell.num_kernel_doorbells = 0;
>>>>>> -        adev->doorbell.ptr = NULL;
>>>>>>            return 0;
>>>>>>        }
>>>>>>    @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct
>>>>>> amdgpu_device *adev)
>>>>>>        if (adev->asic_type >= CHIP_VEGA10)
>>>>>>            adev->doorbell.num_kernel_doorbells += 0x400;
>>>>>>    -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>>>> -                     adev->doorbell.num_kernel_doorbells *
>>>>>> -                     sizeof(u32));
>>>>>> -    if (adev->doorbell.ptr == NULL)
>>>>>> -        return -ENOMEM;
>>>>>> -
>>>>>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>>>> adev->doorbell.size);
>>>>>>        return 0;
>>>>>>    }
>>>>>>    @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct
>>>>>> amdgpu_device *adev)
>>>>>>     */
>>>>>>    void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>>>>>    {
>>>>>> -    iounmap(adev->doorbell.ptr);
>>>>>> -    adev->doorbell.ptr = NULL;
>>>>>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>>>>>> +    amdgpu_doorbell_free_page(adev,
>>>>>> &adev->doorbell.kernel_doorbells);
>>>>>>    }
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> index 203d77a20507..75c6852845c4 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>>>>>            return r;
>>>>>>        }
>>>>>>    +    /* Create a boorbell page for kernel usages */
>>>>>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
>>>>>> +    if (r) {
>>>>>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
>>>>>> +        return r;
>>>>>> +    }
>>>>>> +
>>>>>>        /* Initialize preemptible memory pool */
>>>>>>        r = amdgpu_preempt_mgr_init(adev);
>>>>>>        if (r) {

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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 14:55           ` Alex Deucher
@ 2023-03-30 15:21             ` Shashank Sharma
  2023-03-30 20:35               ` Alex Deucher
  0 siblings, 1 reply; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 15:21 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Luben Tuikov, Alex Deucher,
	Shashank Sharma, Christian Koenig


On 30/03/2023 16:55, Alex Deucher wrote:
> On Thu, Mar 30, 2023 at 10:34 AM Shashank Sharma
> <shashank.sharma@amd.com> wrote:
>>
>> On 30/03/2023 16:15, Luben Tuikov wrote:
>>> On 2023-03-30 10:04, Shashank Sharma wrote:
>>>> On 30/03/2023 15:42, Luben Tuikov wrote:
>>>>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>>>
>>>>>> This patch adds helper functions to create and free doorbell
>>>>>> pages for kernel objects.
>>>>>>
>>>>>> 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_doorbell.h  | 41 ++++++++++++++++
>>>>>>     .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>>>>>>     2 files changed, 90 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> index f9c3b77bf65d..6581b78fe438 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>> @@ -27,6 +27,24 @@
>>>>>>     /*
>>>>>>      * GPU doorbell structures, functions & helpers
>>>>>>      */
>>>>>> +
>>>>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>>>>>> +struct amdgpu_doorbell_obj {
>>>>> In the comment you say "Structure to hold ...";
>>>>> it is a C structure, but then in the name of a function we see "obj".
>>>>> (Object is something which is defined like in memory, i.e. it exists, not
>>>>> something which is only declared.)
>>>>> This is just a declaration of a structure, not an object per se.
>>>>> I'd call it "struct amdgpu_doorbell_struct" or just "struct amdgpu_doorbell".
>>>> It is similar to struct amdgpu buffer object (struct amdgpu_bo), and
>>>> many more existing structure.
>>> The amdpgu_bo is very different than a structure describing a doorbell.
>>> The doorbell description isn't really "an object". I understand
>>> the enthusiasm, but it is really not "an object". It's just a doorbell
>>> description. :-)
>> amdgpu_bo is page of ttm_memory with additional information,
>>
>> amdgpu_doorbell_obj is a page of ttm_doorbells with additional information
>>
>> (it is not just one doorbell description)
>>
>> I don't see a problem here.
> I find the new API confusing.  I would expect to see
> amdgpu_bo_create_kernel(...DOORBELL...), amdgpu_bo_reserve(),
> amdgpu_bo_kmap(), etc.  That makes it consistent with the other
> resource pools that we manage in ttm.

I am assuming here you are talking about why do we need 
amdgpu_doorbell_page_create()/free() API here.

The wrappers here allow us to do additional book keeping work.

For example:

- We need to validate kernel doorbell writes, which means we need the 
range of kernel doorbells.

- There are 3 kernel doorbell pages, for KGD, KFD and MES. These are non 
consecutive pages.

- While we do doorbell_write in kernel, we need to check if this index 
is correct, which means:

kgd_doobrell_min < index < kgd_doorbell_max

kfd_doobrell_min < index < kgd_doorbell_max

mes_doobrell_min < index < kgd_doorbell_max

- which means we need start/end limits set at every object.

- we have to either do this work at each place where we want to call 
amdgpu_bo_create(DOORBELL)

   which means KFD, KGD and MES all places (which will look irrelevant 
in the context)

  or we can do this in one place, which is the doorbell wrapper API.


Please see patch 10 for this range check.


- Shashank


now kfd is setting start/end limits by calling 
amdgpu_get_doorbell_index() function.

>
> Alex
>
>> - Shashank
>>
>>> Regards,
>>> Luben
>>>
>>>> - Shashank
>>>>
>>>>> Then in the definition, you can call it an object/objects, if you'd like,
>>>>> like "struct amdgpu_doorbell *doorb_object[];" then you can say
>>>>> "db = doorb_object[i]";
>>>>>
>>>>> Regards,
>>>>> Luben
>>>>>
>>>>>> +  struct amdgpu_bo *bo;
>>>>>> +  uint64_t gpu_addr;
>>>>>> +  uint32_t *cpu_addr;
>>>>>> +  uint32_t size;
>>>>>> +
>>>>>> +  /* First index in this object */
>>>>>> +  uint32_t start;
>>>>>> +
>>>>>> +  /* Last index in this object */
>>>>>> +  uint32_t end;
>>>>>> +
>>>>>> +  /* bitmap for dynamic doorbell allocation from this object */
>>>>>> +  unsigned long *doorbell_bitmap;
>>>>>> +};
>>>>>> +
>>>>>>     struct amdgpu_doorbell {
>>>>>>             /* doorbell mmio */
>>>>>>             resource_size_t         base;
>>>>>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>>>>>>      */
>>>>>>     void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>>>>>>
>>>>>> +/**
>>>>>> + * amdgpu_doorbell_free_page - Free a doorbell page
>>>>>> + *
>>>>>> + * @adev: amdgpu_device pointer
>>>>>> + *
>>>>>> + * @db_age: previously allocated doobell page details
>>>>>> + *
>>>>>> + */
>>>>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>>>>> +                          struct amdgpu_doorbell_obj *db_obj);
>>>>>> +
>>>>>> +/**
>>>>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>>>>>> + *
>>>>>> + * @adev: amdgpu_device pointer
>>>>>> + *
>>>>>> + * @db_age: doobell page structure to fill details with
>>>>>> + *
>>>>>> + * returns 0 on success, else error number
>>>>>> + */
>>>>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>>> +                          struct amdgpu_doorbell_obj *db_obj);
>>>>>> +
>>>>>>     #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>>>     #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>>>>>     #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> index 1aea92363fd3..8be15b82b545 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>>>>>             }
>>>>>>     }
>>>>>>
>>>>>> +/**
>>>>>> + * amdgpu_doorbell_free_page - Free a doorbell page
>>>>>> + *
>>>>>> + * @adev: amdgpu_device pointer
>>>>>> + *
>>>>>> + * @db_age: previously allocated doobell page details
>>>>>> + *
>>>>>> + */
>>>>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>>>>> +                                  struct amdgpu_doorbell_obj *db_obj)
>>>>>> +{
>>>>>> +  amdgpu_bo_free_kernel(&db_obj->bo,
>>>>>> +                        &db_obj->gpu_addr,
>>>>>> +                        (void **)&db_obj->cpu_addr);
>>>>>> +
>>>>>> +}
>>>>>> +
>>>>>> +/**
>>>>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>>>>>> + *
>>>>>> + * @adev: amdgpu_device pointer
>>>>>> + *
>>>>>> + * @db_age: doobell page structure to fill details with
>>>>>> + *
>>>>>> + * returns 0 on success, else error number
>>>>>> + */
>>>>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>>> +                          struct amdgpu_doorbell_obj *db_obj)
>>>>>> +{
>>>>>> +  int r;
>>>>>> +
>>>>>> +  db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
>>>>>> +
>>>>>> +  r = amdgpu_bo_create_kernel(adev,
>>>>>> +                              db_obj->size,
>>>>>> +                              PAGE_SIZE,
>>>>>> +                              AMDGPU_GEM_DOMAIN_DOORBELL,
>>>>>> +                              &db_obj->bo,
>>>>>> +                              &db_obj->gpu_addr,
>>>>>> +                              (void **)&db_obj->cpu_addr);
>>>>>> +
>>>>>> +  if (r) {
>>>>>> +          DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
>>>>>> +          return r;
>>>>>> +  }
>>>>>> +
>>>>>> +  return 0;
>>>>>> +}
>>>>>> +
>>>>>>     /*
>>>>>>      * GPU doorbell aperture helpers function.
>>>>>>      */

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

* Re: [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
  2023-03-30 14:12             ` Luben Tuikov
@ 2023-03-30 15:32               ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 15:32 UTC (permalink / raw)
  To: Luben Tuikov, Christian König, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling


On 30/03/2023 16:12, Luben Tuikov wrote:
> On 2023-03-30 09:48, Shashank Sharma wrote:
>> On 30/03/2023 15:45, Luben Tuikov wrote:
>>> On 2023-03-30 09:43, Shashank Sharma wrote:
>>>> On 30/03/2023 15:33, Luben Tuikov wrote:
>>>>> On 2023-03-30 07:14, Christian König wrote:
>>>>>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>>>>>>> From: Alex Deucher <alexander.deucher@amd.com>
>>>>>>>
>>>>>>> This patch adds changes:
>>>>>>> - to accommodate the new GEM domain DOORBELL
>>>>>>> - to accommodate the new TTM PL DOORBELL
>>>>>>>
>>>>>>> in order to manage doorbell pages as GEM object.
>>>>>>>
>>>>>>> V2: Addressed reviwe comments from Christian
>>>>>>>         - drop the doorbell changes for pinning/unpinning
>>>>>>>         - drop the doorbell changes for dma-buf map
>>>>>>>         - drop the doorbell changes for sgt
>>>>>>>         - no need to handle TTM_PL_FLAG_CONTIGUOUS for doorbell
>>>>>>>         - add caching type for doorbell
>>>>>>>
>>>>>>> Cc: Alex Deucher <alexander.deucher@amd.com>
>>>>>>> Cc: Christian Koenig <christian.koenig@amd.com>
>>>>>>>
>>>>>>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>>>>>>> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
>>>>> Generally there are no empty lines in the tag list. Perhaps remove it?
>>>> I would prefer to keep it, to highlight the CC parts.
>>> I've never seen a commit with them separated. Perhaps follow Linux custom?
>> IIRC This is not against Linux patch formatting/message body guidelines.
> The tag list forms a block, a paragraph, which is easy to scan and separate out
> of the description of the patch, which in itself can have many paragraphs separated
> by white lines: subject line, paragraph 1, paragraph 2, ..., paragraph of tags.
> Furthermore these tags are added/appended by automated scripts/tools which wouldn't
> add an empty line.
>
> Check out the following resources:
> https://www.kernel.org/doc/html/v4.12/process/5.Posting.html#patch-formatting-and-changelogs
> https://www.kernel.org/doc/html/v4.12/process/submitting-patches.html#the-canonical-patch-format
>
> "git log -- drivers/gpu/drm/." is also a very helpful reference to see some good patch formatting.
>
> Please remove the empty line between the Cc and Sob lines, so it forms a tag paragraph.

Certainly makes sense, agreed.

- Shashank

>
> Regards,
> Luben
>
>
>> - Shashank
>>
>>> Regards,
>>> Luben
>>>
>>>> - Shashank
>>>>
>>>>> Regards,
>>>>> Luben
>>>>>
>>>>>>> ---
>>>>>>>      drivers/gpu/drm/amd/amdgpu/amdgpu_object.c     | 11 ++++++++++-
>>>>>>>      drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h |  2 ++
>>>>>>>      drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c        | 16 +++++++++++++++-
>>>>>>>      drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h        |  1 +
>>>>>>>      4 files changed, 28 insertions(+), 2 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>>>>> index 4e684c2afc70..0ec080e240ad 100644
>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
>>>>>>> @@ -147,6 +147,14 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
>>>>>>>      		c++;
>>>>>>>      	}
>>>>>>>      
>>>>>>> +	if (domain & AMDGPU_GEM_DOMAIN_DOORBELL) {
>>>>>>> +		places[c].fpfn = 0;
>>>>>>> +		places[c].lpfn = 0;
>>>>>>> +		places[c].mem_type = AMDGPU_PL_DOORBELL;
>>>>>>> +		places[c].flags = 0;
>>>>>>> +		c++;
>>>>>>> +	}
>>>>>>> +
>>>>>>>      	if (domain & AMDGPU_GEM_DOMAIN_GTT) {
>>>>>>>      		places[c].fpfn = 0;
>>>>>>>      		places[c].lpfn = 0;
>>>>>>> @@ -466,7 +474,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
>>>>>>>      		goto fail;
>>>>>>>      	}
>>>>>>>      
>>>>>>> -	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
>>>>>>> +	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU,  AMDGPU_GEM_DOMAIN_DOORBELL */
>>>>>>>      	return true;
>>>>>>>      
>>>>>>>      fail:
>>>>>>> @@ -1013,6 +1021,7 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo)
>>>>>>>      	} else if (bo->tbo.resource->mem_type == TTM_PL_TT) {
>>>>>>>      		atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size);
>>>>>>>      	}
>>>>>>> +
>>>>>> Unrelated newline, probably just a leftover.
>>>>>>
>>>>>> Apart from that the patch is Reviewed-by: Christian König
>>>>>> <christian.koenig@amd.com>
>>>>>>
>>>>>> Regards,
>>>>>> Christian.
>>>>>>
>>>>>>>      }
>>>>>>>      
>>>>>>>      static const char *amdgpu_vram_names[] = {
>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>>>>> index 5c4f93ee0c57..3c988cc406e4 100644
>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
>>>>>>> @@ -90,6 +90,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
>>>>>>>      		cur->node = block;
>>>>>>>      		break;
>>>>>>>      	case TTM_PL_TT:
>>>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>>>      		node = to_ttm_range_mgr_node(res)->mm_nodes;
>>>>>>>      		while (start >= node->size << PAGE_SHIFT)
>>>>>>>      			start -= node++->size << PAGE_SHIFT;
>>>>>>> @@ -152,6 +153,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
>>>>>>>      		cur->size = min(amdgpu_vram_mgr_block_size(block), cur->remaining);
>>>>>>>      		break;
>>>>>>>      	case TTM_PL_TT:
>>>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>>>      		node = cur->node;
>>>>>>>      
>>>>>>>      		cur->node = ++node;
>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>>> index 55e0284b2bdd..6f61491ef3dd 100644
>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>>> @@ -128,6 +128,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
>>>>>>>      	case AMDGPU_PL_GDS:
>>>>>>>      	case AMDGPU_PL_GWS:
>>>>>>>      	case AMDGPU_PL_OA:
>>>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>>>      		placement->num_placement = 0;
>>>>>>>      		placement->num_busy_placement = 0;
>>>>>>>      		return;
>>>>>>> @@ -500,9 +501,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
>>>>>>>      	if (old_mem->mem_type == AMDGPU_PL_GDS ||
>>>>>>>      	    old_mem->mem_type == AMDGPU_PL_GWS ||
>>>>>>>      	    old_mem->mem_type == AMDGPU_PL_OA ||
>>>>>>> +	    old_mem->mem_type == AMDGPU_PL_DOORBELL ||
>>>>>>>      	    new_mem->mem_type == AMDGPU_PL_GDS ||
>>>>>>>      	    new_mem->mem_type == AMDGPU_PL_GWS ||
>>>>>>> -	    new_mem->mem_type == AMDGPU_PL_OA) {
>>>>>>> +	    new_mem->mem_type == AMDGPU_PL_OA ||
>>>>>>> +	    new_mem->mem_type == AMDGPU_PL_DOORBELL) {
>>>>>>>      		/* Nothing to save here */
>>>>>>>      		ttm_bo_move_null(bo, new_mem);
>>>>>>>      		goto out;
>>>>>>> @@ -586,6 +589,12 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
>>>>>>>      		mem->bus.offset += adev->gmc.aper_base;
>>>>>>>      		mem->bus.is_iomem = true;
>>>>>>>      		break;
>>>>>>> +	case AMDGPU_PL_DOORBELL:
>>>>>>> +		mem->bus.offset = mem->start << PAGE_SHIFT;
>>>>>>> +		mem->bus.offset += adev->doorbell.base;
>>>>>>> +		mem->bus.is_iomem = true;
>>>>>>> +		mem->bus.caching = ttm_uncached;
>>>>>>> +		break;
>>>>>>>      	default:
>>>>>>>      		return -EINVAL;
>>>>>>>      	}
>>>>>>> @@ -600,6 +609,10 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
>>>>>>>      
>>>>>>>      	amdgpu_res_first(bo->resource, (u64)page_offset << PAGE_SHIFT, 0,
>>>>>>>      			 &cursor);
>>>>>>> +
>>>>>>> +	if (bo->resource->mem_type == AMDGPU_PL_DOORBELL)
>>>>>>> +		return ((uint64_t)(adev->doorbell.base + cursor.start)) >> PAGE_SHIFT;
>>>>>>> +
>>>>>>>      	return (adev->gmc.aper_base + cursor.start) >> PAGE_SHIFT;
>>>>>>>      }
>>>>>>>      
>>>>>>> @@ -1267,6 +1280,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem)
>>>>>>>      		flags |= AMDGPU_PTE_VALID;
>>>>>>>      
>>>>>>>      	if (mem && (mem->mem_type == TTM_PL_TT ||
>>>>>>> +		    mem->mem_type == AMDGPU_PL_DOORBELL ||
>>>>>>>      		    mem->mem_type == AMDGPU_PL_PREEMPT)) {
>>>>>>>      		flags |= AMDGPU_PTE_SYSTEM;
>>>>>>>      
>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>>>>> index e2cd5894afc9..761cd6b2b942 100644
>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
>>>>>>> @@ -33,6 +33,7 @@
>>>>>>>      #define AMDGPU_PL_GWS		(TTM_PL_PRIV + 1)
>>>>>>>      #define AMDGPU_PL_OA		(TTM_PL_PRIV + 2)
>>>>>>>      #define AMDGPU_PL_PREEMPT	(TTM_PL_PRIV + 3)
>>>>>>> +#define AMDGPU_PL_DOORBELL	(TTM_PL_PRIV + 4)
>>>>>>>      
>>>>>>>      #define AMDGPU_GTT_MAX_TRANSFER_SIZE	512
>>>>>>>      #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS	2

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

* Re: [PATCH 11/16] drm/amdgpu: get absolute offset from doorbell index
  2023-03-29 15:47 ` [PATCH 11/16] drm/amdgpu: get absolute offset from doorbell index Shashank Sharma
@ 2023-03-30 17:18   ` Luben Tuikov
  2023-03-30 17:25     ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Luben Tuikov @ 2023-03-30 17:18 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig

On 2023-03-29 11:47, Shashank Sharma wrote:
> This patch adds a helper function which converts a doorbell's
> relative index in a BO to an absolute doorbell offset in the
> doorbell BAR.
> 
> 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_doorbell.h  | 15 +++++++++++
>  .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 26 +++++++++++++++++++
>  2 files changed, 41 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 10a9bb10e974..3481e9d83879 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -383,6 +383,21 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>   */
>  int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev);
>  
> +/**
> + * amdgpu_doorbell_index_on_bar - Find doorbell's absolute offset in BAR
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_bo: doorbell object's bo
> + *
> + * @db_index: doorbell relative index in this doorbell object
> + *
> + * returns doorbell's absolute index in BAR
> + */
> +uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev,
> +				       struct amdgpu_bo *db_bo,
> +				       uint32_t doorbell_index);
> +

Two things:
1. No kernel doc for function declarations--this should go to where
the function is defined. (This also removes redundancy.)

2. No empty lines around function arguments in kernel doc. See this about
the format of function documentation:
https://www.kernel.org/doc/html/v4.12/doc-guide/kernel-doc.html#function-documentation

>  #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>  #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>  #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> index 81713b2c28e1..c263bae6b0c4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> @@ -130,6 +130,32 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>  	}
>  }
>  
> +/**
> + * amdgpu_doorbell_index_on_bar - Find doorbell's absolute offset in BAR
> + *
> + * @adev: amdgpu_device pointer
> + *
> + * @db_bo: doorbell object's bo
> + *
> + * @db_index: doorbell relative index in this doorbell object
> + *
> + * returns doorbell's absolute index in BAR
> + */
> +uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev,
> +				       struct amdgpu_bo *db_bo,
> +				       uint32_t doorbell_index)
> +{
> +	int db_bo_offset;
> +
> +	db_bo_offset = amdgpu_bo_gpu_offset_no_check(db_bo);

amdgpu_bo_gpu_offset_no_check() returns u64. Perhaps use u64,
or u32 (which is what this function returns) and cast it down.

> +
> +	/*
> +	 * doorbell index granularity is maintained at 32 bit
> +	 * but doorbell's size is 64-bit, so index * 2
> +	 */
> +	return db_bo_offset / sizeof(u32) + doorbell_index * 2;

Perhaps add this inside the comment:
* (db_bo_offset + doorbell_index * 8) / sizeof(u32),
which seems clearer to me. But leave the return as is.

Regards,
Luben

> +}
> +
>  /**
>   * amdgpu_doorbell_free_page - Free a doorbell page
>   *


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

* Re: [PATCH 11/16] drm/amdgpu: get absolute offset from doorbell index
  2023-03-30 17:18   ` Luben Tuikov
@ 2023-03-30 17:25     ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-30 17:25 UTC (permalink / raw)
  To: Luben Tuikov, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig


On 30/03/2023 19:18, Luben Tuikov wrote:
> On 2023-03-29 11:47, Shashank Sharma wrote:
>> This patch adds a helper function which converts a doorbell's
>> relative index in a BO to an absolute doorbell offset in the
>> doorbell BAR.
>>
>> 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_doorbell.h  | 15 +++++++++++
>>   .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 26 +++++++++++++++++++
>>   2 files changed, 41 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> index 10a9bb10e974..3481e9d83879 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>> @@ -383,6 +383,21 @@ int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>    */
>>   int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device *adev);
>>   
>> +/**
>> + * amdgpu_doorbell_index_on_bar - Find doorbell's absolute offset in BAR
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_bo: doorbell object's bo
>> + *
>> + * @db_index: doorbell relative index in this doorbell object
>> + *
>> + * returns doorbell's absolute index in BAR
>> + */
>> +uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev,
>> +				       struct amdgpu_bo *db_bo,
>> +				       uint32_t doorbell_index);
>> +
> Two things:
> 1. No kernel doc for function declarations--this should go to where
> the function is defined. (This also removes redundancy.)
>
> 2. No empty lines around function arguments in kernel doc. See this about
> the format of function documentation:
> https://www.kernel.org/doc/html/v4.12/doc-guide/kernel-doc.html#function-documentation

Noted, agreed.

>>   #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>   #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>   #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> index 81713b2c28e1..c263bae6b0c4 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>> @@ -130,6 +130,32 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>   	}
>>   }
>>   
>> +/**
>> + * amdgpu_doorbell_index_on_bar - Find doorbell's absolute offset in BAR
>> + *
>> + * @adev: amdgpu_device pointer
>> + *
>> + * @db_bo: doorbell object's bo
>> + *
>> + * @db_index: doorbell relative index in this doorbell object
>> + *
>> + * returns doorbell's absolute index in BAR
>> + */
>> +uint32_t amdgpu_doorbell_index_on_bar(struct amdgpu_device *adev,
>> +				       struct amdgpu_bo *db_bo,
>> +				       uint32_t doorbell_index)
>> +{
>> +	int db_bo_offset;
>> +
>> +	db_bo_offset = amdgpu_bo_gpu_offset_no_check(db_bo);
> amdgpu_bo_gpu_offset_no_check() returns u64. Perhaps use u64,
> or u32 (which is what this function returns) and cast it down.

Yeah, makes sense, will do it.

- Shashank

>> +
>> +	/*
>> +	 * doorbell index granularity is maintained at 32 bit
>> +	 * but doorbell's size is 64-bit, so index * 2
>> +	 */
>> +	return db_bo_offset / sizeof(u32) + doorbell_index * 2;
> Perhaps add this inside the comment:
> * (db_bo_offset + doorbell_index * 8) / sizeof(u32),
> which seems clearer to me. But leave the return as is.
> Regards,
> Luben
>
>> +}
>> +
>>   /**
>>    * amdgpu_doorbell_free_page - Free a doorbell page
>>    *

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

* Re: [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL
  2023-03-29 15:47 ` [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL Shashank Sharma
  2023-03-30 11:14   ` Christian König
@ 2023-03-30 19:59   ` Alex Deucher
  1 sibling, 0 replies; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 19:59 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig, amd-gfx

On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
> From: Alex Deucher <alexander.deucher@amd.com>
>
> This patch adds changes:
> - to accommodate the new GEM domain DOORBELL
> - to accommodate the new TTM PL DOORBELL
>
> in order to manage doorbell pages as GEM object.
>
> V2: Addressed reviwe comments from Christian
>     - drop the doorbell changes for pinning/unpinning
>     - drop the doorbell changes for dma-buf map
>     - drop the doorbell changes for sgt
>     - no need to handle TTM_PL_FLAG_CONTIGUOUS for doorbell
>     - add caching type for doorbell
>
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_object.c     | 11 ++++++++++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h |  2 ++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c        | 16 +++++++++++++++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h        |  1 +

Also need to update amdgpu_mem_type_to_domain() in amdgpu_object.h

Alex

>  4 files changed, 28 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> index 4e684c2afc70..0ec080e240ad 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> @@ -147,6 +147,14 @@ void amdgpu_bo_placement_from_domain(struct amdgpu_bo *abo, u32 domain)
>                 c++;
>         }
>
> +       if (domain & AMDGPU_GEM_DOMAIN_DOORBELL) {
> +               places[c].fpfn = 0;
> +               places[c].lpfn = 0;
> +               places[c].mem_type = AMDGPU_PL_DOORBELL;
> +               places[c].flags = 0;
> +               c++;
> +       }
> +
>         if (domain & AMDGPU_GEM_DOMAIN_GTT) {
>                 places[c].fpfn = 0;
>                 places[c].lpfn = 0;
> @@ -466,7 +474,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
>                 goto fail;
>         }
>
> -       /* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
> +       /* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU,  AMDGPU_GEM_DOMAIN_DOORBELL */
>         return true;
>
>  fail:
> @@ -1013,6 +1021,7 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo)
>         } else if (bo->tbo.resource->mem_type == TTM_PL_TT) {
>                 atomic64_sub(amdgpu_bo_size(bo), &adev->gart_pin_size);
>         }
> +
>  }
>
>  static const char *amdgpu_vram_names[] = {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
> index 5c4f93ee0c57..3c988cc406e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h
> @@ -90,6 +90,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
>                 cur->node = block;
>                 break;
>         case TTM_PL_TT:
> +       case AMDGPU_PL_DOORBELL:
>                 node = to_ttm_range_mgr_node(res)->mm_nodes;
>                 while (start >= node->size << PAGE_SHIFT)
>                         start -= node++->size << PAGE_SHIFT;
> @@ -152,6 +153,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
>                 cur->size = min(amdgpu_vram_mgr_block_size(block), cur->remaining);
>                 break;
>         case TTM_PL_TT:
> +       case AMDGPU_PL_DOORBELL:
>                 node = cur->node;
>
>                 cur->node = ++node;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 55e0284b2bdd..6f61491ef3dd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -128,6 +128,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
>         case AMDGPU_PL_GDS:
>         case AMDGPU_PL_GWS:
>         case AMDGPU_PL_OA:
> +       case AMDGPU_PL_DOORBELL:
>                 placement->num_placement = 0;
>                 placement->num_busy_placement = 0;
>                 return;
> @@ -500,9 +501,11 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
>         if (old_mem->mem_type == AMDGPU_PL_GDS ||
>             old_mem->mem_type == AMDGPU_PL_GWS ||
>             old_mem->mem_type == AMDGPU_PL_OA ||
> +           old_mem->mem_type == AMDGPU_PL_DOORBELL ||
>             new_mem->mem_type == AMDGPU_PL_GDS ||
>             new_mem->mem_type == AMDGPU_PL_GWS ||
> -           new_mem->mem_type == AMDGPU_PL_OA) {
> +           new_mem->mem_type == AMDGPU_PL_OA ||
> +           new_mem->mem_type == AMDGPU_PL_DOORBELL) {
>                 /* Nothing to save here */
>                 ttm_bo_move_null(bo, new_mem);
>                 goto out;
> @@ -586,6 +589,12 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
>                 mem->bus.offset += adev->gmc.aper_base;
>                 mem->bus.is_iomem = true;
>                 break;
> +       case AMDGPU_PL_DOORBELL:
> +               mem->bus.offset = mem->start << PAGE_SHIFT;
> +               mem->bus.offset += adev->doorbell.base;
> +               mem->bus.is_iomem = true;
> +               mem->bus.caching = ttm_uncached;
> +               break;
>         default:
>                 return -EINVAL;
>         }
> @@ -600,6 +609,10 @@ static unsigned long amdgpu_ttm_io_mem_pfn(struct ttm_buffer_object *bo,
>
>         amdgpu_res_first(bo->resource, (u64)page_offset << PAGE_SHIFT, 0,
>                          &cursor);
> +
> +       if (bo->resource->mem_type == AMDGPU_PL_DOORBELL)
> +               return ((uint64_t)(adev->doorbell.base + cursor.start)) >> PAGE_SHIFT;
> +
>         return (adev->gmc.aper_base + cursor.start) >> PAGE_SHIFT;
>  }
>
> @@ -1267,6 +1280,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem)
>                 flags |= AMDGPU_PTE_VALID;
>
>         if (mem && (mem->mem_type == TTM_PL_TT ||
> +                   mem->mem_type == AMDGPU_PL_DOORBELL ||
>                     mem->mem_type == AMDGPU_PL_PREEMPT)) {
>                 flags |= AMDGPU_PTE_SYSTEM;
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> index e2cd5894afc9..761cd6b2b942 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
> @@ -33,6 +33,7 @@
>  #define AMDGPU_PL_GWS          (TTM_PL_PRIV + 1)
>  #define AMDGPU_PL_OA           (TTM_PL_PRIV + 2)
>  #define AMDGPU_PL_PREEMPT      (TTM_PL_PRIV + 3)
> +#define AMDGPU_PL_DOORBELL     (TTM_PL_PRIV + 4)
>
>  #define AMDGPU_GTT_MAX_TRANSFER_SIZE   512
>  #define AMDGPU_GTT_NUM_TRANSFER_WINDOWS        2
> --
> 2.40.0
>

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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 15:21             ` Shashank Sharma
@ 2023-03-30 20:35               ` Alex Deucher
  2023-03-31  8:26                 ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 20:35 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Luben Tuikov, Alex Deucher,
	Shashank Sharma, Christian Koenig

On Thu, Mar 30, 2023 at 11:21 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
>
> On 30/03/2023 16:55, Alex Deucher wrote:
> > On Thu, Mar 30, 2023 at 10:34 AM Shashank Sharma
> > <shashank.sharma@amd.com> wrote:
> >>
> >> On 30/03/2023 16:15, Luben Tuikov wrote:
> >>> On 2023-03-30 10:04, Shashank Sharma wrote:
> >>>> On 30/03/2023 15:42, Luben Tuikov wrote:
> >>>>> On 2023-03-29 11:47, Shashank Sharma wrote:
> >>>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
> >>>>>>
> >>>>>> This patch adds helper functions to create and free doorbell
> >>>>>> pages for kernel objects.
> >>>>>>
> >>>>>> 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_doorbell.h  | 41 ++++++++++++++++
> >>>>>>     .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
> >>>>>>     2 files changed, 90 insertions(+)
> >>>>>>
> >>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >>>>>> index f9c3b77bf65d..6581b78fe438 100644
> >>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> >>>>>> @@ -27,6 +27,24 @@
> >>>>>>     /*
> >>>>>>      * GPU doorbell structures, functions & helpers
> >>>>>>      */
> >>>>>> +
> >>>>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
> >>>>>> +struct amdgpu_doorbell_obj {
> >>>>> In the comment you say "Structure to hold ...";
> >>>>> it is a C structure, but then in the name of a function we see "obj".
> >>>>> (Object is something which is defined like in memory, i.e. it exists, not
> >>>>> something which is only declared.)
> >>>>> This is just a declaration of a structure, not an object per se.
> >>>>> I'd call it "struct amdgpu_doorbell_struct" or just "struct amdgpu_doorbell".
> >>>> It is similar to struct amdgpu buffer object (struct amdgpu_bo), and
> >>>> many more existing structure.
> >>> The amdpgu_bo is very different than a structure describing a doorbell.
> >>> The doorbell description isn't really "an object". I understand
> >>> the enthusiasm, but it is really not "an object". It's just a doorbell
> >>> description. :-)
> >> amdgpu_bo is page of ttm_memory with additional information,
> >>
> >> amdgpu_doorbell_obj is a page of ttm_doorbells with additional information
> >>
> >> (it is not just one doorbell description)
> >>
> >> I don't see a problem here.
> > I find the new API confusing.  I would expect to see
> > amdgpu_bo_create_kernel(...DOORBELL...), amdgpu_bo_reserve(),
> > amdgpu_bo_kmap(), etc.  That makes it consistent with the other
> > resource pools that we manage in ttm.
>
> I am assuming here you are talking about why do we need
> amdgpu_doorbell_page_create()/free() API here.
>
> The wrappers here allow us to do additional book keeping work.
>
> For example:
>
> - We need to validate kernel doorbell writes, which means we need the
> range of kernel doorbells.
>
> - There are 3 kernel doorbell pages, for KGD, KFD and MES. These are non
> consecutive pages.
>
> - While we do doorbell_write in kernel, we need to check if this index
> is correct, which means:
>
> kgd_doobrell_min < index < kgd_doorbell_max
>
> kfd_doobrell_min < index < kgd_doorbell_max
>
> mes_doobrell_min < index < kgd_doorbell_max
>
> - which means we need start/end limits set at every object.
>
> - we have to either do this work at each place where we want to call
> amdgpu_bo_create(DOORBELL)
>
>    which means KFD, KGD and MES all places (which will look irrelevant
> in the context)
>
>   or we can do this in one place, which is the doorbell wrapper API.
>
>
> Please see patch 10 for this range check.

I don't think we need the range checks for anything other than the
KGD.  The MES stuff should just use the same allocation as KGD.  KFD
has their own mapping in kfd_doorbell.c and they don't use the
WDOORBELL[64] macros.

Alex

>
>
> - Shashank
>
>
> now kfd is setting start/end limits by calling
> amdgpu_get_doorbell_index() function.
>
> >
> > Alex
> >
> >> - Shashank
> >>
> >>> Regards,
> >>> Luben
> >>>
> >>>> - Shashank
> >>>>
> >>>>> Then in the definition, you can call it an object/objects, if you'd like,
> >>>>> like "struct amdgpu_doorbell *doorb_object[];" then you can say
> >>>>> "db = doorb_object[i]";
> >>>>>
> >>>>> Regards,
> >>>>> Luben
> >>>>>
> >>>>>> +  struct amdgpu_bo *bo;
> >>>>>> +  uint64_t gpu_addr;
> >>>>>> +  uint32_t *cpu_addr;
> >>>>>> +  uint32_t size;
> >>>>>> +
> >>>>>> +  /* First index in this object */
> >>>>>> +  uint32_t start;
> >>>>>> +
> >>>>>> +  /* Last index in this object */
> >>>>>> +  uint32_t end;
> >>>>>> +
> >>>>>> +  /* bitmap for dynamic doorbell allocation from this object */
> >>>>>> +  unsigned long *doorbell_bitmap;
> >>>>>> +};
> >>>>>> +
> >>>>>>     struct amdgpu_doorbell {
> >>>>>>             /* doorbell mmio */
> >>>>>>             resource_size_t         base;
> >>>>>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
> >>>>>>      */
> >>>>>>     void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
> >>>>>>
> >>>>>> +/**
> >>>>>> + * amdgpu_doorbell_free_page - Free a doorbell page
> >>>>>> + *
> >>>>>> + * @adev: amdgpu_device pointer
> >>>>>> + *
> >>>>>> + * @db_age: previously allocated doobell page details
> >>>>>> + *
> >>>>>> + */
> >>>>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
> >>>>>> +                          struct amdgpu_doorbell_obj *db_obj);
> >>>>>> +
> >>>>>> +/**
> >>>>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
> >>>>>> + *
> >>>>>> + * @adev: amdgpu_device pointer
> >>>>>> + *
> >>>>>> + * @db_age: doobell page structure to fill details with
> >>>>>> + *
> >>>>>> + * returns 0 on success, else error number
> >>>>>> + */
> >>>>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> >>>>>> +                          struct amdgpu_doorbell_obj *db_obj);
> >>>>>> +
> >>>>>>     #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
> >>>>>>     #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
> >>>>>>     #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
> >>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >>>>>> index 1aea92363fd3..8be15b82b545 100644
> >>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
> >>>>>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
> >>>>>>             }
> >>>>>>     }
> >>>>>>
> >>>>>> +/**
> >>>>>> + * amdgpu_doorbell_free_page - Free a doorbell page
> >>>>>> + *
> >>>>>> + * @adev: amdgpu_device pointer
> >>>>>> + *
> >>>>>> + * @db_age: previously allocated doobell page details
> >>>>>> + *
> >>>>>> + */
> >>>>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
> >>>>>> +                                  struct amdgpu_doorbell_obj *db_obj)
> >>>>>> +{
> >>>>>> +  amdgpu_bo_free_kernel(&db_obj->bo,
> >>>>>> +                        &db_obj->gpu_addr,
> >>>>>> +                        (void **)&db_obj->cpu_addr);
> >>>>>> +
> >>>>>> +}
> >>>>>> +
> >>>>>> +/**
> >>>>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
> >>>>>> + *
> >>>>>> + * @adev: amdgpu_device pointer
> >>>>>> + *
> >>>>>> + * @db_age: doobell page structure to fill details with
> >>>>>> + *
> >>>>>> + * returns 0 on success, else error number
> >>>>>> + */
> >>>>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
> >>>>>> +                          struct amdgpu_doorbell_obj *db_obj)
> >>>>>> +{
> >>>>>> +  int r;
> >>>>>> +
> >>>>>> +  db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
> >>>>>> +
> >>>>>> +  r = amdgpu_bo_create_kernel(adev,
> >>>>>> +                              db_obj->size,
> >>>>>> +                              PAGE_SIZE,
> >>>>>> +                              AMDGPU_GEM_DOMAIN_DOORBELL,
> >>>>>> +                              &db_obj->bo,
> >>>>>> +                              &db_obj->gpu_addr,
> >>>>>> +                              (void **)&db_obj->cpu_addr);
> >>>>>> +
> >>>>>> +  if (r) {
> >>>>>> +          DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
> >>>>>> +          return r;
> >>>>>> +  }
> >>>>>> +
> >>>>>> +  return 0;
> >>>>>> +}
> >>>>>> +
> >>>>>>     /*
> >>>>>>      * GPU doorbell aperture helpers function.
> >>>>>>      */

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

* Re: [PATCH 12/16] drm/amdgpu: use doorbell manager for kfd kernel doorbells
  2023-03-29 15:47 ` [PATCH 12/16] drm/amdgpu: use doorbell manager for kfd kernel doorbells Shashank Sharma
@ 2023-03-30 20:46   ` Alex Deucher
  2023-03-31  8:27     ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 20:46 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig, amd-gfx

On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
> This patch:
> - adds a doorbell manager structure in kfd device structure.
> - plugs-in doorbell manager APIs for KFD kernel doorbell allocations
>   an free functions.
> - removes the doorbell bitmap, uses the one into the doorbell manager
>   structure for all the allocations.
> - updates the get_kernel_doorbell and free_kernel_doorbell functions
>   accordingly
>
> 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/amdkfd/kfd_device.c   |   4 +-
>  drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | 109 ++++++----------------
>  drivers/gpu/drm/amd/amdkfd/kfd_priv.h     |   3 +
>  3 files changed, 35 insertions(+), 81 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
> index b8936340742b..a2e4cbddba26 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
> @@ -435,8 +435,8 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
>         atomic_set(&kfd->compute_profile, 0);
>
>         mutex_init(&kfd->doorbell_mutex);
> -       memset(&kfd->doorbell_available_index, 0,
> -               sizeof(kfd->doorbell_available_index));
> +       memset(kfd->kernel_doorbells.doorbell_bitmap, 0,
> +              kfd->kernel_doorbells.size / BITS_PER_LONG);
>
>         atomic_set(&kfd->sram_ecc_flag, 0);
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
> index cd4e61bf0493..df259f2cc58a 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
> @@ -61,81 +61,37 @@ size_t kfd_doorbell_process_slice(struct kfd_dev *kfd)
>  /* Doorbell calculations for device init. */
>  int kfd_doorbell_init(struct kfd_dev *kfd)
>  {
> -       size_t doorbell_start_offset;
> -       size_t doorbell_aperture_size;
> -       size_t doorbell_process_limit;
> +       int r;
> +       struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
>
> -       /*
> -        * With MES enabled, just set the doorbell base as it is needed
> -        * to calculate doorbell physical address.
> -        */
> -       if (kfd->shared_resources.enable_mes) {
> -               kfd->doorbell_base =
> -                       kfd->shared_resources.doorbell_physical_address;
> -               return 0;
> -       }
> -
> -       /*
> -        * We start with calculations in bytes because the input data might
> -        * only be byte-aligned.
> -        * Only after we have done the rounding can we assume any alignment.
> -        */
> -
> -       doorbell_start_offset =
> -                       roundup(kfd->shared_resources.doorbell_start_offset,
> -                                       kfd_doorbell_process_slice(kfd));
> -
> -       doorbell_aperture_size =
> -                       rounddown(kfd->shared_resources.doorbell_aperture_size,
> -                                       kfd_doorbell_process_slice(kfd));
> -
> -       if (doorbell_aperture_size > doorbell_start_offset)
> -               doorbell_process_limit =
> -                       (doorbell_aperture_size - doorbell_start_offset) /
> -                                               kfd_doorbell_process_slice(kfd);
> -       else
> -               return -ENOSPC;
> -
> -       if (!kfd->max_doorbell_slices ||
> -           doorbell_process_limit < kfd->max_doorbell_slices)
> -               kfd->max_doorbell_slices = doorbell_process_limit;
> -
> -       kfd->doorbell_base = kfd->shared_resources.doorbell_physical_address +
> -                               doorbell_start_offset;
> -
> -       kfd->doorbell_base_dw_offset = doorbell_start_offset / sizeof(u32);
> -
> -       kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base,
> -                                          kfd_doorbell_process_slice(kfd));
> -
> -       if (!kfd->doorbell_kernel_ptr)
> +       /* Bitmap to dynamically allocate doorbells from kernel page */
> +       kernel_doorbells->doorbell_bitmap = bitmap_zalloc(PAGE_SIZE, GFP_KERNEL);
> +       if (!kernel_doorbells->doorbell_bitmap) {
> +               DRM_ERROR("Failed to allocate kernel doorbell bitmap\n");
>                 return -ENOMEM;
> +       }
>
> -       pr_debug("Doorbell initialization:\n");
> -       pr_debug("doorbell base           == 0x%08lX\n",
> -                       (uintptr_t)kfd->doorbell_base);
> -
> -       pr_debug("doorbell_base_dw_offset      == 0x%08lX\n",
> -                       kfd->doorbell_base_dw_offset);
> -
> -       pr_debug("doorbell_process_limit  == 0x%08lX\n",
> -                       doorbell_process_limit);
> -
> -       pr_debug("doorbell_kernel_offset  == 0x%08lX\n",
> -                       (uintptr_t)kfd->doorbell_base);
> -
> -       pr_debug("doorbell aperture size  == 0x%08lX\n",
> -                       kfd->shared_resources.doorbell_aperture_size);
> +       /* Alloc and reserve doorbells for KFD kernel usages */
> +       kernel_doorbells->size = PAGE_SIZE;
> +       r = amdgpu_doorbell_alloc_page(kfd->adev, kernel_doorbells);


Just do something like:
r = amdgpu_bo_create_kernel(kfd->adev, PAGE_SIZE, PAGE_SIZE,
AMDGPU_GEM_DOMAIN_DOORBELL,

&kfd->doorbell_kernel_bo, NULL, &kfd->doorbell_kernel_ptr);

Then you have your KFD pointer to its doorbell memory and no need to
track the ranges.

Alex


> +       if (r) {
> +               pr_err("failed to allocate kernel doorbells\n");
> +               bitmap_free(kernel_doorbells->doorbell_bitmap);
> +               return r;
> +       }
>
> -       pr_debug("doorbell kernel address == %p\n", kfd->doorbell_kernel_ptr);
> +       kfd->doorbell_kernel_ptr = kernel_doorbells->cpu_addr;
> +       pr_debug("Doorbell kernel address == %p\n", kfd->doorbell_kernel_ptr);
>
>         return 0;
>  }
>
>  void kfd_doorbell_fini(struct kfd_dev *kfd)
>  {
> -       if (kfd->doorbell_kernel_ptr)
> -               iounmap(kfd->doorbell_kernel_ptr);
> +       struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
> +
> +       bitmap_free(kernel_doorbells->doorbell_bitmap);
> +       amdgpu_doorbell_free_page(kfd->adev, kernel_doorbells);
>  }
>
>  int kfd_doorbell_mmap(struct kfd_dev *dev, struct kfd_process *process,
> @@ -186,24 +142,19 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
>                                         unsigned int *doorbell_off)
>  {
>         u32 inx;
> +       struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
>
>         mutex_lock(&kfd->doorbell_mutex);
> -       inx = find_first_zero_bit(kfd->doorbell_available_index,
> -                                       KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
> +       inx = find_first_zero_bit(kernel_doorbells->doorbell_bitmap,
> +                                 kernel_doorbells->size);
>
> -       __set_bit(inx, kfd->doorbell_available_index);
> +       __set_bit(inx, kernel_doorbells->doorbell_bitmap);
>         mutex_unlock(&kfd->doorbell_mutex);
>
>         if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
>                 return NULL;
>
> -       inx *= kfd->device_info.doorbell_size / sizeof(u32);
> -
> -       /*
> -        * Calculating the kernel doorbell offset using the first
> -        * doorbell page.
> -        */
> -       *doorbell_off = kfd->doorbell_base_dw_offset + inx;
> +       *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev, kernel_doorbells->bo, inx);
>
>         pr_debug("Get kernel queue doorbell\n"
>                         "     doorbell offset   == 0x%08X\n"
> @@ -216,12 +167,12 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
>  void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr)
>  {
>         unsigned int inx;
> +       struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
>
> -       inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr)
> -               * sizeof(u32) / kfd->device_info.doorbell_size;
> +       inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr);
>
>         mutex_lock(&kfd->doorbell_mutex);
> -       __clear_bit(inx, kfd->doorbell_available_index);
> +       __clear_bit(inx, kernel_doorbells->doorbell_bitmap);
>         mutex_unlock(&kfd->doorbell_mutex);
>  }
>
> @@ -280,7 +231,7 @@ phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
>         if (!pdd->doorbell_index) {
>                 int r = kfd_alloc_process_doorbells(pdd->dev,
>                                                     &pdd->doorbell_index);
> -               if (r)
> +               if (r < 0)
>                         return 0;
>         }
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> index 552c3ac85a13..0ed33416c35f 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> @@ -346,6 +346,9 @@ struct kfd_dev {
>
>         /* HMM page migration MEMORY_DEVICE_PRIVATE mapping */
>         struct dev_pagemap pgmap;
> +
> +       /* Kernel doorbells for KFD device */
> +       struct amdgpu_doorbell_obj kernel_doorbells;
>  };
>
>  enum kfd_mempool {
> --
> 2.40.0
>

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

* Re: [PATCH 13/16] drm/amdgpu: use doorbell manager for kfd process doorbells
  2023-03-29 15:47 ` [PATCH 13/16] drm/amdgpu: use doorbell manager for kfd process doorbells Shashank Sharma
@ 2023-03-30 20:54   ` Alex Deucher
  2023-03-31  8:28     ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 20:54 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig, amd-gfx

On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
> This patch:
> - adds a new doorbell manager object in kfd pdd structure.
> - allocates doorbells for a process while creating its pdd.
> - frees the doorbells with pdd destroy.
> - uses direct doorbell manager API for doorbell indexing.
> - removes previous calls to allocate process doorbells as
>   its not required anymore.
>
> PS: This patch ensures that we don't break the existing KFD
>     functionality, but now KFD userspace library must also
>     move to creating doorbell pages as AMDGPU GEM objects
>     using libdrm functions in userspace. The reference code
>     for the same is available with AMDGPU Usermode queue
>     libdrm MR. Once this is done, we will not need this
>     patch.
>
> 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/amdkfd/kfd_chardev.c      | 13 ----
>  .../drm/amd/amdkfd/kfd_device_queue_manager.c | 16 ++---
>  drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c     | 59 +++++++++----------
>  drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |  8 +--
>  drivers/gpu/drm/amd/amdkfd/kfd_process.c      | 26 ++++----
>  .../amd/amdkfd/kfd_process_queue_manager.c    | 16 ++---
>  6 files changed, 58 insertions(+), 80 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
> index 6d291aa6386b..0e40756417e5 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
> @@ -327,12 +327,6 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
>                 goto err_bind_process;
>         }
>
> -       if (!pdd->doorbell_index &&
> -           kfd_alloc_process_doorbells(dev, &pdd->doorbell_index) < 0) {
> -               err = -ENOMEM;
> -               goto err_alloc_doorbells;
> -       }
> -
>         /* Starting with GFX11, wptr BOs must be mapped to GART for MES to determine work
>          * on unmapped queues for usermode queue oversubscription (no aggregated doorbell)
>          */
> @@ -410,7 +404,6 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
>         if (wptr_bo)
>                 amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);
>  err_wptr_map_gart:
> -err_alloc_doorbells:
>  err_bind_process:
>  err_pdd:
>         mutex_unlock(&p->mutex);
> @@ -2163,12 +2156,6 @@ static int criu_restore_devices(struct kfd_process *p,
>                         ret = PTR_ERR(pdd);
>                         goto exit;
>                 }
> -
> -               if (!pdd->doorbell_index &&
> -                   kfd_alloc_process_doorbells(pdd->dev, &pdd->doorbell_index) < 0) {
> -                       ret = -ENOMEM;
> -                       goto exit;
> -               }
>         }
>
>         /*
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> index ecb4c3abc629..5827db9b18a8 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> @@ -362,7 +362,7 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
>                 /* For CP queues on SOC15 */
>                 if (restore_id) {
>                         /* make sure that ID is free  */
> -                       if (__test_and_set_bit(*restore_id, qpd->doorbell_bitmap))
> +                       if (__test_and_set_bit(*restore_id, qpd->proc_doorbells.doorbell_bitmap))
>                                 return -EINVAL;
>
>                         q->doorbell_id = *restore_id;
> @@ -370,20 +370,20 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
>                         /* or reserve a free doorbell ID */
>                         unsigned int found;
>
> -                       found = find_first_zero_bit(qpd->doorbell_bitmap,
> -                                               KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
> +                       found = find_first_zero_bit(qpd->proc_doorbells.doorbell_bitmap,
> +                                                   KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
>                         if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
>                                 pr_debug("No doorbells available");
>                                 return -EBUSY;
>                         }
> -                       set_bit(found, qpd->doorbell_bitmap);
> +                       set_bit(found, qpd->proc_doorbells.doorbell_bitmap);
>                         q->doorbell_id = found;
>                 }
>         }
>
> -       q->properties.doorbell_off =
> -               kfd_get_doorbell_dw_offset_in_bar(dev, qpd_to_pdd(qpd),
> -                                         q->doorbell_id);
> +       q->properties.doorbell_off = amdgpu_doorbell_index_on_bar(dev->adev,
> +                                                                 qpd->proc_doorbells.bo,
> +                                                                 q->doorbell_id);
>         return 0;
>  }
>
> @@ -398,7 +398,7 @@ static void deallocate_doorbell(struct qcm_process_device *qpd,
>             q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
>                 return;
>
> -       old = test_and_clear_bit(q->doorbell_id, qpd->doorbell_bitmap);
> +       old = test_and_clear_bit(q->doorbell_id, qpd->proc_doorbells.doorbell_bitmap);
>         WARN_ON(!old);
>  }
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
> index df259f2cc58a..7d29653bff81 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
> @@ -228,46 +228,41 @@ uint64_t kfd_get_number_elems(struct kfd_dev *kfd)
>
>  phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
>  {
> -       if (!pdd->doorbell_index) {
> -               int r = kfd_alloc_process_doorbells(pdd->dev,
> -                                                   &pdd->doorbell_index);
> -               if (r < 0)
> -                       return 0;
> -       }
> +       struct amdgpu_device *adev = pdd->dev->adev;
>
> -       return pdd->dev->doorbell_base +
> -               pdd->doorbell_index * kfd_doorbell_process_slice(pdd->dev);
> +       /* Return base of the first doorbell of this process */
> +       return adev->doorbell.base + pdd->qpd.proc_doorbells.start * sizeof(uint32_t);
>  }
>
> -int kfd_alloc_process_doorbells(struct kfd_dev *kfd, unsigned int *doorbell_index)
> +int kfd_alloc_process_doorbells(struct kfd_dev *kfd, struct kfd_process_device *pdd)
>  {
> -       int r = 0;
> -
> -       if (!kfd->shared_resources.enable_mes)
> -               r = ida_simple_get(&kfd->doorbell_ida, 1,
> -                                  kfd->max_doorbell_slices, GFP_KERNEL);
> -       else
> -               r = amdgpu_mes_alloc_process_doorbells(
> -                               (struct amdgpu_device *)kfd->adev,
> -                               doorbell_index);
> -
> -       if (r > 0)
> -               *doorbell_index = r;
> +       int r;
> +       struct qcm_process_device *qpd = &pdd->qpd;
> +       struct amdgpu_doorbell_obj *proc_doorbells = &qpd->proc_doorbells;
> +
> +       /* Allocate bitmap for dynamic doorbell allocation */
> +       proc_doorbells->doorbell_bitmap = bitmap_zalloc(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
> +                                                       GFP_KERNEL);
> +       if (!proc_doorbells->doorbell_bitmap) {
> +               DRM_ERROR("Failed to allocate process doorbell bitmap\n");
> +               return -ENOMEM;
> +       }
>
> -       if (r < 0)
> -               pr_err("Failed to allocate process doorbells\n");
> +       /* Allocate doorbells for this process from the PCI BAR */
> +       proc_doorbells->size = kfd_doorbell_process_slice(kfd);
> +       r = amdgpu_doorbell_alloc_page(kfd->adev, proc_doorbells);

Same thing here as the previous patch.  Just call
amdgpu_bo_create_kernel(..DOORBELL..) and store the bo in the process
structure.

Alex

> +       if (r) {
> +               DRM_ERROR("Failed to allocate process doorbells\n");
> +               return r;
> +       }
>
>         return r;
>  }
>
> -void kfd_free_process_doorbells(struct kfd_dev *kfd, unsigned int doorbell_index)
> +void kfd_free_process_doorbells(struct kfd_dev *kfd, struct kfd_process_device *pdd)
>  {
> -       if (doorbell_index) {
> -               if (!kfd->shared_resources.enable_mes)
> -                       ida_simple_remove(&kfd->doorbell_ida, doorbell_index);
> -               else
> -                       amdgpu_mes_free_process_doorbells(
> -                                       (struct amdgpu_device *)kfd->adev,
> -                                       doorbell_index);
> -       }
> +       struct amdgpu_doorbell_obj *proc_doorbells = &pdd->qpd.proc_doorbells;
> +
> +       bitmap_free(proc_doorbells->doorbell_bitmap);
> +       amdgpu_doorbell_free_page(kfd->adev, proc_doorbells);
>  }
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> index 0ed33416c35f..c97ed8e7e02d 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> @@ -658,8 +658,8 @@ struct qcm_process_device {
>         uint64_t ib_base;
>         void *ib_kaddr;
>
> -       /* doorbell resources per process per device */
> -       unsigned long *doorbell_bitmap;
> +       /* physical doorbell pages */
> +       struct amdgpu_doorbell_obj proc_doorbells;
>  };
>
>  /* KFD Memory Eviction */
> @@ -1006,9 +1006,9 @@ unsigned int kfd_get_doorbell_dw_offset_in_bar(struct kfd_dev *kfd,
>                                         unsigned int doorbell_id);
>  phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd);
>  int kfd_alloc_process_doorbells(struct kfd_dev *kfd,
> -                               unsigned int *doorbell_index);
> +                                struct kfd_process_device *pdd);
>  void kfd_free_process_doorbells(struct kfd_dev *kfd,
> -                               unsigned int doorbell_index);
> +                                struct kfd_process_device *pdd);
>  /* GTT Sub-Allocator */
>
>  int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size,
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
> index 51b1683ac5c1..68d0310c2d53 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
> @@ -1037,10 +1037,9 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
>                         free_pages((unsigned long)pdd->qpd.cwsr_kaddr,
>                                 get_order(KFD_CWSR_TBA_TMA_SIZE));
>
> -               bitmap_free(pdd->qpd.doorbell_bitmap);
>                 idr_destroy(&pdd->alloc_idr);
>
> -               kfd_free_process_doorbells(pdd->dev, pdd->doorbell_index);
> +               kfd_free_process_doorbells(pdd->dev, pdd);
>
>                 if (pdd->dev->shared_resources.enable_mes)
>                         amdgpu_amdkfd_free_gtt_mem(pdd->dev->adev,
> @@ -1449,15 +1448,11 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd,
>         unsigned int i;
>         int range_start = dev->shared_resources.non_cp_doorbells_start;
>         int range_end = dev->shared_resources.non_cp_doorbells_end;
> +       struct amdgpu_doorbell_obj *proc_doorbells = &qpd->proc_doorbells;
>
>         if (!KFD_IS_SOC15(dev))
>                 return 0;
>
> -       qpd->doorbell_bitmap = bitmap_zalloc(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
> -                                            GFP_KERNEL);
> -       if (!qpd->doorbell_bitmap)
> -               return -ENOMEM;
> -
>         /* Mask out doorbells reserved for SDMA, IH, and VCN on SOC15. */
>         pr_debug("reserved doorbell 0x%03x - 0x%03x\n", range_start, range_end);
>         pr_debug("reserved doorbell 0x%03x - 0x%03x\n",
> @@ -1466,9 +1461,9 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd,
>
>         for (i = 0; i < KFD_MAX_NUM_OF_QUEUES_PER_PROCESS / 2; i++) {
>                 if (i >= range_start && i <= range_end) {
> -                       __set_bit(i, qpd->doorbell_bitmap);
> +                       __set_bit(i, proc_doorbells->doorbell_bitmap);
>                         __set_bit(i + KFD_QUEUE_DOORBELL_MIRROR_OFFSET,
> -                                 qpd->doorbell_bitmap);
> +                                 proc_doorbells->doorbell_bitmap);
>                 }
>         }
>
> @@ -1499,9 +1494,15 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
>         if (!pdd)
>                 return NULL;
>
> +       retval = kfd_alloc_process_doorbells(dev, pdd);
> +       if (retval) {
> +               pr_err("failed to allocate process doorbells\n");
> +               goto err_free_pdd;
> +       }
> +
>         if (init_doorbell_bitmap(&pdd->qpd, dev)) {
>                 pr_err("Failed to init doorbell for process\n");
> -               goto err_free_pdd;
> +               goto err_free_db;
>         }
>
>         pdd->dev = dev;
> @@ -1529,7 +1530,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
>                                                 false);
>                 if (retval) {
>                         pr_err("failed to allocate process context bo\n");
> -                       goto err_free_pdd;
> +                       goto err_free_db;
>                 }
>                 memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
>         }
> @@ -1541,6 +1542,9 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
>
>         return pdd;
>
> +err_free_db:
> +       kfd_free_process_doorbells(pdd->dev, pdd);
> +
>  err_free_pdd:
>         kfree(pdd);
>         return NULL;
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
> index 5137476ec18e..693688d789d3 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
> @@ -348,13 +348,11 @@ int pqm_create_queue(struct process_queue_manager *pqm,
>                 /* Return the doorbell offset within the doorbell page
>                  * to the caller so it can be passed up to user mode
>                  * (in bytes).
> -                * There are always 1024 doorbells per process, so in case
> -                * of 8-byte doorbells, there are two doorbell pages per
> -                * process.
> +                * relative doorbell index = Absolute doorbell index -
> +                * absolute index of first doorbell in the page.
>                  */
> -               *p_doorbell_offset_in_process =
> -                       (q->properties.doorbell_off * sizeof(uint32_t)) &
> -                       (kfd_doorbell_process_slice(dev) - 1);
> +               *p_doorbell_offset_in_process = (q->properties.doorbell_off
> +                                               - pdd->qpd.proc_doorbells.start) * sizeof(uint32_t);
>
>         pr_debug("PQM After DQM create queue\n");
>
> @@ -858,12 +856,6 @@ int kfd_criu_restore_queue(struct kfd_process *p,
>                 goto exit;
>         }
>
> -       if (!pdd->doorbell_index &&
> -           kfd_alloc_process_doorbells(pdd->dev, &pdd->doorbell_index) < 0) {
> -               ret = -ENOMEM;
> -               goto exit;
> -       }
> -
>         /* data stored in this order: mqd, ctl_stack */
>         mqd = q_extra_data;
>         ctl_stack = mqd + q_data->mqd_size;
> --
> 2.40.0
>

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

* Re: [PATCH 15/16] drm/amdgpu: use doorbell mgr for MES kernel doorbells
  2023-03-29 15:47 ` [PATCH 15/16] drm/amdgpu: use doorbell mgr for MES kernel doorbells Shashank Sharma
@ 2023-03-30 20:58   ` Alex Deucher
  2023-03-31  8:29     ` Shashank Sharma
  0 siblings, 1 reply; 87+ messages in thread
From: Alex Deucher @ 2023-03-30 20:58 UTC (permalink / raw)
  To: Shashank Sharma
  Cc: Mukul Joshi, Felix Kuehling, Arvind Yadav, amd-gfx, Alex Deucher,
	Christian Koenig

On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
<shashank.sharma@amd.com> wrote:
>
> This patch:
> - adds a doorbell object in MES structure, to manage the MES
>   doorbell requirements in kernel.
> - Removes the doorbell management code, and its variables from
>   the doorbell_init function, it will be done in doorbell manager
>   now.
> - creates doorbell pages for MES kernel level needs (doorbells
>   for MES self tests)
> - current MES code was allocating MES doorbells in MES process context,
>   but those were rung using kernel doorbell calls. This patch allocates
>   MES kernel doorbells instead for this in add_hw_queue.
>
> 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_mes.c | 105 ++++++++++++------------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h |   5 +-
>  2 files changed, 56 insertions(+), 54 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> index 0c546245793b..423cd642647c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
> @@ -65,91 +65,89 @@ unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar(
>                 doorbell_id * 2);
>  }
>
> -static int amdgpu_mes_queue_doorbell_get(struct amdgpu_device *adev,
> +static int amdgpu_mes_kernel_doorbell_get(struct amdgpu_device *adev,
>                                          struct amdgpu_mes_process *process,
>                                          int ip_type, uint64_t *doorbell_index)
>  {
>         unsigned int offset, found;
> +       struct amdgpu_doorbell_obj *doorbells = &adev->mes.kernel_doorbells;
>
> -       if (ip_type == AMDGPU_RING_TYPE_SDMA) {
> +       if (ip_type == AMDGPU_RING_TYPE_SDMA)
>                 offset = adev->doorbell_index.sdma_engine[0];
> -               found = find_next_zero_bit(process->doorbell_bitmap,
> -                                          AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
> -                                          offset);
> -       } else {
> -               found = find_first_zero_bit(process->doorbell_bitmap,
> -                                           AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS);
> -       }
> +       else
> +               offset = 0;
>
> +       found = find_next_zero_bit(doorbells->doorbell_bitmap,
> +                                  AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
> +                                  offset);
>         if (found >= AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS) {
>                 DRM_WARN("No doorbell available\n");
>                 return -ENOSPC;
>         }
>
> -       set_bit(found, process->doorbell_bitmap);
> +       set_bit(found, doorbells->doorbell_bitmap);
>
> -       *doorbell_index = amdgpu_mes_get_doorbell_dw_offset_in_bar(adev,
> -                               process->doorbell_index, found);
> +       *doorbell_index = amdgpu_doorbell_index_on_bar(adev, doorbells->bo, found);
>
>         return 0;
>  }
>
> -static void amdgpu_mes_queue_doorbell_free(struct amdgpu_device *adev,
> +static void amdgpu_mes_kernel_doorbell_free(struct amdgpu_device *adev,
>                                            struct amdgpu_mes_process *process,
>                                            uint32_t doorbell_index)
>  {
>         unsigned int old, doorbell_id;
> +       struct amdgpu_doorbell_obj *doorbells = &adev->mes.kernel_doorbells;
>
> -       doorbell_id = doorbell_index -
> -               (process->doorbell_index *
> -                amdgpu_mes_doorbell_process_slice(adev)) / sizeof(u32);
> +       /* Find the relative index of the doorbell in this object */
> +       doorbell_id = doorbell_index - doorbells->start;
>         doorbell_id /= 2;
>
> -       old = test_and_clear_bit(doorbell_id, process->doorbell_bitmap);
> +       old = test_and_clear_bit(doorbell_id, doorbells->doorbell_bitmap);
>         WARN_ON(!old);
>  }
>
>  static int amdgpu_mes_doorbell_init(struct amdgpu_device *adev)
>  {
> -       size_t doorbell_start_offset;
> -       size_t doorbell_aperture_size;
> -       size_t doorbell_process_limit;
> -       size_t aggregated_doorbell_start;
> -       int i;
> -
> -       aggregated_doorbell_start = (adev->doorbell_index.max_assignment + 1) * sizeof(u32);
> -       aggregated_doorbell_start =
> -               roundup(aggregated_doorbell_start, PAGE_SIZE);
> -
> -       doorbell_start_offset = aggregated_doorbell_start + PAGE_SIZE;
> -       doorbell_start_offset =
> -               roundup(doorbell_start_offset,
> -                       amdgpu_mes_doorbell_process_slice(adev));
> -
> -       doorbell_aperture_size = adev->doorbell.size;
> -       doorbell_aperture_size =
> -                       rounddown(doorbell_aperture_size,
> -                                 amdgpu_mes_doorbell_process_slice(adev));
> -
> -       if (doorbell_aperture_size > doorbell_start_offset)
> -               doorbell_process_limit =
> -                       (doorbell_aperture_size - doorbell_start_offset) /
> -                       amdgpu_mes_doorbell_process_slice(adev);
> -       else
> -               return -ENOSPC;
> +       int i, r;
> +       u32 agg_db_start_index, nbits;
> +       struct amdgpu_doorbell_obj *mes_doorbells = &adev->mes.kernel_doorbells;
>
> -       adev->mes.doorbell_id_offset = doorbell_start_offset / sizeof(u32);
> -       adev->mes.max_doorbell_slices = doorbell_process_limit;
> +               /* Allocated one page doorbells for MES kernel usages */
> +       mes_doorbells->size = PAGE_SIZE;
>
> -       /* allocate Qword range for aggregated doorbell */
> -       for (i = 0; i < AMDGPU_MES_PRIORITY_NUM_LEVELS; i++)
> -               adev->mes.aggregated_doorbells[i] =
> -                       aggregated_doorbell_start / sizeof(u32) + i * 2;
> +       nbits = DIV_ROUND_UP(mes_doorbells->size, sizeof(u32));
> +       mes_doorbells->doorbell_bitmap = bitmap_zalloc(nbits, GFP_KERNEL);
> +       if (!mes_doorbells->doorbell_bitmap) {
> +               DRM_ERROR("Failed to allocate MES doorbell bitmap\n");
> +               return -ENOMEM;
> +       }
> +
> +       r = amdgpu_doorbell_alloc_page(adev, mes_doorbells);

Rather than allocating a separate page here, just allocate two pages
in the earlier patch where you allocate the KGD doorbell and then just
use the second page here.

Alex

> +       if (r) {
> +               DRM_ERROR("Failed to create MES doorbell object\n, err=%d", r);
> +               bitmap_free(mes_doorbells->doorbell_bitmap);
> +               return r;
> +       }
> +
> +       /* Get the absolute doorbell index for aggregated doobells */
> +       agg_db_start_index = mes_doorbells->start;
> +       for (i = 0; i < AMDGPU_MES_PRIORITY_NUM_LEVELS; i++) {
> +               adev->mes.aggregated_doorbells[i] = agg_db_start_index + i;
> +               set_bit(agg_db_start_index + i, mes_doorbells->doorbell_bitmap);
> +       }
>
> -       DRM_INFO("max_doorbell_slices=%zu\n", doorbell_process_limit);
>         return 0;
>  }
>
> +static void amdgpu_mes_doorbell_free(struct amdgpu_device *adev)
> +{
> +       struct amdgpu_doorbell_obj *mes_doorbells = &adev->mes.kernel_doorbells;
> +
> +       bitmap_free(mes_doorbells->doorbell_bitmap);
> +       amdgpu_doorbell_free_page(adev, mes_doorbells);
> +}
> +
>  int amdgpu_mes_init(struct amdgpu_device *adev)
>  {
>         int i, r;
> @@ -248,6 +246,7 @@ void amdgpu_mes_fini(struct amdgpu_device *adev)
>         amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);
>         amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs);
>         amdgpu_device_wb_free(adev, adev->mes.read_val_offs);
> +       amdgpu_mes_doorbell_free(adev);
>
>         idr_destroy(&adev->mes.pasid_idr);
>         idr_destroy(&adev->mes.gang_id_idr);
> @@ -677,7 +676,7 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id,
>         *queue_id = queue->queue_id = r;
>
>         /* allocate a doorbell index for the queue */
> -       r = amdgpu_mes_queue_doorbell_get(adev, gang->process,
> +       r = amdgpu_mes_kernel_doorbell_get(adev, gang->process,
>                                           qprops->queue_type,
>                                           &qprops->doorbell_off);
>         if (r)
> @@ -735,7 +734,7 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id,
>         return 0;
>
>  clean_up_doorbell:
> -       amdgpu_mes_queue_doorbell_free(adev, gang->process,
> +       amdgpu_mes_kernel_doorbell_free(adev, gang->process,
>                                        qprops->doorbell_off);
>  clean_up_queue_id:
>         spin_lock_irqsave(&adev->mes.queue_id_lock, flags);
> @@ -790,7 +789,7 @@ int amdgpu_mes_remove_hw_queue(struct amdgpu_device *adev, int queue_id)
>                           queue_id);
>
>         list_del(&queue->list);
> -       amdgpu_mes_queue_doorbell_free(adev, gang->process,
> +       amdgpu_mes_kernel_doorbell_free(adev, gang->process,
>                                        queue->doorbell_off);
>         amdgpu_mes_unlock(&adev->mes);
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
> index 97c05d08a551..e7e9dfe44c99 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
> @@ -27,6 +27,7 @@
>  #include "amdgpu_irq.h"
>  #include "kgd_kfd_interface.h"
>  #include "amdgpu_gfx.h"
> +#include "amdgpu_doorbell.h"
>  #include <linux/sched/mm.h>
>
>  #define AMDGPU_MES_MAX_COMPUTE_PIPES        8
> @@ -76,7 +77,6 @@ struct amdgpu_mes {
>         uint32_t                        kiq_version;
>
>         uint32_t                        total_max_queue;
> -       uint32_t                        doorbell_id_offset;
>         uint32_t                        max_doorbell_slices;
>
>         uint64_t                        default_process_quantum;
> @@ -128,6 +128,9 @@ struct amdgpu_mes {
>         int                             (*kiq_hw_init)(struct amdgpu_device *adev);
>         int                             (*kiq_hw_fini)(struct amdgpu_device *adev);
>
> +       /* MES Kernel doorbells */
> +       struct amdgpu_doorbell_obj      kernel_doorbells;
> +
>         /* ip specific functions */
>         const struct amdgpu_mes_funcs   *funcs;
>  };
> --
> 2.40.0
>

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

* Re: [PATCH 09/16] drm/amdgpu: create kernel doorbell page
  2023-03-30 15:04             ` Alex Deucher
@ 2023-03-31  8:25               ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-31  8:25 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Alex Deucher,
	Shashank Sharma, Christian König


On 30/03/2023 17:04, Alex Deucher wrote:
> On Thu, Mar 30, 2023 at 10:48 AM Shashank Sharma
> <shashank.sharma@amd.com> wrote:
>>
>> On 30/03/2023 16:42, Christian König wrote:
>>> Am 30.03.23 um 16:39 schrieb Alex Deucher:
>>>> On Thu, Mar 30, 2023 at 7:49 AM Shashank Sharma
>>>> <shashank.sharma@amd.com> wrote:
>>>>> On 30/03/2023 13:30, Christian König wrote:
>>>>>> Am 29.03.23 um 17:47 schrieb Shashank Sharma:
>>>>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>>>>
>>>>>>> This patch:
>>>>>>> - creates a doorbell page for graphics driver usages.
>>>>>>> - removes the adev->doorbell.ptr variable, replaces it with
>>>>>>>      kernel-doorbell-bo's cpu address.
>>>>>>>
>>>>>>> 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_doorbell.h  | 16 ++++++-
>>>>>>>     .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 44
>>>>>>> +++++++++++++++----
>>>>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  7 +++
>>>>>>>     3 files changed, 57 insertions(+), 10 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>>> index 6581b78fe438..10a9bb10e974 100644
>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>>> @@ -49,10 +49,13 @@ struct amdgpu_doorbell {
>>>>>>>         /* doorbell mmio */
>>>>>>>         resource_size_t        base;
>>>>>>>         resource_size_t        size;
>>>>>>> -    u32 __iomem        *ptr;
>>>>>>> +    u32    __iomem        *ptr;
>>>>>> This one can probably go away if we use the pointer from
>>>>>> amdgpu_bo_create_kernel().
>>>>> We started like that, but later realized that the cpu_addr from
>>>>> create_kernel() will just limit us
>>>>>
>>>>> to that object only, whereas we are keeping this ptr to ioremap the
>>>>> whole doorbell space in one shot.
>>>> Why do we need that?  For the kernel driver, we'd only need to mmap
>>>> the page used for kernel doorbells.  Then each user app would mmap its
>>>> doorbell page.
>>> Yes, that is exactly my concern as well.
>>>
>>> The kernel needs a fixed number of doorbells allocated for its
>>> internal use. Everything else should probably use the normal BO API.
>>>
>>> For KFD we can use the BO API internal in the kernel, but that is
>>> certainly completely different to the kernel allocations.
>>>
>> There are 3 different kernel doorbell clients here:
>>
>> - graphics driver
>>
>> - mes (for aggregated doorbells and kernel ring test)
>>
>> - kfd (for kernel ring test and KIQ)
>>
>>
>> The fix num_doorbells are just for kernel graphics driver, but We are
>> allocating doorbell pages for each of those, and they all need to be
>> mapped.
>>
>> Please see patch 12-16 for these details.
> To me, it's clearer that resources managed by ttm are consistently
> dealt with.  Regardless of whether we are talking about VRAM or OA or
> GDS or GTT or doorbells.  When the kernel driver needs a page of vram
> resources, it calls amdgpu_bo_create_kernel(), then if it needs a CPU
> mmap, it calls amdgpu_bo_kmp().  Doorbells should be the same.  In
> this case, the KGD would call amdgpu_bo_create_kernel(...DOORBELL..),
> then create a mmap with amdgpu_bo_kmap() and then use that pointer for
> its use.  KFD would do the same.  User mode doorbell allocations would
> be consistent as well.

Noted,

I will remove the wrapper APIs and make direct calls to amdgpu_bo_create_*

- Shashank

> Alex
>
>
>> - Shashank
>>
>>> Christian.
>>>
>>>> Alex
>>>>
>>>>> - Shashank
>>>>>
>>>>>>>           /* Number of doorbells reserved for amdgpu kernel driver */
>>>>>>>         u32 num_kernel_doorbells;
>>>>>>> +
>>>>>>> +    /* For kernel doorbell pages */
>>>>>>> +    struct amdgpu_doorbell_obj kernel_doorbells;
>>>>>>>     };
>>>>>>>       /* Reserved doorbells for amdgpu (including multimedia).
>>>>>>> @@ -369,6 +372,17 @@ void amdgpu_doorbell_free_page(struct
>>>>>>> amdgpu_device *adev,
>>>>>>>     int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>>>>                     struct amdgpu_doorbell_obj *db_obj);
>>>>>>>     +/**
>>>>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells
>>>>>>> for graphics
>>>>>>> + *
>>>>>>> + * @adev: amdgpu_device pointer
>>>>>>> + *
>>>>>>> + * Creates doorbells for graphics driver
>>>>>>> + *
>>>>>>> + * returns 0 on success, error otherwise.
>>>>>>> + */
>>>>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device
>>>>>>> *adev);
>>>>>>> +
>>>>>>>     #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>>>>     #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev,
>>>>>>> (index), (v))
>>>>>>>     #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>>> index 8be15b82b545..b46fe8b1378d 100644
>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>>> @@ -160,6 +160,38 @@ int amdgpu_doorbell_alloc_page(struct
>>>>>>> amdgpu_device *adev,
>>>>>>>         return 0;
>>>>>>>     }
>>>>>>>     +/**
>>>>>>> + * amdgpu_doorbell_create_kernel_doorbells - Create kernel doorbells
>>>>>>> for graphics
>>>>>>> + *
>>>>>>> + * @adev: amdgpu_device pointer
>>>>>>> + *
>>>>>>> + * Creates doorbells for graphics driver
>>>>>>> + *
>>>>>>> + * returns 0 on success, error otherwise.
>>>>>>> + */
>>>>>>> +int amdgpu_doorbell_create_kernel_doorbells(struct amdgpu_device
>>>>>>> *adev)
>>>>>>> +{
>>>>>>> +    int r;
>>>>>>> +    struct amdgpu_doorbell_obj *kernel_doorbells =
>>>>>>> &adev->doorbell.kernel_doorbells;
>>>>>>> +
>>>>>>> +    kernel_doorbells->doorbell_bitmap =
>>>>>>> bitmap_zalloc(adev->doorbell.num_kernel_doorbells,
>>>>>>> +                              GFP_KERNEL);
>>>>>>> +    if (!kernel_doorbells->doorbell_bitmap) {
>>>>>>> +        DRM_ERROR("Failed to create kernel doorbell bitmap\n");
>>>>>>> +        return -ENOMEM;
>>>>>>> +    }
>>>>>>> +
>>>>>>> +    kernel_doorbells->size = adev->doorbell.num_kernel_doorbells *
>>>>>>> sizeof(u32);
>>>>>>> +    r = amdgpu_doorbell_alloc_page(adev, kernel_doorbells);
>>>>>>> +    if (r) {
>>>>>>> + bitmap_free(kernel_doorbells->doorbell_bitmap);
>>>>>>> +        DRM_ERROR("Failed to allocate kernel doorbells,
>>>>>>> err=%d\n", r);
>>>>>>> +        return r;
>>>>>>> +    }
>>>>>>> +
>>>>>>> +    return 0;
>>>>>>> +}
>>>>>>> +
>>>>>>>     /*
>>>>>>>      * GPU doorbell aperture helpers function.
>>>>>>>      */
>>>>>>> @@ -179,7 +211,6 @@ int amdgpu_device_doorbell_init(struct
>>>>>>> amdgpu_device *adev)
>>>>>>>             adev->doorbell.base = 0;
>>>>>>>             adev->doorbell.size = 0;
>>>>>>>             adev->doorbell.num_kernel_doorbells = 0;
>>>>>>> -        adev->doorbell.ptr = NULL;
>>>>>>>             return 0;
>>>>>>>         }
>>>>>>>     @@ -208,12 +239,7 @@ int amdgpu_device_doorbell_init(struct
>>>>>>> amdgpu_device *adev)
>>>>>>>         if (adev->asic_type >= CHIP_VEGA10)
>>>>>>>             adev->doorbell.num_kernel_doorbells += 0x400;
>>>>>>>     -    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>>>>> - adev->doorbell.num_kernel_doorbells *
>>>>>>> -                     sizeof(u32));
>>>>>>> -    if (adev->doorbell.ptr == NULL)
>>>>>>> -        return -ENOMEM;
>>>>>>> -
>>>>>>> +    adev->doorbell.ptr = ioremap(adev->doorbell.base,
>>>>>>> adev->doorbell.size);
>>>>>>>         return 0;
>>>>>>>     }
>>>>>>>     @@ -226,6 +252,6 @@ int amdgpu_device_doorbell_init(struct
>>>>>>> amdgpu_device *adev)
>>>>>>>      */
>>>>>>>     void amdgpu_device_doorbell_fini(struct amdgpu_device *adev)
>>>>>>>     {
>>>>>>> -    iounmap(adev->doorbell.ptr);
>>>>>>> -    adev->doorbell.ptr = NULL;
>>>>>>> + bitmap_free(adev->doorbell.kernel_doorbells.doorbell_bitmap);
>>>>>>> +    amdgpu_doorbell_free_page(adev,
>>>>>>> &adev->doorbell.kernel_doorbells);
>>>>>>>     }
>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>>> index 203d77a20507..75c6852845c4 100644
>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>>>>> @@ -1866,6 +1866,13 @@ int amdgpu_ttm_init(struct amdgpu_device
>>>>>>> *adev)
>>>>>>>             return r;
>>>>>>>         }
>>>>>>>     +    /* Create a boorbell page for kernel usages */
>>>>>>> +    r = amdgpu_doorbell_create_kernel_doorbells(adev);
>>>>>>> +    if (r) {
>>>>>>> +        DRM_ERROR("Failed to initialize kernel doorbells. \n");
>>>>>>> +        return r;
>>>>>>> +    }
>>>>>>> +
>>>>>>>         /* Initialize preemptible memory pool */
>>>>>>>         r = amdgpu_preempt_mgr_init(adev);
>>>>>>>         if (r) {

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

* Re: [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages
  2023-03-30 20:35               ` Alex Deucher
@ 2023-03-31  8:26                 ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-31  8:26 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Mukul Joshi, Felix Kuehling, amd-gfx, Luben Tuikov, Alex Deucher,
	Shashank Sharma, Christian Koenig


On 30/03/2023 22:35, Alex Deucher wrote:
> On Thu, Mar 30, 2023 at 11:21 AM Shashank Sharma
> <shashank.sharma@amd.com> wrote:
>>
>> On 30/03/2023 16:55, Alex Deucher wrote:
>>> On Thu, Mar 30, 2023 at 10:34 AM Shashank Sharma
>>> <shashank.sharma@amd.com> wrote:
>>>> On 30/03/2023 16:15, Luben Tuikov wrote:
>>>>> On 2023-03-30 10:04, Shashank Sharma wrote:
>>>>>> On 30/03/2023 15:42, Luben Tuikov wrote:
>>>>>>> On 2023-03-29 11:47, Shashank Sharma wrote:
>>>>>>>> From: Shashank Sharma <contactshashanksharma@gmail.com>
>>>>>>>>
>>>>>>>> This patch adds helper functions to create and free doorbell
>>>>>>>> pages for kernel objects.
>>>>>>>>
>>>>>>>> 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_doorbell.h  | 41 ++++++++++++++++
>>>>>>>>      .../gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c  | 49 +++++++++++++++++++
>>>>>>>>      2 files changed, 90 insertions(+)
>>>>>>>>
>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>>>> index f9c3b77bf65d..6581b78fe438 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
>>>>>>>> @@ -27,6 +27,24 @@
>>>>>>>>      /*
>>>>>>>>       * GPU doorbell structures, functions & helpers
>>>>>>>>       */
>>>>>>>> +
>>>>>>>> +/* Structure to hold doorbell pages from PCI doorbell BAR */
>>>>>>>> +struct amdgpu_doorbell_obj {
>>>>>>> In the comment you say "Structure to hold ...";
>>>>>>> it is a C structure, but then in the name of a function we see "obj".
>>>>>>> (Object is something which is defined like in memory, i.e. it exists, not
>>>>>>> something which is only declared.)
>>>>>>> This is just a declaration of a structure, not an object per se.
>>>>>>> I'd call it "struct amdgpu_doorbell_struct" or just "struct amdgpu_doorbell".
>>>>>> It is similar to struct amdgpu buffer object (struct amdgpu_bo), and
>>>>>> many more existing structure.
>>>>> The amdpgu_bo is very different than a structure describing a doorbell.
>>>>> The doorbell description isn't really "an object". I understand
>>>>> the enthusiasm, but it is really not "an object". It's just a doorbell
>>>>> description. :-)
>>>> amdgpu_bo is page of ttm_memory with additional information,
>>>>
>>>> amdgpu_doorbell_obj is a page of ttm_doorbells with additional information
>>>>
>>>> (it is not just one doorbell description)
>>>>
>>>> I don't see a problem here.
>>> I find the new API confusing.  I would expect to see
>>> amdgpu_bo_create_kernel(...DOORBELL...), amdgpu_bo_reserve(),
>>> amdgpu_bo_kmap(), etc.  That makes it consistent with the other
>>> resource pools that we manage in ttm.
>> I am assuming here you are talking about why do we need
>> amdgpu_doorbell_page_create()/free() API here.
>>
>> The wrappers here allow us to do additional book keeping work.
>>
>> For example:
>>
>> - We need to validate kernel doorbell writes, which means we need the
>> range of kernel doorbells.
>>
>> - There are 3 kernel doorbell pages, for KGD, KFD and MES. These are non
>> consecutive pages.
>>
>> - While we do doorbell_write in kernel, we need to check if this index
>> is correct, which means:
>>
>> kgd_doobrell_min < index < kgd_doorbell_max
>>
>> kfd_doobrell_min < index < kgd_doorbell_max
>>
>> mes_doobrell_min < index < kgd_doorbell_max
>>
>> - which means we need start/end limits set at every object.
>>
>> - we have to either do this work at each place where we want to call
>> amdgpu_bo_create(DOORBELL)
>>
>>     which means KFD, KGD and MES all places (which will look irrelevant
>> in the context)
>>
>>    or we can do this in one place, which is the doorbell wrapper API.
>>
>>
>> Please see patch 10 for this range check.
> I don't think we need the range checks for anything other than the
> KGD.  The MES stuff should just use the same allocation as KGD.  KFD
> has their own mapping in kfd_doorbell.c and they don't use the
> WDOORBELL[64] macros.
>
> Alex

Noted, I will remove the book keeping and the wrapper.

- Shashank

>>
>> - Shashank
>>
>>
>> now kfd is setting start/end limits by calling
>> amdgpu_get_doorbell_index() function.
>>
>>> Alex
>>>
>>>> - Shashank
>>>>
>>>>> Regards,
>>>>> Luben
>>>>>
>>>>>> - Shashank
>>>>>>
>>>>>>> Then in the definition, you can call it an object/objects, if you'd like,
>>>>>>> like "struct amdgpu_doorbell *doorb_object[];" then you can say
>>>>>>> "db = doorb_object[i]";
>>>>>>>
>>>>>>> Regards,
>>>>>>> Luben
>>>>>>>
>>>>>>>> +  struct amdgpu_bo *bo;
>>>>>>>> +  uint64_t gpu_addr;
>>>>>>>> +  uint32_t *cpu_addr;
>>>>>>>> +  uint32_t size;
>>>>>>>> +
>>>>>>>> +  /* First index in this object */
>>>>>>>> +  uint32_t start;
>>>>>>>> +
>>>>>>>> +  /* Last index in this object */
>>>>>>>> +  uint32_t end;
>>>>>>>> +
>>>>>>>> +  /* bitmap for dynamic doorbell allocation from this object */
>>>>>>>> +  unsigned long *doorbell_bitmap;
>>>>>>>> +};
>>>>>>>> +
>>>>>>>>      struct amdgpu_doorbell {
>>>>>>>>              /* doorbell mmio */
>>>>>>>>              resource_size_t         base;
>>>>>>>> @@ -328,6 +346,29 @@ int amdgpu_device_doorbell_init(struct amdgpu_device *adev);
>>>>>>>>       */
>>>>>>>>      void amdgpu_device_doorbell_fini(struct amdgpu_device *adev);
>>>>>>>>
>>>>>>>> +/**
>>>>>>>> + * amdgpu_doorbell_free_page - Free a doorbell page
>>>>>>>> + *
>>>>>>>> + * @adev: amdgpu_device pointer
>>>>>>>> + *
>>>>>>>> + * @db_age: previously allocated doobell page details
>>>>>>>> + *
>>>>>>>> + */
>>>>>>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>>>>>>> +                          struct amdgpu_doorbell_obj *db_obj);
>>>>>>>> +
>>>>>>>> +/**
>>>>>>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>>>>>>>> + *
>>>>>>>> + * @adev: amdgpu_device pointer
>>>>>>>> + *
>>>>>>>> + * @db_age: doobell page structure to fill details with
>>>>>>>> + *
>>>>>>>> + * returns 0 on success, else error number
>>>>>>>> + */
>>>>>>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>>>>> +                          struct amdgpu_doorbell_obj *db_obj);
>>>>>>>> +
>>>>>>>>      #define RDOORBELL32(index) amdgpu_mm_rdoorbell(adev, (index))
>>>>>>>>      #define WDOORBELL32(index, v) amdgpu_mm_wdoorbell(adev, (index), (v))
>>>>>>>>      #define RDOORBELL64(index) amdgpu_mm_rdoorbell64(adev, (index))
>>>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>>>> index 1aea92363fd3..8be15b82b545 100644
>>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c
>>>>>>>> @@ -111,6 +111,55 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>>>>>>>>              }
>>>>>>>>      }
>>>>>>>>
>>>>>>>> +/**
>>>>>>>> + * amdgpu_doorbell_free_page - Free a doorbell page
>>>>>>>> + *
>>>>>>>> + * @adev: amdgpu_device pointer
>>>>>>>> + *
>>>>>>>> + * @db_age: previously allocated doobell page details
>>>>>>>> + *
>>>>>>>> + */
>>>>>>>> +void amdgpu_doorbell_free_page(struct amdgpu_device *adev,
>>>>>>>> +                                  struct amdgpu_doorbell_obj *db_obj)
>>>>>>>> +{
>>>>>>>> +  amdgpu_bo_free_kernel(&db_obj->bo,
>>>>>>>> +                        &db_obj->gpu_addr,
>>>>>>>> +                        (void **)&db_obj->cpu_addr);
>>>>>>>> +
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +/**
>>>>>>>> + * amdgpu_doorbell_alloc_page - create a page from doorbell pool
>>>>>>>> + *
>>>>>>>> + * @adev: amdgpu_device pointer
>>>>>>>> + *
>>>>>>>> + * @db_age: doobell page structure to fill details with
>>>>>>>> + *
>>>>>>>> + * returns 0 on success, else error number
>>>>>>>> + */
>>>>>>>> +int amdgpu_doorbell_alloc_page(struct amdgpu_device *adev,
>>>>>>>> +                          struct amdgpu_doorbell_obj *db_obj)
>>>>>>>> +{
>>>>>>>> +  int r;
>>>>>>>> +
>>>>>>>> +  db_obj->size = ALIGN(db_obj->size, PAGE_SIZE);
>>>>>>>> +
>>>>>>>> +  r = amdgpu_bo_create_kernel(adev,
>>>>>>>> +                              db_obj->size,
>>>>>>>> +                              PAGE_SIZE,
>>>>>>>> +                              AMDGPU_GEM_DOMAIN_DOORBELL,
>>>>>>>> +                              &db_obj->bo,
>>>>>>>> +                              &db_obj->gpu_addr,
>>>>>>>> +                              (void **)&db_obj->cpu_addr);
>>>>>>>> +
>>>>>>>> +  if (r) {
>>>>>>>> +          DRM_ERROR("Failed to create doorbell BO, err=%d\n", r);
>>>>>>>> +          return r;
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>> +  return 0;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>      /*
>>>>>>>>       * GPU doorbell aperture helpers function.
>>>>>>>>       */

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

* Re: [PATCH 12/16] drm/amdgpu: use doorbell manager for kfd kernel doorbells
  2023-03-30 20:46   ` Alex Deucher
@ 2023-03-31  8:27     ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-31  8:27 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig, amd-gfx


On 30/03/2023 22:46, Alex Deucher wrote:
> On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
> <shashank.sharma@amd.com> wrote:
>> This patch:
>> - adds a doorbell manager structure in kfd device structure.
>> - plugs-in doorbell manager APIs for KFD kernel doorbell allocations
>>    an free functions.
>> - removes the doorbell bitmap, uses the one into the doorbell manager
>>    structure for all the allocations.
>> - updates the get_kernel_doorbell and free_kernel_doorbell functions
>>    accordingly
>>
>> 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/amdkfd/kfd_device.c   |   4 +-
>>   drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | 109 ++++++----------------
>>   drivers/gpu/drm/amd/amdkfd/kfd_priv.h     |   3 +
>>   3 files changed, 35 insertions(+), 81 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
>> index b8936340742b..a2e4cbddba26 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
>> @@ -435,8 +435,8 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf)
>>          atomic_set(&kfd->compute_profile, 0);
>>
>>          mutex_init(&kfd->doorbell_mutex);
>> -       memset(&kfd->doorbell_available_index, 0,
>> -               sizeof(kfd->doorbell_available_index));
>> +       memset(kfd->kernel_doorbells.doorbell_bitmap, 0,
>> +              kfd->kernel_doorbells.size / BITS_PER_LONG);
>>
>>          atomic_set(&kfd->sram_ecc_flag, 0);
>>
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
>> index cd4e61bf0493..df259f2cc58a 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
>> @@ -61,81 +61,37 @@ size_t kfd_doorbell_process_slice(struct kfd_dev *kfd)
>>   /* Doorbell calculations for device init. */
>>   int kfd_doorbell_init(struct kfd_dev *kfd)
>>   {
>> -       size_t doorbell_start_offset;
>> -       size_t doorbell_aperture_size;
>> -       size_t doorbell_process_limit;
>> +       int r;
>> +       struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
>>
>> -       /*
>> -        * With MES enabled, just set the doorbell base as it is needed
>> -        * to calculate doorbell physical address.
>> -        */
>> -       if (kfd->shared_resources.enable_mes) {
>> -               kfd->doorbell_base =
>> -                       kfd->shared_resources.doorbell_physical_address;
>> -               return 0;
>> -       }
>> -
>> -       /*
>> -        * We start with calculations in bytes because the input data might
>> -        * only be byte-aligned.
>> -        * Only after we have done the rounding can we assume any alignment.
>> -        */
>> -
>> -       doorbell_start_offset =
>> -                       roundup(kfd->shared_resources.doorbell_start_offset,
>> -                                       kfd_doorbell_process_slice(kfd));
>> -
>> -       doorbell_aperture_size =
>> -                       rounddown(kfd->shared_resources.doorbell_aperture_size,
>> -                                       kfd_doorbell_process_slice(kfd));
>> -
>> -       if (doorbell_aperture_size > doorbell_start_offset)
>> -               doorbell_process_limit =
>> -                       (doorbell_aperture_size - doorbell_start_offset) /
>> -                                               kfd_doorbell_process_slice(kfd);
>> -       else
>> -               return -ENOSPC;
>> -
>> -       if (!kfd->max_doorbell_slices ||
>> -           doorbell_process_limit < kfd->max_doorbell_slices)
>> -               kfd->max_doorbell_slices = doorbell_process_limit;
>> -
>> -       kfd->doorbell_base = kfd->shared_resources.doorbell_physical_address +
>> -                               doorbell_start_offset;
>> -
>> -       kfd->doorbell_base_dw_offset = doorbell_start_offset / sizeof(u32);
>> -
>> -       kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base,
>> -                                          kfd_doorbell_process_slice(kfd));
>> -
>> -       if (!kfd->doorbell_kernel_ptr)
>> +       /* Bitmap to dynamically allocate doorbells from kernel page */
>> +       kernel_doorbells->doorbell_bitmap = bitmap_zalloc(PAGE_SIZE, GFP_KERNEL);
>> +       if (!kernel_doorbells->doorbell_bitmap) {
>> +               DRM_ERROR("Failed to allocate kernel doorbell bitmap\n");
>>                  return -ENOMEM;
>> +       }
>>
>> -       pr_debug("Doorbell initialization:\n");
>> -       pr_debug("doorbell base           == 0x%08lX\n",
>> -                       (uintptr_t)kfd->doorbell_base);
>> -
>> -       pr_debug("doorbell_base_dw_offset      == 0x%08lX\n",
>> -                       kfd->doorbell_base_dw_offset);
>> -
>> -       pr_debug("doorbell_process_limit  == 0x%08lX\n",
>> -                       doorbell_process_limit);
>> -
>> -       pr_debug("doorbell_kernel_offset  == 0x%08lX\n",
>> -                       (uintptr_t)kfd->doorbell_base);
>> -
>> -       pr_debug("doorbell aperture size  == 0x%08lX\n",
>> -                       kfd->shared_resources.doorbell_aperture_size);
>> +       /* Alloc and reserve doorbells for KFD kernel usages */
>> +       kernel_doorbells->size = PAGE_SIZE;
>> +       r = amdgpu_doorbell_alloc_page(kfd->adev, kernel_doorbells);
>
> Just do something like:
> r = amdgpu_bo_create_kernel(kfd->adev, PAGE_SIZE, PAGE_SIZE,
> AMDGPU_GEM_DOMAIN_DOORBELL,
>
> &kfd->doorbell_kernel_bo, NULL, &kfd->doorbell_kernel_ptr);
>
> Then you have your KFD pointer to its doorbell memory and no need to
> track the ranges.

Noted,

- Shashank

>
> Alex
>
>
>> +       if (r) {
>> +               pr_err("failed to allocate kernel doorbells\n");
>> +               bitmap_free(kernel_doorbells->doorbell_bitmap);
>> +               return r;
>> +       }
>>
>> -       pr_debug("doorbell kernel address == %p\n", kfd->doorbell_kernel_ptr);
>> +       kfd->doorbell_kernel_ptr = kernel_doorbells->cpu_addr;
>> +       pr_debug("Doorbell kernel address == %p\n", kfd->doorbell_kernel_ptr);
>>
>>          return 0;
>>   }
>>
>>   void kfd_doorbell_fini(struct kfd_dev *kfd)
>>   {
>> -       if (kfd->doorbell_kernel_ptr)
>> -               iounmap(kfd->doorbell_kernel_ptr);
>> +       struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
>> +
>> +       bitmap_free(kernel_doorbells->doorbell_bitmap);
>> +       amdgpu_doorbell_free_page(kfd->adev, kernel_doorbells);
>>   }
>>
>>   int kfd_doorbell_mmap(struct kfd_dev *dev, struct kfd_process *process,
>> @@ -186,24 +142,19 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
>>                                          unsigned int *doorbell_off)
>>   {
>>          u32 inx;
>> +       struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
>>
>>          mutex_lock(&kfd->doorbell_mutex);
>> -       inx = find_first_zero_bit(kfd->doorbell_available_index,
>> -                                       KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
>> +       inx = find_first_zero_bit(kernel_doorbells->doorbell_bitmap,
>> +                                 kernel_doorbells->size);
>>
>> -       __set_bit(inx, kfd->doorbell_available_index);
>> +       __set_bit(inx, kernel_doorbells->doorbell_bitmap);
>>          mutex_unlock(&kfd->doorbell_mutex);
>>
>>          if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
>>                  return NULL;
>>
>> -       inx *= kfd->device_info.doorbell_size / sizeof(u32);
>> -
>> -       /*
>> -        * Calculating the kernel doorbell offset using the first
>> -        * doorbell page.
>> -        */
>> -       *doorbell_off = kfd->doorbell_base_dw_offset + inx;
>> +       *doorbell_off = amdgpu_doorbell_index_on_bar(kfd->adev, kernel_doorbells->bo, inx);
>>
>>          pr_debug("Get kernel queue doorbell\n"
>>                          "     doorbell offset   == 0x%08X\n"
>> @@ -216,12 +167,12 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
>>   void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr)
>>   {
>>          unsigned int inx;
>> +       struct amdgpu_doorbell_obj *kernel_doorbells = &kfd->kernel_doorbells;
>>
>> -       inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr)
>> -               * sizeof(u32) / kfd->device_info.doorbell_size;
>> +       inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr);
>>
>>          mutex_lock(&kfd->doorbell_mutex);
>> -       __clear_bit(inx, kfd->doorbell_available_index);
>> +       __clear_bit(inx, kernel_doorbells->doorbell_bitmap);
>>          mutex_unlock(&kfd->doorbell_mutex);
>>   }
>>
>> @@ -280,7 +231,7 @@ phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
>>          if (!pdd->doorbell_index) {
>>                  int r = kfd_alloc_process_doorbells(pdd->dev,
>>                                                      &pdd->doorbell_index);
>> -               if (r)
>> +               if (r < 0)
>>                          return 0;
>>          }
>>
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
>> index 552c3ac85a13..0ed33416c35f 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
>> @@ -346,6 +346,9 @@ struct kfd_dev {
>>
>>          /* HMM page migration MEMORY_DEVICE_PRIVATE mapping */
>>          struct dev_pagemap pgmap;
>> +
>> +       /* Kernel doorbells for KFD device */
>> +       struct amdgpu_doorbell_obj kernel_doorbells;
>>   };
>>
>>   enum kfd_mempool {
>> --
>> 2.40.0
>>

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

* Re: [PATCH 13/16] drm/amdgpu: use doorbell manager for kfd process doorbells
  2023-03-30 20:54   ` Alex Deucher
@ 2023-03-31  8:28     ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-31  8:28 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Christian Koenig, amd-gfx


On 30/03/2023 22:54, Alex Deucher wrote:
> On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
> <shashank.sharma@amd.com> wrote:
>> This patch:
>> - adds a new doorbell manager object in kfd pdd structure.
>> - allocates doorbells for a process while creating its pdd.
>> - frees the doorbells with pdd destroy.
>> - uses direct doorbell manager API for doorbell indexing.
>> - removes previous calls to allocate process doorbells as
>>    its not required anymore.
>>
>> PS: This patch ensures that we don't break the existing KFD
>>      functionality, but now KFD userspace library must also
>>      move to creating doorbell pages as AMDGPU GEM objects
>>      using libdrm functions in userspace. The reference code
>>      for the same is available with AMDGPU Usermode queue
>>      libdrm MR. Once this is done, we will not need this
>>      patch.
>>
>> 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/amdkfd/kfd_chardev.c      | 13 ----
>>   .../drm/amd/amdkfd/kfd_device_queue_manager.c | 16 ++---
>>   drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c     | 59 +++++++++----------
>>   drivers/gpu/drm/amd/amdkfd/kfd_priv.h         |  8 +--
>>   drivers/gpu/drm/amd/amdkfd/kfd_process.c      | 26 ++++----
>>   .../amd/amdkfd/kfd_process_queue_manager.c    | 16 ++---
>>   6 files changed, 58 insertions(+), 80 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> index 6d291aa6386b..0e40756417e5 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> @@ -327,12 +327,6 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
>>                  goto err_bind_process;
>>          }
>>
>> -       if (!pdd->doorbell_index &&
>> -           kfd_alloc_process_doorbells(dev, &pdd->doorbell_index) < 0) {
>> -               err = -ENOMEM;
>> -               goto err_alloc_doorbells;
>> -       }
>> -
>>          /* Starting with GFX11, wptr BOs must be mapped to GART for MES to determine work
>>           * on unmapped queues for usermode queue oversubscription (no aggregated doorbell)
>>           */
>> @@ -410,7 +404,6 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
>>          if (wptr_bo)
>>                  amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);
>>   err_wptr_map_gart:
>> -err_alloc_doorbells:
>>   err_bind_process:
>>   err_pdd:
>>          mutex_unlock(&p->mutex);
>> @@ -2163,12 +2156,6 @@ static int criu_restore_devices(struct kfd_process *p,
>>                          ret = PTR_ERR(pdd);
>>                          goto exit;
>>                  }
>> -
>> -               if (!pdd->doorbell_index &&
>> -                   kfd_alloc_process_doorbells(pdd->dev, &pdd->doorbell_index) < 0) {
>> -                       ret = -ENOMEM;
>> -                       goto exit;
>> -               }
>>          }
>>
>>          /*
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
>> index ecb4c3abc629..5827db9b18a8 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
>> @@ -362,7 +362,7 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
>>                  /* For CP queues on SOC15 */
>>                  if (restore_id) {
>>                          /* make sure that ID is free  */
>> -                       if (__test_and_set_bit(*restore_id, qpd->doorbell_bitmap))
>> +                       if (__test_and_set_bit(*restore_id, qpd->proc_doorbells.doorbell_bitmap))
>>                                  return -EINVAL;
>>
>>                          q->doorbell_id = *restore_id;
>> @@ -370,20 +370,20 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
>>                          /* or reserve a free doorbell ID */
>>                          unsigned int found;
>>
>> -                       found = find_first_zero_bit(qpd->doorbell_bitmap,
>> -                                               KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
>> +                       found = find_first_zero_bit(qpd->proc_doorbells.doorbell_bitmap,
>> +                                                   KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
>>                          if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
>>                                  pr_debug("No doorbells available");
>>                                  return -EBUSY;
>>                          }
>> -                       set_bit(found, qpd->doorbell_bitmap);
>> +                       set_bit(found, qpd->proc_doorbells.doorbell_bitmap);
>>                          q->doorbell_id = found;
>>                  }
>>          }
>>
>> -       q->properties.doorbell_off =
>> -               kfd_get_doorbell_dw_offset_in_bar(dev, qpd_to_pdd(qpd),
>> -                                         q->doorbell_id);
>> +       q->properties.doorbell_off = amdgpu_doorbell_index_on_bar(dev->adev,
>> +                                                                 qpd->proc_doorbells.bo,
>> +                                                                 q->doorbell_id);
>>          return 0;
>>   }
>>
>> @@ -398,7 +398,7 @@ static void deallocate_doorbell(struct qcm_process_device *qpd,
>>              q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
>>                  return;
>>
>> -       old = test_and_clear_bit(q->doorbell_id, qpd->doorbell_bitmap);
>> +       old = test_and_clear_bit(q->doorbell_id, qpd->proc_doorbells.doorbell_bitmap);
>>          WARN_ON(!old);
>>   }
>>
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
>> index df259f2cc58a..7d29653bff81 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
>> @@ -228,46 +228,41 @@ uint64_t kfd_get_number_elems(struct kfd_dev *kfd)
>>
>>   phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
>>   {
>> -       if (!pdd->doorbell_index) {
>> -               int r = kfd_alloc_process_doorbells(pdd->dev,
>> -                                                   &pdd->doorbell_index);
>> -               if (r < 0)
>> -                       return 0;
>> -       }
>> +       struct amdgpu_device *adev = pdd->dev->adev;
>>
>> -       return pdd->dev->doorbell_base +
>> -               pdd->doorbell_index * kfd_doorbell_process_slice(pdd->dev);
>> +       /* Return base of the first doorbell of this process */
>> +       return adev->doorbell.base + pdd->qpd.proc_doorbells.start * sizeof(uint32_t);
>>   }
>>
>> -int kfd_alloc_process_doorbells(struct kfd_dev *kfd, unsigned int *doorbell_index)
>> +int kfd_alloc_process_doorbells(struct kfd_dev *kfd, struct kfd_process_device *pdd)
>>   {
>> -       int r = 0;
>> -
>> -       if (!kfd->shared_resources.enable_mes)
>> -               r = ida_simple_get(&kfd->doorbell_ida, 1,
>> -                                  kfd->max_doorbell_slices, GFP_KERNEL);
>> -       else
>> -               r = amdgpu_mes_alloc_process_doorbells(
>> -                               (struct amdgpu_device *)kfd->adev,
>> -                               doorbell_index);
>> -
>> -       if (r > 0)
>> -               *doorbell_index = r;
>> +       int r;
>> +       struct qcm_process_device *qpd = &pdd->qpd;
>> +       struct amdgpu_doorbell_obj *proc_doorbells = &qpd->proc_doorbells;
>> +
>> +       /* Allocate bitmap for dynamic doorbell allocation */
>> +       proc_doorbells->doorbell_bitmap = bitmap_zalloc(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
>> +                                                       GFP_KERNEL);
>> +       if (!proc_doorbells->doorbell_bitmap) {
>> +               DRM_ERROR("Failed to allocate process doorbell bitmap\n");
>> +               return -ENOMEM;
>> +       }
>>
>> -       if (r < 0)
>> -               pr_err("Failed to allocate process doorbells\n");
>> +       /* Allocate doorbells for this process from the PCI BAR */
>> +       proc_doorbells->size = kfd_doorbell_process_slice(kfd);
>> +       r = amdgpu_doorbell_alloc_page(kfd->adev, proc_doorbells);
> Same thing here as the previous patch.  Just call
> amdgpu_bo_create_kernel(..DOORBELL..) and store the bo in the process
> structure.
>
> Alex

got it,

- Shashank

>
>> +       if (r) {
>> +               DRM_ERROR("Failed to allocate process doorbells\n");
>> +               return r;
>> +       }
>>
>>          return r;
>>   }
>>
>> -void kfd_free_process_doorbells(struct kfd_dev *kfd, unsigned int doorbell_index)
>> +void kfd_free_process_doorbells(struct kfd_dev *kfd, struct kfd_process_device *pdd)
>>   {
>> -       if (doorbell_index) {
>> -               if (!kfd->shared_resources.enable_mes)
>> -                       ida_simple_remove(&kfd->doorbell_ida, doorbell_index);
>> -               else
>> -                       amdgpu_mes_free_process_doorbells(
>> -                                       (struct amdgpu_device *)kfd->adev,
>> -                                       doorbell_index);
>> -       }
>> +       struct amdgpu_doorbell_obj *proc_doorbells = &pdd->qpd.proc_doorbells;
>> +
>> +       bitmap_free(proc_doorbells->doorbell_bitmap);
>> +       amdgpu_doorbell_free_page(kfd->adev, proc_doorbells);
>>   }
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
>> index 0ed33416c35f..c97ed8e7e02d 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
>> @@ -658,8 +658,8 @@ struct qcm_process_device {
>>          uint64_t ib_base;
>>          void *ib_kaddr;
>>
>> -       /* doorbell resources per process per device */
>> -       unsigned long *doorbell_bitmap;
>> +       /* physical doorbell pages */
>> +       struct amdgpu_doorbell_obj proc_doorbells;
>>   };
>>
>>   /* KFD Memory Eviction */
>> @@ -1006,9 +1006,9 @@ unsigned int kfd_get_doorbell_dw_offset_in_bar(struct kfd_dev *kfd,
>>                                          unsigned int doorbell_id);
>>   phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd);
>>   int kfd_alloc_process_doorbells(struct kfd_dev *kfd,
>> -                               unsigned int *doorbell_index);
>> +                                struct kfd_process_device *pdd);
>>   void kfd_free_process_doorbells(struct kfd_dev *kfd,
>> -                               unsigned int doorbell_index);
>> +                                struct kfd_process_device *pdd);
>>   /* GTT Sub-Allocator */
>>
>>   int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size,
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
>> index 51b1683ac5c1..68d0310c2d53 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
>> @@ -1037,10 +1037,9 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
>>                          free_pages((unsigned long)pdd->qpd.cwsr_kaddr,
>>                                  get_order(KFD_CWSR_TBA_TMA_SIZE));
>>
>> -               bitmap_free(pdd->qpd.doorbell_bitmap);
>>                  idr_destroy(&pdd->alloc_idr);
>>
>> -               kfd_free_process_doorbells(pdd->dev, pdd->doorbell_index);
>> +               kfd_free_process_doorbells(pdd->dev, pdd);
>>
>>                  if (pdd->dev->shared_resources.enable_mes)
>>                          amdgpu_amdkfd_free_gtt_mem(pdd->dev->adev,
>> @@ -1449,15 +1448,11 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd,
>>          unsigned int i;
>>          int range_start = dev->shared_resources.non_cp_doorbells_start;
>>          int range_end = dev->shared_resources.non_cp_doorbells_end;
>> +       struct amdgpu_doorbell_obj *proc_doorbells = &qpd->proc_doorbells;
>>
>>          if (!KFD_IS_SOC15(dev))
>>                  return 0;
>>
>> -       qpd->doorbell_bitmap = bitmap_zalloc(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
>> -                                            GFP_KERNEL);
>> -       if (!qpd->doorbell_bitmap)
>> -               return -ENOMEM;
>> -
>>          /* Mask out doorbells reserved for SDMA, IH, and VCN on SOC15. */
>>          pr_debug("reserved doorbell 0x%03x - 0x%03x\n", range_start, range_end);
>>          pr_debug("reserved doorbell 0x%03x - 0x%03x\n",
>> @@ -1466,9 +1461,9 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd,
>>
>>          for (i = 0; i < KFD_MAX_NUM_OF_QUEUES_PER_PROCESS / 2; i++) {
>>                  if (i >= range_start && i <= range_end) {
>> -                       __set_bit(i, qpd->doorbell_bitmap);
>> +                       __set_bit(i, proc_doorbells->doorbell_bitmap);
>>                          __set_bit(i + KFD_QUEUE_DOORBELL_MIRROR_OFFSET,
>> -                                 qpd->doorbell_bitmap);
>> +                                 proc_doorbells->doorbell_bitmap);
>>                  }
>>          }
>>
>> @@ -1499,9 +1494,15 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
>>          if (!pdd)
>>                  return NULL;
>>
>> +       retval = kfd_alloc_process_doorbells(dev, pdd);
>> +       if (retval) {
>> +               pr_err("failed to allocate process doorbells\n");
>> +               goto err_free_pdd;
>> +       }
>> +
>>          if (init_doorbell_bitmap(&pdd->qpd, dev)) {
>>                  pr_err("Failed to init doorbell for process\n");
>> -               goto err_free_pdd;
>> +               goto err_free_db;
>>          }
>>
>>          pdd->dev = dev;
>> @@ -1529,7 +1530,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
>>                                                  false);
>>                  if (retval) {
>>                          pr_err("failed to allocate process context bo\n");
>> -                       goto err_free_pdd;
>> +                       goto err_free_db;
>>                  }
>>                  memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
>>          }
>> @@ -1541,6 +1542,9 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
>>
>>          return pdd;
>>
>> +err_free_db:
>> +       kfd_free_process_doorbells(pdd->dev, pdd);
>> +
>>   err_free_pdd:
>>          kfree(pdd);
>>          return NULL;
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
>> index 5137476ec18e..693688d789d3 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
>> @@ -348,13 +348,11 @@ int pqm_create_queue(struct process_queue_manager *pqm,
>>                  /* Return the doorbell offset within the doorbell page
>>                   * to the caller so it can be passed up to user mode
>>                   * (in bytes).
>> -                * There are always 1024 doorbells per process, so in case
>> -                * of 8-byte doorbells, there are two doorbell pages per
>> -                * process.
>> +                * relative doorbell index = Absolute doorbell index -
>> +                * absolute index of first doorbell in the page.
>>                   */
>> -               *p_doorbell_offset_in_process =
>> -                       (q->properties.doorbell_off * sizeof(uint32_t)) &
>> -                       (kfd_doorbell_process_slice(dev) - 1);
>> +               *p_doorbell_offset_in_process = (q->properties.doorbell_off
>> +                                               - pdd->qpd.proc_doorbells.start) * sizeof(uint32_t);
>>
>>          pr_debug("PQM After DQM create queue\n");
>>
>> @@ -858,12 +856,6 @@ int kfd_criu_restore_queue(struct kfd_process *p,
>>                  goto exit;
>>          }
>>
>> -       if (!pdd->doorbell_index &&
>> -           kfd_alloc_process_doorbells(pdd->dev, &pdd->doorbell_index) < 0) {
>> -               ret = -ENOMEM;
>> -               goto exit;
>> -       }
>> -
>>          /* data stored in this order: mqd, ctl_stack */
>>          mqd = q_extra_data;
>>          ctl_stack = mqd + q_data->mqd_size;
>> --
>> 2.40.0
>>

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

* Re: [PATCH 15/16] drm/amdgpu: use doorbell mgr for MES kernel doorbells
  2023-03-30 20:58   ` Alex Deucher
@ 2023-03-31  8:29     ` Shashank Sharma
  0 siblings, 0 replies; 87+ messages in thread
From: Shashank Sharma @ 2023-03-31  8:29 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Mukul Joshi, Felix Kuehling, Arvind Yadav, amd-gfx, Alex Deucher,
	Christian Koenig


On 30/03/2023 22:58, Alex Deucher wrote:
> On Wed, Mar 29, 2023 at 11:48 AM Shashank Sharma
> <shashank.sharma@amd.com> wrote:
>> This patch:
>> - adds a doorbell object in MES structure, to manage the MES
>>    doorbell requirements in kernel.
>> - Removes the doorbell management code, and its variables from
>>    the doorbell_init function, it will be done in doorbell manager
>>    now.
>> - creates doorbell pages for MES kernel level needs (doorbells
>>    for MES self tests)
>> - current MES code was allocating MES doorbells in MES process context,
>>    but those were rung using kernel doorbell calls. This patch allocates
>>    MES kernel doorbells instead for this in add_hw_queue.
>>
>> 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_mes.c | 105 ++++++++++++------------
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h |   5 +-
>>   2 files changed, 56 insertions(+), 54 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>> index 0c546245793b..423cd642647c 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
>> @@ -65,91 +65,89 @@ unsigned int amdgpu_mes_get_doorbell_dw_offset_in_bar(
>>                  doorbell_id * 2);
>>   }
>>
>> -static int amdgpu_mes_queue_doorbell_get(struct amdgpu_device *adev,
>> +static int amdgpu_mes_kernel_doorbell_get(struct amdgpu_device *adev,
>>                                           struct amdgpu_mes_process *process,
>>                                           int ip_type, uint64_t *doorbell_index)
>>   {
>>          unsigned int offset, found;
>> +       struct amdgpu_doorbell_obj *doorbells = &adev->mes.kernel_doorbells;
>>
>> -       if (ip_type == AMDGPU_RING_TYPE_SDMA) {
>> +       if (ip_type == AMDGPU_RING_TYPE_SDMA)
>>                  offset = adev->doorbell_index.sdma_engine[0];
>> -               found = find_next_zero_bit(process->doorbell_bitmap,
>> -                                          AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
>> -                                          offset);
>> -       } else {
>> -               found = find_first_zero_bit(process->doorbell_bitmap,
>> -                                           AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS);
>> -       }
>> +       else
>> +               offset = 0;
>>
>> +       found = find_next_zero_bit(doorbells->doorbell_bitmap,
>> +                                  AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS,
>> +                                  offset);
>>          if (found >= AMDGPU_MES_MAX_NUM_OF_QUEUES_PER_PROCESS) {
>>                  DRM_WARN("No doorbell available\n");
>>                  return -ENOSPC;
>>          }
>>
>> -       set_bit(found, process->doorbell_bitmap);
>> +       set_bit(found, doorbells->doorbell_bitmap);
>>
>> -       *doorbell_index = amdgpu_mes_get_doorbell_dw_offset_in_bar(adev,
>> -                               process->doorbell_index, found);
>> +       *doorbell_index = amdgpu_doorbell_index_on_bar(adev, doorbells->bo, found);
>>
>>          return 0;
>>   }
>>
>> -static void amdgpu_mes_queue_doorbell_free(struct amdgpu_device *adev,
>> +static void amdgpu_mes_kernel_doorbell_free(struct amdgpu_device *adev,
>>                                             struct amdgpu_mes_process *process,
>>                                             uint32_t doorbell_index)
>>   {
>>          unsigned int old, doorbell_id;
>> +       struct amdgpu_doorbell_obj *doorbells = &adev->mes.kernel_doorbells;
>>
>> -       doorbell_id = doorbell_index -
>> -               (process->doorbell_index *
>> -                amdgpu_mes_doorbell_process_slice(adev)) / sizeof(u32);
>> +       /* Find the relative index of the doorbell in this object */
>> +       doorbell_id = doorbell_index - doorbells->start;
>>          doorbell_id /= 2;
>>
>> -       old = test_and_clear_bit(doorbell_id, process->doorbell_bitmap);
>> +       old = test_and_clear_bit(doorbell_id, doorbells->doorbell_bitmap);
>>          WARN_ON(!old);
>>   }
>>
>>   static int amdgpu_mes_doorbell_init(struct amdgpu_device *adev)
>>   {
>> -       size_t doorbell_start_offset;
>> -       size_t doorbell_aperture_size;
>> -       size_t doorbell_process_limit;
>> -       size_t aggregated_doorbell_start;
>> -       int i;
>> -
>> -       aggregated_doorbell_start = (adev->doorbell_index.max_assignment + 1) * sizeof(u32);
>> -       aggregated_doorbell_start =
>> -               roundup(aggregated_doorbell_start, PAGE_SIZE);
>> -
>> -       doorbell_start_offset = aggregated_doorbell_start + PAGE_SIZE;
>> -       doorbell_start_offset =
>> -               roundup(doorbell_start_offset,
>> -                       amdgpu_mes_doorbell_process_slice(adev));
>> -
>> -       doorbell_aperture_size = adev->doorbell.size;
>> -       doorbell_aperture_size =
>> -                       rounddown(doorbell_aperture_size,
>> -                                 amdgpu_mes_doorbell_process_slice(adev));
>> -
>> -       if (doorbell_aperture_size > doorbell_start_offset)
>> -               doorbell_process_limit =
>> -                       (doorbell_aperture_size - doorbell_start_offset) /
>> -                       amdgpu_mes_doorbell_process_slice(adev);
>> -       else
>> -               return -ENOSPC;
>> +       int i, r;
>> +       u32 agg_db_start_index, nbits;
>> +       struct amdgpu_doorbell_obj *mes_doorbells = &adev->mes.kernel_doorbells;
>>
>> -       adev->mes.doorbell_id_offset = doorbell_start_offset / sizeof(u32);
>> -       adev->mes.max_doorbell_slices = doorbell_process_limit;
>> +               /* Allocated one page doorbells for MES kernel usages */
>> +       mes_doorbells->size = PAGE_SIZE;
>>
>> -       /* allocate Qword range for aggregated doorbell */
>> -       for (i = 0; i < AMDGPU_MES_PRIORITY_NUM_LEVELS; i++)
>> -               adev->mes.aggregated_doorbells[i] =
>> -                       aggregated_doorbell_start / sizeof(u32) + i * 2;
>> +       nbits = DIV_ROUND_UP(mes_doorbells->size, sizeof(u32));
>> +       mes_doorbells->doorbell_bitmap = bitmap_zalloc(nbits, GFP_KERNEL);
>> +       if (!mes_doorbells->doorbell_bitmap) {
>> +               DRM_ERROR("Failed to allocate MES doorbell bitmap\n");
>> +               return -ENOMEM;
>> +       }
>> +
>> +       r = amdgpu_doorbell_alloc_page(adev, mes_doorbells);
> Rather than allocating a separate page here, just allocate two pages
> in the earlier patch where you allocate the KGD doorbell and then just
> use the second page here.

got it,

- Shashank

> Alex
>
>> +       if (r) {
>> +               DRM_ERROR("Failed to create MES doorbell object\n, err=%d", r);
>> +               bitmap_free(mes_doorbells->doorbell_bitmap);
>> +               return r;
>> +       }
>> +
>> +       /* Get the absolute doorbell index for aggregated doobells */
>> +       agg_db_start_index = mes_doorbells->start;
>> +       for (i = 0; i < AMDGPU_MES_PRIORITY_NUM_LEVELS; i++) {
>> +               adev->mes.aggregated_doorbells[i] = agg_db_start_index + i;
>> +               set_bit(agg_db_start_index + i, mes_doorbells->doorbell_bitmap);
>> +       }
>>
>> -       DRM_INFO("max_doorbell_slices=%zu\n", doorbell_process_limit);
>>          return 0;
>>   }
>>
>> +static void amdgpu_mes_doorbell_free(struct amdgpu_device *adev)
>> +{
>> +       struct amdgpu_doorbell_obj *mes_doorbells = &adev->mes.kernel_doorbells;
>> +
>> +       bitmap_free(mes_doorbells->doorbell_bitmap);
>> +       amdgpu_doorbell_free_page(adev, mes_doorbells);
>> +}
>> +
>>   int amdgpu_mes_init(struct amdgpu_device *adev)
>>   {
>>          int i, r;
>> @@ -248,6 +246,7 @@ void amdgpu_mes_fini(struct amdgpu_device *adev)
>>          amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs);
>>          amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs);
>>          amdgpu_device_wb_free(adev, adev->mes.read_val_offs);
>> +       amdgpu_mes_doorbell_free(adev);
>>
>>          idr_destroy(&adev->mes.pasid_idr);
>>          idr_destroy(&adev->mes.gang_id_idr);
>> @@ -677,7 +676,7 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id,
>>          *queue_id = queue->queue_id = r;
>>
>>          /* allocate a doorbell index for the queue */
>> -       r = amdgpu_mes_queue_doorbell_get(adev, gang->process,
>> +       r = amdgpu_mes_kernel_doorbell_get(adev, gang->process,
>>                                            qprops->queue_type,
>>                                            &qprops->doorbell_off);
>>          if (r)
>> @@ -735,7 +734,7 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id,
>>          return 0;
>>
>>   clean_up_doorbell:
>> -       amdgpu_mes_queue_doorbell_free(adev, gang->process,
>> +       amdgpu_mes_kernel_doorbell_free(adev, gang->process,
>>                                         qprops->doorbell_off);
>>   clean_up_queue_id:
>>          spin_lock_irqsave(&adev->mes.queue_id_lock, flags);
>> @@ -790,7 +789,7 @@ int amdgpu_mes_remove_hw_queue(struct amdgpu_device *adev, int queue_id)
>>                            queue_id);
>>
>>          list_del(&queue->list);
>> -       amdgpu_mes_queue_doorbell_free(adev, gang->process,
>> +       amdgpu_mes_kernel_doorbell_free(adev, gang->process,
>>                                         queue->doorbell_off);
>>          amdgpu_mes_unlock(&adev->mes);
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
>> index 97c05d08a551..e7e9dfe44c99 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h
>> @@ -27,6 +27,7 @@
>>   #include "amdgpu_irq.h"
>>   #include "kgd_kfd_interface.h"
>>   #include "amdgpu_gfx.h"
>> +#include "amdgpu_doorbell.h"
>>   #include <linux/sched/mm.h>
>>
>>   #define AMDGPU_MES_MAX_COMPUTE_PIPES        8
>> @@ -76,7 +77,6 @@ struct amdgpu_mes {
>>          uint32_t                        kiq_version;
>>
>>          uint32_t                        total_max_queue;
>> -       uint32_t                        doorbell_id_offset;
>>          uint32_t                        max_doorbell_slices;
>>
>>          uint64_t                        default_process_quantum;
>> @@ -128,6 +128,9 @@ struct amdgpu_mes {
>>          int                             (*kiq_hw_init)(struct amdgpu_device *adev);
>>          int                             (*kiq_hw_fini)(struct amdgpu_device *adev);
>>
>> +       /* MES Kernel doorbells */
>> +       struct amdgpu_doorbell_obj      kernel_doorbells;
>> +
>>          /* ip specific functions */
>>          const struct amdgpu_mes_funcs   *funcs;
>>   };
>> --
>> 2.40.0
>>

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

* Re: [PATCH 01/16] drm/amdgpu: rename num_doorbells
  2023-03-29 15:47 ` [PATCH 01/16] drm/amdgpu: rename num_doorbells Shashank Sharma
                     ` (2 preceding siblings ...)
  2023-03-30 14:19   ` Alex Deucher
@ 2023-04-04 16:13   ` Luben Tuikov
  3 siblings, 0 replies; 87+ messages in thread
From: Luben Tuikov @ 2023-04-04 16:13 UTC (permalink / raw)
  To: Shashank Sharma, amd-gfx
  Cc: Alex Deucher, Mukul Joshi, Felix Kuehling, Shashank Sharma,
	Christian Koenig

On 2023-03-29 11:47, Shashank Sharma wrote:
> From: Shashank Sharma <contactshashanksharma@gmail.com>
> 
> Rename doorbell.num_doorbells to doorbell.num_kernel_doorbells to
> make it more readable.
> 
> Cc: Alex Deucher <alexander.deucher@amd.com>
> Cc: Christian Koenig <christian.koenig@amd.com>
> Signed-off-by: Shashank Sharma <shashank.sharma@amd.com>
> ---

Is there any reason you break up the Cc list between the Cc tags in the commit message,
and the SMTP CC list?

Just do either/or, but it is preferable to add all Cc into the Cc tags of the commit
message, and then let git-send-email fill in the SMTP CC list, and just using MLs
in the --to= argument. (Although, one can include those too in the Cc list.)

Regards,
Luben

>  drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c   |  6 +++---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c   | 22 ++++++++++----------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h |  4 +++-
>  3 files changed, 17 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> index f99d4873bf22..0385f7f69278 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
> @@ -96,7 +96,7 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
>  					 size_t *start_offset)
>  {
>  	/*
> -	 * The first num_doorbells are used by amdgpu.
> +	 * The first num_kernel_doorbells are used by amdgpu.
>  	 * amdkfd takes whatever's left in the aperture.
>  	 */
>  	if (adev->enable_mes) {
> @@ -109,11 +109,11 @@ static void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
>  		*aperture_base = adev->doorbell.base;
>  		*aperture_size = 0;
>  		*start_offset = 0;
> -	} else if (adev->doorbell.size > adev->doorbell.num_doorbells *
> +	} else if (adev->doorbell.size > adev->doorbell.num_kernel_doorbells *
>  						sizeof(u32)) {
>  		*aperture_base = adev->doorbell.base;
>  		*aperture_size = adev->doorbell.size;
> -		*start_offset = adev->doorbell.num_doorbells * sizeof(u32);
> +		*start_offset = adev->doorbell.num_kernel_doorbells * sizeof(u32);
>  	} else {
>  		*aperture_base = 0;
>  		*aperture_size = 0;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index afe6af9c0138..57ee1c4a81e9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -593,7 +593,7 @@ u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return 0;
>  
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>  		return readl(adev->doorbell.ptr + index);
>  	} else {
>  		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> @@ -616,7 +616,7 @@ void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return;
>  
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>  		writel(v, adev->doorbell.ptr + index);
>  	} else {
>  		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> @@ -637,7 +637,7 @@ u64 amdgpu_mm_rdoorbell64(struct amdgpu_device *adev, u32 index)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return 0;
>  
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>  		return atomic64_read((atomic64_t *)(adev->doorbell.ptr + index));
>  	} else {
>  		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index);
> @@ -660,7 +660,7 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
>  	if (amdgpu_device_skip_hw_access(adev))
>  		return;
>  
> -	if (index < adev->doorbell.num_doorbells) {
> +	if (index < adev->doorbell.num_kernel_doorbells) {
>  		atomic64_set((atomic64_t *)(adev->doorbell.ptr + index), v);
>  	} else {
>  		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index);
> @@ -1034,7 +1034,7 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>  	if (adev->asic_type < CHIP_BONAIRE) {
>  		adev->doorbell.base = 0;
>  		adev->doorbell.size = 0;
> -		adev->doorbell.num_doorbells = 0;
> +		adev->doorbell.num_kernel_doorbells = 0;
>  		adev->doorbell.ptr = NULL;
>  		return 0;
>  	}
> @@ -1049,27 +1049,27 @@ static int amdgpu_device_doorbell_init(struct amdgpu_device *adev)
>  	adev->doorbell.size = pci_resource_len(adev->pdev, 2);
>  
>  	if (adev->enable_mes) {
> -		adev->doorbell.num_doorbells =
> +		adev->doorbell.num_kernel_doorbells =
>  			adev->doorbell.size / sizeof(u32);
>  	} else {
> -		adev->doorbell.num_doorbells =
> +		adev->doorbell.num_kernel_doorbells =
>  			min_t(u32, adev->doorbell.size / sizeof(u32),
>  			      adev->doorbell_index.max_assignment+1);
> -		if (adev->doorbell.num_doorbells == 0)
> +		if (adev->doorbell.num_kernel_doorbells == 0)
>  			return -EINVAL;
>  
>  		/* For Vega, reserve and map two pages on doorbell BAR since SDMA
>  		 * paging queue doorbell use the second page. The
>  		 * AMDGPU_DOORBELL64_MAX_ASSIGNMENT definition assumes all the
>  		 * doorbells are in the first page. So with paging queue enabled,
> -		 * the max num_doorbells should + 1 page (0x400 in dword)
> +		 * the max num_kernel_doorbells should + 1 page (0x400 in dword)
>  		 */
>  		if (adev->asic_type >= CHIP_VEGA10)
> -			adev->doorbell.num_doorbells += 0x400;
> +			adev->doorbell.num_kernel_doorbells += 0x400;
>  	}
>  
>  	adev->doorbell.ptr = ioremap(adev->doorbell.base,
> -				     adev->doorbell.num_doorbells *
> +				     adev->doorbell.num_kernel_doorbells *
>  				     sizeof(u32));
>  	if (adev->doorbell.ptr == NULL)
>  		return -ENOMEM;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> index 7199b6b0be81..12263986f889 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell.h
> @@ -29,7 +29,9 @@ struct amdgpu_doorbell {
>  	resource_size_t		base;
>  	resource_size_t		size;
>  	u32 __iomem		*ptr;
> -	u32			num_doorbells;	/* Number of doorbells actually reserved for amdgpu. */
> +
> +	/* Number of doorbells reserved for amdgpu kernel driver */
> +	u32 num_kernel_doorbells;
>  };
>  
>  /* Reserved doorbells for amdgpu (including multimedia).


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

end of thread, other threads:[~2023-04-04 16:13 UTC | newest]

Thread overview: 87+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-29 15:47 [PATCH 00/16] AMDGPU Doorbell manager Shashank Sharma
2023-03-29 15:47 ` [PATCH 01/16] drm/amdgpu: rename num_doorbells Shashank Sharma
2023-03-30 11:04   ` Christian König
2023-03-30 13:11   ` Luben Tuikov
2023-03-30 13:13     ` Shashank Sharma
2023-03-30 14:19   ` Alex Deucher
2023-04-04 16:13   ` Luben Tuikov
2023-03-29 15:47 ` [PATCH 02/16] drm/amdgpu: include protection for doobell.h Shashank Sharma
2023-03-30 11:05   ` Christian König
2023-03-30 11:07     ` Shashank Sharma
2023-03-30 14:20   ` Alex Deucher
2023-03-29 15:47 ` [PATCH 03/16] drm/amdgpu: create a new file for doorbell manager Shashank Sharma
2023-03-30 11:09   ` Christian König
2023-03-30 13:29     ` Luben Tuikov
2023-03-30 13:42       ` Shashank Sharma
2023-03-30 14:23   ` Alex Deucher
2023-03-30 14:49     ` Shashank Sharma
2023-03-29 15:47 ` [PATCH 04/16] drm/amdgpu: don't modify num_doorbells for mes Shashank Sharma
2023-03-30 11:10   ` Christian König
2023-03-30 14:24   ` Alex Deucher
2023-03-29 15:47 ` [PATCH 05/16] drm/amdgpu: add UAPI for allocating doorbell memory Shashank Sharma
2023-03-30 11:11   ` Christian König
2023-03-29 15:47 ` [PATCH 06/16] drm/amdgpu: accommodate DOMAIN/PL_DOORBELL Shashank Sharma
2023-03-30 11:14   ` Christian König
2023-03-30 13:33     ` Luben Tuikov
2023-03-30 13:43       ` Shashank Sharma
2023-03-30 13:45         ` Luben Tuikov
2023-03-30 13:48           ` Shashank Sharma
2023-03-30 14:12             ` Luben Tuikov
2023-03-30 15:32               ` Shashank Sharma
2023-03-30 19:59   ` Alex Deucher
2023-03-29 15:47 ` [PATCH 07/16] drm/amdgpu: add helper to create doorbell pages Shashank Sharma
2023-03-30 11:29   ` Christian König
2023-03-30 11:46     ` Shashank Sharma
2023-03-30 13:42   ` Luben Tuikov
2023-03-30 13:44     ` Luben Tuikov
2023-03-30 14:04     ` Shashank Sharma
2023-03-30 14:15       ` Luben Tuikov
2023-03-30 14:34         ` Shashank Sharma
2023-03-30 14:37           ` Luben Tuikov
2023-03-30 14:55           ` Alex Deucher
2023-03-30 15:21             ` Shashank Sharma
2023-03-30 20:35               ` Alex Deucher
2023-03-31  8:26                 ` Shashank Sharma
2023-03-30 14:28   ` Alex Deucher
2023-03-30 14:38     ` Luben Tuikov
2023-03-29 15:47 ` [PATCH 08/16] drm/amdgpu: initialize ttm for doorbells Shashank Sharma
2023-03-30 11:22   ` Christian König
2023-03-30 14:33   ` Alex Deucher
2023-03-30 14:54     ` Shashank Sharma
2023-03-29 15:47 ` [PATCH 09/16] drm/amdgpu: create kernel doorbell page Shashank Sharma
2023-03-30 11:30   ` Christian König
2023-03-30 11:48     ` Shashank Sharma
2023-03-30 14:39       ` Alex Deucher
2023-03-30 14:42         ` Christian König
2023-03-30 14:48           ` Shashank Sharma
2023-03-30 14:53             ` Christian König
2023-03-30 15:04             ` Alex Deucher
2023-03-31  8:25               ` Shashank Sharma
2023-03-30 14:24   ` Luben Tuikov
2023-03-30 14:40     ` Shashank Sharma
2023-03-30 14:49       ` Christian König
2023-03-30 14:52         ` Luben Tuikov
2023-03-30 14:53         ` Shashank Sharma
2023-03-30 14:59           ` Luben Tuikov
2023-03-30 15:09             ` Shashank Sharma
2023-03-29 15:47 ` [PATCH 10/16] drm/amdgpu: validate doorbell read/write Shashank Sharma
2023-03-30 14:34   ` Luben Tuikov
2023-03-30 14:37     ` Shashank Sharma
2023-03-30 14:49       ` Luben Tuikov
2023-03-30 15:02         ` Shashank Sharma
2023-03-29 15:47 ` [PATCH 11/16] drm/amdgpu: get absolute offset from doorbell index Shashank Sharma
2023-03-30 17:18   ` Luben Tuikov
2023-03-30 17:25     ` Shashank Sharma
2023-03-29 15:47 ` [PATCH 12/16] drm/amdgpu: use doorbell manager for kfd kernel doorbells Shashank Sharma
2023-03-30 20:46   ` Alex Deucher
2023-03-31  8:27     ` Shashank Sharma
2023-03-29 15:47 ` [PATCH 13/16] drm/amdgpu: use doorbell manager for kfd process doorbells Shashank Sharma
2023-03-30 20:54   ` Alex Deucher
2023-03-31  8:28     ` Shashank Sharma
2023-03-29 15:47 ` [PATCH 14/16] drm/amdgpu: remove ununsed functions and variables Shashank Sharma
2023-03-29 15:47 ` [PATCH 15/16] drm/amdgpu: use doorbell mgr for MES kernel doorbells Shashank Sharma
2023-03-30 20:58   ` Alex Deucher
2023-03-31  8:29     ` Shashank Sharma
2023-03-29 15:47 ` [PATCH 16/16] drm/amdgpu: user doorbell mgr for MES process doorbells Shashank Sharma
2023-03-30 13:49 ` [PATCH 00/16] AMDGPU Doorbell manager Luben Tuikov
2023-03-30 13:56   ` Sharma, Shashank

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.