All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/18] drm/i915/guc: Refactor ADS access to use iosys_map
@ 2022-02-08 10:45 ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

v1: https://patchwork.freedesktop.org/series/99378/
v2: https://patchwork.freedesktop.org/series/99711/

Main from previous version:

	- Rename to iosys-map is already applied
	- Rewrite IOSYS_MAP_INIT_OFFSET() and eliminate most of its
	  users, favoring a offset variable to keep the offset from the
	  original iosys_map.
	- Add map offset to both iosys_map_rd_field() and
	  iosys_map_wr_field()
	- Include documentation with example and expected memory layout
	  for iosys_map_rd_field()
	- Replace

Original cover letter:

While porting i915 to arm64 we noticed some issues accessing lmem.
Some writes were getting corrupted and the final state of the buffer
didn't have exactly what we wrote. This became evident when enabling
GuC submission: depending on the number of engines the ADS struct was
being corrupted and GuC would reject it, refusin to initialize.

From Documentation/core-api/bus-virt-phys-mapping.rst:

	This memory is called "PCI memory" or "shared memory" or "IO memory" or
	whatever, and there is only one way to access it: the readb/writeb and
	related functions. You should never take the address of such memory, because
	there is really nothing you can do with such an address: it's not
	conceptually in the same memory space as "real memory" at all, so you cannot
	just dereference a pointer. (Sadly, on x86 it **is** in the same memory space,
	so on x86 it actually works to just deference a pointer, but it's not
	portable).

When reading or writing words directly to IO memory, in order to be portable
the Linux kernel provides the abstraction detailed in section "Differences
between I/O access functions" of Documentation/driver-api/device-io.rst.

This limits our ability to simply overlay our structs on top a buffer
and directly access it since that buffer may come from IO memory rather than
system memory. Hence the approach taken in intel_guc_ads.c needs to be
refactored. This is not the only place in i915 that neeed to be changed, but
the one causing the most problems, with a real reproducer. This first set of
patch focuses on fixing the gem object to pass the ADS

After the addition of a few helpers in the dma_buf_map API, most of
intel_guc_ads.c can be converted to use it. The exception is the regset
initialization: we'd incur into a lot of extra indirection when
reading/writting each register. So the regset is converted to use a
temporary buffer allocated on probe, which is then copied to its
final location when finishing the initialization or on gt reset.

Testing on some discrete cards, after this change we can correctly pass the
ADS struct to GuC and have it initialized correctly.

thanks
Lucas De Marchi

Lucas De Marchi (18):
  iosys-map: Add offset to iosys_map_memcpy_to()
  iosys-map: Add a few more helpers
  drm/i915/gt: Add helper for shmem copy to iosys_map
  drm/i915/guc: Keep iosys_map of ads_blob around
  drm/i915/guc: Add read/write helpers for ADS blob
  drm/i915/guc: Convert golden context init to iosys_map
  drm/i915/guc: Convert policies update to iosys_map
  drm/i915/guc: Convert engine record to iosys_map
  drm/i915/guc: Convert guc_ads_private_data_reset to iosys_map
  drm/i915/guc: Convert golden context prep to iosys_map
  drm/i915/guc: Replace check for golden context size
  drm/i915/guc: Convert mapping table to iosys_map
  drm/i915/guc: Convert capture list to iosys_map
  drm/i915/guc: Prepare for error propagation
  drm/i915/guc: Use a single pass to calculate regset
  drm/i915/guc: Convert guc_mmio_reg_state_init to iosys_map
  drm/i915/guc: Convert __guc_ads_init to iosys_map
  drm/i915/guc: Remove plain ads_blob pointer

 drivers/gpu/drm/drm_cache.c                   |   2 +-
 drivers/gpu/drm/drm_fb_helper.c               |   2 +-
 drivers/gpu/drm/i915/gt/shmem_utils.c         |  32 ++
 drivers/gpu/drm/i915/gt/shmem_utils.h         |   3 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h        |  14 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c    | 382 +++++++++++-------
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h    |   3 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  17 +-
 include/linux/iosys-map.h                     | 219 +++++++++-
 9 files changed, 500 insertions(+), 174 deletions(-)

-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 00/18] drm/i915/guc: Refactor ADS access to use iosys_map
@ 2022-02-08 10:45 ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

v1: https://patchwork.freedesktop.org/series/99378/
v2: https://patchwork.freedesktop.org/series/99711/

Main from previous version:

	- Rename to iosys-map is already applied
	- Rewrite IOSYS_MAP_INIT_OFFSET() and eliminate most of its
	  users, favoring a offset variable to keep the offset from the
	  original iosys_map.
	- Add map offset to both iosys_map_rd_field() and
	  iosys_map_wr_field()
	- Include documentation with example and expected memory layout
	  for iosys_map_rd_field()
	- Replace

Original cover letter:

While porting i915 to arm64 we noticed some issues accessing lmem.
Some writes were getting corrupted and the final state of the buffer
didn't have exactly what we wrote. This became evident when enabling
GuC submission: depending on the number of engines the ADS struct was
being corrupted and GuC would reject it, refusin to initialize.

From Documentation/core-api/bus-virt-phys-mapping.rst:

	This memory is called "PCI memory" or "shared memory" or "IO memory" or
	whatever, and there is only one way to access it: the readb/writeb and
	related functions. You should never take the address of such memory, because
	there is really nothing you can do with such an address: it's not
	conceptually in the same memory space as "real memory" at all, so you cannot
	just dereference a pointer. (Sadly, on x86 it **is** in the same memory space,
	so on x86 it actually works to just deference a pointer, but it's not
	portable).

When reading or writing words directly to IO memory, in order to be portable
the Linux kernel provides the abstraction detailed in section "Differences
between I/O access functions" of Documentation/driver-api/device-io.rst.

This limits our ability to simply overlay our structs on top a buffer
and directly access it since that buffer may come from IO memory rather than
system memory. Hence the approach taken in intel_guc_ads.c needs to be
refactored. This is not the only place in i915 that neeed to be changed, but
the one causing the most problems, with a real reproducer. This first set of
patch focuses on fixing the gem object to pass the ADS

After the addition of a few helpers in the dma_buf_map API, most of
intel_guc_ads.c can be converted to use it. The exception is the regset
initialization: we'd incur into a lot of extra indirection when
reading/writting each register. So the regset is converted to use a
temporary buffer allocated on probe, which is then copied to its
final location when finishing the initialization or on gt reset.

Testing on some discrete cards, after this change we can correctly pass the
ADS struct to GuC and have it initialized correctly.

thanks
Lucas De Marchi

Lucas De Marchi (18):
  iosys-map: Add offset to iosys_map_memcpy_to()
  iosys-map: Add a few more helpers
  drm/i915/gt: Add helper for shmem copy to iosys_map
  drm/i915/guc: Keep iosys_map of ads_blob around
  drm/i915/guc: Add read/write helpers for ADS blob
  drm/i915/guc: Convert golden context init to iosys_map
  drm/i915/guc: Convert policies update to iosys_map
  drm/i915/guc: Convert engine record to iosys_map
  drm/i915/guc: Convert guc_ads_private_data_reset to iosys_map
  drm/i915/guc: Convert golden context prep to iosys_map
  drm/i915/guc: Replace check for golden context size
  drm/i915/guc: Convert mapping table to iosys_map
  drm/i915/guc: Convert capture list to iosys_map
  drm/i915/guc: Prepare for error propagation
  drm/i915/guc: Use a single pass to calculate regset
  drm/i915/guc: Convert guc_mmio_reg_state_init to iosys_map
  drm/i915/guc: Convert __guc_ads_init to iosys_map
  drm/i915/guc: Remove plain ads_blob pointer

 drivers/gpu/drm/drm_cache.c                   |   2 +-
 drivers/gpu/drm/drm_fb_helper.c               |   2 +-
 drivers/gpu/drm/i915/gt/shmem_utils.c         |  32 ++
 drivers/gpu/drm/i915/gt/shmem_utils.h         |   3 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h        |  14 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c    | 382 +++++++++++-------
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h    |   3 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  17 +-
 include/linux/iosys-map.h                     | 219 +++++++++-
 9 files changed, 500 insertions(+), 174 deletions(-)

-- 
2.35.1


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

* [PATCH v2 01/18] iosys-map: Add offset to iosys_map_memcpy_to()
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
  (?)
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	linux-kernel, Daniele Ceraolo Spurio, Thomas Zimmermann,
	Christian König, John Harrison

In certain situations it's useful to be able to write to an
offset of the mapping. Add a dst_offset to iosys_map_memcpy_to().

Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Christian König <christian.koenig@amd.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/drm_cache.c     |  2 +-
 drivers/gpu/drm/drm_fb_helper.c |  2 +-
 include/linux/iosys-map.h       | 17 +++++++++--------
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 66597e411764..c3e6e615bf09 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -218,7 +218,7 @@ static void memcpy_fallback(struct iosys_map *dst,
 	if (!dst->is_iomem && !src->is_iomem) {
 		memcpy(dst->vaddr, src->vaddr, len);
 	} else if (!src->is_iomem) {
-		iosys_map_memcpy_to(dst, src->vaddr, len);
+		iosys_map_memcpy_to(dst, 0, src->vaddr, len);
 	} else if (!dst->is_iomem) {
 		memcpy_fromio(dst->vaddr, src->vaddr_iomem, len);
 	} else {
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 238f815cb2a0..bf5cc9a42e5a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -385,7 +385,7 @@ static void drm_fb_helper_damage_blit_real(struct drm_fb_helper *fb_helper,
 	iosys_map_incr(dst, offset); /* go to first pixel within clip rect */
 
 	for (y = clip->y1; y < clip->y2; y++) {
-		iosys_map_memcpy_to(dst, src, len);
+		iosys_map_memcpy_to(dst, 0, src, len);
 		iosys_map_incr(dst, fb->pitches[0]);
 		src += fb->pitches[0];
 	}
diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index f4186f91caa6..edd730b1e899 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -220,22 +220,23 @@ static inline void iosys_map_clear(struct iosys_map *map)
 }
 
 /**
- * iosys_map_memcpy_to - Memcpy into iosys mapping
+ * iosys_map_memcpy_to - Memcpy into offset of iosys_map
  * @dst:	The iosys_map structure
+ * @dst_offset:	The offset from which to copy
  * @src:	The source buffer
  * @len:	The number of byte in src
  *
- * Copies data into a iosys mapping. The source buffer is in system
- * memory. Depending on the buffer's location, the helper picks the correct
- * method of accessing the memory.
+ * Copies data into a iosys_map with an offset. The source buffer is in
+ * system memory. Depending on the buffer's location, the helper picks the
+ * correct method of accessing the memory.
  */
-static inline void iosys_map_memcpy_to(struct iosys_map *dst, const void *src,
-				       size_t len)
+static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
+				       const void *src, size_t len)
 {
 	if (dst->is_iomem)
-		memcpy_toio(dst->vaddr_iomem, src, len);
+		memcpy_toio(dst->vaddr_iomem + dst_offset, src, len);
 	else
-		memcpy(dst->vaddr, src, len);
+		memcpy(dst->vaddr + dst_offset, src, len);
 }
 
 /**
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 01/18] iosys-map: Add offset to iosys_map_memcpy_to()
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, linux-kernel,
	Sumit Semwal, Thomas Zimmermann, Christian König

In certain situations it's useful to be able to write to an
offset of the mapping. Add a dst_offset to iosys_map_memcpy_to().

Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Christian König <christian.koenig@amd.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/drm_cache.c     |  2 +-
 drivers/gpu/drm/drm_fb_helper.c |  2 +-
 include/linux/iosys-map.h       | 17 +++++++++--------
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 66597e411764..c3e6e615bf09 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -218,7 +218,7 @@ static void memcpy_fallback(struct iosys_map *dst,
 	if (!dst->is_iomem && !src->is_iomem) {
 		memcpy(dst->vaddr, src->vaddr, len);
 	} else if (!src->is_iomem) {
-		iosys_map_memcpy_to(dst, src->vaddr, len);
+		iosys_map_memcpy_to(dst, 0, src->vaddr, len);
 	} else if (!dst->is_iomem) {
 		memcpy_fromio(dst->vaddr, src->vaddr_iomem, len);
 	} else {
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 238f815cb2a0..bf5cc9a42e5a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -385,7 +385,7 @@ static void drm_fb_helper_damage_blit_real(struct drm_fb_helper *fb_helper,
 	iosys_map_incr(dst, offset); /* go to first pixel within clip rect */
 
 	for (y = clip->y1; y < clip->y2; y++) {
-		iosys_map_memcpy_to(dst, src, len);
+		iosys_map_memcpy_to(dst, 0, src, len);
 		iosys_map_incr(dst, fb->pitches[0]);
 		src += fb->pitches[0];
 	}
diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index f4186f91caa6..edd730b1e899 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -220,22 +220,23 @@ static inline void iosys_map_clear(struct iosys_map *map)
 }
 
 /**
- * iosys_map_memcpy_to - Memcpy into iosys mapping
+ * iosys_map_memcpy_to - Memcpy into offset of iosys_map
  * @dst:	The iosys_map structure
+ * @dst_offset:	The offset from which to copy
  * @src:	The source buffer
  * @len:	The number of byte in src
  *
- * Copies data into a iosys mapping. The source buffer is in system
- * memory. Depending on the buffer's location, the helper picks the correct
- * method of accessing the memory.
+ * Copies data into a iosys_map with an offset. The source buffer is in
+ * system memory. Depending on the buffer's location, the helper picks the
+ * correct method of accessing the memory.
  */
-static inline void iosys_map_memcpy_to(struct iosys_map *dst, const void *src,
-				       size_t len)
+static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
+				       const void *src, size_t len)
 {
 	if (dst->is_iomem)
-		memcpy_toio(dst->vaddr_iomem, src, len);
+		memcpy_toio(dst->vaddr_iomem + dst_offset, src, len);
 	else
-		memcpy(dst->vaddr, src, len);
+		memcpy(dst->vaddr + dst_offset, src, len);
 }
 
 /**
-- 
2.35.1


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

* [PATCH v2 01/18] iosys-map: Add offset to iosys_map_memcpy_to()
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: John Harrison, Matthew Brost, Daniele Ceraolo Spurio, Matt Roper,
	Thomas Hellström, Thomas Zimmermann, Christian König,
	Sumit Semwal, Lucas De Marchi, linux-kernel

In certain situations it's useful to be able to write to an
offset of the mapping. Add a dst_offset to iosys_map_memcpy_to().

Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Christian König <christian.koenig@amd.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/gpu/drm/drm_cache.c     |  2 +-
 drivers/gpu/drm/drm_fb_helper.c |  2 +-
 include/linux/iosys-map.h       | 17 +++++++++--------
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 66597e411764..c3e6e615bf09 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -218,7 +218,7 @@ static void memcpy_fallback(struct iosys_map *dst,
 	if (!dst->is_iomem && !src->is_iomem) {
 		memcpy(dst->vaddr, src->vaddr, len);
 	} else if (!src->is_iomem) {
-		iosys_map_memcpy_to(dst, src->vaddr, len);
+		iosys_map_memcpy_to(dst, 0, src->vaddr, len);
 	} else if (!dst->is_iomem) {
 		memcpy_fromio(dst->vaddr, src->vaddr_iomem, len);
 	} else {
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 238f815cb2a0..bf5cc9a42e5a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -385,7 +385,7 @@ static void drm_fb_helper_damage_blit_real(struct drm_fb_helper *fb_helper,
 	iosys_map_incr(dst, offset); /* go to first pixel within clip rect */
 
 	for (y = clip->y1; y < clip->y2; y++) {
-		iosys_map_memcpy_to(dst, src, len);
+		iosys_map_memcpy_to(dst, 0, src, len);
 		iosys_map_incr(dst, fb->pitches[0]);
 		src += fb->pitches[0];
 	}
diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index f4186f91caa6..edd730b1e899 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -220,22 +220,23 @@ static inline void iosys_map_clear(struct iosys_map *map)
 }
 
 /**
- * iosys_map_memcpy_to - Memcpy into iosys mapping
+ * iosys_map_memcpy_to - Memcpy into offset of iosys_map
  * @dst:	The iosys_map structure
+ * @dst_offset:	The offset from which to copy
  * @src:	The source buffer
  * @len:	The number of byte in src
  *
- * Copies data into a iosys mapping. The source buffer is in system
- * memory. Depending on the buffer's location, the helper picks the correct
- * method of accessing the memory.
+ * Copies data into a iosys_map with an offset. The source buffer is in
+ * system memory. Depending on the buffer's location, the helper picks the
+ * correct method of accessing the memory.
  */
-static inline void iosys_map_memcpy_to(struct iosys_map *dst, const void *src,
-				       size_t len)
+static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
+				       const void *src, size_t len)
 {
 	if (dst->is_iomem)
-		memcpy_toio(dst->vaddr_iomem, src, len);
+		memcpy_toio(dst->vaddr_iomem + dst_offset, src, len);
 	else
-		memcpy(dst->vaddr, src, len);
+		memcpy(dst->vaddr + dst_offset, src, len);
 }
 
 /**
-- 
2.35.1


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

* [PATCH v2 02/18] iosys-map: Add a few more helpers
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
  (?)
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	linux-kernel, Daniele Ceraolo Spurio, Thomas Zimmermann,
	Mauro Carvalho Chehab, Christian König, John Harrison

First the simplest ones:

	- iosys_map_memset(): when abstracting system and I/O memory,
	  just like the memcpy() use case, memset() also has dedicated
	  functions to be called for using IO memory.
	- iosys_map_memcpy_from(): we may need to copy data from I/O
	  memory, not only to.

In certain situations it's useful to be able to read or write to an
offset that is calculated by having the memory layout given by a struct
declaration. Usually we are going to read/write a u8, u16, u32 or u64.

As a pre-requisite for the implementation, add iosys_map_memcpy_from()
to be the equivalent of iosys_map_memcpy_to(), but in the other
direction. Then add 2 pairs of macros:

	- iosys_map_rd() / iosys_map_wr()
	- iosys_map_rd_field() / iosys_map_wr_field()

The first pair takes the C-type and offset to read/write. The second
pair uses a struct describing the layout of the mapping in order to
calculate the offset and size being read/written.

We could use readb, readw, readl, readq and the write* counterparts,
however due to alignment issues this may not work on all architectures.
If alignment needs to be checked to call the right function, it's not
possible to decide at compile-time which function to call: so just leave
the decision to the memcpy function that will do exactly that.

Finally, in order to use the above macros with a map derived from
another, add another initializer: IOSYS_MAP_INIT_OFFSET().

v2:
  - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
    within the union
  - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
    allow the struct itself to be at an offset from the mapping
  - Add documentation to iosys_map_rd_field() with example and expected
    memory layout

Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Christian König <christian.koenig@amd.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 202 insertions(+)

diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index edd730b1e899..c6b223534b21 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -6,6 +6,7 @@
 #ifndef __IOSYS_MAP_H__
 #define __IOSYS_MAP_H__
 
+#include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/string.h>
 
@@ -120,6 +121,45 @@ struct iosys_map {
 		.is_iomem = false,	\
 	}
 
+/**
+ * IOSYS_MAP_INIT_OFFSET - Initializes struct iosys_map from another iosys_map
+ * @map_:	The dma-buf mapping structure to copy from
+ * @offset_:	Offset to add to the other mapping
+ *
+ * Initializes a new iosys_map struct based on another passed as argument. It
+ * does a shallow copy of the struct so it's possible to update the back storage
+ * without changing where the original map points to. It is the equivalent of
+ * doing:
+ *
+ * .. code-block:: c
+ *
+ *	iosys_map map = other_map;
+ *	iosys_map_incr(&map, &offset);
+ *
+ * Example usage:
+ *
+ * .. code-block:: c
+ *
+ *	void foo(struct device *dev, struct iosys_map *base_map)
+ *	{
+ *		...
+ *		struct iosys_map map = IOSYS_MAP_INIT_OFFSET(base_map, FIELD_OFFSET);
+ *		...
+ *	}
+ *
+ * The advantage of using the initializer over just increasing the offset with
+ * iosys_map_incr() like above is that the new map will always point to the
+ * right place of the buffer during its scope. It reduces the risk of updating
+ * the wrong part of the buffer and having no compiler warning about that. If
+ * the assignment to IOSYS_MAP_INIT_OFFSET() is forgotten, the compiler can warn
+ * about the use of uninitialized variable.
+ */
+#define IOSYS_MAP_INIT_OFFSET(map_, offset_) ({				\
+	struct iosys_map copy = *map_;					\
+	iosys_map_incr(&copy, offset_);					\
+	copy;								\
+})
+
 /**
  * iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory
  * @map:	The iosys_map structure
@@ -239,6 +279,26 @@ static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
 		memcpy(dst->vaddr + dst_offset, src, len);
 }
 
+/**
+ * iosys_map_memcpy_from - Memcpy from iosys_map into system memory
+ * @dst:	Destination in system memory
+ * @src:	The iosys_map structure
+ * @src_offset:	The offset from which to copy
+ * @len:	The number of byte in src
+ *
+ * Copies data from a iosys_map with an offset. The dest buffer is in
+ * system memory. Depending on the mapping location, the helper picks the
+ * correct method of accessing the memory.
+ */
+static inline void iosys_map_memcpy_from(void *dst, const struct iosys_map *src,
+					 size_t src_offset, size_t len)
+{
+	if (src->is_iomem)
+		memcpy_fromio(dst, src->vaddr_iomem + src_offset, len);
+	else
+		memcpy(dst, src->vaddr + src_offset, len);
+}
+
 /**
  * iosys_map_incr - Increments the address stored in a iosys mapping
  * @map:	The iosys_map structure
@@ -255,4 +315,146 @@ static inline void iosys_map_incr(struct iosys_map *map, size_t incr)
 		map->vaddr += incr;
 }
 
+/**
+ * iosys_map_memset - Memset iosys_map
+ * @dst:	The iosys_map structure
+ * @offset:	Offset from dst where to start setting value
+ * @value:	The value to set
+ * @len:	The number of bytes to set in dst
+ *
+ * Set value in iosys_map. Depending on the buffer's location, the helper
+ * picks the correct method of accessing the memory.
+ */
+static inline void iosys_map_memset(struct iosys_map *dst, size_t offset,
+				    int value, size_t len)
+{
+	if (dst->is_iomem)
+		memset_io(dst->vaddr_iomem + offset, value, len);
+	else
+		memset(dst->vaddr + offset, value, len);
+}
+
+/**
+ * iosys_map_rd - Read a C-type value from the iosys_map
+ *
+ * @map__:	The iosys_map structure
+ * @offset__:	The offset from which to read
+ * @type__:	Type of the value being read
+ *
+ * Read a C type value from iosys_map, handling possible un-aligned accesses to
+ * the mapping.
+ *
+ * Returns:
+ * The value read from the mapping.
+ */
+#define iosys_map_rd(map__, offset__, type__) ({			\
+	type__ val;							\
+	iosys_map_memcpy_from(&val, map__, offset__, sizeof(val));	\
+	val;								\
+})
+
+/**
+ * iosys_map_wr - Write a C-type value to the iosys_map
+ *
+ * @map__:	The iosys_map structure
+ * @offset__:	The offset from the mapping to write to
+ * @type__:	Type of the value being written
+ * @val__:	Value to write
+ *
+ * Write a C-type value to the iosys_map, handling possible un-aligned accesses
+ * to the mapping.
+ */
+#define iosys_map_wr(map__, offset__, type__, val__) ({			\
+	type__ val = (val__);						\
+	iosys_map_memcpy_to(map__, offset__, &val, sizeof(val));	\
+})
+
+/**
+ * iosys_map_rd_field - Read a member from a struct in the iosys_map
+ *
+ * @map__:		The iosys_map structure
+ * @struct_offset__:	Offset from the beggining of the map, where the struct
+ *			is located
+ * @struct_type__:	The struct describing the layout of the mapping
+ * @field__:		Member of the struct to read
+ *
+ * Read a value from iosys_map considering its layout is described by a C struct
+ * starting at @struct_offset__. The field offset and size is calculated and its
+ * value read handling possible un-aligned memory accesses. For example: suppose
+ * there is a @struct foo defined as below and the value ``foo.field2.inner2``
+ * needs to be read from the iosys_map:
+ *
+ * .. code-block:: c
+ *
+ *	struct foo {
+ *		int field1;
+ *		struct {
+ *			int inner1;
+ *			int inner2;
+ *		} field2;
+ *		int field3;
+ *	} __packed;
+ *
+ * This is the expected memory layout of a buffer using iosys_map_rd_field():
+ *
+ * +------------------------------+--------------------------+
+ * | Address                      | Content                  |
+ * +==============================+==========================+
+ * | buffer + 0000                | start of mmapped buffer  |
+ * |                              | pointed by iosys_map     |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + ``struct_offset__`` | start of ``struct foo``  |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + wwww                | ``foo.field2.inner2``    |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + yyyy                | end of ``struct foo``    |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + zzzz                | end of mmaped buffer     |
+ * +------------------------------+--------------------------+
+ *
+ * Values automatically calculated by this macro or not needed are denoted by
+ * wwww, yyyy and zzzz. This is the code to read that value:
+ *
+ * .. code-block:: c
+ *
+ *	x = iosys_map_rd_field(&map, offset, struct foo, field2.inner2);
+ *
+ * Returns:
+ * The value read from the mapping.
+ */
+#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
+	struct_type__ *s;							\
+	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
+		     typeof(s->field__));					\
+})
+
+/**
+ * iosys_map_wr_field - Write to a member of a struct in the iosys_map
+ *
+ * @map__:		The iosys_map structure
+ * @struct_offset__:	Offset from the beggining of the map, where the struct
+ *			is located
+ * @struct_type__:	The struct describing the layout of the mapping
+ * @field__:		Member of the struct to read
+ * @val__:		Value to write
+ *
+ * Write a value to the iosys_map considering its layout is described by a C struct
+ * starting at @struct_offset__. The field offset and size is calculated and the
+ * @val__ is written handling possible un-aligned memory accesses. Refer to
+ * iosys_map_rd_field() for expected usage and memory layout.
+ */
+#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
+	struct_type__ *s;								\
+	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
+		     typeof(s->field__), val__);					\
+})
+
 #endif /* __IOSYS_MAP_H__ */
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 02/18] iosys-map: Add a few more helpers
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, linux-kernel,
	Sumit Semwal, Thomas Zimmermann, Mauro Carvalho Chehab,
	Christian König

First the simplest ones:

	- iosys_map_memset(): when abstracting system and I/O memory,
	  just like the memcpy() use case, memset() also has dedicated
	  functions to be called for using IO memory.
	- iosys_map_memcpy_from(): we may need to copy data from I/O
	  memory, not only to.

In certain situations it's useful to be able to read or write to an
offset that is calculated by having the memory layout given by a struct
declaration. Usually we are going to read/write a u8, u16, u32 or u64.

As a pre-requisite for the implementation, add iosys_map_memcpy_from()
to be the equivalent of iosys_map_memcpy_to(), but in the other
direction. Then add 2 pairs of macros:

	- iosys_map_rd() / iosys_map_wr()
	- iosys_map_rd_field() / iosys_map_wr_field()

The first pair takes the C-type and offset to read/write. The second
pair uses a struct describing the layout of the mapping in order to
calculate the offset and size being read/written.

We could use readb, readw, readl, readq and the write* counterparts,
however due to alignment issues this may not work on all architectures.
If alignment needs to be checked to call the right function, it's not
possible to decide at compile-time which function to call: so just leave
the decision to the memcpy function that will do exactly that.

Finally, in order to use the above macros with a map derived from
another, add another initializer: IOSYS_MAP_INIT_OFFSET().

v2:
  - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
    within the union
  - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
    allow the struct itself to be at an offset from the mapping
  - Add documentation to iosys_map_rd_field() with example and expected
    memory layout

Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Christian König <christian.koenig@amd.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 202 insertions(+)

diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index edd730b1e899..c6b223534b21 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -6,6 +6,7 @@
 #ifndef __IOSYS_MAP_H__
 #define __IOSYS_MAP_H__
 
+#include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/string.h>
 
@@ -120,6 +121,45 @@ struct iosys_map {
 		.is_iomem = false,	\
 	}
 
+/**
+ * IOSYS_MAP_INIT_OFFSET - Initializes struct iosys_map from another iosys_map
+ * @map_:	The dma-buf mapping structure to copy from
+ * @offset_:	Offset to add to the other mapping
+ *
+ * Initializes a new iosys_map struct based on another passed as argument. It
+ * does a shallow copy of the struct so it's possible to update the back storage
+ * without changing where the original map points to. It is the equivalent of
+ * doing:
+ *
+ * .. code-block:: c
+ *
+ *	iosys_map map = other_map;
+ *	iosys_map_incr(&map, &offset);
+ *
+ * Example usage:
+ *
+ * .. code-block:: c
+ *
+ *	void foo(struct device *dev, struct iosys_map *base_map)
+ *	{
+ *		...
+ *		struct iosys_map map = IOSYS_MAP_INIT_OFFSET(base_map, FIELD_OFFSET);
+ *		...
+ *	}
+ *
+ * The advantage of using the initializer over just increasing the offset with
+ * iosys_map_incr() like above is that the new map will always point to the
+ * right place of the buffer during its scope. It reduces the risk of updating
+ * the wrong part of the buffer and having no compiler warning about that. If
+ * the assignment to IOSYS_MAP_INIT_OFFSET() is forgotten, the compiler can warn
+ * about the use of uninitialized variable.
+ */
+#define IOSYS_MAP_INIT_OFFSET(map_, offset_) ({				\
+	struct iosys_map copy = *map_;					\
+	iosys_map_incr(&copy, offset_);					\
+	copy;								\
+})
+
 /**
  * iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory
  * @map:	The iosys_map structure
@@ -239,6 +279,26 @@ static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
 		memcpy(dst->vaddr + dst_offset, src, len);
 }
 
+/**
+ * iosys_map_memcpy_from - Memcpy from iosys_map into system memory
+ * @dst:	Destination in system memory
+ * @src:	The iosys_map structure
+ * @src_offset:	The offset from which to copy
+ * @len:	The number of byte in src
+ *
+ * Copies data from a iosys_map with an offset. The dest buffer is in
+ * system memory. Depending on the mapping location, the helper picks the
+ * correct method of accessing the memory.
+ */
+static inline void iosys_map_memcpy_from(void *dst, const struct iosys_map *src,
+					 size_t src_offset, size_t len)
+{
+	if (src->is_iomem)
+		memcpy_fromio(dst, src->vaddr_iomem + src_offset, len);
+	else
+		memcpy(dst, src->vaddr + src_offset, len);
+}
+
 /**
  * iosys_map_incr - Increments the address stored in a iosys mapping
  * @map:	The iosys_map structure
@@ -255,4 +315,146 @@ static inline void iosys_map_incr(struct iosys_map *map, size_t incr)
 		map->vaddr += incr;
 }
 
+/**
+ * iosys_map_memset - Memset iosys_map
+ * @dst:	The iosys_map structure
+ * @offset:	Offset from dst where to start setting value
+ * @value:	The value to set
+ * @len:	The number of bytes to set in dst
+ *
+ * Set value in iosys_map. Depending on the buffer's location, the helper
+ * picks the correct method of accessing the memory.
+ */
+static inline void iosys_map_memset(struct iosys_map *dst, size_t offset,
+				    int value, size_t len)
+{
+	if (dst->is_iomem)
+		memset_io(dst->vaddr_iomem + offset, value, len);
+	else
+		memset(dst->vaddr + offset, value, len);
+}
+
+/**
+ * iosys_map_rd - Read a C-type value from the iosys_map
+ *
+ * @map__:	The iosys_map structure
+ * @offset__:	The offset from which to read
+ * @type__:	Type of the value being read
+ *
+ * Read a C type value from iosys_map, handling possible un-aligned accesses to
+ * the mapping.
+ *
+ * Returns:
+ * The value read from the mapping.
+ */
+#define iosys_map_rd(map__, offset__, type__) ({			\
+	type__ val;							\
+	iosys_map_memcpy_from(&val, map__, offset__, sizeof(val));	\
+	val;								\
+})
+
+/**
+ * iosys_map_wr - Write a C-type value to the iosys_map
+ *
+ * @map__:	The iosys_map structure
+ * @offset__:	The offset from the mapping to write to
+ * @type__:	Type of the value being written
+ * @val__:	Value to write
+ *
+ * Write a C-type value to the iosys_map, handling possible un-aligned accesses
+ * to the mapping.
+ */
+#define iosys_map_wr(map__, offset__, type__, val__) ({			\
+	type__ val = (val__);						\
+	iosys_map_memcpy_to(map__, offset__, &val, sizeof(val));	\
+})
+
+/**
+ * iosys_map_rd_field - Read a member from a struct in the iosys_map
+ *
+ * @map__:		The iosys_map structure
+ * @struct_offset__:	Offset from the beggining of the map, where the struct
+ *			is located
+ * @struct_type__:	The struct describing the layout of the mapping
+ * @field__:		Member of the struct to read
+ *
+ * Read a value from iosys_map considering its layout is described by a C struct
+ * starting at @struct_offset__. The field offset and size is calculated and its
+ * value read handling possible un-aligned memory accesses. For example: suppose
+ * there is a @struct foo defined as below and the value ``foo.field2.inner2``
+ * needs to be read from the iosys_map:
+ *
+ * .. code-block:: c
+ *
+ *	struct foo {
+ *		int field1;
+ *		struct {
+ *			int inner1;
+ *			int inner2;
+ *		} field2;
+ *		int field3;
+ *	} __packed;
+ *
+ * This is the expected memory layout of a buffer using iosys_map_rd_field():
+ *
+ * +------------------------------+--------------------------+
+ * | Address                      | Content                  |
+ * +==============================+==========================+
+ * | buffer + 0000                | start of mmapped buffer  |
+ * |                              | pointed by iosys_map     |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + ``struct_offset__`` | start of ``struct foo``  |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + wwww                | ``foo.field2.inner2``    |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + yyyy                | end of ``struct foo``    |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + zzzz                | end of mmaped buffer     |
+ * +------------------------------+--------------------------+
+ *
+ * Values automatically calculated by this macro or not needed are denoted by
+ * wwww, yyyy and zzzz. This is the code to read that value:
+ *
+ * .. code-block:: c
+ *
+ *	x = iosys_map_rd_field(&map, offset, struct foo, field2.inner2);
+ *
+ * Returns:
+ * The value read from the mapping.
+ */
+#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
+	struct_type__ *s;							\
+	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
+		     typeof(s->field__));					\
+})
+
+/**
+ * iosys_map_wr_field - Write to a member of a struct in the iosys_map
+ *
+ * @map__:		The iosys_map structure
+ * @struct_offset__:	Offset from the beggining of the map, where the struct
+ *			is located
+ * @struct_type__:	The struct describing the layout of the mapping
+ * @field__:		Member of the struct to read
+ * @val__:		Value to write
+ *
+ * Write a value to the iosys_map considering its layout is described by a C struct
+ * starting at @struct_offset__. The field offset and size is calculated and the
+ * @val__ is written handling possible un-aligned memory accesses. Refer to
+ * iosys_map_rd_field() for expected usage and memory layout.
+ */
+#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
+	struct_type__ *s;								\
+	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
+		     typeof(s->field__), val__);					\
+})
+
 #endif /* __IOSYS_MAP_H__ */
-- 
2.35.1


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

* [PATCH v2 02/18] iosys-map: Add a few more helpers
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: John Harrison, Matthew Brost, Daniele Ceraolo Spurio, Matt Roper,
	Thomas Hellström, Thomas Zimmermann, Christian König,
	Sumit Semwal, Lucas De Marchi, Mauro Carvalho Chehab,
	linux-kernel

First the simplest ones:

	- iosys_map_memset(): when abstracting system and I/O memory,
	  just like the memcpy() use case, memset() also has dedicated
	  functions to be called for using IO memory.
	- iosys_map_memcpy_from(): we may need to copy data from I/O
	  memory, not only to.

In certain situations it's useful to be able to read or write to an
offset that is calculated by having the memory layout given by a struct
declaration. Usually we are going to read/write a u8, u16, u32 or u64.

As a pre-requisite for the implementation, add iosys_map_memcpy_from()
to be the equivalent of iosys_map_memcpy_to(), but in the other
direction. Then add 2 pairs of macros:

	- iosys_map_rd() / iosys_map_wr()
	- iosys_map_rd_field() / iosys_map_wr_field()

The first pair takes the C-type and offset to read/write. The second
pair uses a struct describing the layout of the mapping in order to
calculate the offset and size being read/written.

We could use readb, readw, readl, readq and the write* counterparts,
however due to alignment issues this may not work on all architectures.
If alignment needs to be checked to call the right function, it's not
possible to decide at compile-time which function to call: so just leave
the decision to the memcpy function that will do exactly that.

Finally, in order to use the above macros with a map derived from
another, add another initializer: IOSYS_MAP_INIT_OFFSET().

v2:
  - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
    within the union
  - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
    allow the struct itself to be at an offset from the mapping
  - Add documentation to iosys_map_rd_field() with example and expected
    memory layout

Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Christian König <christian.koenig@amd.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 202 insertions(+)

diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index edd730b1e899..c6b223534b21 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -6,6 +6,7 @@
 #ifndef __IOSYS_MAP_H__
 #define __IOSYS_MAP_H__
 
+#include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/string.h>
 
@@ -120,6 +121,45 @@ struct iosys_map {
 		.is_iomem = false,	\
 	}
 
+/**
+ * IOSYS_MAP_INIT_OFFSET - Initializes struct iosys_map from another iosys_map
+ * @map_:	The dma-buf mapping structure to copy from
+ * @offset_:	Offset to add to the other mapping
+ *
+ * Initializes a new iosys_map struct based on another passed as argument. It
+ * does a shallow copy of the struct so it's possible to update the back storage
+ * without changing where the original map points to. It is the equivalent of
+ * doing:
+ *
+ * .. code-block:: c
+ *
+ *	iosys_map map = other_map;
+ *	iosys_map_incr(&map, &offset);
+ *
+ * Example usage:
+ *
+ * .. code-block:: c
+ *
+ *	void foo(struct device *dev, struct iosys_map *base_map)
+ *	{
+ *		...
+ *		struct iosys_map map = IOSYS_MAP_INIT_OFFSET(base_map, FIELD_OFFSET);
+ *		...
+ *	}
+ *
+ * The advantage of using the initializer over just increasing the offset with
+ * iosys_map_incr() like above is that the new map will always point to the
+ * right place of the buffer during its scope. It reduces the risk of updating
+ * the wrong part of the buffer and having no compiler warning about that. If
+ * the assignment to IOSYS_MAP_INIT_OFFSET() is forgotten, the compiler can warn
+ * about the use of uninitialized variable.
+ */
+#define IOSYS_MAP_INIT_OFFSET(map_, offset_) ({				\
+	struct iosys_map copy = *map_;					\
+	iosys_map_incr(&copy, offset_);					\
+	copy;								\
+})
+
 /**
  * iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory
  * @map:	The iosys_map structure
@@ -239,6 +279,26 @@ static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
 		memcpy(dst->vaddr + dst_offset, src, len);
 }
 
+/**
+ * iosys_map_memcpy_from - Memcpy from iosys_map into system memory
+ * @dst:	Destination in system memory
+ * @src:	The iosys_map structure
+ * @src_offset:	The offset from which to copy
+ * @len:	The number of byte in src
+ *
+ * Copies data from a iosys_map with an offset. The dest buffer is in
+ * system memory. Depending on the mapping location, the helper picks the
+ * correct method of accessing the memory.
+ */
+static inline void iosys_map_memcpy_from(void *dst, const struct iosys_map *src,
+					 size_t src_offset, size_t len)
+{
+	if (src->is_iomem)
+		memcpy_fromio(dst, src->vaddr_iomem + src_offset, len);
+	else
+		memcpy(dst, src->vaddr + src_offset, len);
+}
+
 /**
  * iosys_map_incr - Increments the address stored in a iosys mapping
  * @map:	The iosys_map structure
@@ -255,4 +315,146 @@ static inline void iosys_map_incr(struct iosys_map *map, size_t incr)
 		map->vaddr += incr;
 }
 
+/**
+ * iosys_map_memset - Memset iosys_map
+ * @dst:	The iosys_map structure
+ * @offset:	Offset from dst where to start setting value
+ * @value:	The value to set
+ * @len:	The number of bytes to set in dst
+ *
+ * Set value in iosys_map. Depending on the buffer's location, the helper
+ * picks the correct method of accessing the memory.
+ */
+static inline void iosys_map_memset(struct iosys_map *dst, size_t offset,
+				    int value, size_t len)
+{
+	if (dst->is_iomem)
+		memset_io(dst->vaddr_iomem + offset, value, len);
+	else
+		memset(dst->vaddr + offset, value, len);
+}
+
+/**
+ * iosys_map_rd - Read a C-type value from the iosys_map
+ *
+ * @map__:	The iosys_map structure
+ * @offset__:	The offset from which to read
+ * @type__:	Type of the value being read
+ *
+ * Read a C type value from iosys_map, handling possible un-aligned accesses to
+ * the mapping.
+ *
+ * Returns:
+ * The value read from the mapping.
+ */
+#define iosys_map_rd(map__, offset__, type__) ({			\
+	type__ val;							\
+	iosys_map_memcpy_from(&val, map__, offset__, sizeof(val));	\
+	val;								\
+})
+
+/**
+ * iosys_map_wr - Write a C-type value to the iosys_map
+ *
+ * @map__:	The iosys_map structure
+ * @offset__:	The offset from the mapping to write to
+ * @type__:	Type of the value being written
+ * @val__:	Value to write
+ *
+ * Write a C-type value to the iosys_map, handling possible un-aligned accesses
+ * to the mapping.
+ */
+#define iosys_map_wr(map__, offset__, type__, val__) ({			\
+	type__ val = (val__);						\
+	iosys_map_memcpy_to(map__, offset__, &val, sizeof(val));	\
+})
+
+/**
+ * iosys_map_rd_field - Read a member from a struct in the iosys_map
+ *
+ * @map__:		The iosys_map structure
+ * @struct_offset__:	Offset from the beggining of the map, where the struct
+ *			is located
+ * @struct_type__:	The struct describing the layout of the mapping
+ * @field__:		Member of the struct to read
+ *
+ * Read a value from iosys_map considering its layout is described by a C struct
+ * starting at @struct_offset__. The field offset and size is calculated and its
+ * value read handling possible un-aligned memory accesses. For example: suppose
+ * there is a @struct foo defined as below and the value ``foo.field2.inner2``
+ * needs to be read from the iosys_map:
+ *
+ * .. code-block:: c
+ *
+ *	struct foo {
+ *		int field1;
+ *		struct {
+ *			int inner1;
+ *			int inner2;
+ *		} field2;
+ *		int field3;
+ *	} __packed;
+ *
+ * This is the expected memory layout of a buffer using iosys_map_rd_field():
+ *
+ * +------------------------------+--------------------------+
+ * | Address                      | Content                  |
+ * +==============================+==========================+
+ * | buffer + 0000                | start of mmapped buffer  |
+ * |                              | pointed by iosys_map     |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + ``struct_offset__`` | start of ``struct foo``  |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + wwww                | ``foo.field2.inner2``    |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + yyyy                | end of ``struct foo``    |
+ * +------------------------------+--------------------------+
+ * | ...                          | ...                      |
+ * +------------------------------+--------------------------+
+ * | buffer + zzzz                | end of mmaped buffer     |
+ * +------------------------------+--------------------------+
+ *
+ * Values automatically calculated by this macro or not needed are denoted by
+ * wwww, yyyy and zzzz. This is the code to read that value:
+ *
+ * .. code-block:: c
+ *
+ *	x = iosys_map_rd_field(&map, offset, struct foo, field2.inner2);
+ *
+ * Returns:
+ * The value read from the mapping.
+ */
+#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
+	struct_type__ *s;							\
+	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
+		     typeof(s->field__));					\
+})
+
+/**
+ * iosys_map_wr_field - Write to a member of a struct in the iosys_map
+ *
+ * @map__:		The iosys_map structure
+ * @struct_offset__:	Offset from the beggining of the map, where the struct
+ *			is located
+ * @struct_type__:	The struct describing the layout of the mapping
+ * @field__:		Member of the struct to read
+ * @val__:		Value to write
+ *
+ * Write a value to the iosys_map considering its layout is described by a C struct
+ * starting at @struct_offset__. The field offset and size is calculated and the
+ * @val__ is written handling possible un-aligned memory accesses. Refer to
+ * iosys_map_rd_field() for expected usage and memory layout.
+ */
+#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
+	struct_type__ *s;								\
+	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
+		     typeof(s->field__), val__);					\
+})
+
 #endif /* __IOSYS_MAP_H__ */
-- 
2.35.1


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

* [PATCH v2 03/18] drm/i915/gt: Add helper for shmem copy to iosys_map
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Tvrtko Ursulin,
	David Airlie, Lucas De Marchi, Daniele Ceraolo Spurio,
	Matthew Auld, Thomas Zimmermann, Christian König,
	John Harrison

Add a variant of shmem_read() that takes a iosys_map pointer rather
than a plain pointer as argument. It's mostly a copy __shmem_rw() but
adapting the api and removing the write support since there's currently
only need to use iosys_map as destination.

Reworking __shmem_rw() to share the implementation was tempting, but
finding a good balance between reuse and clarity pushed towards a little
code duplication. Since the function is small, just add the similar
function with a copy/paste/adapt approach.

v2: Add an offset as argument and instead of using a map iterator, use the
offset to keep track of where we are writing data to.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/shmem_utils.c | 32 +++++++++++++++++++++++++++
 drivers/gpu/drm/i915/gt/shmem_utils.h |  3 +++
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c
index 0683b27a3890..402f085f3a02 100644
--- a/drivers/gpu/drm/i915/gt/shmem_utils.c
+++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
@@ -3,6 +3,7 @@
  * Copyright © 2020 Intel Corporation
  */
 
+#include <linux/iosys-map.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/shmem_fs.h>
@@ -123,6 +124,37 @@ static int __shmem_rw(struct file *file, loff_t off,
 	return 0;
 }
 
+int shmem_read_to_iosys_map(struct file *file, loff_t off,
+			    struct iosys_map *map, size_t map_off, size_t len)
+{
+	unsigned long pfn;
+
+	for (pfn = off >> PAGE_SHIFT; len; pfn++) {
+		unsigned int this =
+			min_t(size_t, PAGE_SIZE - offset_in_page(off), len);
+		struct page *page;
+		void *vaddr;
+
+		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
+						   GFP_KERNEL);
+		if (IS_ERR(page))
+			return PTR_ERR(page);
+
+		vaddr = kmap(page);
+		iosys_map_memcpy_to(map, map_off, vaddr + offset_in_page(off),
+				    this);
+		mark_page_accessed(page);
+		kunmap(page);
+		put_page(page);
+
+		len -= this;
+		map_off += this;
+		off = 0;
+	}
+
+	return 0;
+}
+
 int shmem_read(struct file *file, loff_t off, void *dst, size_t len)
 {
 	return __shmem_rw(file, off, dst, len, false);
diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.h b/drivers/gpu/drm/i915/gt/shmem_utils.h
index c1669170c351..b2b04d88c6e5 100644
--- a/drivers/gpu/drm/i915/gt/shmem_utils.h
+++ b/drivers/gpu/drm/i915/gt/shmem_utils.h
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 
+struct iosys_map;
 struct drm_i915_gem_object;
 struct file;
 
@@ -17,6 +18,8 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj);
 void *shmem_pin_map(struct file *file);
 void shmem_unpin_map(struct file *file, void *ptr);
 
+int shmem_read_to_iosys_map(struct file *file, loff_t off,
+			    struct iosys_map *map, size_t map_off, size_t len);
 int shmem_read(struct file *file, loff_t off, void *dst, size_t len);
 int shmem_write(struct file *file, loff_t off, void *src, size_t len);
 
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 03/18] drm/i915/gt: Add helper for shmem copy to iosys_map
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, David Airlie, Lucas De Marchi,
	Sumit Semwal, Matthew Auld, Thomas Zimmermann,
	Christian König

Add a variant of shmem_read() that takes a iosys_map pointer rather
than a plain pointer as argument. It's mostly a copy __shmem_rw() but
adapting the api and removing the write support since there's currently
only need to use iosys_map as destination.

Reworking __shmem_rw() to share the implementation was tempting, but
finding a good balance between reuse and clarity pushed towards a little
code duplication. Since the function is small, just add the similar
function with a copy/paste/adapt approach.

v2: Add an offset as argument and instead of using a map iterator, use the
offset to keep track of where we are writing data to.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/shmem_utils.c | 32 +++++++++++++++++++++++++++
 drivers/gpu/drm/i915/gt/shmem_utils.h |  3 +++
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c
index 0683b27a3890..402f085f3a02 100644
--- a/drivers/gpu/drm/i915/gt/shmem_utils.c
+++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
@@ -3,6 +3,7 @@
  * Copyright © 2020 Intel Corporation
  */
 
+#include <linux/iosys-map.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/shmem_fs.h>
@@ -123,6 +124,37 @@ static int __shmem_rw(struct file *file, loff_t off,
 	return 0;
 }
 
+int shmem_read_to_iosys_map(struct file *file, loff_t off,
+			    struct iosys_map *map, size_t map_off, size_t len)
+{
+	unsigned long pfn;
+
+	for (pfn = off >> PAGE_SHIFT; len; pfn++) {
+		unsigned int this =
+			min_t(size_t, PAGE_SIZE - offset_in_page(off), len);
+		struct page *page;
+		void *vaddr;
+
+		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
+						   GFP_KERNEL);
+		if (IS_ERR(page))
+			return PTR_ERR(page);
+
+		vaddr = kmap(page);
+		iosys_map_memcpy_to(map, map_off, vaddr + offset_in_page(off),
+				    this);
+		mark_page_accessed(page);
+		kunmap(page);
+		put_page(page);
+
+		len -= this;
+		map_off += this;
+		off = 0;
+	}
+
+	return 0;
+}
+
 int shmem_read(struct file *file, loff_t off, void *dst, size_t len)
 {
 	return __shmem_rw(file, off, dst, len, false);
diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.h b/drivers/gpu/drm/i915/gt/shmem_utils.h
index c1669170c351..b2b04d88c6e5 100644
--- a/drivers/gpu/drm/i915/gt/shmem_utils.h
+++ b/drivers/gpu/drm/i915/gt/shmem_utils.h
@@ -8,6 +8,7 @@
 
 #include <linux/types.h>
 
+struct iosys_map;
 struct drm_i915_gem_object;
 struct file;
 
@@ -17,6 +18,8 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj);
 void *shmem_pin_map(struct file *file);
 void shmem_unpin_map(struct file *file, void *ptr);
 
+int shmem_read_to_iosys_map(struct file *file, loff_t off,
+			    struct iosys_map *map, size_t map_off, size_t len);
 int shmem_read(struct file *file, loff_t off, void *dst, size_t len);
 int shmem_write(struct file *file, loff_t off, void *src, size_t len);
 
-- 
2.35.1


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

* [PATCH v2 04/18] drm/i915/guc: Keep iosys_map of ads_blob around
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Convert intel_guc_ads_create() and initialization to use iosys_map
rather than plain pointer and save it in the guc struct. This will help
with additional updates to the ads_blob after the
creation/initialization by abstracting the IO vs system memory.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h     | 4 +++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 6 ++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 697d9d66acef..9b9ba79f7594 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -6,8 +6,9 @@
 #ifndef _INTEL_GUC_H_
 #define _INTEL_GUC_H_
 
-#include <linux/xarray.h>
 #include <linux/delay.h>
+#include <linux/iosys-map.h>
+#include <linux/xarray.h>
 
 #include "intel_uncore.h"
 #include "intel_guc_fw.h"
@@ -148,6 +149,7 @@ struct intel_guc {
 	struct i915_vma *ads_vma;
 	/** @ads_blob: contents of the GuC ADS */
 	struct __guc_ads_blob *ads_blob;
+	struct iosys_map ads_map;
 	/** @ads_regset_size: size of the save/restore regsets in the ADS */
 	u32 ads_regset_size;
 	/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index e61150adcbe9..13671b186908 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -624,6 +624,11 @@ int intel_guc_ads_create(struct intel_guc *guc)
 	if (ret)
 		return ret;
 
+	if (i915_gem_object_is_lmem(guc->ads_vma->obj))
+		iosys_map_set_vaddr_iomem(&guc->ads_map, (void __iomem *)guc->ads_blob);
+	else
+		iosys_map_set_vaddr(&guc->ads_map, guc->ads_blob);
+
 	__guc_ads_init(guc);
 
 	return 0;
@@ -645,6 +650,7 @@ void intel_guc_ads_destroy(struct intel_guc *guc)
 {
 	i915_vma_unpin_and_release(&guc->ads_vma, I915_VMA_RELEASE_MAP);
 	guc->ads_blob = NULL;
+	iosys_map_clear(&guc->ads_map);
 }
 
 static void guc_ads_private_data_reset(struct intel_guc *guc)
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 04/18] drm/i915/guc: Keep iosys_map of ads_blob around
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Convert intel_guc_ads_create() and initialization to use iosys_map
rather than plain pointer and save it in the guc struct. This will help
with additional updates to the ads_blob after the
creation/initialization by abstracting the IO vs system memory.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h     | 4 +++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 6 ++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 697d9d66acef..9b9ba79f7594 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -6,8 +6,9 @@
 #ifndef _INTEL_GUC_H_
 #define _INTEL_GUC_H_
 
-#include <linux/xarray.h>
 #include <linux/delay.h>
+#include <linux/iosys-map.h>
+#include <linux/xarray.h>
 
 #include "intel_uncore.h"
 #include "intel_guc_fw.h"
@@ -148,6 +149,7 @@ struct intel_guc {
 	struct i915_vma *ads_vma;
 	/** @ads_blob: contents of the GuC ADS */
 	struct __guc_ads_blob *ads_blob;
+	struct iosys_map ads_map;
 	/** @ads_regset_size: size of the save/restore regsets in the ADS */
 	u32 ads_regset_size;
 	/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index e61150adcbe9..13671b186908 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -624,6 +624,11 @@ int intel_guc_ads_create(struct intel_guc *guc)
 	if (ret)
 		return ret;
 
+	if (i915_gem_object_is_lmem(guc->ads_vma->obj))
+		iosys_map_set_vaddr_iomem(&guc->ads_map, (void __iomem *)guc->ads_blob);
+	else
+		iosys_map_set_vaddr(&guc->ads_map, guc->ads_blob);
+
 	__guc_ads_init(guc);
 
 	return 0;
@@ -645,6 +650,7 @@ void intel_guc_ads_destroy(struct intel_guc *guc)
 {
 	i915_vma_unpin_and_release(&guc->ads_vma, I915_VMA_RELEASE_MAP);
 	guc->ads_blob = NULL;
+	iosys_map_clear(&guc->ads_map);
 }
 
 static void guc_ads_private_data_reset(struct intel_guc *guc)
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 05/18] drm/i915/guc: Add read/write helpers for ADS blob
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Add helpers on top of iosys_map_read_field() /
iosys_map_write_field() functions so they always use the right
arguments and make code easier to read.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 13671b186908..9bf9096b8337 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -60,6 +60,13 @@ struct __guc_ads_blob {
 	struct guc_mmio_reg regset[0];
 } __packed;
 
+#define ads_blob_read(guc_, field_)					\
+	iosys_map_rd_field(&(guc_)->ads_map, 0, struct __guc_ads_blob, field_)
+
+#define ads_blob_write(guc_, field_, val_)				\
+	iosys_map_wr_field(&(guc_)->ads_map, 0, struct __guc_ads_blob,	\
+			   field_, val_)
+
 static u32 guc_ads_regset_size(struct intel_guc *guc)
 {
 	GEM_BUG_ON(!guc->ads_regset_size);
-- 
2.35.1


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

* [PATCH v2 05/18] drm/i915/guc: Add read/write helpers for ADS blob
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Add helpers on top of iosys_map_read_field() /
iosys_map_write_field() functions so they always use the right
arguments and make code easier to read.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 13671b186908..9bf9096b8337 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -60,6 +60,13 @@ struct __guc_ads_blob {
 	struct guc_mmio_reg regset[0];
 } __packed;
 
+#define ads_blob_read(guc_, field_)					\
+	iosys_map_rd_field(&(guc_)->ads_map, 0, struct __guc_ads_blob, field_)
+
+#define ads_blob_write(guc_, field_, val_)				\
+	iosys_map_wr_field(&(guc_)->ads_map, 0, struct __guc_ads_blob,	\
+			   field_, val_)
+
 static u32 guc_ads_regset_size(struct intel_guc *guc)
 {
 	GEM_BUG_ON(!guc->ads_regset_size);
-- 
2.35.1


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

* [PATCH v2 06/18] drm/i915/guc: Convert golden context init to iosys_map
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Now the map is saved during creation, so use it to initialize the
golden context, reading from shmem and writing to either system or IO
memory.

v2: Do not use a map iterator: add an offset to keep track of
destination

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 26 ++++++++++------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 9bf9096b8337..b5b3a39f0c28 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -473,18 +473,16 @@ static struct intel_engine_cs *find_engine_state(struct intel_gt *gt, u8 engine_
 
 static void guc_init_golden_context(struct intel_guc *guc)
 {
-	struct __guc_ads_blob *blob = guc->ads_blob;
 	struct intel_engine_cs *engine;
 	struct intel_gt *gt = guc_to_gt(guc);
-	u32 addr_ggtt, offset;
-	u32 total_size = 0, alloc_size, real_size;
+	unsigned long offset;
+	u32 addr_ggtt, total_size = 0, alloc_size, real_size;
 	u8 engine_class, guc_class;
-	u8 *ptr;
 
 	if (!intel_uc_uses_guc_submission(&gt->uc))
 		return;
 
-	GEM_BUG_ON(!blob);
+	GEM_BUG_ON(iosys_map_is_null(&guc->ads_map));
 
 	/*
 	 * Go back and fill in the golden context data now that it is
@@ -492,15 +490,13 @@ static void guc_init_golden_context(struct intel_guc *guc)
 	 */
 	offset = guc_ads_golden_ctxt_offset(guc);
 	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
-	ptr = ((u8 *)blob) + offset;
 
 	for (engine_class = 0; engine_class <= MAX_ENGINE_CLASS; ++engine_class) {
 		if (engine_class == OTHER_CLASS)
 			continue;
 
 		guc_class = engine_class_to_guc_class(engine_class);
-
-		if (!blob->system_info.engine_enabled_masks[guc_class])
+		if (!ads_blob_read(guc, system_info.engine_enabled_masks[guc_class]))
 			continue;
 
 		real_size = intel_engine_context_size(gt, engine_class);
@@ -511,18 +507,20 @@ static void guc_init_golden_context(struct intel_guc *guc)
 		if (!engine) {
 			drm_err(&gt->i915->drm, "No engine state recorded for class %d!\n",
 				engine_class);
-			blob->ads.eng_state_size[guc_class] = 0;
-			blob->ads.golden_context_lrca[guc_class] = 0;
+			ads_blob_write(guc, ads.eng_state_size[guc_class], 0);
+			ads_blob_write(guc, ads.golden_context_lrca[guc_class], 0);
 			continue;
 		}
 
-		GEM_BUG_ON(blob->ads.eng_state_size[guc_class] !=
+		GEM_BUG_ON(ads_blob_read(guc, ads.eng_state_size[guc_class]) !=
 			   real_size - LRC_SKIP_SIZE);
-		GEM_BUG_ON(blob->ads.golden_context_lrca[guc_class] != addr_ggtt);
+		GEM_BUG_ON(ads_blob_read(guc, ads.golden_context_lrca[guc_class]) != addr_ggtt);
+
 		addr_ggtt += alloc_size;
 
-		shmem_read(engine->default_state, 0, ptr, real_size);
-		ptr += alloc_size;
+		shmem_read_to_iosys_map(engine->default_state, 0, &guc->ads_map,
+					offset, real_size);
+		offset += alloc_size;
 	}
 
 	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 06/18] drm/i915/guc: Convert golden context init to iosys_map
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Now the map is saved during creation, so use it to initialize the
golden context, reading from shmem and writing to either system or IO
memory.

v2: Do not use a map iterator: add an offset to keep track of
destination

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 26 ++++++++++------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 9bf9096b8337..b5b3a39f0c28 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -473,18 +473,16 @@ static struct intel_engine_cs *find_engine_state(struct intel_gt *gt, u8 engine_
 
 static void guc_init_golden_context(struct intel_guc *guc)
 {
-	struct __guc_ads_blob *blob = guc->ads_blob;
 	struct intel_engine_cs *engine;
 	struct intel_gt *gt = guc_to_gt(guc);
-	u32 addr_ggtt, offset;
-	u32 total_size = 0, alloc_size, real_size;
+	unsigned long offset;
+	u32 addr_ggtt, total_size = 0, alloc_size, real_size;
 	u8 engine_class, guc_class;
-	u8 *ptr;
 
 	if (!intel_uc_uses_guc_submission(&gt->uc))
 		return;
 
-	GEM_BUG_ON(!blob);
+	GEM_BUG_ON(iosys_map_is_null(&guc->ads_map));
 
 	/*
 	 * Go back and fill in the golden context data now that it is
@@ -492,15 +490,13 @@ static void guc_init_golden_context(struct intel_guc *guc)
 	 */
 	offset = guc_ads_golden_ctxt_offset(guc);
 	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
-	ptr = ((u8 *)blob) + offset;
 
 	for (engine_class = 0; engine_class <= MAX_ENGINE_CLASS; ++engine_class) {
 		if (engine_class == OTHER_CLASS)
 			continue;
 
 		guc_class = engine_class_to_guc_class(engine_class);
-
-		if (!blob->system_info.engine_enabled_masks[guc_class])
+		if (!ads_blob_read(guc, system_info.engine_enabled_masks[guc_class]))
 			continue;
 
 		real_size = intel_engine_context_size(gt, engine_class);
@@ -511,18 +507,20 @@ static void guc_init_golden_context(struct intel_guc *guc)
 		if (!engine) {
 			drm_err(&gt->i915->drm, "No engine state recorded for class %d!\n",
 				engine_class);
-			blob->ads.eng_state_size[guc_class] = 0;
-			blob->ads.golden_context_lrca[guc_class] = 0;
+			ads_blob_write(guc, ads.eng_state_size[guc_class], 0);
+			ads_blob_write(guc, ads.golden_context_lrca[guc_class], 0);
 			continue;
 		}
 
-		GEM_BUG_ON(blob->ads.eng_state_size[guc_class] !=
+		GEM_BUG_ON(ads_blob_read(guc, ads.eng_state_size[guc_class]) !=
 			   real_size - LRC_SKIP_SIZE);
-		GEM_BUG_ON(blob->ads.golden_context_lrca[guc_class] != addr_ggtt);
+		GEM_BUG_ON(ads_blob_read(guc, ads.golden_context_lrca[guc_class]) != addr_ggtt);
+
 		addr_ggtt += alloc_size;
 
-		shmem_read(engine->default_state, 0, ptr, real_size);
-		ptr += alloc_size;
+		shmem_read_to_iosys_map(engine->default_state, 0, &guc->ads_map,
+					offset, real_size);
+		offset += alloc_size;
 	}
 
 	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
-- 
2.35.1


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

* [PATCH v2 07/18] drm/i915/guc: Convert policies update to iosys_map
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Use iosys_map to write the policies update so access to IO and system
memory is abstracted away.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 41 ++++++++++++----------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index b5b3a39f0c28..6a34ab38b45f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -130,33 +130,37 @@ static u32 guc_ads_blob_size(struct intel_guc *guc)
 	       guc_ads_private_data_size(guc);
 }
 
-static void guc_policies_init(struct intel_guc *guc, struct guc_policies *policies)
+static void guc_policies_init(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct drm_i915_private *i915 = gt->i915;
+	u32 global_flags = 0;
 
-	policies->dpc_promote_time = GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US;
-	policies->max_num_work_items = GLOBAL_POLICY_MAX_NUM_WI;
+	ads_blob_write(guc, policies.dpc_promote_time,
+		       GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US);
+	ads_blob_write(guc, policies.max_num_work_items,
+		       GLOBAL_POLICY_MAX_NUM_WI);
 
-	policies->global_flags = 0;
 	if (i915->params.reset < 2)
-		policies->global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET;
+		global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET;
 
-	policies->is_valid = 1;
+	ads_blob_write(guc, policies.global_flags, global_flags);
+	ads_blob_write(guc, policies.is_valid, 1);
 }
 
 void intel_guc_ads_print_policy_info(struct intel_guc *guc,
 				     struct drm_printer *dp)
 {
-	struct __guc_ads_blob *blob = guc->ads_blob;
-
-	if (unlikely(!blob))
+	if (unlikely(iosys_map_is_null(&guc->ads_map)))
 		return;
 
 	drm_printf(dp, "Global scheduling policies:\n");
-	drm_printf(dp, "  DPC promote time   = %u\n", blob->policies.dpc_promote_time);
-	drm_printf(dp, "  Max num work items = %u\n", blob->policies.max_num_work_items);
-	drm_printf(dp, "  Flags              = %u\n", blob->policies.global_flags);
+	drm_printf(dp, "  DPC promote time   = %u\n",
+		   ads_blob_read(guc, policies.dpc_promote_time));
+	drm_printf(dp, "  Max num work items = %u\n",
+		   ads_blob_read(guc, policies.max_num_work_items));
+	drm_printf(dp, "  Flags              = %u\n",
+		   ads_blob_read(guc, policies.global_flags));
 }
 
 static int guc_action_policies_update(struct intel_guc *guc, u32 policy_offset)
@@ -171,23 +175,24 @@ static int guc_action_policies_update(struct intel_guc *guc, u32 policy_offset)
 
 int intel_guc_global_policies_update(struct intel_guc *guc)
 {
-	struct __guc_ads_blob *blob = guc->ads_blob;
 	struct intel_gt *gt = guc_to_gt(guc);
+	u32 scheduler_policies;
 	intel_wakeref_t wakeref;
 	int ret;
 
-	if (!blob)
+	if (iosys_map_is_null(&guc->ads_map))
 		return -EOPNOTSUPP;
 
-	GEM_BUG_ON(!blob->ads.scheduler_policies);
+	scheduler_policies = ads_blob_read(guc, ads.scheduler_policies);
+	GEM_BUG_ON(!scheduler_policies);
 
-	guc_policies_init(guc, &blob->policies);
+	guc_policies_init(guc);
 
 	if (!intel_guc_is_ready(guc))
 		return 0;
 
 	with_intel_runtime_pm(&gt->i915->runtime_pm, wakeref)
-		ret = guc_action_policies_update(guc, blob->ads.scheduler_policies);
+		ret = guc_action_policies_update(guc, scheduler_policies);
 
 	return ret;
 }
@@ -554,7 +559,7 @@ static void __guc_ads_init(struct intel_guc *guc)
 	u32 base;
 
 	/* GuC scheduling policies */
-	guc_policies_init(guc, &blob->policies);
+	guc_policies_init(guc);
 
 	/* System info */
 	fill_engine_enable_masks(gt, &blob->system_info);
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 07/18] drm/i915/guc: Convert policies update to iosys_map
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Use iosys_map to write the policies update so access to IO and system
memory is abstracted away.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 41 ++++++++++++----------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index b5b3a39f0c28..6a34ab38b45f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -130,33 +130,37 @@ static u32 guc_ads_blob_size(struct intel_guc *guc)
 	       guc_ads_private_data_size(guc);
 }
 
-static void guc_policies_init(struct intel_guc *guc, struct guc_policies *policies)
+static void guc_policies_init(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct drm_i915_private *i915 = gt->i915;
+	u32 global_flags = 0;
 
-	policies->dpc_promote_time = GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US;
-	policies->max_num_work_items = GLOBAL_POLICY_MAX_NUM_WI;
+	ads_blob_write(guc, policies.dpc_promote_time,
+		       GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US);
+	ads_blob_write(guc, policies.max_num_work_items,
+		       GLOBAL_POLICY_MAX_NUM_WI);
 
-	policies->global_flags = 0;
 	if (i915->params.reset < 2)
-		policies->global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET;
+		global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET;
 
-	policies->is_valid = 1;
+	ads_blob_write(guc, policies.global_flags, global_flags);
+	ads_blob_write(guc, policies.is_valid, 1);
 }
 
 void intel_guc_ads_print_policy_info(struct intel_guc *guc,
 				     struct drm_printer *dp)
 {
-	struct __guc_ads_blob *blob = guc->ads_blob;
-
-	if (unlikely(!blob))
+	if (unlikely(iosys_map_is_null(&guc->ads_map)))
 		return;
 
 	drm_printf(dp, "Global scheduling policies:\n");
-	drm_printf(dp, "  DPC promote time   = %u\n", blob->policies.dpc_promote_time);
-	drm_printf(dp, "  Max num work items = %u\n", blob->policies.max_num_work_items);
-	drm_printf(dp, "  Flags              = %u\n", blob->policies.global_flags);
+	drm_printf(dp, "  DPC promote time   = %u\n",
+		   ads_blob_read(guc, policies.dpc_promote_time));
+	drm_printf(dp, "  Max num work items = %u\n",
+		   ads_blob_read(guc, policies.max_num_work_items));
+	drm_printf(dp, "  Flags              = %u\n",
+		   ads_blob_read(guc, policies.global_flags));
 }
 
 static int guc_action_policies_update(struct intel_guc *guc, u32 policy_offset)
@@ -171,23 +175,24 @@ static int guc_action_policies_update(struct intel_guc *guc, u32 policy_offset)
 
 int intel_guc_global_policies_update(struct intel_guc *guc)
 {
-	struct __guc_ads_blob *blob = guc->ads_blob;
 	struct intel_gt *gt = guc_to_gt(guc);
+	u32 scheduler_policies;
 	intel_wakeref_t wakeref;
 	int ret;
 
-	if (!blob)
+	if (iosys_map_is_null(&guc->ads_map))
 		return -EOPNOTSUPP;
 
-	GEM_BUG_ON(!blob->ads.scheduler_policies);
+	scheduler_policies = ads_blob_read(guc, ads.scheduler_policies);
+	GEM_BUG_ON(!scheduler_policies);
 
-	guc_policies_init(guc, &blob->policies);
+	guc_policies_init(guc);
 
 	if (!intel_guc_is_ready(guc))
 		return 0;
 
 	with_intel_runtime_pm(&gt->i915->runtime_pm, wakeref)
-		ret = guc_action_policies_update(guc, blob->ads.scheduler_policies);
+		ret = guc_action_policies_update(guc, scheduler_policies);
 
 	return ret;
 }
@@ -554,7 +559,7 @@ static void __guc_ads_init(struct intel_guc *guc)
 	u32 base;
 
 	/* GuC scheduling policies */
-	guc_policies_init(guc, &blob->policies);
+	guc_policies_init(guc);
 
 	/* System info */
 	fill_engine_enable_masks(gt, &blob->system_info);
-- 
2.35.1


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

* [PATCH v2 08/18] drm/i915/guc: Convert engine record to iosys_map
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Use iosys_map to read fields from the dma_blob so access to IO and
system memory is abstracted away.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c      | 14 ++++++--------
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h      |  3 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c   | 17 ++++++++++-------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 6a34ab38b45f..383c5994d4ef 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -695,18 +695,16 @@ void intel_guc_ads_reset(struct intel_guc *guc)
 
 u32 intel_guc_engine_usage_offset(struct intel_guc *guc)
 {
-	struct __guc_ads_blob *blob = guc->ads_blob;
-	u32 base = intel_guc_ggtt_offset(guc, guc->ads_vma);
-	u32 offset = base + ptr_offset(blob, engine_usage);
-
-	return offset;
+	return intel_guc_ggtt_offset(guc, guc->ads_vma) +
+		offsetof(struct __guc_ads_blob, engine_usage);
 }
 
-struct guc_engine_usage_record *intel_guc_engine_usage(struct intel_engine_cs *engine)
+struct iosys_map intel_guc_engine_usage_record_map(struct intel_engine_cs *engine)
 {
 	struct intel_guc *guc = &engine->gt->uc.guc;
-	struct __guc_ads_blob *blob = guc->ads_blob;
 	u8 guc_class = engine_class_to_guc_class(engine->class);
+	size_t offset = offsetof(struct __guc_ads_blob,
+				 engine_usage.engines[guc_class][ilog2(engine->logical_mask)]);
 
-	return &blob->engine_usage.engines[guc_class][ilog2(engine->logical_mask)];
+	return IOSYS_MAP_INIT_OFFSET(&guc->ads_map, offset);
 }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h
index e74c110facff..1c64f4d6ea21 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h
@@ -7,6 +7,7 @@
 #define _INTEL_GUC_ADS_H_
 
 #include <linux/types.h>
+#include <linux/iosys-map.h>
 
 struct intel_guc;
 struct drm_printer;
@@ -18,7 +19,7 @@ void intel_guc_ads_init_late(struct intel_guc *guc);
 void intel_guc_ads_reset(struct intel_guc *guc);
 void intel_guc_ads_print_policy_info(struct intel_guc *guc,
 				     struct drm_printer *p);
-struct guc_engine_usage_record *intel_guc_engine_usage(struct intel_engine_cs *engine);
+struct iosys_map intel_guc_engine_usage_record_map(struct intel_engine_cs *engine);
 u32 intel_guc_engine_usage_offset(struct intel_guc *guc);
 
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index b3a429a92c0d..ab3cea352fb3 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1139,6 +1139,9 @@ __extend_last_switch(struct intel_guc *guc, u64 *prev_start, u32 new_start)
 	*prev_start = ((u64)gt_stamp_hi << 32) | new_start;
 }
 
+#define record_read(map_, field_) \
+	iosys_map_rd_field(map_, 0, struct guc_engine_usage_record, field_)
+
 /*
  * GuC updates shared memory and KMD reads it. Since this is not synchronized,
  * we run into a race where the value read is inconsistent. Sometimes the
@@ -1153,17 +1156,17 @@ __extend_last_switch(struct intel_guc *guc, u64 *prev_start, u32 new_start)
 static void __get_engine_usage_record(struct intel_engine_cs *engine,
 				      u32 *last_in, u32 *id, u32 *total)
 {
-	struct guc_engine_usage_record *rec = intel_guc_engine_usage(engine);
+	struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine);
 	int i = 0;
 
 	do {
-		*last_in = READ_ONCE(rec->last_switch_in_stamp);
-		*id = READ_ONCE(rec->current_context_index);
-		*total = READ_ONCE(rec->total_runtime);
+		*last_in = record_read(&rec_map, last_switch_in_stamp);
+		*id = record_read(&rec_map, current_context_index);
+		*total = record_read(&rec_map, total_runtime);
 
-		if (READ_ONCE(rec->last_switch_in_stamp) == *last_in &&
-		    READ_ONCE(rec->current_context_index) == *id &&
-		    READ_ONCE(rec->total_runtime) == *total)
+		if (record_read(&rec_map, last_switch_in_stamp) == *last_in &&
+		    record_read(&rec_map, current_context_index) == *id &&
+		    record_read(&rec_map, total_runtime) == *total)
 			break;
 	} while (++i < 6);
 }
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 08/18] drm/i915/guc: Convert engine record to iosys_map
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Use iosys_map to read fields from the dma_blob so access to IO and
system memory is abstracted away.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c      | 14 ++++++--------
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h      |  3 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c   | 17 ++++++++++-------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 6a34ab38b45f..383c5994d4ef 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -695,18 +695,16 @@ void intel_guc_ads_reset(struct intel_guc *guc)
 
 u32 intel_guc_engine_usage_offset(struct intel_guc *guc)
 {
-	struct __guc_ads_blob *blob = guc->ads_blob;
-	u32 base = intel_guc_ggtt_offset(guc, guc->ads_vma);
-	u32 offset = base + ptr_offset(blob, engine_usage);
-
-	return offset;
+	return intel_guc_ggtt_offset(guc, guc->ads_vma) +
+		offsetof(struct __guc_ads_blob, engine_usage);
 }
 
-struct guc_engine_usage_record *intel_guc_engine_usage(struct intel_engine_cs *engine)
+struct iosys_map intel_guc_engine_usage_record_map(struct intel_engine_cs *engine)
 {
 	struct intel_guc *guc = &engine->gt->uc.guc;
-	struct __guc_ads_blob *blob = guc->ads_blob;
 	u8 guc_class = engine_class_to_guc_class(engine->class);
+	size_t offset = offsetof(struct __guc_ads_blob,
+				 engine_usage.engines[guc_class][ilog2(engine->logical_mask)]);
 
-	return &blob->engine_usage.engines[guc_class][ilog2(engine->logical_mask)];
+	return IOSYS_MAP_INIT_OFFSET(&guc->ads_map, offset);
 }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h
index e74c110facff..1c64f4d6ea21 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h
@@ -7,6 +7,7 @@
 #define _INTEL_GUC_ADS_H_
 
 #include <linux/types.h>
+#include <linux/iosys-map.h>
 
 struct intel_guc;
 struct drm_printer;
@@ -18,7 +19,7 @@ void intel_guc_ads_init_late(struct intel_guc *guc);
 void intel_guc_ads_reset(struct intel_guc *guc);
 void intel_guc_ads_print_policy_info(struct intel_guc *guc,
 				     struct drm_printer *p);
-struct guc_engine_usage_record *intel_guc_engine_usage(struct intel_engine_cs *engine);
+struct iosys_map intel_guc_engine_usage_record_map(struct intel_engine_cs *engine);
 u32 intel_guc_engine_usage_offset(struct intel_guc *guc);
 
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index b3a429a92c0d..ab3cea352fb3 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1139,6 +1139,9 @@ __extend_last_switch(struct intel_guc *guc, u64 *prev_start, u32 new_start)
 	*prev_start = ((u64)gt_stamp_hi << 32) | new_start;
 }
 
+#define record_read(map_, field_) \
+	iosys_map_rd_field(map_, 0, struct guc_engine_usage_record, field_)
+
 /*
  * GuC updates shared memory and KMD reads it. Since this is not synchronized,
  * we run into a race where the value read is inconsistent. Sometimes the
@@ -1153,17 +1156,17 @@ __extend_last_switch(struct intel_guc *guc, u64 *prev_start, u32 new_start)
 static void __get_engine_usage_record(struct intel_engine_cs *engine,
 				      u32 *last_in, u32 *id, u32 *total)
 {
-	struct guc_engine_usage_record *rec = intel_guc_engine_usage(engine);
+	struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine);
 	int i = 0;
 
 	do {
-		*last_in = READ_ONCE(rec->last_switch_in_stamp);
-		*id = READ_ONCE(rec->current_context_index);
-		*total = READ_ONCE(rec->total_runtime);
+		*last_in = record_read(&rec_map, last_switch_in_stamp);
+		*id = record_read(&rec_map, current_context_index);
+		*total = record_read(&rec_map, total_runtime);
 
-		if (READ_ONCE(rec->last_switch_in_stamp) == *last_in &&
-		    READ_ONCE(rec->current_context_index) == *id &&
-		    READ_ONCE(rec->total_runtime) == *total)
+		if (record_read(&rec_map, last_switch_in_stamp) == *last_in &&
+		    record_read(&rec_map, current_context_index) == *id &&
+		    record_read(&rec_map, total_runtime) == *total)
 			break;
 	} while (++i < 6);
 }
-- 
2.35.1


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

* [PATCH v2 09/18] drm/i915/guc: Convert guc_ads_private_data_reset to iosys_map
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Use iosys_map_memset() to zero the private data as ADS may be either
on system or IO memory.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 383c5994d4ef..7e355eef8d64 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -671,8 +671,8 @@ static void guc_ads_private_data_reset(struct intel_guc *guc)
 	if (!size)
 		return;
 
-	memset((void *)guc->ads_blob + guc_ads_private_data_offset(guc), 0,
-	       size);
+	iosys_map_memset(&guc->ads_map, guc_ads_private_data_offset(guc),
+			 0, size);
 }
 
 /**
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 09/18] drm/i915/guc: Convert guc_ads_private_data_reset to iosys_map
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Use iosys_map_memset() to zero the private data as ADS may be either
on system or IO memory.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 383c5994d4ef..7e355eef8d64 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -671,8 +671,8 @@ static void guc_ads_private_data_reset(struct intel_guc *guc)
 	if (!size)
 		return;
 
-	memset((void *)guc->ads_blob + guc_ads_private_data_offset(guc), 0,
-	       size);
+	iosys_map_memset(&guc->ads_map, guc_ads_private_data_offset(guc),
+			 0, size);
 }
 
 /**
-- 
2.35.1


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

* [PATCH v2 10/18] drm/i915/guc: Convert golden context prep to iosys_map
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Use the saved ads_map to prepare the golden context. One difference from
the init context is that this function can be called before there is a
gem object (and thus the guc->ads_map) to calculare the size of the
golden context that should be allocated for that object.

So in this case the function needs to be prepared for not having the
system_info with enabled engines filled out. To accomplish that an
info_map is prepared on the side to point either to the gem object
or the local variable on the stack. This allows making
fill_engine_enable_masks() operate always with a iosys_map
argument.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 52 +++++++++++++---------
 1 file changed, 32 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 7e355eef8d64..483a919328a9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -67,6 +67,12 @@ struct __guc_ads_blob {
 	iosys_map_wr_field(&(guc_)->ads_map, 0, struct __guc_ads_blob,	\
 			   field_, val_)
 
+#define info_map_write(map_, field_, val_) \
+	iosys_map_wr_field(map_, 0, struct guc_gt_system_info, field_, val_)
+
+#define info_map_read(map_, field_) \
+	iosys_map_rd_field(map_, 0, struct guc_gt_system_info, field_)
+
 static u32 guc_ads_regset_size(struct intel_guc *guc)
 {
 	GEM_BUG_ON(!guc->ads_regset_size);
@@ -378,24 +384,24 @@ static void guc_mmio_reg_state_init(struct intel_guc *guc,
 }
 
 static void fill_engine_enable_masks(struct intel_gt *gt,
-				     struct guc_gt_system_info *info)
+				     struct iosys_map *info_map)
 {
-	info->engine_enabled_masks[GUC_RENDER_CLASS] = 1;
-	info->engine_enabled_masks[GUC_BLITTER_CLASS] = 1;
-	info->engine_enabled_masks[GUC_VIDEO_CLASS] = VDBOX_MASK(gt);
-	info->engine_enabled_masks[GUC_VIDEOENHANCE_CLASS] = VEBOX_MASK(gt);
+	info_map_write(info_map, engine_enabled_masks[GUC_RENDER_CLASS], 1);
+	info_map_write(info_map, engine_enabled_masks[GUC_BLITTER_CLASS], 1);
+	info_map_write(info_map, engine_enabled_masks[GUC_VIDEO_CLASS], VDBOX_MASK(gt));
+	info_map_write(info_map, engine_enabled_masks[GUC_VIDEOENHANCE_CLASS], VEBOX_MASK(gt));
 }
 
 #define LR_HW_CONTEXT_SIZE (80 * sizeof(u32))
 #define LRC_SKIP_SIZE (LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE)
-static int guc_prep_golden_context(struct intel_guc *guc,
-				   struct __guc_ads_blob *blob)
+static int guc_prep_golden_context(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	u32 addr_ggtt, offset;
 	u32 total_size = 0, alloc_size, real_size;
 	u8 engine_class, guc_class;
-	struct guc_gt_system_info *info, local_info;
+	struct guc_gt_system_info local_info;
+	struct iosys_map info_map;
 
 	/*
 	 * Reserve the memory for the golden contexts and point GuC at it but
@@ -409,14 +415,15 @@ static int guc_prep_golden_context(struct intel_guc *guc,
 	 * GuC will also validate that the LRC base + size fall within the
 	 * allowed GGTT range.
 	 */
-	if (blob) {
+	if (!iosys_map_is_null(&guc->ads_map)) {
 		offset = guc_ads_golden_ctxt_offset(guc);
 		addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
-		info = &blob->system_info;
+		info_map = IOSYS_MAP_INIT_OFFSET(&guc->ads_map,
+						 offsetof(struct __guc_ads_blob, system_info));
 	} else {
 		memset(&local_info, 0, sizeof(local_info));
-		info = &local_info;
-		fill_engine_enable_masks(gt, info);
+		iosys_map_set_vaddr(&info_map, &local_info);
+		fill_engine_enable_masks(gt, &info_map);
 	}
 
 	for (engine_class = 0; engine_class <= MAX_ENGINE_CLASS; ++engine_class) {
@@ -425,14 +432,14 @@ static int guc_prep_golden_context(struct intel_guc *guc,
 
 		guc_class = engine_class_to_guc_class(engine_class);
 
-		if (!info->engine_enabled_masks[guc_class])
+		if (!info_map_read(&info_map, engine_enabled_masks[guc_class]))
 			continue;
 
 		real_size = intel_engine_context_size(gt, engine_class);
 		alloc_size = PAGE_ALIGN(real_size);
 		total_size += alloc_size;
 
-		if (!blob)
+		if (iosys_map_is_null(&guc->ads_map))
 			continue;
 
 		/*
@@ -446,12 +453,15 @@ static int guc_prep_golden_context(struct intel_guc *guc,
 		 * what comes before it in the context image (which is identical
 		 * on all engines).
 		 */
-		blob->ads.eng_state_size[guc_class] = real_size - LRC_SKIP_SIZE;
-		blob->ads.golden_context_lrca[guc_class] = addr_ggtt;
+		ads_blob_write(guc, ads.eng_state_size[guc_class],
+			       real_size - LRC_SKIP_SIZE);
+		ads_blob_write(guc, ads.golden_context_lrca[guc_class],
+			       addr_ggtt);
+
 		addr_ggtt += alloc_size;
 	}
 
-	if (!blob)
+	if (iosys_map_is_null(&guc->ads_map))
 		return total_size;
 
 	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
@@ -556,13 +566,15 @@ static void __guc_ads_init(struct intel_guc *guc)
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct drm_i915_private *i915 = gt->i915;
 	struct __guc_ads_blob *blob = guc->ads_blob;
+	struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(&guc->ads_map,
+			offsetof(struct __guc_ads_blob, system_info));
 	u32 base;
 
 	/* GuC scheduling policies */
 	guc_policies_init(guc);
 
 	/* System info */
-	fill_engine_enable_masks(gt, &blob->system_info);
+	fill_engine_enable_masks(gt, &info_map);
 
 	blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED] =
 		hweight8(gt->info.sseu.slice_mask);
@@ -578,7 +590,7 @@ static void __guc_ads_init(struct intel_guc *guc)
 	}
 
 	/* Golden contexts for re-initialising after a watchdog reset */
-	guc_prep_golden_context(guc, blob);
+	guc_prep_golden_context(guc);
 
 	guc_mapping_table_init(guc_to_gt(guc), &blob->system_info);
 
@@ -621,7 +633,7 @@ int intel_guc_ads_create(struct intel_guc *guc)
 	guc->ads_regset_size = ret;
 
 	/* Likewise the golden contexts: */
-	ret = guc_prep_golden_context(guc, NULL);
+	ret = guc_prep_golden_context(guc);
 	if (ret < 0)
 		return ret;
 	guc->ads_golden_ctxt_size = ret;
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 10/18] drm/i915/guc: Convert golden context prep to iosys_map
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Use the saved ads_map to prepare the golden context. One difference from
the init context is that this function can be called before there is a
gem object (and thus the guc->ads_map) to calculare the size of the
golden context that should be allocated for that object.

So in this case the function needs to be prepared for not having the
system_info with enabled engines filled out. To accomplish that an
info_map is prepared on the side to point either to the gem object
or the local variable on the stack. This allows making
fill_engine_enable_masks() operate always with a iosys_map
argument.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 52 +++++++++++++---------
 1 file changed, 32 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 7e355eef8d64..483a919328a9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -67,6 +67,12 @@ struct __guc_ads_blob {
 	iosys_map_wr_field(&(guc_)->ads_map, 0, struct __guc_ads_blob,	\
 			   field_, val_)
 
+#define info_map_write(map_, field_, val_) \
+	iosys_map_wr_field(map_, 0, struct guc_gt_system_info, field_, val_)
+
+#define info_map_read(map_, field_) \
+	iosys_map_rd_field(map_, 0, struct guc_gt_system_info, field_)
+
 static u32 guc_ads_regset_size(struct intel_guc *guc)
 {
 	GEM_BUG_ON(!guc->ads_regset_size);
@@ -378,24 +384,24 @@ static void guc_mmio_reg_state_init(struct intel_guc *guc,
 }
 
 static void fill_engine_enable_masks(struct intel_gt *gt,
-				     struct guc_gt_system_info *info)
+				     struct iosys_map *info_map)
 {
-	info->engine_enabled_masks[GUC_RENDER_CLASS] = 1;
-	info->engine_enabled_masks[GUC_BLITTER_CLASS] = 1;
-	info->engine_enabled_masks[GUC_VIDEO_CLASS] = VDBOX_MASK(gt);
-	info->engine_enabled_masks[GUC_VIDEOENHANCE_CLASS] = VEBOX_MASK(gt);
+	info_map_write(info_map, engine_enabled_masks[GUC_RENDER_CLASS], 1);
+	info_map_write(info_map, engine_enabled_masks[GUC_BLITTER_CLASS], 1);
+	info_map_write(info_map, engine_enabled_masks[GUC_VIDEO_CLASS], VDBOX_MASK(gt));
+	info_map_write(info_map, engine_enabled_masks[GUC_VIDEOENHANCE_CLASS], VEBOX_MASK(gt));
 }
 
 #define LR_HW_CONTEXT_SIZE (80 * sizeof(u32))
 #define LRC_SKIP_SIZE (LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE)
-static int guc_prep_golden_context(struct intel_guc *guc,
-				   struct __guc_ads_blob *blob)
+static int guc_prep_golden_context(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	u32 addr_ggtt, offset;
 	u32 total_size = 0, alloc_size, real_size;
 	u8 engine_class, guc_class;
-	struct guc_gt_system_info *info, local_info;
+	struct guc_gt_system_info local_info;
+	struct iosys_map info_map;
 
 	/*
 	 * Reserve the memory for the golden contexts and point GuC at it but
@@ -409,14 +415,15 @@ static int guc_prep_golden_context(struct intel_guc *guc,
 	 * GuC will also validate that the LRC base + size fall within the
 	 * allowed GGTT range.
 	 */
-	if (blob) {
+	if (!iosys_map_is_null(&guc->ads_map)) {
 		offset = guc_ads_golden_ctxt_offset(guc);
 		addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
-		info = &blob->system_info;
+		info_map = IOSYS_MAP_INIT_OFFSET(&guc->ads_map,
+						 offsetof(struct __guc_ads_blob, system_info));
 	} else {
 		memset(&local_info, 0, sizeof(local_info));
-		info = &local_info;
-		fill_engine_enable_masks(gt, info);
+		iosys_map_set_vaddr(&info_map, &local_info);
+		fill_engine_enable_masks(gt, &info_map);
 	}
 
 	for (engine_class = 0; engine_class <= MAX_ENGINE_CLASS; ++engine_class) {
@@ -425,14 +432,14 @@ static int guc_prep_golden_context(struct intel_guc *guc,
 
 		guc_class = engine_class_to_guc_class(engine_class);
 
-		if (!info->engine_enabled_masks[guc_class])
+		if (!info_map_read(&info_map, engine_enabled_masks[guc_class]))
 			continue;
 
 		real_size = intel_engine_context_size(gt, engine_class);
 		alloc_size = PAGE_ALIGN(real_size);
 		total_size += alloc_size;
 
-		if (!blob)
+		if (iosys_map_is_null(&guc->ads_map))
 			continue;
 
 		/*
@@ -446,12 +453,15 @@ static int guc_prep_golden_context(struct intel_guc *guc,
 		 * what comes before it in the context image (which is identical
 		 * on all engines).
 		 */
-		blob->ads.eng_state_size[guc_class] = real_size - LRC_SKIP_SIZE;
-		blob->ads.golden_context_lrca[guc_class] = addr_ggtt;
+		ads_blob_write(guc, ads.eng_state_size[guc_class],
+			       real_size - LRC_SKIP_SIZE);
+		ads_blob_write(guc, ads.golden_context_lrca[guc_class],
+			       addr_ggtt);
+
 		addr_ggtt += alloc_size;
 	}
 
-	if (!blob)
+	if (iosys_map_is_null(&guc->ads_map))
 		return total_size;
 
 	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
@@ -556,13 +566,15 @@ static void __guc_ads_init(struct intel_guc *guc)
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct drm_i915_private *i915 = gt->i915;
 	struct __guc_ads_blob *blob = guc->ads_blob;
+	struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(&guc->ads_map,
+			offsetof(struct __guc_ads_blob, system_info));
 	u32 base;
 
 	/* GuC scheduling policies */
 	guc_policies_init(guc);
 
 	/* System info */
-	fill_engine_enable_masks(gt, &blob->system_info);
+	fill_engine_enable_masks(gt, &info_map);
 
 	blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED] =
 		hweight8(gt->info.sseu.slice_mask);
@@ -578,7 +590,7 @@ static void __guc_ads_init(struct intel_guc *guc)
 	}
 
 	/* Golden contexts for re-initialising after a watchdog reset */
-	guc_prep_golden_context(guc, blob);
+	guc_prep_golden_context(guc);
 
 	guc_mapping_table_init(guc_to_gt(guc), &blob->system_info);
 
@@ -621,7 +633,7 @@ int intel_guc_ads_create(struct intel_guc *guc)
 	guc->ads_regset_size = ret;
 
 	/* Likewise the golden contexts: */
-	ret = guc_prep_golden_context(guc, NULL);
+	ret = guc_prep_golden_context(guc);
 	if (ret < 0)
 		return ret;
 	guc->ads_golden_ctxt_size = ret;
-- 
2.35.1


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

* [PATCH v2 11/18] drm/i915/guc: Replace check for golden context size
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

In the other places in this function, guc->ads_map is being protected
from access when it's not yet set. However the last check is actually
about guc->ads_golden_ctxt_size been set before.  These checks should
always match as the size is initialized on the first call to
guc_prep_golden_context(), but it's clearer if we have a single return
and check for guc->ads_golden_ctxt_size.

This is just a readability improvement, no change in behavior.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 483a919328a9..63f305597214 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -461,10 +461,10 @@ static int guc_prep_golden_context(struct intel_guc *guc)
 		addr_ggtt += alloc_size;
 	}
 
-	if (iosys_map_is_null(&guc->ads_map))
-		return total_size;
+	/* Make sure current size matches what we calculated previously */
+	if (guc->ads_golden_ctxt_size)
+		GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
 
-	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
 	return total_size;
 }
 
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 11/18] drm/i915/guc: Replace check for golden context size
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

In the other places in this function, guc->ads_map is being protected
from access when it's not yet set. However the last check is actually
about guc->ads_golden_ctxt_size been set before.  These checks should
always match as the size is initialized on the first call to
guc_prep_golden_context(), but it's clearer if we have a single return
and check for guc->ads_golden_ctxt_size.

This is just a readability improvement, no change in behavior.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 483a919328a9..63f305597214 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -461,10 +461,10 @@ static int guc_prep_golden_context(struct intel_guc *guc)
 		addr_ggtt += alloc_size;
 	}
 
-	if (iosys_map_is_null(&guc->ads_map))
-		return total_size;
+	/* Make sure current size matches what we calculated previously */
+	if (guc->ads_golden_ctxt_size)
+		GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
 
-	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
 	return total_size;
 }
 
-- 
2.35.1


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

* [PATCH v2 12/18] drm/i915/guc: Convert mapping table to iosys_map
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Use iosys_map to write the fields system_info.mapping_table[][].
Since we already have the info_map around where needed, just use it
instead of going through guc->ads_map.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 63f305597214..9230e1a499aa 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -204,7 +204,7 @@ int intel_guc_global_policies_update(struct intel_guc *guc)
 }
 
 static void guc_mapping_table_init(struct intel_gt *gt,
-				   struct guc_gt_system_info *system_info)
+				   struct iosys_map *info_map)
 {
 	unsigned int i, j;
 	struct intel_engine_cs *engine;
@@ -213,14 +213,14 @@ static void guc_mapping_table_init(struct intel_gt *gt,
 	/* Table must be set to invalid values for entries not used */
 	for (i = 0; i < GUC_MAX_ENGINE_CLASSES; ++i)
 		for (j = 0; j < GUC_MAX_INSTANCES_PER_CLASS; ++j)
-			system_info->mapping_table[i][j] =
-				GUC_MAX_INSTANCES_PER_CLASS;
+			info_map_write(info_map, mapping_table[i][j],
+				       GUC_MAX_INSTANCES_PER_CLASS);
 
 	for_each_engine(engine, gt, id) {
 		u8 guc_class = engine_class_to_guc_class(engine->class);
 
-		system_info->mapping_table[guc_class][ilog2(engine->logical_mask)] =
-			engine->instance;
+		info_map_write(info_map, mapping_table[guc_class][ilog2(engine->logical_mask)],
+			       engine->instance);
 	}
 }
 
@@ -592,7 +592,7 @@ static void __guc_ads_init(struct intel_guc *guc)
 	/* Golden contexts for re-initialising after a watchdog reset */
 	guc_prep_golden_context(guc);
 
-	guc_mapping_table_init(guc_to_gt(guc), &blob->system_info);
+	guc_mapping_table_init(guc_to_gt(guc), &info_map);
 
 	base = intel_guc_ggtt_offset(guc, guc->ads_vma);
 
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 12/18] drm/i915/guc: Convert mapping table to iosys_map
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Use iosys_map to write the fields system_info.mapping_table[][].
Since we already have the info_map around where needed, just use it
instead of going through guc->ads_map.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 63f305597214..9230e1a499aa 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -204,7 +204,7 @@ int intel_guc_global_policies_update(struct intel_guc *guc)
 }
 
 static void guc_mapping_table_init(struct intel_gt *gt,
-				   struct guc_gt_system_info *system_info)
+				   struct iosys_map *info_map)
 {
 	unsigned int i, j;
 	struct intel_engine_cs *engine;
@@ -213,14 +213,14 @@ static void guc_mapping_table_init(struct intel_gt *gt,
 	/* Table must be set to invalid values for entries not used */
 	for (i = 0; i < GUC_MAX_ENGINE_CLASSES; ++i)
 		for (j = 0; j < GUC_MAX_INSTANCES_PER_CLASS; ++j)
-			system_info->mapping_table[i][j] =
-				GUC_MAX_INSTANCES_PER_CLASS;
+			info_map_write(info_map, mapping_table[i][j],
+				       GUC_MAX_INSTANCES_PER_CLASS);
 
 	for_each_engine(engine, gt, id) {
 		u8 guc_class = engine_class_to_guc_class(engine->class);
 
-		system_info->mapping_table[guc_class][ilog2(engine->logical_mask)] =
-			engine->instance;
+		info_map_write(info_map, mapping_table[guc_class][ilog2(engine->logical_mask)],
+			       engine->instance);
 	}
 }
 
@@ -592,7 +592,7 @@ static void __guc_ads_init(struct intel_guc *guc)
 	/* Golden contexts for re-initialising after a watchdog reset */
 	guc_prep_golden_context(guc);
 
-	guc_mapping_table_init(guc_to_gt(guc), &blob->system_info);
+	guc_mapping_table_init(guc_to_gt(guc), &info_map);
 
 	base = intel_guc_ggtt_offset(guc, guc->ads_vma);
 
-- 
2.35.1


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

* [PATCH v2 13/18] drm/i915/guc: Convert capture list to iosys_map
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Use iosys_map to write the fields ads.capture_*.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 9230e1a499aa..1f6a3d4d9431 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -541,7 +541,7 @@ static void guc_init_golden_context(struct intel_guc *guc)
 	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
 }
 
-static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *blob)
+static void guc_capture_list_init(struct intel_guc *guc)
 {
 	int i, j;
 	u32 addr_ggtt, offset;
@@ -553,11 +553,11 @@ static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *
 
 	for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) {
 		for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) {
-			blob->ads.capture_instance[i][j] = addr_ggtt;
-			blob->ads.capture_class[i][j] = addr_ggtt;
+			ads_blob_write(guc, ads.capture_instance[i][j], addr_ggtt);
+			ads_blob_write(guc, ads.capture_class[i][j], addr_ggtt);
 		}
 
-		blob->ads.capture_global[i] = addr_ggtt;
+		ads_blob_write(guc, ads.capture_global[i], addr_ggtt);
 	}
 }
 
@@ -597,7 +597,7 @@ static void __guc_ads_init(struct intel_guc *guc)
 	base = intel_guc_ggtt_offset(guc, guc->ads_vma);
 
 	/* Capture list for hang debug */
-	guc_capture_list_init(guc, blob);
+	guc_capture_list_init(guc);
 
 	/* ADS */
 	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 13/18] drm/i915/guc: Convert capture list to iosys_map
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Use iosys_map to write the fields ads.capture_*.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 9230e1a499aa..1f6a3d4d9431 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -541,7 +541,7 @@ static void guc_init_golden_context(struct intel_guc *guc)
 	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
 }
 
-static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *blob)
+static void guc_capture_list_init(struct intel_guc *guc)
 {
 	int i, j;
 	u32 addr_ggtt, offset;
@@ -553,11 +553,11 @@ static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *
 
 	for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) {
 		for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) {
-			blob->ads.capture_instance[i][j] = addr_ggtt;
-			blob->ads.capture_class[i][j] = addr_ggtt;
+			ads_blob_write(guc, ads.capture_instance[i][j], addr_ggtt);
+			ads_blob_write(guc, ads.capture_class[i][j], addr_ggtt);
 		}
 
-		blob->ads.capture_global[i] = addr_ggtt;
+		ads_blob_write(guc, ads.capture_global[i], addr_ggtt);
 	}
 }
 
@@ -597,7 +597,7 @@ static void __guc_ads_init(struct intel_guc *guc)
 	base = intel_guc_ggtt_offset(guc, guc->ads_vma);
 
 	/* Capture list for hang debug */
-	guc_capture_list_init(guc, blob);
+	guc_capture_list_init(guc);
 
 	/* ADS */
 	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
-- 
2.35.1


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

* [PATCH v2 14/18] drm/i915/guc: Prepare for error propagation
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Currently guc_mmio_reg_add() relies on having enough memory available in
the array to add a new slot. It uses
`GEM_BUG_ON(count >= regset->size);` to protect going above the
threshold.

In order to allow guc_mmio_reg_add() to handle the memory allocation by
itself, it must return an error in case of failures.  Adjust return code
so this error can be propagated to the callers of guc_mmio_reg_add() and
guc_mmio_regset_init().

No intended change in behavior.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 31 +++++++++++++---------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 1f6a3d4d9431..21e975d371e6 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -244,8 +244,8 @@ static int guc_mmio_reg_cmp(const void *a, const void *b)
 	return (int)ra->offset - (int)rb->offset;
 }
 
-static void guc_mmio_reg_add(struct temp_regset *regset,
-			     u32 offset, u32 flags)
+static long __must_check guc_mmio_reg_add(struct temp_regset *regset,
+					  u32 offset, u32 flags)
 {
 	u32 count = regset->used;
 	struct guc_mmio_reg reg = {
@@ -264,7 +264,7 @@ static void guc_mmio_reg_add(struct temp_regset *regset,
 	 */
 	if (bsearch(&reg, regset->registers, count,
 		    sizeof(reg), guc_mmio_reg_cmp))
-		return;
+		return 0;
 
 	slot = &regset->registers[count];
 	regset->used++;
@@ -277,6 +277,8 @@ static void guc_mmio_reg_add(struct temp_regset *regset,
 
 		swap(slot[1], slot[0]);
 	}
+
+	return 0;
 }
 
 #define GUC_MMIO_REG_ADD(regset, reg, masked) \
@@ -284,32 +286,35 @@ static void guc_mmio_reg_add(struct temp_regset *regset,
 			 i915_mmio_reg_offset((reg)), \
 			 (masked) ? GUC_REGSET_MASKED : 0)
 
-static void guc_mmio_regset_init(struct temp_regset *regset,
-				 struct intel_engine_cs *engine)
+static int guc_mmio_regset_init(struct temp_regset *regset,
+				struct intel_engine_cs *engine)
 {
 	const u32 base = engine->mmio_base;
 	struct i915_wa_list *wal = &engine->wa_list;
 	struct i915_wa *wa;
 	unsigned int i;
+	int ret = 0;
 
 	regset->used = 0;
 
-	GUC_MMIO_REG_ADD(regset, RING_MODE_GEN7(base), true);
-	GUC_MMIO_REG_ADD(regset, RING_HWS_PGA(base), false);
-	GUC_MMIO_REG_ADD(regset, RING_IMR(base), false);
+	ret |= GUC_MMIO_REG_ADD(regset, RING_MODE_GEN7(base), true);
+	ret |= GUC_MMIO_REG_ADD(regset, RING_HWS_PGA(base), false);
+	ret |= GUC_MMIO_REG_ADD(regset, RING_IMR(base), false);
 
 	for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
-		GUC_MMIO_REG_ADD(regset, wa->reg, wa->masked_reg);
+		ret |= GUC_MMIO_REG_ADD(regset, wa->reg, wa->masked_reg);
 
 	/* Be extra paranoid and include all whitelist registers. */
 	for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++)
-		GUC_MMIO_REG_ADD(regset,
-				 RING_FORCE_TO_NONPRIV(base, i),
-				 false);
+		ret |= GUC_MMIO_REG_ADD(regset,
+					RING_FORCE_TO_NONPRIV(base, i),
+					false);
 
 	/* add in local MOCS registers */
 	for (i = 0; i < GEN9_LNCFCMOCS_REG_COUNT; i++)
-		GUC_MMIO_REG_ADD(regset, GEN9_LNCFCMOCS(i), false);
+		ret |= GUC_MMIO_REG_ADD(regset, GEN9_LNCFCMOCS(i), false);
+
+	return ret ? -1 : 0;
 }
 
 static int guc_mmio_reg_state_query(struct intel_guc *guc)
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 14/18] drm/i915/guc: Prepare for error propagation
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Currently guc_mmio_reg_add() relies on having enough memory available in
the array to add a new slot. It uses
`GEM_BUG_ON(count >= regset->size);` to protect going above the
threshold.

In order to allow guc_mmio_reg_add() to handle the memory allocation by
itself, it must return an error in case of failures.  Adjust return code
so this error can be propagated to the callers of guc_mmio_reg_add() and
guc_mmio_regset_init().

No intended change in behavior.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 31 +++++++++++++---------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 1f6a3d4d9431..21e975d371e6 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -244,8 +244,8 @@ static int guc_mmio_reg_cmp(const void *a, const void *b)
 	return (int)ra->offset - (int)rb->offset;
 }
 
-static void guc_mmio_reg_add(struct temp_regset *regset,
-			     u32 offset, u32 flags)
+static long __must_check guc_mmio_reg_add(struct temp_regset *regset,
+					  u32 offset, u32 flags)
 {
 	u32 count = regset->used;
 	struct guc_mmio_reg reg = {
@@ -264,7 +264,7 @@ static void guc_mmio_reg_add(struct temp_regset *regset,
 	 */
 	if (bsearch(&reg, regset->registers, count,
 		    sizeof(reg), guc_mmio_reg_cmp))
-		return;
+		return 0;
 
 	slot = &regset->registers[count];
 	regset->used++;
@@ -277,6 +277,8 @@ static void guc_mmio_reg_add(struct temp_regset *regset,
 
 		swap(slot[1], slot[0]);
 	}
+
+	return 0;
 }
 
 #define GUC_MMIO_REG_ADD(regset, reg, masked) \
@@ -284,32 +286,35 @@ static void guc_mmio_reg_add(struct temp_regset *regset,
 			 i915_mmio_reg_offset((reg)), \
 			 (masked) ? GUC_REGSET_MASKED : 0)
 
-static void guc_mmio_regset_init(struct temp_regset *regset,
-				 struct intel_engine_cs *engine)
+static int guc_mmio_regset_init(struct temp_regset *regset,
+				struct intel_engine_cs *engine)
 {
 	const u32 base = engine->mmio_base;
 	struct i915_wa_list *wal = &engine->wa_list;
 	struct i915_wa *wa;
 	unsigned int i;
+	int ret = 0;
 
 	regset->used = 0;
 
-	GUC_MMIO_REG_ADD(regset, RING_MODE_GEN7(base), true);
-	GUC_MMIO_REG_ADD(regset, RING_HWS_PGA(base), false);
-	GUC_MMIO_REG_ADD(regset, RING_IMR(base), false);
+	ret |= GUC_MMIO_REG_ADD(regset, RING_MODE_GEN7(base), true);
+	ret |= GUC_MMIO_REG_ADD(regset, RING_HWS_PGA(base), false);
+	ret |= GUC_MMIO_REG_ADD(regset, RING_IMR(base), false);
 
 	for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
-		GUC_MMIO_REG_ADD(regset, wa->reg, wa->masked_reg);
+		ret |= GUC_MMIO_REG_ADD(regset, wa->reg, wa->masked_reg);
 
 	/* Be extra paranoid and include all whitelist registers. */
 	for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++)
-		GUC_MMIO_REG_ADD(regset,
-				 RING_FORCE_TO_NONPRIV(base, i),
-				 false);
+		ret |= GUC_MMIO_REG_ADD(regset,
+					RING_FORCE_TO_NONPRIV(base, i),
+					false);
 
 	/* add in local MOCS registers */
 	for (i = 0; i < GEN9_LNCFCMOCS_REG_COUNT; i++)
-		GUC_MMIO_REG_ADD(regset, GEN9_LNCFCMOCS(i), false);
+		ret |= GUC_MMIO_REG_ADD(regset, GEN9_LNCFCMOCS(i), false);
+
+	return ret ? -1 : 0;
 }
 
 static int guc_mmio_reg_state_query(struct intel_guc *guc)
-- 
2.35.1


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

* [PATCH v2 15/18] drm/i915/guc: Use a single pass to calculate regset
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

The ADS initialitazion was using 2 passes to calculate the regset sent
to GuC to initialize each engine: the first pass to just have the final
object size and the second to set each register in place in the final
gem object.

However in order to maintain an ordered set of registers to pass to guc,
each register needs to be added and moved in the final array. The second
phase may actually happen in IO memory rather than system memory and
accessing IO memory by simply dereferencing the pointer doesn't work on
all architectures. Other places of the ADS initializaition were
converted to use the iosys_map API, but here there may be a lot more
accesses to IO memory. So, instead of following that same approach,
convert the regset initialization to calculate the final array in 1
pass and in the second pass that array is just copied to its final
location, updating the pointers for each engine written to the ADS blob.

One important thing is that struct temp_regset now have
different semantics: `registers` continues to track the registers of a
single engine, however the other fields are updated together, according
to the newly added `storage`, which tracks the memory allocated for
all the registers. So rename some of these fields and add a
__mmio_reg_add(): this function (possibly) allocates memory and operates
on the storage pointer while guc_mmio_reg_add() continues to manage the
registers pointer.

On a Tiger Lake system using enable_guc=3, the following log message is
now seen:

	[  187.334310] i915 0000:00:02.0: [drm:intel_guc_ads_create [i915]] Used 4 KB for temporary ADS regset

This change has also been tested on an ARM64 host with DG2 and other
discrete graphics cards.

v2 (Daniele):
  - Fix leaking tempset on error path
  - Add comments on struct temp_regset to document the meaning of each
    field

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h     |   7 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 128 +++++++++++++--------
 2 files changed, 90 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 9b9ba79f7594..f857e9190750 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -152,6 +152,13 @@ struct intel_guc {
 	struct iosys_map ads_map;
 	/** @ads_regset_size: size of the save/restore regsets in the ADS */
 	u32 ads_regset_size;
+	/**
+	 * @ads_regset_count: number of save/restore registers in the ADS for
+	 * each engine
+	 */
+	u32 ads_regset_count[I915_NUM_ENGINES];
+	/** @ads_regset: save/restore regsets in the ADS */
+	struct guc_mmio_reg *ads_regset;
 	/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
 	u32 ads_golden_ctxt_size;
 	/** @ads_engine_usage_size: size of engine usage in the ADS */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 21e975d371e6..ec0ccdf98dfa 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -226,14 +226,18 @@ static void guc_mapping_table_init(struct intel_gt *gt,
 
 /*
  * The save/restore register list must be pre-calculated to a temporary
- * buffer of driver defined size before it can be generated in place
- * inside the ADS.
+ * buffer before it can be copied inside the ADS.
  */
-#define MAX_MMIO_REGS	128	/* Arbitrary size, increase as needed */
 struct temp_regset {
+	/*
+	 * ptr to the section of the storage for the engine currently being
+	 * worked on
+	 */
 	struct guc_mmio_reg *registers;
-	u32 used;
-	u32 size;
+	/* ptr to the base of the allocated storage for all engines */
+	struct guc_mmio_reg *storage;
+	u32 storage_used;
+	u32 storage_max;
 };
 
 static int guc_mmio_reg_cmp(const void *a, const void *b)
@@ -244,18 +248,44 @@ static int guc_mmio_reg_cmp(const void *a, const void *b)
 	return (int)ra->offset - (int)rb->offset;
 }
 
+static struct guc_mmio_reg * __must_check
+__mmio_reg_add(struct temp_regset *regset, struct guc_mmio_reg *reg)
+{
+	u32 pos = regset->storage_used;
+	struct guc_mmio_reg *slot;
+
+	if (pos >= regset->storage_max) {
+		size_t size = ALIGN((pos + 1) * sizeof(*slot), PAGE_SIZE);
+		struct guc_mmio_reg *r = krealloc(regset->storage,
+						  size, GFP_KERNEL);
+		if (!r) {
+			WARN_ONCE(1, "Incomplete regset list: can't add register (%d)\n",
+				  -ENOMEM);
+			return ERR_PTR(-ENOMEM);
+		}
+
+		regset->registers = r + (regset->registers - regset->storage);
+		regset->storage = r;
+		regset->storage_max = size / sizeof(*slot);
+	}
+
+	slot = &regset->storage[pos];
+	regset->storage_used++;
+	*slot = *reg;
+
+	return slot;
+}
+
 static long __must_check guc_mmio_reg_add(struct temp_regset *regset,
 					  u32 offset, u32 flags)
 {
-	u32 count = regset->used;
+	u32 count = regset->storage_used - (regset->registers - regset->storage);
 	struct guc_mmio_reg reg = {
 		.offset = offset,
 		.flags = flags,
 	};
 	struct guc_mmio_reg *slot;
 
-	GEM_BUG_ON(count >= regset->size);
-
 	/*
 	 * The mmio list is built using separate lists within the driver.
 	 * It's possible that at some point we may attempt to add the same
@@ -266,9 +296,9 @@ static long __must_check guc_mmio_reg_add(struct temp_regset *regset,
 		    sizeof(reg), guc_mmio_reg_cmp))
 		return 0;
 
-	slot = &regset->registers[count];
-	regset->used++;
-	*slot = reg;
+	slot = __mmio_reg_add(regset, &reg);
+	if (IS_ERR(slot))
+		return PTR_ERR(slot);
 
 	while (slot-- > regset->registers) {
 		GEM_BUG_ON(slot[0].offset == slot[1].offset);
@@ -295,7 +325,11 @@ static int guc_mmio_regset_init(struct temp_regset *regset,
 	unsigned int i;
 	int ret = 0;
 
-	regset->used = 0;
+	/*
+	 * Each engine's registers point to a new start relative to
+	 * storage
+	 */
+	regset->registers = regset->storage + regset->storage_used;
 
 	ret |= GUC_MMIO_REG_ADD(regset, RING_MODE_GEN7(base), true);
 	ret |= GUC_MMIO_REG_ADD(regset, RING_HWS_PGA(base), false);
@@ -317,34 +351,36 @@ static int guc_mmio_regset_init(struct temp_regset *regset,
 	return ret ? -1 : 0;
 }
 
-static int guc_mmio_reg_state_query(struct intel_guc *guc)
+static long guc_mmio_reg_state_create(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
-	struct temp_regset temp_set;
-	u32 total;
+	struct temp_regset temp_set = {};
+	long total = 0;
+	long ret;
 
-	/*
-	 * Need to actually build the list in order to filter out
-	 * duplicates and other such data dependent constructions.
-	 */
-	temp_set.size = MAX_MMIO_REGS;
-	temp_set.registers = kmalloc_array(temp_set.size,
-					   sizeof(*temp_set.registers),
-					   GFP_KERNEL);
-	if (!temp_set.registers)
-		return -ENOMEM;
-
-	total = 0;
 	for_each_engine(engine, gt, id) {
-		guc_mmio_regset_init(&temp_set, engine);
-		total += temp_set.used;
+		u32 used = temp_set.storage_used;
+
+		ret = guc_mmio_regset_init(&temp_set, engine);
+		if (ret < 0)
+			goto fail_regset_init;
+
+		guc->ads_regset_count[id] = temp_set.storage_used - used;
+		total += guc->ads_regset_count[id];
 	}
 
-	kfree(temp_set.registers);
+	guc->ads_regset = temp_set.storage;
+
+	drm_dbg(&guc_to_gt(guc)->i915->drm, "Used %zu KB for temporary ADS regset\n",
+		(temp_set.storage_max * sizeof(struct guc_mmio_reg)) >> 10);
 
 	return total * sizeof(struct guc_mmio_reg);
+
+fail_regset_init:
+	kfree(temp_set.storage);
+	return ret;
 }
 
 static void guc_mmio_reg_state_init(struct intel_guc *guc,
@@ -352,40 +388,38 @@ static void guc_mmio_reg_state_init(struct intel_guc *guc,
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct intel_engine_cs *engine;
+	struct guc_mmio_reg *ads_registers;
 	enum intel_engine_id id;
-	struct temp_regset temp_set;
-	struct guc_mmio_reg_set *ads_reg_set;
 	u32 addr_ggtt, offset;
-	u8 guc_class;
 
 	offset = guc_ads_regset_offset(guc);
 	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
-	temp_set.registers = (struct guc_mmio_reg *)(((u8 *)blob) + offset);
-	temp_set.size = guc->ads_regset_size / sizeof(temp_set.registers[0]);
+	ads_registers = (struct guc_mmio_reg *)(((u8 *)blob) + offset);
+
+	memcpy(ads_registers, guc->ads_regset, guc->ads_regset_size);
 
 	for_each_engine(engine, gt, id) {
+		u32 count = guc->ads_regset_count[id];
+		struct guc_mmio_reg_set *ads_reg_set;
+		u8 guc_class;
+
 		/* Class index is checked in class converter */
 		GEM_BUG_ON(engine->instance >= GUC_MAX_INSTANCES_PER_CLASS);
 
 		guc_class = engine_class_to_guc_class(engine->class);
 		ads_reg_set = &blob->ads.reg_state_list[guc_class][engine->instance];
 
-		guc_mmio_regset_init(&temp_set, engine);
-		if (!temp_set.used) {
+		if (!count) {
 			ads_reg_set->address = 0;
 			ads_reg_set->count = 0;
 			continue;
 		}
 
 		ads_reg_set->address = addr_ggtt;
-		ads_reg_set->count = temp_set.used;
+		ads_reg_set->count = count;
 
-		temp_set.size -= temp_set.used;
-		temp_set.registers += temp_set.used;
-		addr_ggtt += temp_set.used * sizeof(struct guc_mmio_reg);
+		addr_ggtt += count * sizeof(struct guc_mmio_reg);
 	}
-
-	GEM_BUG_ON(temp_set.size);
 }
 
 static void fill_engine_enable_masks(struct intel_gt *gt,
@@ -631,8 +665,11 @@ int intel_guc_ads_create(struct intel_guc *guc)
 
 	GEM_BUG_ON(guc->ads_vma);
 
-	/* Need to calculate the reg state size dynamically: */
-	ret = guc_mmio_reg_state_query(guc);
+	/*
+	 * Create reg state size dynamically on system memory to be copied to
+	 * the final ads blob on gt init/reset
+	 */
+	ret = guc_mmio_reg_state_create(guc);
 	if (ret < 0)
 		return ret;
 	guc->ads_regset_size = ret;
@@ -678,6 +715,7 @@ void intel_guc_ads_destroy(struct intel_guc *guc)
 	i915_vma_unpin_and_release(&guc->ads_vma, I915_VMA_RELEASE_MAP);
 	guc->ads_blob = NULL;
 	iosys_map_clear(&guc->ads_map);
+	kfree(guc->ads_regset);
 }
 
 static void guc_ads_private_data_reset(struct intel_guc *guc)
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 15/18] drm/i915/guc: Use a single pass to calculate regset
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

The ADS initialitazion was using 2 passes to calculate the regset sent
to GuC to initialize each engine: the first pass to just have the final
object size and the second to set each register in place in the final
gem object.

However in order to maintain an ordered set of registers to pass to guc,
each register needs to be added and moved in the final array. The second
phase may actually happen in IO memory rather than system memory and
accessing IO memory by simply dereferencing the pointer doesn't work on
all architectures. Other places of the ADS initializaition were
converted to use the iosys_map API, but here there may be a lot more
accesses to IO memory. So, instead of following that same approach,
convert the regset initialization to calculate the final array in 1
pass and in the second pass that array is just copied to its final
location, updating the pointers for each engine written to the ADS blob.

One important thing is that struct temp_regset now have
different semantics: `registers` continues to track the registers of a
single engine, however the other fields are updated together, according
to the newly added `storage`, which tracks the memory allocated for
all the registers. So rename some of these fields and add a
__mmio_reg_add(): this function (possibly) allocates memory and operates
on the storage pointer while guc_mmio_reg_add() continues to manage the
registers pointer.

On a Tiger Lake system using enable_guc=3, the following log message is
now seen:

	[  187.334310] i915 0000:00:02.0: [drm:intel_guc_ads_create [i915]] Used 4 KB for temporary ADS regset

This change has also been tested on an ARM64 host with DG2 and other
discrete graphics cards.

v2 (Daniele):
  - Fix leaking tempset on error path
  - Add comments on struct temp_regset to document the meaning of each
    field

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h     |   7 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 128 +++++++++++++--------
 2 files changed, 90 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 9b9ba79f7594..f857e9190750 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -152,6 +152,13 @@ struct intel_guc {
 	struct iosys_map ads_map;
 	/** @ads_regset_size: size of the save/restore regsets in the ADS */
 	u32 ads_regset_size;
+	/**
+	 * @ads_regset_count: number of save/restore registers in the ADS for
+	 * each engine
+	 */
+	u32 ads_regset_count[I915_NUM_ENGINES];
+	/** @ads_regset: save/restore regsets in the ADS */
+	struct guc_mmio_reg *ads_regset;
 	/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
 	u32 ads_golden_ctxt_size;
 	/** @ads_engine_usage_size: size of engine usage in the ADS */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 21e975d371e6..ec0ccdf98dfa 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -226,14 +226,18 @@ static void guc_mapping_table_init(struct intel_gt *gt,
 
 /*
  * The save/restore register list must be pre-calculated to a temporary
- * buffer of driver defined size before it can be generated in place
- * inside the ADS.
+ * buffer before it can be copied inside the ADS.
  */
-#define MAX_MMIO_REGS	128	/* Arbitrary size, increase as needed */
 struct temp_regset {
+	/*
+	 * ptr to the section of the storage for the engine currently being
+	 * worked on
+	 */
 	struct guc_mmio_reg *registers;
-	u32 used;
-	u32 size;
+	/* ptr to the base of the allocated storage for all engines */
+	struct guc_mmio_reg *storage;
+	u32 storage_used;
+	u32 storage_max;
 };
 
 static int guc_mmio_reg_cmp(const void *a, const void *b)
@@ -244,18 +248,44 @@ static int guc_mmio_reg_cmp(const void *a, const void *b)
 	return (int)ra->offset - (int)rb->offset;
 }
 
+static struct guc_mmio_reg * __must_check
+__mmio_reg_add(struct temp_regset *regset, struct guc_mmio_reg *reg)
+{
+	u32 pos = regset->storage_used;
+	struct guc_mmio_reg *slot;
+
+	if (pos >= regset->storage_max) {
+		size_t size = ALIGN((pos + 1) * sizeof(*slot), PAGE_SIZE);
+		struct guc_mmio_reg *r = krealloc(regset->storage,
+						  size, GFP_KERNEL);
+		if (!r) {
+			WARN_ONCE(1, "Incomplete regset list: can't add register (%d)\n",
+				  -ENOMEM);
+			return ERR_PTR(-ENOMEM);
+		}
+
+		regset->registers = r + (regset->registers - regset->storage);
+		regset->storage = r;
+		regset->storage_max = size / sizeof(*slot);
+	}
+
+	slot = &regset->storage[pos];
+	regset->storage_used++;
+	*slot = *reg;
+
+	return slot;
+}
+
 static long __must_check guc_mmio_reg_add(struct temp_regset *regset,
 					  u32 offset, u32 flags)
 {
-	u32 count = regset->used;
+	u32 count = regset->storage_used - (regset->registers - regset->storage);
 	struct guc_mmio_reg reg = {
 		.offset = offset,
 		.flags = flags,
 	};
 	struct guc_mmio_reg *slot;
 
-	GEM_BUG_ON(count >= regset->size);
-
 	/*
 	 * The mmio list is built using separate lists within the driver.
 	 * It's possible that at some point we may attempt to add the same
@@ -266,9 +296,9 @@ static long __must_check guc_mmio_reg_add(struct temp_regset *regset,
 		    sizeof(reg), guc_mmio_reg_cmp))
 		return 0;
 
-	slot = &regset->registers[count];
-	regset->used++;
-	*slot = reg;
+	slot = __mmio_reg_add(regset, &reg);
+	if (IS_ERR(slot))
+		return PTR_ERR(slot);
 
 	while (slot-- > regset->registers) {
 		GEM_BUG_ON(slot[0].offset == slot[1].offset);
@@ -295,7 +325,11 @@ static int guc_mmio_regset_init(struct temp_regset *regset,
 	unsigned int i;
 	int ret = 0;
 
-	regset->used = 0;
+	/*
+	 * Each engine's registers point to a new start relative to
+	 * storage
+	 */
+	regset->registers = regset->storage + regset->storage_used;
 
 	ret |= GUC_MMIO_REG_ADD(regset, RING_MODE_GEN7(base), true);
 	ret |= GUC_MMIO_REG_ADD(regset, RING_HWS_PGA(base), false);
@@ -317,34 +351,36 @@ static int guc_mmio_regset_init(struct temp_regset *regset,
 	return ret ? -1 : 0;
 }
 
-static int guc_mmio_reg_state_query(struct intel_guc *guc)
+static long guc_mmio_reg_state_create(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
-	struct temp_regset temp_set;
-	u32 total;
+	struct temp_regset temp_set = {};
+	long total = 0;
+	long ret;
 
-	/*
-	 * Need to actually build the list in order to filter out
-	 * duplicates and other such data dependent constructions.
-	 */
-	temp_set.size = MAX_MMIO_REGS;
-	temp_set.registers = kmalloc_array(temp_set.size,
-					   sizeof(*temp_set.registers),
-					   GFP_KERNEL);
-	if (!temp_set.registers)
-		return -ENOMEM;
-
-	total = 0;
 	for_each_engine(engine, gt, id) {
-		guc_mmio_regset_init(&temp_set, engine);
-		total += temp_set.used;
+		u32 used = temp_set.storage_used;
+
+		ret = guc_mmio_regset_init(&temp_set, engine);
+		if (ret < 0)
+			goto fail_regset_init;
+
+		guc->ads_regset_count[id] = temp_set.storage_used - used;
+		total += guc->ads_regset_count[id];
 	}
 
-	kfree(temp_set.registers);
+	guc->ads_regset = temp_set.storage;
+
+	drm_dbg(&guc_to_gt(guc)->i915->drm, "Used %zu KB for temporary ADS regset\n",
+		(temp_set.storage_max * sizeof(struct guc_mmio_reg)) >> 10);
 
 	return total * sizeof(struct guc_mmio_reg);
+
+fail_regset_init:
+	kfree(temp_set.storage);
+	return ret;
 }
 
 static void guc_mmio_reg_state_init(struct intel_guc *guc,
@@ -352,40 +388,38 @@ static void guc_mmio_reg_state_init(struct intel_guc *guc,
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct intel_engine_cs *engine;
+	struct guc_mmio_reg *ads_registers;
 	enum intel_engine_id id;
-	struct temp_regset temp_set;
-	struct guc_mmio_reg_set *ads_reg_set;
 	u32 addr_ggtt, offset;
-	u8 guc_class;
 
 	offset = guc_ads_regset_offset(guc);
 	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
-	temp_set.registers = (struct guc_mmio_reg *)(((u8 *)blob) + offset);
-	temp_set.size = guc->ads_regset_size / sizeof(temp_set.registers[0]);
+	ads_registers = (struct guc_mmio_reg *)(((u8 *)blob) + offset);
+
+	memcpy(ads_registers, guc->ads_regset, guc->ads_regset_size);
 
 	for_each_engine(engine, gt, id) {
+		u32 count = guc->ads_regset_count[id];
+		struct guc_mmio_reg_set *ads_reg_set;
+		u8 guc_class;
+
 		/* Class index is checked in class converter */
 		GEM_BUG_ON(engine->instance >= GUC_MAX_INSTANCES_PER_CLASS);
 
 		guc_class = engine_class_to_guc_class(engine->class);
 		ads_reg_set = &blob->ads.reg_state_list[guc_class][engine->instance];
 
-		guc_mmio_regset_init(&temp_set, engine);
-		if (!temp_set.used) {
+		if (!count) {
 			ads_reg_set->address = 0;
 			ads_reg_set->count = 0;
 			continue;
 		}
 
 		ads_reg_set->address = addr_ggtt;
-		ads_reg_set->count = temp_set.used;
+		ads_reg_set->count = count;
 
-		temp_set.size -= temp_set.used;
-		temp_set.registers += temp_set.used;
-		addr_ggtt += temp_set.used * sizeof(struct guc_mmio_reg);
+		addr_ggtt += count * sizeof(struct guc_mmio_reg);
 	}
-
-	GEM_BUG_ON(temp_set.size);
 }
 
 static void fill_engine_enable_masks(struct intel_gt *gt,
@@ -631,8 +665,11 @@ int intel_guc_ads_create(struct intel_guc *guc)
 
 	GEM_BUG_ON(guc->ads_vma);
 
-	/* Need to calculate the reg state size dynamically: */
-	ret = guc_mmio_reg_state_query(guc);
+	/*
+	 * Create reg state size dynamically on system memory to be copied to
+	 * the final ads blob on gt init/reset
+	 */
+	ret = guc_mmio_reg_state_create(guc);
 	if (ret < 0)
 		return ret;
 	guc->ads_regset_size = ret;
@@ -678,6 +715,7 @@ void intel_guc_ads_destroy(struct intel_guc *guc)
 	i915_vma_unpin_and_release(&guc->ads_vma, I915_VMA_RELEASE_MAP);
 	guc->ads_blob = NULL;
 	iosys_map_clear(&guc->ads_map);
+	kfree(guc->ads_regset);
 }
 
 static void guc_ads_private_data_reset(struct intel_guc *guc)
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 16/18] drm/i915/guc: Convert guc_mmio_reg_state_init to iosys_map
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Now that the regset list is prepared, convert guc_mmio_reg_state_init()
to use iosys_map to copy the array to the final location and
initialize additional fields in ads.reg_state_list.

v2: Just use an offset instead of temporary iosys_map.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 28 ++++++++++++----------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index ec0ccdf98dfa..90cbb93a2945 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -383,40 +383,44 @@ static long guc_mmio_reg_state_create(struct intel_guc *guc)
 	return ret;
 }
 
-static void guc_mmio_reg_state_init(struct intel_guc *guc,
-				    struct __guc_ads_blob *blob)
+static void guc_mmio_reg_state_init(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct intel_engine_cs *engine;
-	struct guc_mmio_reg *ads_registers;
 	enum intel_engine_id id;
 	u32 addr_ggtt, offset;
 
 	offset = guc_ads_regset_offset(guc);
 	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
-	ads_registers = (struct guc_mmio_reg *)(((u8 *)blob) + offset);
 
-	memcpy(ads_registers, guc->ads_regset, guc->ads_regset_size);
+	iosys_map_memcpy_to(&guc->ads_map, offset, guc->ads_regset,
+			    guc->ads_regset_size);
 
 	for_each_engine(engine, gt, id) {
 		u32 count = guc->ads_regset_count[id];
-		struct guc_mmio_reg_set *ads_reg_set;
 		u8 guc_class;
 
 		/* Class index is checked in class converter */
 		GEM_BUG_ON(engine->instance >= GUC_MAX_INSTANCES_PER_CLASS);
 
 		guc_class = engine_class_to_guc_class(engine->class);
-		ads_reg_set = &blob->ads.reg_state_list[guc_class][engine->instance];
 
 		if (!count) {
-			ads_reg_set->address = 0;
-			ads_reg_set->count = 0;
+			ads_blob_write(guc,
+				       ads.reg_state_list[guc_class][engine->instance].address,
+				       0);
+			ads_blob_write(guc,
+				       ads.reg_state_list[guc_class][engine->instance].count,
+				       0);
 			continue;
 		}
 
-		ads_reg_set->address = addr_ggtt;
-		ads_reg_set->count = count;
+		ads_blob_write(guc,
+			       ads.reg_state_list[guc_class][engine->instance].address,
+			       addr_ggtt);
+		ads_blob_write(guc,
+			       ads.reg_state_list[guc_class][engine->instance].count,
+			       count);
 
 		addr_ggtt += count * sizeof(struct guc_mmio_reg);
 	}
@@ -643,7 +647,7 @@ static void __guc_ads_init(struct intel_guc *guc)
 	blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
 
 	/* MMIO save/restore list */
-	guc_mmio_reg_state_init(guc, blob);
+	guc_mmio_reg_state_init(guc);
 
 	/* Private Data */
 	blob->ads.private_data = base + guc_ads_private_data_offset(guc);
-- 
2.35.1


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

* [PATCH v2 16/18] drm/i915/guc: Convert guc_mmio_reg_state_init to iosys_map
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Now that the regset list is prepared, convert guc_mmio_reg_state_init()
to use iosys_map to copy the array to the final location and
initialize additional fields in ads.reg_state_list.

v2: Just use an offset instead of temporary iosys_map.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 28 ++++++++++++----------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index ec0ccdf98dfa..90cbb93a2945 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -383,40 +383,44 @@ static long guc_mmio_reg_state_create(struct intel_guc *guc)
 	return ret;
 }
 
-static void guc_mmio_reg_state_init(struct intel_guc *guc,
-				    struct __guc_ads_blob *blob)
+static void guc_mmio_reg_state_init(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct intel_engine_cs *engine;
-	struct guc_mmio_reg *ads_registers;
 	enum intel_engine_id id;
 	u32 addr_ggtt, offset;
 
 	offset = guc_ads_regset_offset(guc);
 	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
-	ads_registers = (struct guc_mmio_reg *)(((u8 *)blob) + offset);
 
-	memcpy(ads_registers, guc->ads_regset, guc->ads_regset_size);
+	iosys_map_memcpy_to(&guc->ads_map, offset, guc->ads_regset,
+			    guc->ads_regset_size);
 
 	for_each_engine(engine, gt, id) {
 		u32 count = guc->ads_regset_count[id];
-		struct guc_mmio_reg_set *ads_reg_set;
 		u8 guc_class;
 
 		/* Class index is checked in class converter */
 		GEM_BUG_ON(engine->instance >= GUC_MAX_INSTANCES_PER_CLASS);
 
 		guc_class = engine_class_to_guc_class(engine->class);
-		ads_reg_set = &blob->ads.reg_state_list[guc_class][engine->instance];
 
 		if (!count) {
-			ads_reg_set->address = 0;
-			ads_reg_set->count = 0;
+			ads_blob_write(guc,
+				       ads.reg_state_list[guc_class][engine->instance].address,
+				       0);
+			ads_blob_write(guc,
+				       ads.reg_state_list[guc_class][engine->instance].count,
+				       0);
 			continue;
 		}
 
-		ads_reg_set->address = addr_ggtt;
-		ads_reg_set->count = count;
+		ads_blob_write(guc,
+			       ads.reg_state_list[guc_class][engine->instance].address,
+			       addr_ggtt);
+		ads_blob_write(guc,
+			       ads.reg_state_list[guc_class][engine->instance].count,
+			       count);
 
 		addr_ggtt += count * sizeof(struct guc_mmio_reg);
 	}
@@ -643,7 +647,7 @@ static void __guc_ads_init(struct intel_guc *guc)
 	blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
 
 	/* MMIO save/restore list */
-	guc_mmio_reg_state_init(guc, blob);
+	guc_mmio_reg_state_init(guc);
 
 	/* Private Data */
 	blob->ads.private_data = base + guc_ads_private_data_offset(guc);
-- 
2.35.1


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

* [PATCH v2 17/18] drm/i915/guc: Convert __guc_ads_init to iosys_map
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Now that all the called functions from __guc_ads_init() are converted to
use ads_map, stop using ads_blob in __guc_ads_init().

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 25 ++++++++++++----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 90cbb93a2945..d0593063c0dc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -608,7 +608,6 @@ static void __guc_ads_init(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct drm_i915_private *i915 = gt->i915;
-	struct __guc_ads_blob *blob = guc->ads_blob;
 	struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(&guc->ads_map,
 			offsetof(struct __guc_ads_blob, system_info));
 	u32 base;
@@ -619,17 +618,18 @@ static void __guc_ads_init(struct intel_guc *guc)
 	/* System info */
 	fill_engine_enable_masks(gt, &info_map);
 
-	blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED] =
-		hweight8(gt->info.sseu.slice_mask);
-	blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK] =
-		gt->info.vdbox_sfc_access;
+	ads_blob_write(guc, system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED],
+		       hweight8(gt->info.sseu.slice_mask));
+	ads_blob_write(guc, system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK],
+		       gt->info.vdbox_sfc_access);
 
 	if (GRAPHICS_VER(i915) >= 12 && !IS_DGFX(i915)) {
 		u32 distdbreg = intel_uncore_read(gt->uncore,
 						  GEN12_DIST_DBS_POPULATED);
-		blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI] =
-			((distdbreg >> GEN12_DOORBELLS_PER_SQIDI_SHIFT) &
-			 GEN12_DOORBELLS_PER_SQIDI) + 1;
+		ads_blob_write(guc,
+			       system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI],
+			       ((distdbreg >> GEN12_DOORBELLS_PER_SQIDI_SHIFT)
+				& GEN12_DOORBELLS_PER_SQIDI) + 1);
 	}
 
 	/* Golden contexts for re-initialising after a watchdog reset */
@@ -643,14 +643,17 @@ static void __guc_ads_init(struct intel_guc *guc)
 	guc_capture_list_init(guc);
 
 	/* ADS */
-	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
-	blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
+	ads_blob_write(guc, ads.scheduler_policies, base +
+		       offsetof(struct __guc_ads_blob, policies));
+	ads_blob_write(guc, ads.gt_system_info, base +
+		       offsetof(struct __guc_ads_blob, system_info));
 
 	/* MMIO save/restore list */
 	guc_mmio_reg_state_init(guc);
 
 	/* Private Data */
-	blob->ads.private_data = base + guc_ads_private_data_offset(guc);
+	ads_blob_write(guc, ads.private_data, base +
+		       guc_ads_private_data_offset(guc));
 
 	i915_gem_object_flush_map(guc->ads_vma->obj);
 }
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 17/18] drm/i915/guc: Convert __guc_ads_init to iosys_map
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Now that all the called functions from __guc_ads_init() are converted to
use ads_map, stop using ads_blob in __guc_ads_init().

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 25 ++++++++++++----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 90cbb93a2945..d0593063c0dc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -608,7 +608,6 @@ static void __guc_ads_init(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
 	struct drm_i915_private *i915 = gt->i915;
-	struct __guc_ads_blob *blob = guc->ads_blob;
 	struct iosys_map info_map = IOSYS_MAP_INIT_OFFSET(&guc->ads_map,
 			offsetof(struct __guc_ads_blob, system_info));
 	u32 base;
@@ -619,17 +618,18 @@ static void __guc_ads_init(struct intel_guc *guc)
 	/* System info */
 	fill_engine_enable_masks(gt, &info_map);
 
-	blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED] =
-		hweight8(gt->info.sseu.slice_mask);
-	blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK] =
-		gt->info.vdbox_sfc_access;
+	ads_blob_write(guc, system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED],
+		       hweight8(gt->info.sseu.slice_mask));
+	ads_blob_write(guc, system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK],
+		       gt->info.vdbox_sfc_access);
 
 	if (GRAPHICS_VER(i915) >= 12 && !IS_DGFX(i915)) {
 		u32 distdbreg = intel_uncore_read(gt->uncore,
 						  GEN12_DIST_DBS_POPULATED);
-		blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI] =
-			((distdbreg >> GEN12_DOORBELLS_PER_SQIDI_SHIFT) &
-			 GEN12_DOORBELLS_PER_SQIDI) + 1;
+		ads_blob_write(guc,
+			       system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI],
+			       ((distdbreg >> GEN12_DOORBELLS_PER_SQIDI_SHIFT)
+				& GEN12_DOORBELLS_PER_SQIDI) + 1);
 	}
 
 	/* Golden contexts for re-initialising after a watchdog reset */
@@ -643,14 +643,17 @@ static void __guc_ads_init(struct intel_guc *guc)
 	guc_capture_list_init(guc);
 
 	/* ADS */
-	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
-	blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
+	ads_blob_write(guc, ads.scheduler_policies, base +
+		       offsetof(struct __guc_ads_blob, policies));
+	ads_blob_write(guc, ads.gt_system_info, base +
+		       offsetof(struct __guc_ads_blob, system_info));
 
 	/* MMIO save/restore list */
 	guc_mmio_reg_state_init(guc);
 
 	/* Private Data */
-	blob->ads.private_data = base + guc_ads_private_data_offset(guc);
+	ads_blob_write(guc, ads.private_data, base +
+		       guc_ads_private_data_offset(guc));
 
 	i915_gem_object_flush_map(guc->ads_vma->obj);
 }
-- 
2.35.1


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

* [PATCH v2 18/18] drm/i915/guc: Remove plain ads_blob pointer
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-08 10:45   ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, Lucas De Marchi,
	Daniele Ceraolo Spurio, Thomas Zimmermann, Christian König,
	John Harrison

Now we have the access to content of GuC ADS either using iosys_map
API or using a temporary buffer. Remove guc->ads_blob as there shouldn't
be updates using the bare pointer anymore.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h     | 3 +--
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 8 ++++----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index f857e9190750..bf7079480d47 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -147,8 +147,7 @@ struct intel_guc {
 
 	/** @ads_vma: object allocated to hold the GuC ADS */
 	struct i915_vma *ads_vma;
-	/** @ads_blob: contents of the GuC ADS */
-	struct __guc_ads_blob *ads_blob;
+	/** @ads_map: contents of the GuC ADS */
 	struct iosys_map ads_map;
 	/** @ads_regset_size: size of the save/restore regsets in the ADS */
 	u32 ads_regset_size;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index d0593063c0dc..847e00390b00 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -667,6 +667,7 @@ static void __guc_ads_init(struct intel_guc *guc)
  */
 int intel_guc_ads_create(struct intel_guc *guc)
 {
+	void *ads_blob;
 	u32 size;
 	int ret;
 
@@ -691,14 +692,14 @@ int intel_guc_ads_create(struct intel_guc *guc)
 	size = guc_ads_blob_size(guc);
 
 	ret = intel_guc_allocate_and_map_vma(guc, size, &guc->ads_vma,
-					     (void **)&guc->ads_blob);
+					     &ads_blob);
 	if (ret)
 		return ret;
 
 	if (i915_gem_object_is_lmem(guc->ads_vma->obj))
-		iosys_map_set_vaddr_iomem(&guc->ads_map, (void __iomem *)guc->ads_blob);
+		iosys_map_set_vaddr_iomem(&guc->ads_map, (void __iomem *)ads_blob);
 	else
-		iosys_map_set_vaddr(&guc->ads_map, guc->ads_blob);
+		iosys_map_set_vaddr(&guc->ads_map, ads_blob);
 
 	__guc_ads_init(guc);
 
@@ -720,7 +721,6 @@ void intel_guc_ads_init_late(struct intel_guc *guc)
 void intel_guc_ads_destroy(struct intel_guc *guc)
 {
 	i915_vma_unpin_and_release(&guc->ads_vma, I915_VMA_RELEASE_MAP);
-	guc->ads_blob = NULL;
 	iosys_map_clear(&guc->ads_map);
 	kfree(guc->ads_regset);
 }
-- 
2.35.1


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

* [Intel-gfx] [PATCH v2 18/18] drm/i915/guc: Remove plain ads_blob pointer
@ 2022-02-08 10:45   ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-08 10:45 UTC (permalink / raw)
  To: intel-gfx, dri-devel
  Cc: Thomas Hellström, Lucas De Marchi, Sumit Semwal,
	Thomas Zimmermann, Christian König

Now we have the access to content of GuC ADS either using iosys_map
API or using a temporary buffer. Remove guc->ads_blob as there shouldn't
be updates using the bare pointer anymore.

Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h     | 3 +--
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 8 ++++----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index f857e9190750..bf7079480d47 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -147,8 +147,7 @@ struct intel_guc {
 
 	/** @ads_vma: object allocated to hold the GuC ADS */
 	struct i915_vma *ads_vma;
-	/** @ads_blob: contents of the GuC ADS */
-	struct __guc_ads_blob *ads_blob;
+	/** @ads_map: contents of the GuC ADS */
 	struct iosys_map ads_map;
 	/** @ads_regset_size: size of the save/restore regsets in the ADS */
 	u32 ads_regset_size;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index d0593063c0dc..847e00390b00 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -667,6 +667,7 @@ static void __guc_ads_init(struct intel_guc *guc)
  */
 int intel_guc_ads_create(struct intel_guc *guc)
 {
+	void *ads_blob;
 	u32 size;
 	int ret;
 
@@ -691,14 +692,14 @@ int intel_guc_ads_create(struct intel_guc *guc)
 	size = guc_ads_blob_size(guc);
 
 	ret = intel_guc_allocate_and_map_vma(guc, size, &guc->ads_vma,
-					     (void **)&guc->ads_blob);
+					     &ads_blob);
 	if (ret)
 		return ret;
 
 	if (i915_gem_object_is_lmem(guc->ads_vma->obj))
-		iosys_map_set_vaddr_iomem(&guc->ads_map, (void __iomem *)guc->ads_blob);
+		iosys_map_set_vaddr_iomem(&guc->ads_map, (void __iomem *)ads_blob);
 	else
-		iosys_map_set_vaddr(&guc->ads_map, guc->ads_blob);
+		iosys_map_set_vaddr(&guc->ads_map, ads_blob);
 
 	__guc_ads_init(guc);
 
@@ -720,7 +721,6 @@ void intel_guc_ads_init_late(struct intel_guc *guc)
 void intel_guc_ads_destroy(struct intel_guc *guc)
 {
 	i915_vma_unpin_and_release(&guc->ads_vma, I915_VMA_RELEASE_MAP);
-	guc->ads_blob = NULL;
 	iosys_map_clear(&guc->ads_map);
 	kfree(guc->ads_regset);
 }
-- 
2.35.1


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

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/guc: Refactor ADS access to use iosys_map (rev2)
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
                   ` (18 preceding siblings ...)
  (?)
@ 2022-02-08 11:18 ` Patchwork
  -1 siblings, 0 replies; 59+ messages in thread
From: Patchwork @ 2022-02-08 11:18 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/guc: Refactor ADS access to use iosys_map (rev2)
URL   : https://patchwork.freedesktop.org/series/99711/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
80cfc4e5862f iosys-map: Add offset to iosys_map_memcpy_to()
2997557ba29b iosys-map: Add a few more helpers
-:106: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'map_' may be better as '(map_)' to avoid precedence issues
#106: FILE: include/linux/iosys-map.h:157:
+#define IOSYS_MAP_INIT_OFFSET(map_, offset_) ({				\
+	struct iosys_map copy = *map_;					\
+	iosys_map_incr(&copy, offset_);					\
+	copy;								\
+})

-:261: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'struct_offset__' may be better as '(struct_offset__)' to avoid precedence issues
#261: FILE: include/linux/iosys-map.h:433:
+#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
+	struct_type__ *s;							\
+	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
+		     typeof(s->field__));					\
+})

-:261: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'struct_type__' may be better as '(struct_type__)' to avoid precedence issues
#261: FILE: include/linux/iosys-map.h:433:
+#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
+	struct_type__ *s;							\
+	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
+		     typeof(s->field__));					\
+})

-:261: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'field__' - possible side-effects?
#261: FILE: include/linux/iosys-map.h:433:
+#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
+	struct_type__ *s;							\
+	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
+		     typeof(s->field__));					\
+})

-:282: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'struct_offset__' may be better as '(struct_offset__)' to avoid precedence issues
#282: FILE: include/linux/iosys-map.h:454:
+#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
+	struct_type__ *s;								\
+	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
+		     typeof(s->field__), val__);					\
+})

-:282: CHECK:MACRO_ARG_PRECEDENCE: Macro argument 'struct_type__' may be better as '(struct_type__)' to avoid precedence issues
#282: FILE: include/linux/iosys-map.h:454:
+#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
+	struct_type__ *s;								\
+	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
+		     typeof(s->field__), val__);					\
+})

-:282: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'field__' - possible side-effects?
#282: FILE: include/linux/iosys-map.h:454:
+#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
+	struct_type__ *s;								\
+	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
+		     typeof(s->field__), val__);					\
+})

total: 0 errors, 0 warnings, 7 checks, 224 lines checked
342e2b55298e drm/i915/gt: Add helper for shmem copy to iosys_map
75652221ece7 drm/i915/guc: Keep iosys_map of ads_blob around
e909c8680cf3 drm/i915/guc: Add read/write helpers for ADS blob
3f919b8d697b drm/i915/guc: Convert golden context init to iosys_map
dab9247a24d0 drm/i915/guc: Convert policies update to iosys_map
46fcb66d43f0 drm/i915/guc: Convert engine record to iosys_map
2edec322d581 drm/i915/guc: Convert guc_ads_private_data_reset to iosys_map
550662116c5a drm/i915/guc: Convert golden context prep to iosys_map
ceddc2cf4b84 drm/i915/guc: Replace check for golden context size
658eb1647538 drm/i915/guc: Convert mapping table to iosys_map
91176455914b drm/i915/guc: Convert capture list to iosys_map
4c99355845f0 drm/i915/guc: Prepare for error propagation
a65c1205676e drm/i915/guc: Use a single pass to calculate regset
67c37ac3868b drm/i915/guc: Convert guc_mmio_reg_state_init to iosys_map
ff9c86ae5eea drm/i915/guc: Convert __guc_ads_init to iosys_map
-:42: WARNING:LONG_LINE: line length of 106 exceeds 100 columns
#42: FILE: drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c:623:
+	ads_blob_write(guc, system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK],

-:52: WARNING:LONG_LINE: line length of 111 exceeds 100 columns
#52: FILE: drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c:630:
+			       system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI],

total: 0 errors, 2 warnings, 0 checks, 52 lines checked
692f09e09c1c drm/i915/guc: Remove plain ads_blob pointer



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

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/i915/guc: Refactor ADS access to use iosys_map (rev2)
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
                   ` (19 preceding siblings ...)
  (?)
@ 2022-02-08 11:20 ` Patchwork
  -1 siblings, 0 replies; 59+ messages in thread
From: Patchwork @ 2022-02-08 11:20 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/guc: Refactor ADS access to use iosys_map (rev2)
URL   : https://patchwork.freedesktop.org/series/99711/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.



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

* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915/guc: Refactor ADS access to use iosys_map (rev2)
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
                   ` (20 preceding siblings ...)
  (?)
@ 2022-02-08 11:50 ` Patchwork
  -1 siblings, 0 replies; 59+ messages in thread
From: Patchwork @ 2022-02-08 11:50 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 12950 bytes --]

== Series Details ==

Series: drm/i915/guc: Refactor ADS access to use iosys_map (rev2)
URL   : https://patchwork.freedesktop.org/series/99711/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_11200 -> Patchwork_22201
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/index.html

Participating hosts (42 -> 43)
------------------------------

  Additional (3): fi-kbl-soraka bat-jsl-2 bat-dg1-5 
  Missing    (2): shard-rkl shard-tglu 

Known issues
------------

  Here are the changes found in Patchwork_22201 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@amdgpu/amd_cs_nop@fork-compute0:
    - fi-blb-e6850:       NOTRUN -> [SKIP][1] ([fdo#109271]) +17 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-blb-e6850/igt@amdgpu/amd_cs_nop@fork-compute0.html

  * igt@gem_exec_fence@basic-busy@bcs0:
    - fi-kbl-soraka:      NOTRUN -> [SKIP][2] ([fdo#109271]) +8 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-kbl-soraka/igt@gem_exec_fence@basic-busy@bcs0.html

  * igt@gem_exec_gttfill@basic:
    - bat-dg1-5:          NOTRUN -> [SKIP][3] ([i915#4086])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@gem_exec_gttfill@basic.html

  * igt@gem_exec_suspend@basic-s3@smem:
    - fi-bdw-5557u:       [PASS][4] -> [INCOMPLETE][5] ([i915#146])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/fi-bdw-5557u/igt@gem_exec_suspend@basic-s3@smem.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-bdw-5557u/igt@gem_exec_suspend@basic-s3@smem.html

  * igt@gem_flink_basic@bad-flink:
    - fi-skl-6600u:       NOTRUN -> [INCOMPLETE][6] ([i915#4547])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-skl-6600u/igt@gem_flink_basic@bad-flink.html

  * igt@gem_huc_copy@huc-copy:
    - fi-kbl-soraka:      NOTRUN -> [SKIP][7] ([fdo#109271] / [i915#2190])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-kbl-soraka/igt@gem_huc_copy@huc-copy.html

  * igt@gem_lmem_swapping@parallel-random-engines:
    - fi-kbl-soraka:      NOTRUN -> [SKIP][8] ([fdo#109271] / [i915#4613]) +3 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-kbl-soraka/igt@gem_lmem_swapping@parallel-random-engines.html

  * igt@gem_mmap@basic:
    - bat-dg1-5:          NOTRUN -> [SKIP][9] ([i915#4083])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@gem_mmap@basic.html

  * igt@gem_mmap_gtt@basic:
    - bat-dg1-5:          NOTRUN -> [SKIP][10] ([i915#4077]) +2 similar issues
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@gem_mmap_gtt@basic.html

  * igt@gem_tiled_pread_basic:
    - bat-dg1-5:          NOTRUN -> [SKIP][11] ([i915#4079]) +1 similar issue
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@gem_tiled_pread_basic.html

  * igt@i915_pm_backlight@basic-brightness:
    - bat-dg1-5:          NOTRUN -> [SKIP][12] ([i915#1155])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@i915_pm_backlight@basic-brightness.html

  * igt@i915_selftest@live@gt_pm:
    - fi-kbl-soraka:      NOTRUN -> [DMESG-FAIL][13] ([i915#1886] / [i915#2291])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-kbl-soraka/igt@i915_selftest@live@gt_pm.html

  * igt@i915_selftest@live@hangcheck:
    - bat-dg1-5:          NOTRUN -> [DMESG-FAIL][14] ([i915#4494] / [i915#4957])
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@i915_selftest@live@hangcheck.html
    - fi-hsw-4770:        [PASS][15] -> [INCOMPLETE][16] ([i915#4785])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/fi-hsw-4770/igt@i915_selftest@live@hangcheck.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-hsw-4770/igt@i915_selftest@live@hangcheck.html

  * igt@kms_addfb_basic@basic-y-tiled-legacy:
    - bat-dg1-5:          NOTRUN -> [SKIP][17] ([i915#4215])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@kms_addfb_basic@basic-y-tiled-legacy.html

  * igt@kms_addfb_basic@tile-pitch-mismatch:
    - bat-dg1-5:          NOTRUN -> [SKIP][18] ([i915#4212]) +7 similar issues
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@kms_addfb_basic@tile-pitch-mismatch.html

  * igt@kms_chamelium@dp-edid-read:
    - fi-kbl-soraka:      NOTRUN -> [SKIP][19] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-kbl-soraka/igt@kms_chamelium@dp-edid-read.html

  * igt@kms_chamelium@dp-hpd-fast:
    - bat-dg1-5:          NOTRUN -> [SKIP][20] ([fdo#111827]) +8 similar issues
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@kms_chamelium@dp-hpd-fast.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - bat-dg1-5:          NOTRUN -> [SKIP][21] ([i915#4103] / [i915#4213]) +1 similar issue
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_force_connector_basic@force-load-detect:
    - bat-dg1-5:          NOTRUN -> [SKIP][22] ([fdo#109285])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d:
    - fi-kbl-soraka:      NOTRUN -> [SKIP][23] ([fdo#109271] / [i915#533])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-kbl-soraka/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html

  * igt@kms_psr@primary_page_flip:
    - bat-dg1-5:          NOTRUN -> [SKIP][24] ([i915#1072] / [i915#4078]) +3 similar issues
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@kms_psr@primary_page_flip.html

  * igt@prime_vgem@basic-fence-flip:
    - bat-dg1-5:          NOTRUN -> [SKIP][25] ([i915#3708]) +3 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@prime_vgem@basic-fence-flip.html

  * igt@prime_vgem@basic-fence-mmap:
    - bat-dg1-5:          NOTRUN -> [SKIP][26] ([i915#3708] / [i915#4077]) +1 similar issue
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@prime_vgem@basic-fence-mmap.html

  * igt@prime_vgem@basic-userptr:
    - bat-dg1-5:          NOTRUN -> [SKIP][27] ([i915#3708] / [i915#4873])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-5/igt@prime_vgem@basic-userptr.html

  * igt@runner@aborted:
    - fi-hsw-4770:        NOTRUN -> [FAIL][28] ([fdo#109271] / [i915#1436] / [i915#4312])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-hsw-4770/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s3@smem:
    - fi-skl-6600u:       [INCOMPLETE][29] ([i915#4547]) -> [PASS][30]
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/fi-skl-6600u/igt@gem_exec_suspend@basic-s3@smem.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-skl-6600u/igt@gem_exec_suspend@basic-s3@smem.html

  * igt@i915_selftest@live@hangcheck:
    - bat-dg1-6:          [DMESG-FAIL][31] ([i915#4494] / [i915#4957]) -> [PASS][32]
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/bat-dg1-6/igt@i915_selftest@live@hangcheck.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/bat-dg1-6/igt@i915_selftest@live@hangcheck.html

  * igt@i915_selftest@live@requests:
    - fi-blb-e6850:       [DMESG-FAIL][33] ([i915#4528] / [i915#5026]) -> [PASS][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/fi-blb-e6850/igt@i915_selftest@live@requests.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-blb-e6850/igt@i915_selftest@live@requests.html

  * igt@kms_frontbuffer_tracking@basic:
    - fi-cml-u2:          [DMESG-WARN][35] ([i915#4269]) -> [PASS][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/fi-cml-u2/igt@kms_frontbuffer_tracking@basic.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-cml-u2/igt@kms_frontbuffer_tracking@basic.html

  
#### Warnings ####

  * igt@runner@aborted:
    - fi-skl-6600u:       [FAIL][37] ([i915#4312]) -> [FAIL][38] ([i915#2722] / [i915#4312])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/fi-skl-6600u/igt@runner@aborted.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/fi-skl-6600u/igt@runner@aborted.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
  [i915#1155]: https://gitlab.freedesktop.org/drm/intel/issues/1155
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#146]: https://gitlab.freedesktop.org/drm/intel/issues/146
  [i915#1886]: https://gitlab.freedesktop.org/drm/intel/issues/1886
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#2291]: https://gitlab.freedesktop.org/drm/intel/issues/2291
  [i915#2582]: https://gitlab.freedesktop.org/drm/intel/issues/2582
  [i915#2722]: https://gitlab.freedesktop.org/drm/intel/issues/2722
  [i915#3301]: https://gitlab.freedesktop.org/drm/intel/issues/3301
  [i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
  [i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
  [i915#4078]: https://gitlab.freedesktop.org/drm/intel/issues/4078
  [i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
  [i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
  [i915#4086]: https://gitlab.freedesktop.org/drm/intel/issues/4086
  [i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
  [i915#4212]: https://gitlab.freedesktop.org/drm/intel/issues/4212
  [i915#4213]: https://gitlab.freedesktop.org/drm/intel/issues/4213
  [i915#4215]: https://gitlab.freedesktop.org/drm/intel/issues/4215
  [i915#4269]: https://gitlab.freedesktop.org/drm/intel/issues/4269
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4494]: https://gitlab.freedesktop.org/drm/intel/issues/4494
  [i915#4528]: https://gitlab.freedesktop.org/drm/intel/issues/4528
  [i915#4547]: https://gitlab.freedesktop.org/drm/intel/issues/4547
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4785]: https://gitlab.freedesktop.org/drm/intel/issues/4785
  [i915#4873]: https://gitlab.freedesktop.org/drm/intel/issues/4873
  [i915#4898]: https://gitlab.freedesktop.org/drm/intel/issues/4898
  [i915#4957]: https://gitlab.freedesktop.org/drm/intel/issues/4957
  [i915#5026]: https://gitlab.freedesktop.org/drm/intel/issues/5026
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533


Build changes
-------------

  * Linux: CI_DRM_11200 -> Patchwork_22201

  CI-20190529: 20190529
  CI_DRM_11200: a82048d804ae32de6e00da56d2c74e449d486738 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6341: a96674e747ea2f2431bbf8813156adc44ec3162a @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_22201: 692f09e09c1c011a27e4987c422fbfbcac7e79ad @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

692f09e09c1c drm/i915/guc: Remove plain ads_blob pointer
ff9c86ae5eea drm/i915/guc: Convert __guc_ads_init to iosys_map
67c37ac3868b drm/i915/guc: Convert guc_mmio_reg_state_init to iosys_map
a65c1205676e drm/i915/guc: Use a single pass to calculate regset
4c99355845f0 drm/i915/guc: Prepare for error propagation
91176455914b drm/i915/guc: Convert capture list to iosys_map
658eb1647538 drm/i915/guc: Convert mapping table to iosys_map
ceddc2cf4b84 drm/i915/guc: Replace check for golden context size
550662116c5a drm/i915/guc: Convert golden context prep to iosys_map
2edec322d581 drm/i915/guc: Convert guc_ads_private_data_reset to iosys_map
46fcb66d43f0 drm/i915/guc: Convert engine record to iosys_map
dab9247a24d0 drm/i915/guc: Convert policies update to iosys_map
3f919b8d697b drm/i915/guc: Convert golden context init to iosys_map
e909c8680cf3 drm/i915/guc: Add read/write helpers for ADS blob
75652221ece7 drm/i915/guc: Keep iosys_map of ads_blob around
342e2b55298e drm/i915/gt: Add helper for shmem copy to iosys_map
2997557ba29b iosys-map: Add a few more helpers
80cfc4e5862f iosys-map: Add offset to iosys_map_memcpy_to()

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/index.html

[-- Attachment #2: Type: text/html, Size: 15215 bytes --]

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

* [Intel-gfx] ✗ Fi.CI.IGT: failure for drm/i915/guc: Refactor ADS access to use iosys_map (rev2)
  2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
                   ` (21 preceding siblings ...)
  (?)
@ 2022-02-08 13:07 ` Patchwork
  -1 siblings, 0 replies; 59+ messages in thread
From: Patchwork @ 2022-02-08 13:07 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 30280 bytes --]

== Series Details ==

Series: drm/i915/guc: Refactor ADS access to use iosys_map (rev2)
URL   : https://patchwork.freedesktop.org/series/99711/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_11200_full -> Patchwork_22201_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_22201_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_22201_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Participating hosts (11 -> 11)
------------------------------

  No changes in participating hosts

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_22201_full:

### IGT changes ###

#### Possible regressions ####

  * igt@perf@non-zero-reason:
    - shard-skl:          [PASS][1] -> [FAIL][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl4/igt@perf@non-zero-reason.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl4/igt@perf@non-zero-reason.html

  * igt@syncobj_timeline@invalid-transfer-non-existent-point:
    - shard-apl:          NOTRUN -> [DMESG-WARN][3]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl8/igt@syncobj_timeline@invalid-transfer-non-existent-point.html
    - shard-iclb:         NOTRUN -> [DMESG-WARN][4]
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb8/igt@syncobj_timeline@invalid-transfer-non-existent-point.html

  * igt@syncobj_timeline@transfer-timeline-point:
    - shard-skl:          NOTRUN -> [DMESG-WARN][5]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl10/igt@syncobj_timeline@transfer-timeline-point.html

  
#### Warnings ####

  * igt@gem_exec_balancer@parallel-keep-submit-fence:
    - shard-iclb:         [SKIP][6] ([i915#4525]) -> [DMESG-WARN][7]
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb5/igt@gem_exec_balancer@parallel-keep-submit-fence.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb2/igt@gem_exec_balancer@parallel-keep-submit-fence.html

  
Known issues
------------

  Here are the changes found in Patchwork_22201_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_create@create-massive:
    - shard-skl:          NOTRUN -> [DMESG-WARN][8] ([i915#4991])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl9/igt@gem_create@create-massive.html

  * igt@gem_ctx_param@set-priority-not-supported:
    - shard-iclb:         NOTRUN -> [SKIP][9] ([fdo#109314])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb8/igt@gem_ctx_param@set-priority-not-supported.html

  * igt@gem_exec_capture@pi@rcs0:
    - shard-skl:          [PASS][10] -> [INCOMPLETE][11] ([i915#4547])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl10/igt@gem_exec_capture@pi@rcs0.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl6/igt@gem_exec_capture@pi@rcs0.html

  * igt@gem_exec_fair@basic-deadline:
    - shard-apl:          NOTRUN -> [FAIL][12] ([i915#2846])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl4/igt@gem_exec_fair@basic-deadline.html

  * igt@gem_exec_fair@basic-none-solo@rcs0:
    - shard-kbl:          NOTRUN -> [FAIL][13] ([i915#2842])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl4/igt@gem_exec_fair@basic-none-solo@rcs0.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - shard-tglb:         [PASS][14] -> [FAIL][15] ([i915#2842])
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-tglb2/igt@gem_exec_fair@basic-pace-share@rcs0.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-tglb3/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_exec_fair@basic-pace@rcs0:
    - shard-kbl:          [PASS][16] -> [FAIL][17] ([i915#2842]) +2 similar issues
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-kbl3/igt@gem_exec_fair@basic-pace@rcs0.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl7/igt@gem_exec_fair@basic-pace@rcs0.html

  * igt@gem_lmem_swapping@heavy-multi:
    - shard-apl:          NOTRUN -> [SKIP][18] ([fdo#109271] / [i915#4613])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl8/igt@gem_lmem_swapping@heavy-multi.html
    - shard-iclb:         NOTRUN -> [SKIP][19] ([i915#4613])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb8/igt@gem_lmem_swapping@heavy-multi.html

  * igt@gem_lmem_swapping@random:
    - shard-skl:          NOTRUN -> [SKIP][20] ([fdo#109271] / [i915#4613])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl10/igt@gem_lmem_swapping@random.html

  * igt@gem_lmem_swapping@smem-oom:
    - shard-kbl:          NOTRUN -> [SKIP][21] ([fdo#109271] / [i915#4613])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl6/igt@gem_lmem_swapping@smem-oom.html

  * igt@gem_pwrite@basic-exhaustion:
    - shard-kbl:          NOTRUN -> [WARN][22] ([i915#2658])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl4/igt@gem_pwrite@basic-exhaustion.html

  * igt@gem_pxp@reject-modify-context-protection-on:
    - shard-iclb:         NOTRUN -> [SKIP][23] ([i915#4270])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@gem_pxp@reject-modify-context-protection-on.html

  * igt@gem_render_copy@y-tiled-mc-ccs-to-yf-tiled-ccs:
    - shard-iclb:         NOTRUN -> [SKIP][24] ([i915#768])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@gem_render_copy@y-tiled-mc-ccs-to-yf-tiled-ccs.html

  * igt@gem_userptr_blits@unsync-unmap-after-close:
    - shard-iclb:         NOTRUN -> [SKIP][25] ([i915#3297])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@gem_userptr_blits@unsync-unmap-after-close.html

  * igt@gen7_exec_parse@batch-without-end:
    - shard-iclb:         NOTRUN -> [SKIP][26] ([fdo#109289])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb8/igt@gen7_exec_parse@batch-without-end.html

  * igt@gen9_exec_parse@bb-oversize:
    - shard-iclb:         NOTRUN -> [SKIP][27] ([i915#2856])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@gen9_exec_parse@bb-oversize.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-kbl:          NOTRUN -> [FAIL][28] ([i915#454])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl4/igt@i915_pm_dc@dc6-dpms.html

  * igt@i915_suspend@forcewake:
    - shard-skl:          [PASS][29] -> [INCOMPLETE][30] ([i915#636])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl9/igt@i915_suspend@forcewake.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl1/igt@i915_suspend@forcewake.html

  * igt@kms_atomic@plane-primary-overlay-mutable-zpos:
    - shard-iclb:         NOTRUN -> [SKIP][31] ([i915#404])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb8/igt@kms_atomic@plane-primary-overlay-mutable-zpos.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip:
    - shard-apl:          NOTRUN -> [SKIP][32] ([fdo#109271] / [i915#3777]) +2 similar issues
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl1/igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip:
    - shard-kbl:          NOTRUN -> [SKIP][33] ([fdo#109271] / [i915#3777])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl6/igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-hflip-async-flip.html

  * igt@kms_big_fb@y-tiled-64bpp-rotate-90:
    - shard-iclb:         NOTRUN -> [SKIP][34] ([fdo#110725] / [fdo#111614])
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_big_fb@y-tiled-64bpp-rotate-90.html

  * igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180-async-flip:
    - shard-skl:          NOTRUN -> [FAIL][35] ([i915#3743]) +1 similar issue
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl9/igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180-async-flip.html

  * igt@kms_ccs@pipe-a-crc-primary-rotation-180-y_tiled_gen12_rc_ccs_cc:
    - shard-kbl:          NOTRUN -> [SKIP][36] ([fdo#109271] / [i915#3886]) +6 similar issues
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl4/igt@kms_ccs@pipe-a-crc-primary-rotation-180-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-b-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc:
    - shard-skl:          NOTRUN -> [SKIP][37] ([fdo#109271] / [i915#3886]) +3 similar issues
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl9/igt@kms_ccs@pipe-b-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-b-crc-sprite-planes-basic-y_tiled_gen12_rc_ccs_cc:
    - shard-apl:          NOTRUN -> [SKIP][38] ([fdo#109271] / [i915#3886]) +6 similar issues
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl3/igt@kms_ccs@pipe-b-crc-sprite-planes-basic-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-b-missing-ccs-buffer-y_tiled_gen12_rc_ccs_cc:
    - shard-iclb:         NOTRUN -> [SKIP][39] ([fdo#109278] / [i915#3886]) +1 similar issue
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_ccs@pipe-b-missing-ccs-buffer-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-d-crc-primary-rotation-180-yf_tiled_ccs:
    - shard-apl:          NOTRUN -> [SKIP][40] ([fdo#109271]) +102 similar issues
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl3/igt@kms_ccs@pipe-d-crc-primary-rotation-180-yf_tiled_ccs.html

  * igt@kms_chamelium@dp-crc-multiple:
    - shard-skl:          NOTRUN -> [SKIP][41] ([fdo#109271] / [fdo#111827]) +2 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl10/igt@kms_chamelium@dp-crc-multiple.html

  * igt@kms_chamelium@dp-hpd-storm:
    - shard-iclb:         NOTRUN -> [SKIP][42] ([fdo#109284] / [fdo#111827]) +2 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_chamelium@dp-hpd-storm.html

  * igt@kms_chamelium@hdmi-edid-change-during-suspend:
    - shard-apl:          NOTRUN -> [SKIP][43] ([fdo#109271] / [fdo#111827]) +6 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl4/igt@kms_chamelium@hdmi-edid-change-during-suspend.html

  * igt@kms_color@pipe-d-ctm-green-to-red:
    - shard-iclb:         NOTRUN -> [SKIP][44] ([fdo#109278] / [i915#1149])
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_color@pipe-d-ctm-green-to-red.html

  * igt@kms_color_chamelium@pipe-a-ctm-0-75:
    - shard-kbl:          NOTRUN -> [SKIP][45] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl7/igt@kms_color_chamelium@pipe-a-ctm-0-75.html

  * igt@kms_content_protection@dp-mst-type-1:
    - shard-iclb:         NOTRUN -> [SKIP][46] ([i915#3116])
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_content_protection@dp-mst-type-1.html

  * igt@kms_cursor_crc@pipe-a-cursor-512x512-random:
    - shard-iclb:         NOTRUN -> [SKIP][47] ([fdo#109278] / [fdo#109279])
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_cursor_crc@pipe-a-cursor-512x512-random.html

  * igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic:
    - shard-iclb:         NOTRUN -> [SKIP][48] ([fdo#109274] / [fdo#109278])
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_cursor_legacy@2x-flip-vs-cursor-atomic.html

  * igt@kms_flip@2x-flip-vs-wf_vblank-interruptible:
    - shard-iclb:         NOTRUN -> [SKIP][49] ([fdo#109274]) +2 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_flip@2x-flip-vs-wf_vblank-interruptible.html

  * igt@kms_flip@flip-vs-expired-vblank@a-edp1:
    - shard-skl:          [PASS][50] -> [FAIL][51] ([i915#79])
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl6/igt@kms_flip@flip-vs-expired-vblank@a-edp1.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl10/igt@kms_flip@flip-vs-expired-vblank@a-edp1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling:
    - shard-skl:          NOTRUN -> [INCOMPLETE][52] ([i915#3701])
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl9/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-blt:
    - shard-skl:          NOTRUN -> [SKIP][53] ([fdo#109271]) +57 similar issues
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl9/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-mmap-cpu:
    - shard-kbl:          NOTRUN -> [SKIP][54] ([fdo#109271]) +105 similar issues
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl7/igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-mmap-cpu.html

  * igt@kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-blt:
    - shard-iclb:         NOTRUN -> [SKIP][55] ([fdo#109280]) +5 similar issues
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-blt.html

  * igt@kms_hdr@bpc-switch:
    - shard-skl:          [PASS][56] -> [FAIL][57] ([i915#1188])
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl4/igt@kms_hdr@bpc-switch.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl2/igt@kms_hdr@bpc-switch.html

  * igt@kms_hdr@bpc-switch-dpms:
    - shard-skl:          NOTRUN -> [FAIL][58] ([i915#1188])
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl10/igt@kms_hdr@bpc-switch-dpms.html

  * igt@kms_hdr@static-toggle-suspend:
    - shard-iclb:         NOTRUN -> [SKIP][59] ([i915#1187])
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_hdr@static-toggle-suspend.html

  * igt@kms_pipe_crc_basic@hang-read-crc-pipe-d:
    - shard-kbl:          NOTRUN -> [SKIP][60] ([fdo#109271] / [i915#533])
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl4/igt@kms_pipe_crc_basic@hang-read-crc-pipe-d.html

  * igt@kms_pipe_crc_basic@read-crc-pipe-d:
    - shard-apl:          NOTRUN -> [SKIP][61] ([fdo#109271] / [i915#533])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl3/igt@kms_pipe_crc_basic@read-crc-pipe-d.html

  * igt@kms_pipe_crc_basic@read-crc-pipe-d-frame-sequence:
    - shard-skl:          NOTRUN -> [SKIP][62] ([fdo#109271] / [i915#533])
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl9/igt@kms_pipe_crc_basic@read-crc-pipe-d-frame-sequence.html

  * igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes:
    - shard-apl:          [PASS][63] -> [DMESG-WARN][64] ([i915#180]) +2 similar issues
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-apl8/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl8/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-a-planes.html

  * igt@kms_plane_alpha_blend@pipe-b-alpha-opaque-fb:
    - shard-kbl:          NOTRUN -> [FAIL][65] ([fdo#108145] / [i915#265]) +1 similar issue
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl7/igt@kms_plane_alpha_blend@pipe-b-alpha-opaque-fb.html

  * igt@kms_plane_scaling@scaler-with-clipping-clamping@pipe-c-scaler-with-clipping-clamping:
    - shard-kbl:          NOTRUN -> [SKIP][66] ([fdo#109271] / [i915#2733])
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl7/igt@kms_plane_scaling@scaler-with-clipping-clamping@pipe-c-scaler-with-clipping-clamping.html

  * igt@kms_psr2_sf@cursor-plane-update-sf:
    - shard-apl:          NOTRUN -> [SKIP][67] ([fdo#109271] / [i915#658]) +1 similar issue
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl1/igt@kms_psr2_sf@cursor-plane-update-sf.html

  * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area:
    - shard-skl:          NOTRUN -> [SKIP][68] ([fdo#109271] / [i915#658])
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl9/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area.html

  * igt@kms_psr2_su@page_flip-xrgb8888:
    - shard-kbl:          NOTRUN -> [SKIP][69] ([fdo#109271] / [i915#658]) +1 similar issue
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl7/igt@kms_psr2_su@page_flip-xrgb8888.html

  * igt@kms_psr@psr2_basic:
    - shard-iclb:         NOTRUN -> [SKIP][70] ([fdo#109441])
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@kms_psr@psr2_basic.html

  * igt@kms_psr@psr2_cursor_blt:
    - shard-iclb:         [PASS][71] -> [SKIP][72] ([fdo#109441]) +4 similar issues
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb2/igt@kms_psr@psr2_cursor_blt.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb8/igt@kms_psr@psr2_cursor_blt.html

  * igt@kms_vblank@pipe-c-ts-continuation-suspend:
    - shard-kbl:          [PASS][73] -> [DMESG-WARN][74] ([i915#180])
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-kbl4/igt@kms_vblank@pipe-c-ts-continuation-suspend.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl1/igt@kms_vblank@pipe-c-ts-continuation-suspend.html

  * igt@kms_vblank@pipe-d-ts-continuation-modeset-rpm:
    - shard-iclb:         NOTRUN -> [SKIP][75] ([fdo#109278]) +14 similar issues
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb8/igt@kms_vblank@pipe-d-ts-continuation-modeset-rpm.html

  * igt@kms_writeback@writeback-check-output:
    - shard-skl:          NOTRUN -> [SKIP][76] ([fdo#109271] / [i915#2437])
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl9/igt@kms_writeback@writeback-check-output.html

  * igt@prime_nv_test@i915_nv_sharing:
    - shard-iclb:         NOTRUN -> [SKIP][77] ([fdo#109291])
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@prime_nv_test@i915_nv_sharing.html

  * igt@prime_self_import@basic-with_one_bo_two_files:
    - shard-skl:          [PASS][78] -> [DMESG-WARN][79] ([i915#1982])
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl9/igt@prime_self_import@basic-with_one_bo_two_files.html
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl8/igt@prime_self_import@basic-with_one_bo_two_files.html

  * igt@sysfs_clients@create:
    - shard-apl:          NOTRUN -> [SKIP][80] ([fdo#109271] / [i915#2994])
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl4/igt@sysfs_clients@create.html

  * igt@sysfs_clients@fair-3:
    - shard-kbl:          NOTRUN -> [SKIP][81] ([fdo#109271] / [i915#2994])
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl1/igt@sysfs_clients@fair-3.html

  * igt@sysfs_clients@fair-7:
    - shard-skl:          NOTRUN -> [SKIP][82] ([fdo#109271] / [i915#2994])
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl9/igt@sysfs_clients@fair-7.html

  * igt@sysfs_heartbeat_interval@mixed@vcs0:
    - shard-skl:          [PASS][83] -> [FAIL][84] ([i915#1731])
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl10/igt@sysfs_heartbeat_interval@mixed@vcs0.html
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl3/igt@sysfs_heartbeat_interval@mixed@vcs0.html

  
#### Possible fixes ####

  * igt@gem_eio@in-flight-contexts-immediate:
    - shard-iclb:         [TIMEOUT][85] ([i915#3070]) -> [PASS][86]
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb8/igt@gem_eio@in-flight-contexts-immediate.html
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb7/igt@gem_eio@in-flight-contexts-immediate.html

  * igt@gem_exec_balancer@parallel-balancer:
    - shard-iclb:         [SKIP][87] ([i915#4525]) -> [PASS][88]
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb7/igt@gem_exec_balancer@parallel-balancer.html
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb2/igt@gem_exec_balancer@parallel-balancer.html

  * igt@gem_exec_capture@pi@rcs0:
    - shard-iclb:         [INCOMPLETE][89] ([i915#3371]) -> [PASS][90]
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb8/igt@gem_exec_capture@pi@rcs0.html
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@gem_exec_capture@pi@rcs0.html

  * igt@gen9_exec_parse@allowed-single:
    - shard-skl:          [DMESG-WARN][91] ([i915#1436] / [i915#716]) -> [PASS][92]
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl6/igt@gen9_exec_parse@allowed-single.html
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl10/igt@gen9_exec_parse@allowed-single.html

  * igt@i915_pm_dc@dc6-psr:
    - shard-iclb:         [FAIL][93] ([i915#454]) -> [PASS][94]
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb3/igt@i915_pm_dc@dc6-psr.html
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb5/igt@i915_pm_dc@dc6-psr.html

  * igt@kms_big_fb@x-tiled-32bpp-rotate-180:
    - {shard-tglu}:       [DMESG-WARN][95] ([i915#402]) -> [PASS][96]
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-tglu-8/igt@kms_big_fb@x-tiled-32bpp-rotate-180.html
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-tglu-1/igt@kms_big_fb@x-tiled-32bpp-rotate-180.html

  * igt@kms_cursor_crc@pipe-a-cursor-128x128-sliding:
    - shard-snb:          [SKIP][97] ([fdo#109271]) -> [PASS][98]
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-snb7/igt@kms_cursor_crc@pipe-a-cursor-128x128-sliding.html
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-snb7/igt@kms_cursor_crc@pipe-a-cursor-128x128-sliding.html

  * igt@kms_cursor_crc@pipe-a-cursor-suspend:
    - shard-kbl:          [DMESG-WARN][99] ([i915#180]) -> [PASS][100] +5 similar issues
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-kbl6/igt@kms_cursor_crc@pipe-a-cursor-suspend.html
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-kbl7/igt@kms_cursor_crc@pipe-a-cursor-suspend.html

  * igt@kms_cursor_crc@pipe-b-cursor-suspend:
    - shard-apl:          [DMESG-WARN][101] ([i915#180]) -> [PASS][102] +2 similar issues
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-apl3/igt@kms_cursor_crc@pipe-b-cursor-suspend.html
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl1/igt@kms_cursor_crc@pipe-b-cursor-suspend.html

  * igt@kms_cursor_legacy@flip-vs-cursor-busy-crc-legacy:
    - shard-skl:          [FAIL][103] ([i915#2346]) -> [PASS][104]
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl8/igt@kms_cursor_legacy@flip-vs-cursor-busy-crc-legacy.html
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl1/igt@kms_cursor_legacy@flip-vs-cursor-busy-crc-legacy.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-apl:          [INCOMPLETE][105] ([i915#180] / [i915#1982]) -> [PASS][106]
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-apl8/igt@kms_fbcon_fbt@fbc-suspend.html
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl8/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_flip@flip-vs-expired-vblank@c-edp1:
    - shard-skl:          [FAIL][107] ([i915#79]) -> [PASS][108]
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl6/igt@kms_flip@flip-vs-expired-vblank@c-edp1.html
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl10/igt@kms_flip@flip-vs-expired-vblank@c-edp1.html

  * igt@kms_flip@plain-flip-fb-recreate@a-edp1:
    - shard-skl:          [FAIL][109] ([i915#2122]) -> [PASS][110]
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl8/igt@kms_flip@plain-flip-fb-recreate@a-edp1.html
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl1/igt@kms_flip@plain-flip-fb-recreate@a-edp1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling:
    - shard-iclb:         [SKIP][111] ([i915#3701]) -> [PASS][112]
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling.html
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb8/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - shard-apl:          [DMESG-WARN][113] ([i915#180] / [i915#1982]) -> [PASS][114]
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-apl1/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-apl4/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [SKIP][115] ([fdo#109441]) -> [PASS][116] +2 similar issues
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb7/igt@kms_psr@psr2_sprite_plane_move.html
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html

  * igt@perf@blocking:
    - shard-tglb:         [FAIL][117] ([i915#1542]) -> [PASS][118]
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-tglb6/igt@perf@blocking.html
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-tglb8/igt@perf@blocking.html

  
#### Warnings ####

  * igt@gem_exec_balancer@parallel:
    - shard-iclb:         [DMESG-WARN][119] -> [SKIP][120] ([i915#4525]) +1 similar issue
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb2/igt@gem_exec_balancer@parallel.html
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb6/igt@gem_exec_balancer@parallel.html

  * igt@i915_pm_rc6_residency@rc6-fence:
    - shard-iclb:         [WARN][121] ([i915#2684]) -> [WARN][122] ([i915#1804] / [i915#2684])
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb8/igt@i915_pm_rc6_residency@rc6-fence.html
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb7/igt@i915_pm_rc6_residency@rc6-fence.html

  * igt@i915_pm_rc6_residency@rc6-idle:
    - shard-iclb:         [WARN][123] ([i915#1804] / [i915#2684]) -> [WARN][124] ([i915#2684])
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb6/igt@i915_pm_rc6_residency@rc6-idle.html
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb8/igt@i915_pm_rc6_residency@rc6-idle.html

  * igt@kms_flip@2x-plain-flip-interruptible:
    - shard-skl:          [SKIP][125] ([fdo#109271]) -> [SKIP][126] ([fdo#109271] / [i915#1888])
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl8/igt@kms_flip@2x-plain-flip-interruptible.html
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl1/igt@kms_flip@2x-plain-flip-interruptible.html

  * igt@kms_hdr@bpc-switch-suspend:
    - shard-skl:          [INCOMPLETE][127] ([i915#2828]) -> [FAIL][128] ([i915#1188])
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-skl10/igt@kms_hdr@bpc-switch-suspend.html
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-skl9/igt@kms_hdr@bpc-switch-suspend.html

  * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area:
    - shard-iclb:         [SKIP][129] ([i915#2920]) -> [SKIP][130] ([fdo#111068] / [i915#658])
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb2/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area.html
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb8/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area.html

  * igt@kms_psr2_su@page_flip-nv12:
    - shard-iclb:         [SKIP][131] ([fdo#109642] / [fdo#111068] / [i915#658]) -> [FAIL][132] ([i915#4148])
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-iclb3/igt@kms_psr2_su@page_flip-nv12.html
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/shard-iclb2/igt@kms_psr2_su@page_flip-nv12.html

  * igt@runner@aborted:
    - shard-kbl:          ([FAIL][133], [FAIL][134], [FAIL][135], [FAIL][136], [FAIL][137], [FAIL][138], [FAIL][139], [FAIL][140], [FAIL][141], [FAIL][142], [FAIL][143], [FAIL][144], [FAIL][145], [FAIL][146], [FAIL][147], [FAIL][148]) ([i915#1436] / [i915#180] / [i915#1814] / [i915#3002] / [i915#4312]) -> ([FAIL][149], [FAIL][150], [FAIL][151], [FAIL][152], [FAIL][153], [FAIL][154], [FAIL][155], [FAIL][156], [FAIL][157], [FAIL][158], [FAIL][159]) ([i915#1436] / [i915#180] / [i915#1814] / [i915#3002] / [i915#4312] / [i915#602])
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-kbl6/igt@runner@aborted.html
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-kbl1/igt@runner@aborted.html
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-kbl6/igt@runner@aborted.html
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11200/shard-kbl1/igt@runner@aborted.html
   [137]: https://intel-gfx-ci.01.org

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22201/index.html

[-- Attachment #2: Type: text/html, Size: 33505 bytes --]

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

* Re: [Intel-gfx] [PATCH v2 02/18] iosys-map: Add a few more helpers
  2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
  (?)
  (?)
@ 2022-02-08 22:53   ` Matt Atwood
  -1 siblings, 0 replies; 59+ messages in thread
From: Matt Atwood @ 2022-02-08 22:53 UTC (permalink / raw)
  To: Lucas De Marchi

On Tue, Feb 08, 2022 at 02:45:08AM -0800, Lucas De Marchi wrote:
> First the simplest ones:
> 
> 	- iosys_map_memset(): when abstracting system and I/O memory,
> 	  just like the memcpy() use case, memset() also has dedicated
> 	  functions to be called for using IO memory.
> 	- iosys_map_memcpy_from(): we may need to copy data from I/O
> 	  memory, not only to.
> 
> In certain situations it's useful to be able to read or write to an
> offset that is calculated by having the memory layout given by a struct
> declaration. Usually we are going to read/write a u8, u16, u32 or u64.
> 
> As a pre-requisite for the implementation, add iosys_map_memcpy_from()
> to be the equivalent of iosys_map_memcpy_to(), but in the other
> direction. Then add 2 pairs of macros:
> 
> 	- iosys_map_rd() / iosys_map_wr()
> 	- iosys_map_rd_field() / iosys_map_wr_field()
> 
> The first pair takes the C-type and offset to read/write. The second
> pair uses a struct describing the layout of the mapping in order to
> calculate the offset and size being read/written.
> 
> We could use readb, readw, readl, readq and the write* counterparts,
> however due to alignment issues this may not work on all architectures.
> If alignment needs to be checked to call the right function, it's not
> possible to decide at compile-time which function to call: so just leave
> the decision to the memcpy function that will do exactly that.
> 
> Finally, in order to use the above macros with a map derived from
> another, add another initializer: IOSYS_MAP_INIT_OFFSET().
> 
> v2:
>   - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
>     within the union
>   - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
>     allow the struct itself to be at an offset from the mapping
>   - Add documentation to iosys_map_rd_field() with example and expected
>     memory layout
> 
> Cc: Sumit Semwal <sumit.semwal@linaro.org>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-kernel@vger.kernel.org
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
> ---
>  include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 202 insertions(+)
> 
> diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
> index edd730b1e899..c6b223534b21 100644
> --- a/include/linux/iosys-map.h
> +++ b/include/linux/iosys-map.h
> @@ -6,6 +6,7 @@
>  #ifndef __IOSYS_MAP_H__
>  #define __IOSYS_MAP_H__
>  
> +#include <linux/kernel.h>
>  #include <linux/io.h>
>  #include <linux/string.h>
>  
> @@ -120,6 +121,45 @@ struct iosys_map {
>  		.is_iomem = false,	\
>  	}
>  
> +/**
> + * IOSYS_MAP_INIT_OFFSET - Initializes struct iosys_map from another iosys_map
> + * @map_:	The dma-buf mapping structure to copy from
> + * @offset_:	Offset to add to the other mapping
> + *
> + * Initializes a new iosys_map struct based on another passed as argument. It
> + * does a shallow copy of the struct so it's possible to update the back storage
> + * without changing where the original map points to. It is the equivalent of
> + * doing:
> + *
> + * .. code-block:: c
> + *
> + *	iosys_map map = other_map;
> + *	iosys_map_incr(&map, &offset);
> + *
> + * Example usage:
> + *
> + * .. code-block:: c
> + *
> + *	void foo(struct device *dev, struct iosys_map *base_map)
> + *	{
> + *		...
> + *		struct iosys_map map = IOSYS_MAP_INIT_OFFSET(base_map, FIELD_OFFSET);
> + *		...
> + *	}
> + *
> + * The advantage of using the initializer over just increasing the offset with
> + * iosys_map_incr() like above is that the new map will always point to the
> + * right place of the buffer during its scope. It reduces the risk of updating
> + * the wrong part of the buffer and having no compiler warning about that. If
> + * the assignment to IOSYS_MAP_INIT_OFFSET() is forgotten, the compiler can warn
> + * about the use of uninitialized variable.
> + */
> +#define IOSYS_MAP_INIT_OFFSET(map_, offset_) ({				\
> +	struct iosys_map copy = *map_;					\
> +	iosys_map_incr(&copy, offset_);					\
> +	copy;								\
> +})
> +
>  /**
>   * iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory
>   * @map:	The iosys_map structure
> @@ -239,6 +279,26 @@ static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
>  		memcpy(dst->vaddr + dst_offset, src, len);
>  }
>  
> +/**
> + * iosys_map_memcpy_from - Memcpy from iosys_map into system memory
> + * @dst:	Destination in system memory
> + * @src:	The iosys_map structure
> + * @src_offset:	The offset from which to copy
> + * @len:	The number of byte in src
> + *
> + * Copies data from a iosys_map with an offset. The dest buffer is in
> + * system memory. Depending on the mapping location, the helper picks the
> + * correct method of accessing the memory.
> + */
> +static inline void iosys_map_memcpy_from(void *dst, const struct iosys_map *src,
> +					 size_t src_offset, size_t len)
> +{
> +	if (src->is_iomem)
> +		memcpy_fromio(dst, src->vaddr_iomem + src_offset, len);
> +	else
> +		memcpy(dst, src->vaddr + src_offset, len);
> +}
> +
>  /**
>   * iosys_map_incr - Increments the address stored in a iosys mapping
>   * @map:	The iosys_map structure
> @@ -255,4 +315,146 @@ static inline void iosys_map_incr(struct iosys_map *map, size_t incr)
>  		map->vaddr += incr;
>  }
>  
> +/**
> + * iosys_map_memset - Memset iosys_map
> + * @dst:	The iosys_map structure
> + * @offset:	Offset from dst where to start setting value
> + * @value:	The value to set
> + * @len:	The number of bytes to set in dst
> + *
> + * Set value in iosys_map. Depending on the buffer's location, the helper
> + * picks the correct method of accessing the memory.
> + */
> +static inline void iosys_map_memset(struct iosys_map *dst, size_t offset,
> +				    int value, size_t len)
> +{
> +	if (dst->is_iomem)
> +		memset_io(dst->vaddr_iomem + offset, value, len);
> +	else
> +		memset(dst->vaddr + offset, value, len);
> +}
> +
> +/**
> + * iosys_map_rd - Read a C-type value from the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from which to read
> + * @type__:	Type of the value being read
> + *
> + * Read a C type value from iosys_map, handling possible un-aligned accesses to
> + * the mapping.
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd(map__, offset__, type__) ({			\
> +	type__ val;							\
> +	iosys_map_memcpy_from(&val, map__, offset__, sizeof(val));	\
> +	val;								\
> +})
> +
> +/**
> + * iosys_map_wr - Write a C-type value to the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from the mapping to write to
> + * @type__:	Type of the value being written
> + * @val__:	Value to write
> + *
> + * Write a C-type value to the iosys_map, handling possible un-aligned accesses
> + * to the mapping.
> + */
> +#define iosys_map_wr(map__, offset__, type__, val__) ({			\
> +	type__ val = (val__);						\
> +	iosys_map_memcpy_to(map__, offset__, &val, sizeof(val));	\
> +})
> +
> +/**
> + * iosys_map_rd_field - Read a member from a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + *
> + * Read a value from iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and its
> + * value read handling possible un-aligned memory accesses. For example: suppose
> + * there is a @struct foo defined as below and the value ``foo.field2.inner2``
> + * needs to be read from the iosys_map:
> + *
> + * .. code-block:: c
> + *
> + *	struct foo {
> + *		int field1;
> + *		struct {
> + *			int inner1;
> + *			int inner2;
> + *		} field2;
> + *		int field3;
> + *	} __packed;
> + *
> + * This is the expected memory layout of a buffer using iosys_map_rd_field():
> + *
> + * +------------------------------+--------------------------+
> + * | Address                      | Content                  |
> + * +==============================+==========================+
> + * | buffer + 0000                | start of mmapped buffer  |
> + * |                              | pointed by iosys_map     |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + ``struct_offset__`` | start of ``struct foo``  |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + wwww                | ``foo.field2.inner2``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + yyyy                | end of ``struct foo``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + zzzz                | end of mmaped buffer     |
> + * +------------------------------+--------------------------+
> + *
> + * Values automatically calculated by this macro or not needed are denoted by
> + * wwww, yyyy and zzzz. This is the code to read that value:
> + *
> + * .. code-block:: c
> + *
> + *	x = iosys_map_rd_field(&map, offset, struct foo, field2.inner2);
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
> +	struct_type__ *s;							\
> +	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
> +		     typeof(s->field__));					\
> +})
> +
> +/**
> + * iosys_map_wr_field - Write to a member of a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + * @val__:		Value to write
> + *
> + * Write a value to the iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and the
> + * @val__ is written handling possible un-aligned memory accesses. Refer to
> + * iosys_map_rd_field() for expected usage and memory layout.
> + */
> +#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
> +	struct_type__ *s;								\
> +	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
> +		     typeof(s->field__), val__);					\
> +})
> +
>  #endif /* __IOSYS_MAP_H__ */
> -- 
> 2.35.1
> 

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

* Re: [Intel-gfx] [PATCH v2 03/18] drm/i915/gt: Add helper for shmem copy to iosys_map
  2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
  (?)
@ 2022-02-08 23:08   ` Matt Atwood
  -1 siblings, 0 replies; 59+ messages in thread
From: Matt Atwood @ 2022-02-08 23:08 UTC (permalink / raw)
  To: Lucas De Marchi

On Tue, Feb 08, 2022 at 02:45:09AM -0800, Lucas De Marchi wrote:
> Add a variant of shmem_read() that takes a iosys_map pointer rather
> than a plain pointer as argument. It's mostly a copy __shmem_rw() but
> adapting the api and removing the write support since there's currently
> only need to use iosys_map as destination.
> 
> Reworking __shmem_rw() to share the implementation was tempting, but
> finding a good balance between reuse and clarity pushed towards a little
> code duplication. Since the function is small, just add the similar
> function with a copy/paste/adapt approach.
> 
> v2: Add an offset as argument and instead of using a map iterator, use the
> offset to keep track of where we are writing data to.
> 
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: Matthew Auld <matthew.auld@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
> ---
>  drivers/gpu/drm/i915/gt/shmem_utils.c | 32 +++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/gt/shmem_utils.h |  3 +++
>  2 files changed, 35 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c
> index 0683b27a3890..402f085f3a02 100644
> --- a/drivers/gpu/drm/i915/gt/shmem_utils.c
> +++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
> @@ -3,6 +3,7 @@
>   * Copyright © 2020 Intel Corporation
>   */
>  
> +#include <linux/iosys-map.h>
>  #include <linux/mm.h>
>  #include <linux/pagemap.h>
>  #include <linux/shmem_fs.h>
> @@ -123,6 +124,37 @@ static int __shmem_rw(struct file *file, loff_t off,
>  	return 0;
>  }
>  
> +int shmem_read_to_iosys_map(struct file *file, loff_t off,
> +			    struct iosys_map *map, size_t map_off, size_t len)
> +{
> +	unsigned long pfn;
> +
> +	for (pfn = off >> PAGE_SHIFT; len; pfn++) {
> +		unsigned int this =
> +			min_t(size_t, PAGE_SIZE - offset_in_page(off), len);
> +		struct page *page;
> +		void *vaddr;
> +
> +		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
> +						   GFP_KERNEL);
> +		if (IS_ERR(page))
> +			return PTR_ERR(page);
> +
> +		vaddr = kmap(page);
> +		iosys_map_memcpy_to(map, map_off, vaddr + offset_in_page(off),
> +				    this);
> +		mark_page_accessed(page);
> +		kunmap(page);
> +		put_page(page);
> +
> +		len -= this;
> +		map_off += this;
> +		off = 0;
> +	}
> +
> +	return 0;
> +}
> +
>  int shmem_read(struct file *file, loff_t off, void *dst, size_t len)
>  {
>  	return __shmem_rw(file, off, dst, len, false);
> diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.h b/drivers/gpu/drm/i915/gt/shmem_utils.h
> index c1669170c351..b2b04d88c6e5 100644
> --- a/drivers/gpu/drm/i915/gt/shmem_utils.h
> +++ b/drivers/gpu/drm/i915/gt/shmem_utils.h
> @@ -8,6 +8,7 @@
>  
>  #include <linux/types.h>
>  
> +struct iosys_map;
>  struct drm_i915_gem_object;
>  struct file;
>  
> @@ -17,6 +18,8 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj);
>  void *shmem_pin_map(struct file *file);
>  void shmem_unpin_map(struct file *file, void *ptr);
>  
> +int shmem_read_to_iosys_map(struct file *file, loff_t off,
> +			    struct iosys_map *map, size_t map_off, size_t len);
>  int shmem_read(struct file *file, loff_t off, void *dst, size_t len);
>  int shmem_write(struct file *file, loff_t off, void *src, size_t len);
>  
> -- 
> 2.35.1
> 

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

* Re: [PATCH v2 02/18] iosys-map: Add a few more helpers
  2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
  (?)
@ 2022-02-09  6:14     ` Mauro Carvalho Chehab
  -1 siblings, 0 replies; 59+ messages in thread
From: Mauro Carvalho Chehab @ 2022-02-09  6:14 UTC (permalink / raw)
  To: Lucas De Marchi
  Cc: Matthew Brost, Thomas Hellström, intel-gfx, linux-kernel,
	dri-devel, Sumit Semwal, Daniele Ceraolo Spurio,
	Thomas Zimmermann, Christian König, John Harrison

Em Tue,  8 Feb 2022 02:45:08 -0800
Lucas De Marchi <lucas.demarchi@intel.com> escreveu:

> First the simplest ones:
> 
> 	- iosys_map_memset(): when abstracting system and I/O memory,
> 	  just like the memcpy() use case, memset() also has dedicated
> 	  functions to be called for using IO memory.
> 	- iosys_map_memcpy_from(): we may need to copy data from I/O
> 	  memory, not only to.
> 
> In certain situations it's useful to be able to read or write to an
> offset that is calculated by having the memory layout given by a struct
> declaration. Usually we are going to read/write a u8, u16, u32 or u64.
> 
> As a pre-requisite for the implementation, add iosys_map_memcpy_from()
> to be the equivalent of iosys_map_memcpy_to(), but in the other
> direction. Then add 2 pairs of macros:
> 
> 	- iosys_map_rd() / iosys_map_wr()
> 	- iosys_map_rd_field() / iosys_map_wr_field()
> 
> The first pair takes the C-type and offset to read/write. The second
> pair uses a struct describing the layout of the mapping in order to
> calculate the offset and size being read/written.
> 
> We could use readb, readw, readl, readq and the write* counterparts,
> however due to alignment issues this may not work on all architectures.
> If alignment needs to be checked to call the right function, it's not
> possible to decide at compile-time which function to call: so just leave
> the decision to the memcpy function that will do exactly that.
> 
> Finally, in order to use the above macros with a map derived from
> another, add another initializer: IOSYS_MAP_INIT_OFFSET().
> 
> v2:
>   - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
>     within the union
>   - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
>     allow the struct itself to be at an offset from the mapping
>   - Add documentation to iosys_map_rd_field() with example and expected
>     memory layout
> 
> Cc: Sumit Semwal <sumit.semwal@linaro.org>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>

LGTM.

Reviewed-by: Mauro Carvalho Chehab <mchehab@kernel.org>

Regards,
Mauro

> ---
>  include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 202 insertions(+)
> 
> diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
> index edd730b1e899..c6b223534b21 100644
> --- a/include/linux/iosys-map.h
> +++ b/include/linux/iosys-map.h
> @@ -6,6 +6,7 @@
>  #ifndef __IOSYS_MAP_H__
>  #define __IOSYS_MAP_H__
>  
> +#include <linux/kernel.h>
>  #include <linux/io.h>
>  #include <linux/string.h>
>  
> @@ -120,6 +121,45 @@ struct iosys_map {
>  		.is_iomem = false,	\
>  	}
>  
> +/**
> + * IOSYS_MAP_INIT_OFFSET - Initializes struct iosys_map from another iosys_map
> + * @map_:	The dma-buf mapping structure to copy from
> + * @offset_:	Offset to add to the other mapping
> + *
> + * Initializes a new iosys_map struct based on another passed as argument. It
> + * does a shallow copy of the struct so it's possible to update the back storage
> + * without changing where the original map points to. It is the equivalent of
> + * doing:
> + *
> + * .. code-block:: c
> + *
> + *	iosys_map map = other_map;
> + *	iosys_map_incr(&map, &offset);
> + *
> + * Example usage:
> + *
> + * .. code-block:: c
> + *
> + *	void foo(struct device *dev, struct iosys_map *base_map)
> + *	{
> + *		...
> + *		struct iosys_map map = IOSYS_MAP_INIT_OFFSET(base_map, FIELD_OFFSET);
> + *		...
> + *	}
> + *
> + * The advantage of using the initializer over just increasing the offset with
> + * iosys_map_incr() like above is that the new map will always point to the
> + * right place of the buffer during its scope. It reduces the risk of updating
> + * the wrong part of the buffer and having no compiler warning about that. If
> + * the assignment to IOSYS_MAP_INIT_OFFSET() is forgotten, the compiler can warn
> + * about the use of uninitialized variable.
> + */
> +#define IOSYS_MAP_INIT_OFFSET(map_, offset_) ({				\
> +	struct iosys_map copy = *map_;					\
> +	iosys_map_incr(&copy, offset_);					\
> +	copy;								\
> +})
> +
>  /**
>   * iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory
>   * @map:	The iosys_map structure
> @@ -239,6 +279,26 @@ static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
>  		memcpy(dst->vaddr + dst_offset, src, len);
>  }
>  
> +/**
> + * iosys_map_memcpy_from - Memcpy from iosys_map into system memory
> + * @dst:	Destination in system memory
> + * @src:	The iosys_map structure
> + * @src_offset:	The offset from which to copy
> + * @len:	The number of byte in src
> + *
> + * Copies data from a iosys_map with an offset. The dest buffer is in
> + * system memory. Depending on the mapping location, the helper picks the
> + * correct method of accessing the memory.
> + */
> +static inline void iosys_map_memcpy_from(void *dst, const struct iosys_map *src,
> +					 size_t src_offset, size_t len)
> +{
> +	if (src->is_iomem)
> +		memcpy_fromio(dst, src->vaddr_iomem + src_offset, len);
> +	else
> +		memcpy(dst, src->vaddr + src_offset, len);
> +}
> +
>  /**
>   * iosys_map_incr - Increments the address stored in a iosys mapping
>   * @map:	The iosys_map structure
> @@ -255,4 +315,146 @@ static inline void iosys_map_incr(struct iosys_map *map, size_t incr)
>  		map->vaddr += incr;
>  }
>  
> +/**
> + * iosys_map_memset - Memset iosys_map
> + * @dst:	The iosys_map structure
> + * @offset:	Offset from dst where to start setting value
> + * @value:	The value to set
> + * @len:	The number of bytes to set in dst
> + *
> + * Set value in iosys_map. Depending on the buffer's location, the helper
> + * picks the correct method of accessing the memory.
> + */
> +static inline void iosys_map_memset(struct iosys_map *dst, size_t offset,
> +				    int value, size_t len)
> +{
> +	if (dst->is_iomem)
> +		memset_io(dst->vaddr_iomem + offset, value, len);
> +	else
> +		memset(dst->vaddr + offset, value, len);
> +}
> +
> +/**
> + * iosys_map_rd - Read a C-type value from the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from which to read
> + * @type__:	Type of the value being read
> + *
> + * Read a C type value from iosys_map, handling possible un-aligned accesses to
> + * the mapping.
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd(map__, offset__, type__) ({			\
> +	type__ val;							\
> +	iosys_map_memcpy_from(&val, map__, offset__, sizeof(val));	\
> +	val;								\
> +})
> +
> +/**
> + * iosys_map_wr - Write a C-type value to the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from the mapping to write to
> + * @type__:	Type of the value being written
> + * @val__:	Value to write
> + *
> + * Write a C-type value to the iosys_map, handling possible un-aligned accesses
> + * to the mapping.
> + */
> +#define iosys_map_wr(map__, offset__, type__, val__) ({			\
> +	type__ val = (val__);						\
> +	iosys_map_memcpy_to(map__, offset__, &val, sizeof(val));	\
> +})
> +
> +/**
> + * iosys_map_rd_field - Read a member from a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + *
> + * Read a value from iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and its
> + * value read handling possible un-aligned memory accesses. For example: suppose
> + * there is a @struct foo defined as below and the value ``foo.field2.inner2``
> + * needs to be read from the iosys_map:
> + *
> + * .. code-block:: c
> + *
> + *	struct foo {
> + *		int field1;
> + *		struct {
> + *			int inner1;
> + *			int inner2;
> + *		} field2;
> + *		int field3;
> + *	} __packed;
> + *
> + * This is the expected memory layout of a buffer using iosys_map_rd_field():
> + *
> + * +------------------------------+--------------------------+
> + * | Address                      | Content                  |
> + * +==============================+==========================+
> + * | buffer + 0000                | start of mmapped buffer  |
> + * |                              | pointed by iosys_map     |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + ``struct_offset__`` | start of ``struct foo``  |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + wwww                | ``foo.field2.inner2``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + yyyy                | end of ``struct foo``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + zzzz                | end of mmaped buffer     |
> + * +------------------------------+--------------------------+
> + *
> + * Values automatically calculated by this macro or not needed are denoted by
> + * wwww, yyyy and zzzz. This is the code to read that value:
> + *
> + * .. code-block:: c
> + *
> + *	x = iosys_map_rd_field(&map, offset, struct foo, field2.inner2);
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
> +	struct_type__ *s;							\
> +	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
> +		     typeof(s->field__));					\
> +})
> +
> +/**
> + * iosys_map_wr_field - Write to a member of a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + * @val__:		Value to write
> + *
> + * Write a value to the iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and the
> + * @val__ is written handling possible un-aligned memory accesses. Refer to
> + * iosys_map_rd_field() for expected usage and memory layout.
> + */
> +#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
> +	struct_type__ *s;								\
> +	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
> +		     typeof(s->field__), val__);					\
> +})
> +
>  #endif /* __IOSYS_MAP_H__ */



Thanks,
Mauro

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

* Re: [Intel-gfx] [PATCH v2 02/18] iosys-map: Add a few more helpers
@ 2022-02-09  6:14     ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 59+ messages in thread
From: Mauro Carvalho Chehab @ 2022-02-09  6:14 UTC (permalink / raw)
  To: Lucas De Marchi
  Cc: Thomas Hellström, intel-gfx, linux-kernel, dri-devel,
	Sumit Semwal, Thomas Zimmermann, Christian König

Em Tue,  8 Feb 2022 02:45:08 -0800
Lucas De Marchi <lucas.demarchi@intel.com> escreveu:

> First the simplest ones:
> 
> 	- iosys_map_memset(): when abstracting system and I/O memory,
> 	  just like the memcpy() use case, memset() also has dedicated
> 	  functions to be called for using IO memory.
> 	- iosys_map_memcpy_from(): we may need to copy data from I/O
> 	  memory, not only to.
> 
> In certain situations it's useful to be able to read or write to an
> offset that is calculated by having the memory layout given by a struct
> declaration. Usually we are going to read/write a u8, u16, u32 or u64.
> 
> As a pre-requisite for the implementation, add iosys_map_memcpy_from()
> to be the equivalent of iosys_map_memcpy_to(), but in the other
> direction. Then add 2 pairs of macros:
> 
> 	- iosys_map_rd() / iosys_map_wr()
> 	- iosys_map_rd_field() / iosys_map_wr_field()
> 
> The first pair takes the C-type and offset to read/write. The second
> pair uses a struct describing the layout of the mapping in order to
> calculate the offset and size being read/written.
> 
> We could use readb, readw, readl, readq and the write* counterparts,
> however due to alignment issues this may not work on all architectures.
> If alignment needs to be checked to call the right function, it's not
> possible to decide at compile-time which function to call: so just leave
> the decision to the memcpy function that will do exactly that.
> 
> Finally, in order to use the above macros with a map derived from
> another, add another initializer: IOSYS_MAP_INIT_OFFSET().
> 
> v2:
>   - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
>     within the union
>   - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
>     allow the struct itself to be at an offset from the mapping
>   - Add documentation to iosys_map_rd_field() with example and expected
>     memory layout
> 
> Cc: Sumit Semwal <sumit.semwal@linaro.org>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>

LGTM.

Reviewed-by: Mauro Carvalho Chehab <mchehab@kernel.org>

Regards,
Mauro

> ---
>  include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 202 insertions(+)
> 
> diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
> index edd730b1e899..c6b223534b21 100644
> --- a/include/linux/iosys-map.h
> +++ b/include/linux/iosys-map.h
> @@ -6,6 +6,7 @@
>  #ifndef __IOSYS_MAP_H__
>  #define __IOSYS_MAP_H__
>  
> +#include <linux/kernel.h>
>  #include <linux/io.h>
>  #include <linux/string.h>
>  
> @@ -120,6 +121,45 @@ struct iosys_map {
>  		.is_iomem = false,	\
>  	}
>  
> +/**
> + * IOSYS_MAP_INIT_OFFSET - Initializes struct iosys_map from another iosys_map
> + * @map_:	The dma-buf mapping structure to copy from
> + * @offset_:	Offset to add to the other mapping
> + *
> + * Initializes a new iosys_map struct based on another passed as argument. It
> + * does a shallow copy of the struct so it's possible to update the back storage
> + * without changing where the original map points to. It is the equivalent of
> + * doing:
> + *
> + * .. code-block:: c
> + *
> + *	iosys_map map = other_map;
> + *	iosys_map_incr(&map, &offset);
> + *
> + * Example usage:
> + *
> + * .. code-block:: c
> + *
> + *	void foo(struct device *dev, struct iosys_map *base_map)
> + *	{
> + *		...
> + *		struct iosys_map map = IOSYS_MAP_INIT_OFFSET(base_map, FIELD_OFFSET);
> + *		...
> + *	}
> + *
> + * The advantage of using the initializer over just increasing the offset with
> + * iosys_map_incr() like above is that the new map will always point to the
> + * right place of the buffer during its scope. It reduces the risk of updating
> + * the wrong part of the buffer and having no compiler warning about that. If
> + * the assignment to IOSYS_MAP_INIT_OFFSET() is forgotten, the compiler can warn
> + * about the use of uninitialized variable.
> + */
> +#define IOSYS_MAP_INIT_OFFSET(map_, offset_) ({				\
> +	struct iosys_map copy = *map_;					\
> +	iosys_map_incr(&copy, offset_);					\
> +	copy;								\
> +})
> +
>  /**
>   * iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory
>   * @map:	The iosys_map structure
> @@ -239,6 +279,26 @@ static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
>  		memcpy(dst->vaddr + dst_offset, src, len);
>  }
>  
> +/**
> + * iosys_map_memcpy_from - Memcpy from iosys_map into system memory
> + * @dst:	Destination in system memory
> + * @src:	The iosys_map structure
> + * @src_offset:	The offset from which to copy
> + * @len:	The number of byte in src
> + *
> + * Copies data from a iosys_map with an offset. The dest buffer is in
> + * system memory. Depending on the mapping location, the helper picks the
> + * correct method of accessing the memory.
> + */
> +static inline void iosys_map_memcpy_from(void *dst, const struct iosys_map *src,
> +					 size_t src_offset, size_t len)
> +{
> +	if (src->is_iomem)
> +		memcpy_fromio(dst, src->vaddr_iomem + src_offset, len);
> +	else
> +		memcpy(dst, src->vaddr + src_offset, len);
> +}
> +
>  /**
>   * iosys_map_incr - Increments the address stored in a iosys mapping
>   * @map:	The iosys_map structure
> @@ -255,4 +315,146 @@ static inline void iosys_map_incr(struct iosys_map *map, size_t incr)
>  		map->vaddr += incr;
>  }
>  
> +/**
> + * iosys_map_memset - Memset iosys_map
> + * @dst:	The iosys_map structure
> + * @offset:	Offset from dst where to start setting value
> + * @value:	The value to set
> + * @len:	The number of bytes to set in dst
> + *
> + * Set value in iosys_map. Depending on the buffer's location, the helper
> + * picks the correct method of accessing the memory.
> + */
> +static inline void iosys_map_memset(struct iosys_map *dst, size_t offset,
> +				    int value, size_t len)
> +{
> +	if (dst->is_iomem)
> +		memset_io(dst->vaddr_iomem + offset, value, len);
> +	else
> +		memset(dst->vaddr + offset, value, len);
> +}
> +
> +/**
> + * iosys_map_rd - Read a C-type value from the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from which to read
> + * @type__:	Type of the value being read
> + *
> + * Read a C type value from iosys_map, handling possible un-aligned accesses to
> + * the mapping.
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd(map__, offset__, type__) ({			\
> +	type__ val;							\
> +	iosys_map_memcpy_from(&val, map__, offset__, sizeof(val));	\
> +	val;								\
> +})
> +
> +/**
> + * iosys_map_wr - Write a C-type value to the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from the mapping to write to
> + * @type__:	Type of the value being written
> + * @val__:	Value to write
> + *
> + * Write a C-type value to the iosys_map, handling possible un-aligned accesses
> + * to the mapping.
> + */
> +#define iosys_map_wr(map__, offset__, type__, val__) ({			\
> +	type__ val = (val__);						\
> +	iosys_map_memcpy_to(map__, offset__, &val, sizeof(val));	\
> +})
> +
> +/**
> + * iosys_map_rd_field - Read a member from a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + *
> + * Read a value from iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and its
> + * value read handling possible un-aligned memory accesses. For example: suppose
> + * there is a @struct foo defined as below and the value ``foo.field2.inner2``
> + * needs to be read from the iosys_map:
> + *
> + * .. code-block:: c
> + *
> + *	struct foo {
> + *		int field1;
> + *		struct {
> + *			int inner1;
> + *			int inner2;
> + *		} field2;
> + *		int field3;
> + *	} __packed;
> + *
> + * This is the expected memory layout of a buffer using iosys_map_rd_field():
> + *
> + * +------------------------------+--------------------------+
> + * | Address                      | Content                  |
> + * +==============================+==========================+
> + * | buffer + 0000                | start of mmapped buffer  |
> + * |                              | pointed by iosys_map     |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + ``struct_offset__`` | start of ``struct foo``  |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + wwww                | ``foo.field2.inner2``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + yyyy                | end of ``struct foo``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + zzzz                | end of mmaped buffer     |
> + * +------------------------------+--------------------------+
> + *
> + * Values automatically calculated by this macro or not needed are denoted by
> + * wwww, yyyy and zzzz. This is the code to read that value:
> + *
> + * .. code-block:: c
> + *
> + *	x = iosys_map_rd_field(&map, offset, struct foo, field2.inner2);
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
> +	struct_type__ *s;							\
> +	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
> +		     typeof(s->field__));					\
> +})
> +
> +/**
> + * iosys_map_wr_field - Write to a member of a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + * @val__:		Value to write
> + *
> + * Write a value to the iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and the
> + * @val__ is written handling possible un-aligned memory accesses. Refer to
> + * iosys_map_rd_field() for expected usage and memory layout.
> + */
> +#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
> +	struct_type__ *s;								\
> +	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
> +		     typeof(s->field__), val__);					\
> +})
> +
>  #endif /* __IOSYS_MAP_H__ */



Thanks,
Mauro

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

* Re: [PATCH v2 02/18] iosys-map: Add a few more helpers
@ 2022-02-09  6:14     ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 59+ messages in thread
From: Mauro Carvalho Chehab @ 2022-02-09  6:14 UTC (permalink / raw)
  To: Lucas De Marchi
  Cc: intel-gfx, dri-devel, John Harrison, Matthew Brost,
	Daniele Ceraolo Spurio, Matt Roper, Thomas Hellström,
	Thomas Zimmermann, Christian König, Sumit Semwal,
	linux-kernel

Em Tue,  8 Feb 2022 02:45:08 -0800
Lucas De Marchi <lucas.demarchi@intel.com> escreveu:

> First the simplest ones:
> 
> 	- iosys_map_memset(): when abstracting system and I/O memory,
> 	  just like the memcpy() use case, memset() also has dedicated
> 	  functions to be called for using IO memory.
> 	- iosys_map_memcpy_from(): we may need to copy data from I/O
> 	  memory, not only to.
> 
> In certain situations it's useful to be able to read or write to an
> offset that is calculated by having the memory layout given by a struct
> declaration. Usually we are going to read/write a u8, u16, u32 or u64.
> 
> As a pre-requisite for the implementation, add iosys_map_memcpy_from()
> to be the equivalent of iosys_map_memcpy_to(), but in the other
> direction. Then add 2 pairs of macros:
> 
> 	- iosys_map_rd() / iosys_map_wr()
> 	- iosys_map_rd_field() / iosys_map_wr_field()
> 
> The first pair takes the C-type and offset to read/write. The second
> pair uses a struct describing the layout of the mapping in order to
> calculate the offset and size being read/written.
> 
> We could use readb, readw, readl, readq and the write* counterparts,
> however due to alignment issues this may not work on all architectures.
> If alignment needs to be checked to call the right function, it's not
> possible to decide at compile-time which function to call: so just leave
> the decision to the memcpy function that will do exactly that.
> 
> Finally, in order to use the above macros with a map derived from
> another, add another initializer: IOSYS_MAP_INIT_OFFSET().
> 
> v2:
>   - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
>     within the union
>   - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
>     allow the struct itself to be at an offset from the mapping
>   - Add documentation to iosys_map_rd_field() with example and expected
>     memory layout
> 
> Cc: Sumit Semwal <sumit.semwal@linaro.org>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>

LGTM.

Reviewed-by: Mauro Carvalho Chehab <mchehab@kernel.org>

Regards,
Mauro

> ---
>  include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 202 insertions(+)
> 
> diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
> index edd730b1e899..c6b223534b21 100644
> --- a/include/linux/iosys-map.h
> +++ b/include/linux/iosys-map.h
> @@ -6,6 +6,7 @@
>  #ifndef __IOSYS_MAP_H__
>  #define __IOSYS_MAP_H__
>  
> +#include <linux/kernel.h>
>  #include <linux/io.h>
>  #include <linux/string.h>
>  
> @@ -120,6 +121,45 @@ struct iosys_map {
>  		.is_iomem = false,	\
>  	}
>  
> +/**
> + * IOSYS_MAP_INIT_OFFSET - Initializes struct iosys_map from another iosys_map
> + * @map_:	The dma-buf mapping structure to copy from
> + * @offset_:	Offset to add to the other mapping
> + *
> + * Initializes a new iosys_map struct based on another passed as argument. It
> + * does a shallow copy of the struct so it's possible to update the back storage
> + * without changing where the original map points to. It is the equivalent of
> + * doing:
> + *
> + * .. code-block:: c
> + *
> + *	iosys_map map = other_map;
> + *	iosys_map_incr(&map, &offset);
> + *
> + * Example usage:
> + *
> + * .. code-block:: c
> + *
> + *	void foo(struct device *dev, struct iosys_map *base_map)
> + *	{
> + *		...
> + *		struct iosys_map map = IOSYS_MAP_INIT_OFFSET(base_map, FIELD_OFFSET);
> + *		...
> + *	}
> + *
> + * The advantage of using the initializer over just increasing the offset with
> + * iosys_map_incr() like above is that the new map will always point to the
> + * right place of the buffer during its scope. It reduces the risk of updating
> + * the wrong part of the buffer and having no compiler warning about that. If
> + * the assignment to IOSYS_MAP_INIT_OFFSET() is forgotten, the compiler can warn
> + * about the use of uninitialized variable.
> + */
> +#define IOSYS_MAP_INIT_OFFSET(map_, offset_) ({				\
> +	struct iosys_map copy = *map_;					\
> +	iosys_map_incr(&copy, offset_);					\
> +	copy;								\
> +})
> +
>  /**
>   * iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory
>   * @map:	The iosys_map structure
> @@ -239,6 +279,26 @@ static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
>  		memcpy(dst->vaddr + dst_offset, src, len);
>  }
>  
> +/**
> + * iosys_map_memcpy_from - Memcpy from iosys_map into system memory
> + * @dst:	Destination in system memory
> + * @src:	The iosys_map structure
> + * @src_offset:	The offset from which to copy
> + * @len:	The number of byte in src
> + *
> + * Copies data from a iosys_map with an offset. The dest buffer is in
> + * system memory. Depending on the mapping location, the helper picks the
> + * correct method of accessing the memory.
> + */
> +static inline void iosys_map_memcpy_from(void *dst, const struct iosys_map *src,
> +					 size_t src_offset, size_t len)
> +{
> +	if (src->is_iomem)
> +		memcpy_fromio(dst, src->vaddr_iomem + src_offset, len);
> +	else
> +		memcpy(dst, src->vaddr + src_offset, len);
> +}
> +
>  /**
>   * iosys_map_incr - Increments the address stored in a iosys mapping
>   * @map:	The iosys_map structure
> @@ -255,4 +315,146 @@ static inline void iosys_map_incr(struct iosys_map *map, size_t incr)
>  		map->vaddr += incr;
>  }
>  
> +/**
> + * iosys_map_memset - Memset iosys_map
> + * @dst:	The iosys_map structure
> + * @offset:	Offset from dst where to start setting value
> + * @value:	The value to set
> + * @len:	The number of bytes to set in dst
> + *
> + * Set value in iosys_map. Depending on the buffer's location, the helper
> + * picks the correct method of accessing the memory.
> + */
> +static inline void iosys_map_memset(struct iosys_map *dst, size_t offset,
> +				    int value, size_t len)
> +{
> +	if (dst->is_iomem)
> +		memset_io(dst->vaddr_iomem + offset, value, len);
> +	else
> +		memset(dst->vaddr + offset, value, len);
> +}
> +
> +/**
> + * iosys_map_rd - Read a C-type value from the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from which to read
> + * @type__:	Type of the value being read
> + *
> + * Read a C type value from iosys_map, handling possible un-aligned accesses to
> + * the mapping.
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd(map__, offset__, type__) ({			\
> +	type__ val;							\
> +	iosys_map_memcpy_from(&val, map__, offset__, sizeof(val));	\
> +	val;								\
> +})
> +
> +/**
> + * iosys_map_wr - Write a C-type value to the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from the mapping to write to
> + * @type__:	Type of the value being written
> + * @val__:	Value to write
> + *
> + * Write a C-type value to the iosys_map, handling possible un-aligned accesses
> + * to the mapping.
> + */
> +#define iosys_map_wr(map__, offset__, type__, val__) ({			\
> +	type__ val = (val__);						\
> +	iosys_map_memcpy_to(map__, offset__, &val, sizeof(val));	\
> +})
> +
> +/**
> + * iosys_map_rd_field - Read a member from a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + *
> + * Read a value from iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and its
> + * value read handling possible un-aligned memory accesses. For example: suppose
> + * there is a @struct foo defined as below and the value ``foo.field2.inner2``
> + * needs to be read from the iosys_map:
> + *
> + * .. code-block:: c
> + *
> + *	struct foo {
> + *		int field1;
> + *		struct {
> + *			int inner1;
> + *			int inner2;
> + *		} field2;
> + *		int field3;
> + *	} __packed;
> + *
> + * This is the expected memory layout of a buffer using iosys_map_rd_field():
> + *
> + * +------------------------------+--------------------------+
> + * | Address                      | Content                  |
> + * +==============================+==========================+
> + * | buffer + 0000                | start of mmapped buffer  |
> + * |                              | pointed by iosys_map     |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + ``struct_offset__`` | start of ``struct foo``  |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + wwww                | ``foo.field2.inner2``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + yyyy                | end of ``struct foo``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + zzzz                | end of mmaped buffer     |
> + * +------------------------------+--------------------------+
> + *
> + * Values automatically calculated by this macro or not needed are denoted by
> + * wwww, yyyy and zzzz. This is the code to read that value:
> + *
> + * .. code-block:: c
> + *
> + *	x = iosys_map_rd_field(&map, offset, struct foo, field2.inner2);
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
> +	struct_type__ *s;							\
> +	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
> +		     typeof(s->field__));					\
> +})
> +
> +/**
> + * iosys_map_wr_field - Write to a member of a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + * @val__:		Value to write
> + *
> + * Write a value to the iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and the
> + * @val__ is written handling possible un-aligned memory accesses. Refer to
> + * iosys_map_rd_field() for expected usage and memory layout.
> + */
> +#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
> +	struct_type__ *s;								\
> +	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
> +		     typeof(s->field__), val__);					\
> +})
> +
>  #endif /* __IOSYS_MAP_H__ */



Thanks,
Mauro

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

* Re: [PATCH v2 02/18] iosys-map: Add a few more helpers
  2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
@ 2022-02-09  6:23     ` Thomas Zimmermann
  -1 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2022-02-09  6:23 UTC (permalink / raw)
  To: Lucas De Marchi, intel-gfx, dri-devel
  Cc: Matthew Brost, Thomas Hellström, linux-kernel,
	Daniele Ceraolo Spurio, Mauro Carvalho Chehab,
	Christian König, John Harrison


[-- Attachment #1.1: Type: text/plain, Size: 11826 bytes --]

Hi

Am 08.02.22 um 11:45 schrieb Lucas De Marchi:
> First the simplest ones:
> 
> 	- iosys_map_memset(): when abstracting system and I/O memory,
> 	  just like the memcpy() use case, memset() also has dedicated
> 	  functions to be called for using IO memory.
> 	- iosys_map_memcpy_from(): we may need to copy data from I/O
> 	  memory, not only to.
> 
> In certain situations it's useful to be able to read or write to an
> offset that is calculated by having the memory layout given by a struct
> declaration. Usually we are going to read/write a u8, u16, u32 or u64.
> 
> As a pre-requisite for the implementation, add iosys_map_memcpy_from()
> to be the equivalent of iosys_map_memcpy_to(), but in the other
> direction. Then add 2 pairs of macros:
> 
> 	- iosys_map_rd() / iosys_map_wr()
> 	- iosys_map_rd_field() / iosys_map_wr_field()
> 
> The first pair takes the C-type and offset to read/write. The second
> pair uses a struct describing the layout of the mapping in order to
> calculate the offset and size being read/written.
> 
> We could use readb, readw, readl, readq and the write* counterparts,
> however due to alignment issues this may not work on all architectures.
> If alignment needs to be checked to call the right function, it's not
> possible to decide at compile-time which function to call: so just leave
> the decision to the memcpy function that will do exactly that.
> 
> Finally, in order to use the above macros with a map derived from
> another, add another initializer: IOSYS_MAP_INIT_OFFSET().
> 
> v2:
>    - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
>      within the union
>    - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
>      allow the struct itself to be at an offset from the mapping
>    - Add documentation to iosys_map_rd_field() with example and expected
>      memory layout
> 
> Cc: Sumit Semwal <sumit.semwal@linaro.org>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
> ---
>   include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
>   1 file changed, 202 insertions(+)
> 
> diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
> index edd730b1e899..c6b223534b21 100644
> --- a/include/linux/iosys-map.h
> +++ b/include/linux/iosys-map.h
> @@ -6,6 +6,7 @@
>   #ifndef __IOSYS_MAP_H__
>   #define __IOSYS_MAP_H__
>   
> +#include <linux/kernel.h>
>   #include <linux/io.h>
>   #include <linux/string.h>

Alphabetically sorted, please.

What requires kernel.h? Can this be reduced to another include 
statement? Maybe stddef.h for offsetof() ?

Best regards
Thomas

>   
> @@ -120,6 +121,45 @@ struct iosys_map {
>   		.is_iomem = false,	\
>   	}
>   
> +/**
> + * IOSYS_MAP_INIT_OFFSET - Initializes struct iosys_map from another iosys_map
> + * @map_:	The dma-buf mapping structure to copy from
> + * @offset_:	Offset to add to the other mapping
> + *
> + * Initializes a new iosys_map struct based on another passed as argument. It
> + * does a shallow copy of the struct so it's possible to update the back storage
> + * without changing where the original map points to. It is the equivalent of
> + * doing:
> + *
> + * .. code-block:: c
> + *
> + *	iosys_map map = other_map;
> + *	iosys_map_incr(&map, &offset);
> + *
> + * Example usage:
> + *
> + * .. code-block:: c
> + *
> + *	void foo(struct device *dev, struct iosys_map *base_map)
> + *	{
> + *		...
> + *		struct iosys_map map = IOSYS_MAP_INIT_OFFSET(base_map, FIELD_OFFSET);
> + *		...
> + *	}
> + *
> + * The advantage of using the initializer over just increasing the offset with
> + * iosys_map_incr() like above is that the new map will always point to the
> + * right place of the buffer during its scope. It reduces the risk of updating
> + * the wrong part of the buffer and having no compiler warning about that. If
> + * the assignment to IOSYS_MAP_INIT_OFFSET() is forgotten, the compiler can warn
> + * about the use of uninitialized variable.
> + */
> +#define IOSYS_MAP_INIT_OFFSET(map_, offset_) ({				\
> +	struct iosys_map copy = *map_;					\
> +	iosys_map_incr(&copy, offset_);					\
> +	copy;								\
> +})
> +
>   /**
>    * iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory
>    * @map:	The iosys_map structure
> @@ -239,6 +279,26 @@ static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
>   		memcpy(dst->vaddr + dst_offset, src, len);
>   }
>   
> +/**
> + * iosys_map_memcpy_from - Memcpy from iosys_map into system memory
> + * @dst:	Destination in system memory
> + * @src:	The iosys_map structure
> + * @src_offset:	The offset from which to copy
> + * @len:	The number of byte in src
> + *
> + * Copies data from a iosys_map with an offset. The dest buffer is in
> + * system memory. Depending on the mapping location, the helper picks the
> + * correct method of accessing the memory.
> + */
> +static inline void iosys_map_memcpy_from(void *dst, const struct iosys_map *src,
> +					 size_t src_offset, size_t len)
> +{
> +	if (src->is_iomem)
> +		memcpy_fromio(dst, src->vaddr_iomem + src_offset, len);
> +	else
> +		memcpy(dst, src->vaddr + src_offset, len);
> +}
> +
>   /**
>    * iosys_map_incr - Increments the address stored in a iosys mapping
>    * @map:	The iosys_map structure
> @@ -255,4 +315,146 @@ static inline void iosys_map_incr(struct iosys_map *map, size_t incr)
>   		map->vaddr += incr;
>   }
>   
> +/**
> + * iosys_map_memset - Memset iosys_map
> + * @dst:	The iosys_map structure
> + * @offset:	Offset from dst where to start setting value
> + * @value:	The value to set
> + * @len:	The number of bytes to set in dst
> + *
> + * Set value in iosys_map. Depending on the buffer's location, the helper
> + * picks the correct method of accessing the memory.
> + */
> +static inline void iosys_map_memset(struct iosys_map *dst, size_t offset,
> +				    int value, size_t len)
> +{
> +	if (dst->is_iomem)
> +		memset_io(dst->vaddr_iomem + offset, value, len);
> +	else
> +		memset(dst->vaddr + offset, value, len);
> +}
> +
> +/**
> + * iosys_map_rd - Read a C-type value from the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from which to read
> + * @type__:	Type of the value being read
> + *
> + * Read a C type value from iosys_map, handling possible un-aligned accesses to
> + * the mapping.
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd(map__, offset__, type__) ({			\
> +	type__ val;							\
> +	iosys_map_memcpy_from(&val, map__, offset__, sizeof(val));	\
> +	val;								\
> +})
> +
> +/**
> + * iosys_map_wr - Write a C-type value to the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from the mapping to write to
> + * @type__:	Type of the value being written
> + * @val__:	Value to write
> + *
> + * Write a C-type value to the iosys_map, handling possible un-aligned accesses
> + * to the mapping.
> + */
> +#define iosys_map_wr(map__, offset__, type__, val__) ({			\
> +	type__ val = (val__);						\
> +	iosys_map_memcpy_to(map__, offset__, &val, sizeof(val));	\
> +})
> +
> +/**
> + * iosys_map_rd_field - Read a member from a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + *
> + * Read a value from iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and its
> + * value read handling possible un-aligned memory accesses. For example: suppose
> + * there is a @struct foo defined as below and the value ``foo.field2.inner2``
> + * needs to be read from the iosys_map:
> + *
> + * .. code-block:: c
> + *
> + *	struct foo {
> + *		int field1;
> + *		struct {
> + *			int inner1;
> + *			int inner2;
> + *		} field2;
> + *		int field3;
> + *	} __packed;
> + *
> + * This is the expected memory layout of a buffer using iosys_map_rd_field():
> + *
> + * +------------------------------+--------------------------+
> + * | Address                      | Content                  |
> + * +==============================+==========================+
> + * | buffer + 0000                | start of mmapped buffer  |
> + * |                              | pointed by iosys_map     |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + ``struct_offset__`` | start of ``struct foo``  |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + wwww                | ``foo.field2.inner2``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + yyyy                | end of ``struct foo``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + zzzz                | end of mmaped buffer     |
> + * +------------------------------+--------------------------+
> + *
> + * Values automatically calculated by this macro or not needed are denoted by
> + * wwww, yyyy and zzzz. This is the code to read that value:
> + *
> + * .. code-block:: c
> + *
> + *	x = iosys_map_rd_field(&map, offset, struct foo, field2.inner2);
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
> +	struct_type__ *s;							\
> +	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
> +		     typeof(s->field__));					\
> +})
> +
> +/**
> + * iosys_map_wr_field - Write to a member of a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + * @val__:		Value to write
> + *
> + * Write a value to the iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and the
> + * @val__ is written handling possible un-aligned memory accesses. Refer to
> + * iosys_map_rd_field() for expected usage and memory layout.
> + */
> +#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
> +	struct_type__ *s;								\
> +	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
> +		     typeof(s->field__), val__);					\
> +})
> +
>   #endif /* __IOSYS_MAP_H__ */

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

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

* Re: [Intel-gfx] [PATCH v2 02/18] iosys-map: Add a few more helpers
@ 2022-02-09  6:23     ` Thomas Zimmermann
  0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2022-02-09  6:23 UTC (permalink / raw)
  To: Lucas De Marchi, intel-gfx, dri-devel
  Cc: Thomas Hellström, linux-kernel, Mauro Carvalho Chehab,
	Christian König


[-- Attachment #1.1: Type: text/plain, Size: 11826 bytes --]

Hi

Am 08.02.22 um 11:45 schrieb Lucas De Marchi:
> First the simplest ones:
> 
> 	- iosys_map_memset(): when abstracting system and I/O memory,
> 	  just like the memcpy() use case, memset() also has dedicated
> 	  functions to be called for using IO memory.
> 	- iosys_map_memcpy_from(): we may need to copy data from I/O
> 	  memory, not only to.
> 
> In certain situations it's useful to be able to read or write to an
> offset that is calculated by having the memory layout given by a struct
> declaration. Usually we are going to read/write a u8, u16, u32 or u64.
> 
> As a pre-requisite for the implementation, add iosys_map_memcpy_from()
> to be the equivalent of iosys_map_memcpy_to(), but in the other
> direction. Then add 2 pairs of macros:
> 
> 	- iosys_map_rd() / iosys_map_wr()
> 	- iosys_map_rd_field() / iosys_map_wr_field()
> 
> The first pair takes the C-type and offset to read/write. The second
> pair uses a struct describing the layout of the mapping in order to
> calculate the offset and size being read/written.
> 
> We could use readb, readw, readl, readq and the write* counterparts,
> however due to alignment issues this may not work on all architectures.
> If alignment needs to be checked to call the right function, it's not
> possible to decide at compile-time which function to call: so just leave
> the decision to the memcpy function that will do exactly that.
> 
> Finally, in order to use the above macros with a map derived from
> another, add another initializer: IOSYS_MAP_INIT_OFFSET().
> 
> v2:
>    - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
>      within the union
>    - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
>      allow the struct itself to be at an offset from the mapping
>    - Add documentation to iosys_map_rd_field() with example and expected
>      memory layout
> 
> Cc: Sumit Semwal <sumit.semwal@linaro.org>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
> ---
>   include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
>   1 file changed, 202 insertions(+)
> 
> diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
> index edd730b1e899..c6b223534b21 100644
> --- a/include/linux/iosys-map.h
> +++ b/include/linux/iosys-map.h
> @@ -6,6 +6,7 @@
>   #ifndef __IOSYS_MAP_H__
>   #define __IOSYS_MAP_H__
>   
> +#include <linux/kernel.h>
>   #include <linux/io.h>
>   #include <linux/string.h>

Alphabetically sorted, please.

What requires kernel.h? Can this be reduced to another include 
statement? Maybe stddef.h for offsetof() ?

Best regards
Thomas

>   
> @@ -120,6 +121,45 @@ struct iosys_map {
>   		.is_iomem = false,	\
>   	}
>   
> +/**
> + * IOSYS_MAP_INIT_OFFSET - Initializes struct iosys_map from another iosys_map
> + * @map_:	The dma-buf mapping structure to copy from
> + * @offset_:	Offset to add to the other mapping
> + *
> + * Initializes a new iosys_map struct based on another passed as argument. It
> + * does a shallow copy of the struct so it's possible to update the back storage
> + * without changing where the original map points to. It is the equivalent of
> + * doing:
> + *
> + * .. code-block:: c
> + *
> + *	iosys_map map = other_map;
> + *	iosys_map_incr(&map, &offset);
> + *
> + * Example usage:
> + *
> + * .. code-block:: c
> + *
> + *	void foo(struct device *dev, struct iosys_map *base_map)
> + *	{
> + *		...
> + *		struct iosys_map map = IOSYS_MAP_INIT_OFFSET(base_map, FIELD_OFFSET);
> + *		...
> + *	}
> + *
> + * The advantage of using the initializer over just increasing the offset with
> + * iosys_map_incr() like above is that the new map will always point to the
> + * right place of the buffer during its scope. It reduces the risk of updating
> + * the wrong part of the buffer and having no compiler warning about that. If
> + * the assignment to IOSYS_MAP_INIT_OFFSET() is forgotten, the compiler can warn
> + * about the use of uninitialized variable.
> + */
> +#define IOSYS_MAP_INIT_OFFSET(map_, offset_) ({				\
> +	struct iosys_map copy = *map_;					\
> +	iosys_map_incr(&copy, offset_);					\
> +	copy;								\
> +})
> +
>   /**
>    * iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory
>    * @map:	The iosys_map structure
> @@ -239,6 +279,26 @@ static inline void iosys_map_memcpy_to(struct iosys_map *dst, size_t dst_offset,
>   		memcpy(dst->vaddr + dst_offset, src, len);
>   }
>   
> +/**
> + * iosys_map_memcpy_from - Memcpy from iosys_map into system memory
> + * @dst:	Destination in system memory
> + * @src:	The iosys_map structure
> + * @src_offset:	The offset from which to copy
> + * @len:	The number of byte in src
> + *
> + * Copies data from a iosys_map with an offset. The dest buffer is in
> + * system memory. Depending on the mapping location, the helper picks the
> + * correct method of accessing the memory.
> + */
> +static inline void iosys_map_memcpy_from(void *dst, const struct iosys_map *src,
> +					 size_t src_offset, size_t len)
> +{
> +	if (src->is_iomem)
> +		memcpy_fromio(dst, src->vaddr_iomem + src_offset, len);
> +	else
> +		memcpy(dst, src->vaddr + src_offset, len);
> +}
> +
>   /**
>    * iosys_map_incr - Increments the address stored in a iosys mapping
>    * @map:	The iosys_map structure
> @@ -255,4 +315,146 @@ static inline void iosys_map_incr(struct iosys_map *map, size_t incr)
>   		map->vaddr += incr;
>   }
>   
> +/**
> + * iosys_map_memset - Memset iosys_map
> + * @dst:	The iosys_map structure
> + * @offset:	Offset from dst where to start setting value
> + * @value:	The value to set
> + * @len:	The number of bytes to set in dst
> + *
> + * Set value in iosys_map. Depending on the buffer's location, the helper
> + * picks the correct method of accessing the memory.
> + */
> +static inline void iosys_map_memset(struct iosys_map *dst, size_t offset,
> +				    int value, size_t len)
> +{
> +	if (dst->is_iomem)
> +		memset_io(dst->vaddr_iomem + offset, value, len);
> +	else
> +		memset(dst->vaddr + offset, value, len);
> +}
> +
> +/**
> + * iosys_map_rd - Read a C-type value from the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from which to read
> + * @type__:	Type of the value being read
> + *
> + * Read a C type value from iosys_map, handling possible un-aligned accesses to
> + * the mapping.
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd(map__, offset__, type__) ({			\
> +	type__ val;							\
> +	iosys_map_memcpy_from(&val, map__, offset__, sizeof(val));	\
> +	val;								\
> +})
> +
> +/**
> + * iosys_map_wr - Write a C-type value to the iosys_map
> + *
> + * @map__:	The iosys_map structure
> + * @offset__:	The offset from the mapping to write to
> + * @type__:	Type of the value being written
> + * @val__:	Value to write
> + *
> + * Write a C-type value to the iosys_map, handling possible un-aligned accesses
> + * to the mapping.
> + */
> +#define iosys_map_wr(map__, offset__, type__, val__) ({			\
> +	type__ val = (val__);						\
> +	iosys_map_memcpy_to(map__, offset__, &val, sizeof(val));	\
> +})
> +
> +/**
> + * iosys_map_rd_field - Read a member from a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + *
> + * Read a value from iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and its
> + * value read handling possible un-aligned memory accesses. For example: suppose
> + * there is a @struct foo defined as below and the value ``foo.field2.inner2``
> + * needs to be read from the iosys_map:
> + *
> + * .. code-block:: c
> + *
> + *	struct foo {
> + *		int field1;
> + *		struct {
> + *			int inner1;
> + *			int inner2;
> + *		} field2;
> + *		int field3;
> + *	} __packed;
> + *
> + * This is the expected memory layout of a buffer using iosys_map_rd_field():
> + *
> + * +------------------------------+--------------------------+
> + * | Address                      | Content                  |
> + * +==============================+==========================+
> + * | buffer + 0000                | start of mmapped buffer  |
> + * |                              | pointed by iosys_map     |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + ``struct_offset__`` | start of ``struct foo``  |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + wwww                | ``foo.field2.inner2``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + yyyy                | end of ``struct foo``    |
> + * +------------------------------+--------------------------+
> + * | ...                          | ...                      |
> + * +------------------------------+--------------------------+
> + * | buffer + zzzz                | end of mmaped buffer     |
> + * +------------------------------+--------------------------+
> + *
> + * Values automatically calculated by this macro or not needed are denoted by
> + * wwww, yyyy and zzzz. This is the code to read that value:
> + *
> + * .. code-block:: c
> + *
> + *	x = iosys_map_rd_field(&map, offset, struct foo, field2.inner2);
> + *
> + * Returns:
> + * The value read from the mapping.
> + */
> +#define iosys_map_rd_field(map__, struct_offset__, struct_type__, field__) ({	\
> +	struct_type__ *s;							\
> +	iosys_map_rd(map__, struct_offset__ + offsetof(struct_type__, field__),	\
> +		     typeof(s->field__));					\
> +})
> +
> +/**
> + * iosys_map_wr_field - Write to a member of a struct in the iosys_map
> + *
> + * @map__:		The iosys_map structure
> + * @struct_offset__:	Offset from the beggining of the map, where the struct
> + *			is located
> + * @struct_type__:	The struct describing the layout of the mapping
> + * @field__:		Member of the struct to read
> + * @val__:		Value to write
> + *
> + * Write a value to the iosys_map considering its layout is described by a C struct
> + * starting at @struct_offset__. The field offset and size is calculated and the
> + * @val__ is written handling possible un-aligned memory accesses. Refer to
> + * iosys_map_rd_field() for expected usage and memory layout.
> + */
> +#define iosys_map_wr_field(map__, struct_offset__, struct_type__, field__, val__) ({	\
> +	struct_type__ *s;								\
> +	iosys_map_wr(map__, struct_offset__ + offsetof(struct_type__, field__),		\
> +		     typeof(s->field__), val__);					\
> +})
> +
>   #endif /* __IOSYS_MAP_H__ */

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

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

* Re: [PATCH v2 02/18] iosys-map: Add a few more helpers
  2022-02-09  6:23     ` [Intel-gfx] " Thomas Zimmermann
  (?)
@ 2022-02-09  6:43       ` Lucas De Marchi
  -1 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-09  6:43 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: intel-gfx, dri-devel, Matthew Brost, Thomas Hellström,
	linux-kernel, Daniele Ceraolo Spurio, Mauro Carvalho Chehab,
	Christian König, John Harrison

On Wed, Feb 09, 2022 at 07:23:04AM +0100, Thomas Zimmermann wrote:
>Hi
>
>Am 08.02.22 um 11:45 schrieb Lucas De Marchi:
>>First the simplest ones:
>>
>>	- iosys_map_memset(): when abstracting system and I/O memory,
>>	  just like the memcpy() use case, memset() also has dedicated
>>	  functions to be called for using IO memory.
>>	- iosys_map_memcpy_from(): we may need to copy data from I/O
>>	  memory, not only to.
>>
>>In certain situations it's useful to be able to read or write to an
>>offset that is calculated by having the memory layout given by a struct
>>declaration. Usually we are going to read/write a u8, u16, u32 or u64.
>>
>>As a pre-requisite for the implementation, add iosys_map_memcpy_from()
>>to be the equivalent of iosys_map_memcpy_to(), but in the other
>>direction. Then add 2 pairs of macros:
>>
>>	- iosys_map_rd() / iosys_map_wr()
>>	- iosys_map_rd_field() / iosys_map_wr_field()
>>
>>The first pair takes the C-type and offset to read/write. The second
>>pair uses a struct describing the layout of the mapping in order to
>>calculate the offset and size being read/written.
>>
>>We could use readb, readw, readl, readq and the write* counterparts,
>>however due to alignment issues this may not work on all architectures.
>>If alignment needs to be checked to call the right function, it's not
>>possible to decide at compile-time which function to call: so just leave
>>the decision to the memcpy function that will do exactly that.
>>
>>Finally, in order to use the above macros with a map derived from
>>another, add another initializer: IOSYS_MAP_INIT_OFFSET().
>>
>>v2:
>>   - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
>>     within the union
>>   - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
>>     allow the struct itself to be at an offset from the mapping
>>   - Add documentation to iosys_map_rd_field() with example and expected
>>     memory layout
>>
>>Cc: Sumit Semwal <sumit.semwal@linaro.org>
>>Cc: Christian König <christian.koenig@amd.com>
>>Cc: Thomas Zimmermann <tzimmermann@suse.de>
>>Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
>>Cc: dri-devel@lists.freedesktop.org
>>Cc: linux-kernel@vger.kernel.org
>>Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
>>---
>>  include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 202 insertions(+)
>>
>>diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
>>index edd730b1e899..c6b223534b21 100644
>>--- a/include/linux/iosys-map.h
>>+++ b/include/linux/iosys-map.h
>>@@ -6,6 +6,7 @@
>>  #ifndef __IOSYS_MAP_H__
>>  #define __IOSYS_MAP_H__
>>+#include <linux/kernel.h>
>>  #include <linux/io.h>
>>  #include <linux/string.h>
>
>Alphabetically sorted, please.
>
>What requires kernel.h? Can this be reduced to another include 
>statement? Maybe stddef.h for offsetof() ?

Humn... I believe it was something in the previous implementation that
is not there anymore. Because this builds fine without the include now
and I don't think it is something being included by the headers already
here.  So this additional include can just be removed.

Lucas De Marchi

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

* Re: [PATCH v2 02/18] iosys-map: Add a few more helpers
@ 2022-02-09  6:43       ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-09  6:43 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Matthew Brost, Thomas Hellström, intel-gfx, linux-kernel,
	dri-devel, Daniele Ceraolo Spurio, Mauro Carvalho Chehab,
	Christian König, John Harrison

On Wed, Feb 09, 2022 at 07:23:04AM +0100, Thomas Zimmermann wrote:
>Hi
>
>Am 08.02.22 um 11:45 schrieb Lucas De Marchi:
>>First the simplest ones:
>>
>>	- iosys_map_memset(): when abstracting system and I/O memory,
>>	  just like the memcpy() use case, memset() also has dedicated
>>	  functions to be called for using IO memory.
>>	- iosys_map_memcpy_from(): we may need to copy data from I/O
>>	  memory, not only to.
>>
>>In certain situations it's useful to be able to read or write to an
>>offset that is calculated by having the memory layout given by a struct
>>declaration. Usually we are going to read/write a u8, u16, u32 or u64.
>>
>>As a pre-requisite for the implementation, add iosys_map_memcpy_from()
>>to be the equivalent of iosys_map_memcpy_to(), but in the other
>>direction. Then add 2 pairs of macros:
>>
>>	- iosys_map_rd() / iosys_map_wr()
>>	- iosys_map_rd_field() / iosys_map_wr_field()
>>
>>The first pair takes the C-type and offset to read/write. The second
>>pair uses a struct describing the layout of the mapping in order to
>>calculate the offset and size being read/written.
>>
>>We could use readb, readw, readl, readq and the write* counterparts,
>>however due to alignment issues this may not work on all architectures.
>>If alignment needs to be checked to call the right function, it's not
>>possible to decide at compile-time which function to call: so just leave
>>the decision to the memcpy function that will do exactly that.
>>
>>Finally, in order to use the above macros with a map derived from
>>another, add another initializer: IOSYS_MAP_INIT_OFFSET().
>>
>>v2:
>>   - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
>>     within the union
>>   - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
>>     allow the struct itself to be at an offset from the mapping
>>   - Add documentation to iosys_map_rd_field() with example and expected
>>     memory layout
>>
>>Cc: Sumit Semwal <sumit.semwal@linaro.org>
>>Cc: Christian König <christian.koenig@amd.com>
>>Cc: Thomas Zimmermann <tzimmermann@suse.de>
>>Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
>>Cc: dri-devel@lists.freedesktop.org
>>Cc: linux-kernel@vger.kernel.org
>>Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
>>---
>>  include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 202 insertions(+)
>>
>>diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
>>index edd730b1e899..c6b223534b21 100644
>>--- a/include/linux/iosys-map.h
>>+++ b/include/linux/iosys-map.h
>>@@ -6,6 +6,7 @@
>>  #ifndef __IOSYS_MAP_H__
>>  #define __IOSYS_MAP_H__
>>+#include <linux/kernel.h>
>>  #include <linux/io.h>
>>  #include <linux/string.h>
>
>Alphabetically sorted, please.
>
>What requires kernel.h? Can this be reduced to another include 
>statement? Maybe stddef.h for offsetof() ?

Humn... I believe it was something in the previous implementation that
is not there anymore. Because this builds fine without the include now
and I don't think it is something being included by the headers already
here.  So this additional include can just be removed.

Lucas De Marchi

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

* Re: [Intel-gfx] [PATCH v2 02/18] iosys-map: Add a few more helpers
@ 2022-02-09  6:43       ` Lucas De Marchi
  0 siblings, 0 replies; 59+ messages in thread
From: Lucas De Marchi @ 2022-02-09  6:43 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Thomas Hellström, intel-gfx, linux-kernel, dri-devel,
	Mauro Carvalho Chehab, Christian König

On Wed, Feb 09, 2022 at 07:23:04AM +0100, Thomas Zimmermann wrote:
>Hi
>
>Am 08.02.22 um 11:45 schrieb Lucas De Marchi:
>>First the simplest ones:
>>
>>	- iosys_map_memset(): when abstracting system and I/O memory,
>>	  just like the memcpy() use case, memset() also has dedicated
>>	  functions to be called for using IO memory.
>>	- iosys_map_memcpy_from(): we may need to copy data from I/O
>>	  memory, not only to.
>>
>>In certain situations it's useful to be able to read or write to an
>>offset that is calculated by having the memory layout given by a struct
>>declaration. Usually we are going to read/write a u8, u16, u32 or u64.
>>
>>As a pre-requisite for the implementation, add iosys_map_memcpy_from()
>>to be the equivalent of iosys_map_memcpy_to(), but in the other
>>direction. Then add 2 pairs of macros:
>>
>>	- iosys_map_rd() / iosys_map_wr()
>>	- iosys_map_rd_field() / iosys_map_wr_field()
>>
>>The first pair takes the C-type and offset to read/write. The second
>>pair uses a struct describing the layout of the mapping in order to
>>calculate the offset and size being read/written.
>>
>>We could use readb, readw, readl, readq and the write* counterparts,
>>however due to alignment issues this may not work on all architectures.
>>If alignment needs to be checked to call the right function, it's not
>>possible to decide at compile-time which function to call: so just leave
>>the decision to the memcpy function that will do exactly that.
>>
>>Finally, in order to use the above macros with a map derived from
>>another, add another initializer: IOSYS_MAP_INIT_OFFSET().
>>
>>v2:
>>   - Rework IOSYS_MAP_INIT_OFFSET() so it doesn't rely on aliasing rules
>>     within the union
>>   - Add offset to both iosys_map_rd_field() and iosys_map_wr_field() to
>>     allow the struct itself to be at an offset from the mapping
>>   - Add documentation to iosys_map_rd_field() with example and expected
>>     memory layout
>>
>>Cc: Sumit Semwal <sumit.semwal@linaro.org>
>>Cc: Christian König <christian.koenig@amd.com>
>>Cc: Thomas Zimmermann <tzimmermann@suse.de>
>>Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
>>Cc: dri-devel@lists.freedesktop.org
>>Cc: linux-kernel@vger.kernel.org
>>Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
>>---
>>  include/linux/iosys-map.h | 202 ++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 202 insertions(+)
>>
>>diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
>>index edd730b1e899..c6b223534b21 100644
>>--- a/include/linux/iosys-map.h
>>+++ b/include/linux/iosys-map.h
>>@@ -6,6 +6,7 @@
>>  #ifndef __IOSYS_MAP_H__
>>  #define __IOSYS_MAP_H__
>>+#include <linux/kernel.h>
>>  #include <linux/io.h>
>>  #include <linux/string.h>
>
>Alphabetically sorted, please.
>
>What requires kernel.h? Can this be reduced to another include 
>statement? Maybe stddef.h for offsetof() ?

Humn... I believe it was something in the previous implementation that
is not there anymore. Because this builds fine without the include now
and I don't think it is something being included by the headers already
here.  So this additional include can just be removed.

Lucas De Marchi

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

* Re: [Intel-gfx] [PATCH v2 04/18] drm/i915/guc: Keep iosys_map of ads_blob around
  2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
  (?)
@ 2022-02-10 22:56   ` Matt Atwood
  -1 siblings, 0 replies; 59+ messages in thread
From: Matt Atwood @ 2022-02-10 22:56 UTC (permalink / raw)
  To: Lucas De Marchi

On Tue, Feb 08, 2022 at 02:45:10AM -0800, Lucas De Marchi wrote:
> Convert intel_guc_ads_create() and initialization to use iosys_map
> rather than plain pointer and save it in the guc struct. This will help
> with additional updates to the ads_blob after the
> creation/initialization by abstracting the IO vs system memory.
> 
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: John Harrison <John.C.Harrison@Intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc.h     | 4 +++-
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 6 ++++++
>  2 files changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> index 697d9d66acef..9b9ba79f7594 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> @@ -6,8 +6,9 @@
>  #ifndef _INTEL_GUC_H_
>  #define _INTEL_GUC_H_
>  
> -#include <linux/xarray.h>
>  #include <linux/delay.h>
> +#include <linux/iosys-map.h>
> +#include <linux/xarray.h>
>  
>  #include "intel_uncore.h"
>  #include "intel_guc_fw.h"
> @@ -148,6 +149,7 @@ struct intel_guc {
>  	struct i915_vma *ads_vma;
>  	/** @ads_blob: contents of the GuC ADS */
>  	struct __guc_ads_blob *ads_blob;
> +	struct iosys_map ads_map;
>  	/** @ads_regset_size: size of the save/restore regsets in the ADS */
>  	u32 ads_regset_size;
>  	/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> index e61150adcbe9..13671b186908 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> @@ -624,6 +624,11 @@ int intel_guc_ads_create(struct intel_guc *guc)
>  	if (ret)
>  		return ret;
>  
> +	if (i915_gem_object_is_lmem(guc->ads_vma->obj))
> +		iosys_map_set_vaddr_iomem(&guc->ads_map, (void __iomem *)guc->ads_blob);
> +	else
> +		iosys_map_set_vaddr(&guc->ads_map, guc->ads_blob);
> +
>  	__guc_ads_init(guc);
>  
>  	return 0;
> @@ -645,6 +650,7 @@ void intel_guc_ads_destroy(struct intel_guc *guc)
>  {
>  	i915_vma_unpin_and_release(&guc->ads_vma, I915_VMA_RELEASE_MAP);
>  	guc->ads_blob = NULL;
> +	iosys_map_clear(&guc->ads_map);
>  }
>  
>  static void guc_ads_private_data_reset(struct intel_guc *guc)
> -- 
> 2.35.1
> 

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

* Re: [Intel-gfx] [PATCH v2 05/18] drm/i915/guc: Add read/write helpers for ADS blob
  2022-02-08 10:45   ` Lucas De Marchi
  (?)
@ 2022-02-10 23:00   ` Matt Atwood
  -1 siblings, 0 replies; 59+ messages in thread
From: Matt Atwood @ 2022-02-10 23:00 UTC (permalink / raw)
  To: Lucas De Marchi

On Tue, Feb 08, 2022 at 02:45:11AM -0800, Lucas De Marchi wrote:
> Add helpers on top of iosys_map_read_field() /
> iosys_map_write_field() functions so they always use the right
> arguments and make code easier to read.
> 
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: John Harrison <John.C.Harrison@Intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> index 13671b186908..9bf9096b8337 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> @@ -60,6 +60,13 @@ struct __guc_ads_blob {
>  	struct guc_mmio_reg regset[0];
>  } __packed;
>  
> +#define ads_blob_read(guc_, field_)					\
> +	iosys_map_rd_field(&(guc_)->ads_map, 0, struct __guc_ads_blob, field_)
> +
> +#define ads_blob_write(guc_, field_, val_)				\
> +	iosys_map_wr_field(&(guc_)->ads_map, 0, struct __guc_ads_blob,	\
> +			   field_, val_)
> +
>  static u32 guc_ads_regset_size(struct intel_guc *guc)
>  {
>  	GEM_BUG_ON(!guc->ads_regset_size);
> -- 
> 2.35.1
> 

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

* Re: [Intel-gfx] [PATCH v2 06/18] drm/i915/guc: Convert golden context init to iosys_map
  2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
  (?)
@ 2022-02-10 23:07   ` Matt Atwood
  -1 siblings, 0 replies; 59+ messages in thread
From: Matt Atwood @ 2022-02-10 23:07 UTC (permalink / raw)
  To: Lucas De Marchi

On Tue, Feb 08, 2022 at 02:45:12AM -0800, Lucas De Marchi wrote:
> Now the map is saved during creation, so use it to initialize the
> golden context, reading from shmem and writing to either system or IO
> memory.
> 
> v2: Do not use a map iterator: add an offset to keep track of
> destination
> 
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: John Harrison <John.C.Harrison@Intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 26 ++++++++++------------
>  1 file changed, 12 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> index 9bf9096b8337..b5b3a39f0c28 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> @@ -473,18 +473,16 @@ static struct intel_engine_cs *find_engine_state(struct intel_gt *gt, u8 engine_
>  
>  static void guc_init_golden_context(struct intel_guc *guc)
>  {
> -	struct __guc_ads_blob *blob = guc->ads_blob;
>  	struct intel_engine_cs *engine;
>  	struct intel_gt *gt = guc_to_gt(guc);
> -	u32 addr_ggtt, offset;
> -	u32 total_size = 0, alloc_size, real_size;
> +	unsigned long offset;
> +	u32 addr_ggtt, total_size = 0, alloc_size, real_size;
>  	u8 engine_class, guc_class;
> -	u8 *ptr;
>  
>  	if (!intel_uc_uses_guc_submission(&gt->uc))
>  		return;
>  
> -	GEM_BUG_ON(!blob);
> +	GEM_BUG_ON(iosys_map_is_null(&guc->ads_map));
>  
>  	/*
>  	 * Go back and fill in the golden context data now that it is
> @@ -492,15 +490,13 @@ static void guc_init_golden_context(struct intel_guc *guc)
>  	 */
>  	offset = guc_ads_golden_ctxt_offset(guc);
>  	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
> -	ptr = ((u8 *)blob) + offset;
>  
>  	for (engine_class = 0; engine_class <= MAX_ENGINE_CLASS; ++engine_class) {
>  		if (engine_class == OTHER_CLASS)
>  			continue;
>  
>  		guc_class = engine_class_to_guc_class(engine_class);
> -
> -		if (!blob->system_info.engine_enabled_masks[guc_class])
> +		if (!ads_blob_read(guc, system_info.engine_enabled_masks[guc_class]))
>  			continue;
>  
>  		real_size = intel_engine_context_size(gt, engine_class);
> @@ -511,18 +507,20 @@ static void guc_init_golden_context(struct intel_guc *guc)
>  		if (!engine) {
>  			drm_err(&gt->i915->drm, "No engine state recorded for class %d!\n",
>  				engine_class);
> -			blob->ads.eng_state_size[guc_class] = 0;
> -			blob->ads.golden_context_lrca[guc_class] = 0;
> +			ads_blob_write(guc, ads.eng_state_size[guc_class], 0);
> +			ads_blob_write(guc, ads.golden_context_lrca[guc_class], 0);
>  			continue;
>  		}
>  
> -		GEM_BUG_ON(blob->ads.eng_state_size[guc_class] !=
> +		GEM_BUG_ON(ads_blob_read(guc, ads.eng_state_size[guc_class]) !=
>  			   real_size - LRC_SKIP_SIZE);
> -		GEM_BUG_ON(blob->ads.golden_context_lrca[guc_class] != addr_ggtt);
> +		GEM_BUG_ON(ads_blob_read(guc, ads.golden_context_lrca[guc_class]) != addr_ggtt);
> +
>  		addr_ggtt += alloc_size;
>  
> -		shmem_read(engine->default_state, 0, ptr, real_size);
> -		ptr += alloc_size;
> +		shmem_read_to_iosys_map(engine->default_state, 0, &guc->ads_map,
> +					offset, real_size);
> +		offset += alloc_size;
>  	}
>  
>  	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
> -- 
> 2.35.1
> 

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

* Re: [Intel-gfx] [PATCH v2 07/18] drm/i915/guc: Convert policies update to iosys_map
  2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
  (?)
@ 2022-02-10 23:56   ` Matt Atwood
  -1 siblings, 0 replies; 59+ messages in thread
From: Matt Atwood @ 2022-02-10 23:56 UTC (permalink / raw)
  To: Lucas De Marchi

On Tue, Feb 08, 2022 at 02:45:13AM -0800, Lucas De Marchi wrote:
> Use iosys_map to write the policies update so access to IO and system
> memory is abstracted away.
> 
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: John Harrison <John.C.Harrison@Intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 41 ++++++++++++----------
>  1 file changed, 23 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> index b5b3a39f0c28..6a34ab38b45f 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> @@ -130,33 +130,37 @@ static u32 guc_ads_blob_size(struct intel_guc *guc)
>  	       guc_ads_private_data_size(guc);
>  }
>  
> -static void guc_policies_init(struct intel_guc *guc, struct guc_policies *policies)
> +static void guc_policies_init(struct intel_guc *guc)
>  {
>  	struct intel_gt *gt = guc_to_gt(guc);
>  	struct drm_i915_private *i915 = gt->i915;
> +	u32 global_flags = 0;
>  
> -	policies->dpc_promote_time = GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US;
> -	policies->max_num_work_items = GLOBAL_POLICY_MAX_NUM_WI;
> +	ads_blob_write(guc, policies.dpc_promote_time,
> +		       GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US);
> +	ads_blob_write(guc, policies.max_num_work_items,
> +		       GLOBAL_POLICY_MAX_NUM_WI);
>  
> -	policies->global_flags = 0;
>  	if (i915->params.reset < 2)
> -		policies->global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET;
> +		global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET;
>  
> -	policies->is_valid = 1;
> +	ads_blob_write(guc, policies.global_flags, global_flags);
> +	ads_blob_write(guc, policies.is_valid, 1);
>  }
>  
>  void intel_guc_ads_print_policy_info(struct intel_guc *guc,
>  				     struct drm_printer *dp)
>  {
> -	struct __guc_ads_blob *blob = guc->ads_blob;
> -
> -	if (unlikely(!blob))
> +	if (unlikely(iosys_map_is_null(&guc->ads_map)))
>  		return;
>  
>  	drm_printf(dp, "Global scheduling policies:\n");
> -	drm_printf(dp, "  DPC promote time   = %u\n", blob->policies.dpc_promote_time);
> -	drm_printf(dp, "  Max num work items = %u\n", blob->policies.max_num_work_items);
> -	drm_printf(dp, "  Flags              = %u\n", blob->policies.global_flags);
> +	drm_printf(dp, "  DPC promote time   = %u\n",
> +		   ads_blob_read(guc, policies.dpc_promote_time));
> +	drm_printf(dp, "  Max num work items = %u\n",
> +		   ads_blob_read(guc, policies.max_num_work_items));
> +	drm_printf(dp, "  Flags              = %u\n",
> +		   ads_blob_read(guc, policies.global_flags));
>  }
>  
>  static int guc_action_policies_update(struct intel_guc *guc, u32 policy_offset)
> @@ -171,23 +175,24 @@ static int guc_action_policies_update(struct intel_guc *guc, u32 policy_offset)
>  
>  int intel_guc_global_policies_update(struct intel_guc *guc)
>  {
> -	struct __guc_ads_blob *blob = guc->ads_blob;
>  	struct intel_gt *gt = guc_to_gt(guc);
> +	u32 scheduler_policies;
>  	intel_wakeref_t wakeref;
>  	int ret;
>  
> -	if (!blob)
> +	if (iosys_map_is_null(&guc->ads_map))
>  		return -EOPNOTSUPP;
>  
> -	GEM_BUG_ON(!blob->ads.scheduler_policies);
> +	scheduler_policies = ads_blob_read(guc, ads.scheduler_policies);
> +	GEM_BUG_ON(!scheduler_policies);
>  
> -	guc_policies_init(guc, &blob->policies);
> +	guc_policies_init(guc);
>  
>  	if (!intel_guc_is_ready(guc))
>  		return 0;
>  
>  	with_intel_runtime_pm(&gt->i915->runtime_pm, wakeref)
> -		ret = guc_action_policies_update(guc, blob->ads.scheduler_policies);
> +		ret = guc_action_policies_update(guc, scheduler_policies);
>  
>  	return ret;
>  }
> @@ -554,7 +559,7 @@ static void __guc_ads_init(struct intel_guc *guc)
>  	u32 base;
>  
>  	/* GuC scheduling policies */
> -	guc_policies_init(guc, &blob->policies);
> +	guc_policies_init(guc);
>  
>  	/* System info */
>  	fill_engine_enable_masks(gt, &blob->system_info);
> -- 
> 2.35.1
> 

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

* Re: [Intel-gfx] [PATCH v2 08/18] drm/i915/guc: Convert engine record to iosys_map
  2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
  (?)
@ 2022-02-15 23:28   ` Matt Atwood
  -1 siblings, 0 replies; 59+ messages in thread
From: Matt Atwood @ 2022-02-15 23:28 UTC (permalink / raw)
  To: Lucas De Marchi

On Tue, Feb 08, 2022 at 02:45:14AM -0800, Lucas De Marchi wrote:
> Use iosys_map to read fields from the dma_blob so access to IO and
> system memory is abstracted away.
> 
> Cc: Matt Roper <matthew.d.roper@intel.com>
> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: John Harrison <John.C.Harrison@Intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Matt Atwood<matthew.s.atwood@intel.com>
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c      | 14 ++++++--------
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h      |  3 ++-
>  .../gpu/drm/i915/gt/uc/intel_guc_submission.c   | 17 ++++++++++-------
>  3 files changed, 18 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> index 6a34ab38b45f..383c5994d4ef 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> @@ -695,18 +695,16 @@ void intel_guc_ads_reset(struct intel_guc *guc)
>  
>  u32 intel_guc_engine_usage_offset(struct intel_guc *guc)
>  {
> -	struct __guc_ads_blob *blob = guc->ads_blob;
> -	u32 base = intel_guc_ggtt_offset(guc, guc->ads_vma);
> -	u32 offset = base + ptr_offset(blob, engine_usage);
> -
> -	return offset;
> +	return intel_guc_ggtt_offset(guc, guc->ads_vma) +
> +		offsetof(struct __guc_ads_blob, engine_usage);
>  }
>  
> -struct guc_engine_usage_record *intel_guc_engine_usage(struct intel_engine_cs *engine)
> +struct iosys_map intel_guc_engine_usage_record_map(struct intel_engine_cs *engine)
>  {
>  	struct intel_guc *guc = &engine->gt->uc.guc;
> -	struct __guc_ads_blob *blob = guc->ads_blob;
>  	u8 guc_class = engine_class_to_guc_class(engine->class);
> +	size_t offset = offsetof(struct __guc_ads_blob,
> +				 engine_usage.engines[guc_class][ilog2(engine->logical_mask)]);
>  
> -	return &blob->engine_usage.engines[guc_class][ilog2(engine->logical_mask)];
> +	return IOSYS_MAP_INIT_OFFSET(&guc->ads_map, offset);
>  }
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h
> index e74c110facff..1c64f4d6ea21 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h
> @@ -7,6 +7,7 @@
>  #define _INTEL_GUC_ADS_H_
>  
>  #include <linux/types.h>
> +#include <linux/iosys-map.h>
>  
>  struct intel_guc;
>  struct drm_printer;
> @@ -18,7 +19,7 @@ void intel_guc_ads_init_late(struct intel_guc *guc);
>  void intel_guc_ads_reset(struct intel_guc *guc);
>  void intel_guc_ads_print_policy_info(struct intel_guc *guc,
>  				     struct drm_printer *p);
> -struct guc_engine_usage_record *intel_guc_engine_usage(struct intel_engine_cs *engine);
> +struct iosys_map intel_guc_engine_usage_record_map(struct intel_engine_cs *engine);
>  u32 intel_guc_engine_usage_offset(struct intel_guc *guc);
>  
>  #endif
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> index b3a429a92c0d..ab3cea352fb3 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> @@ -1139,6 +1139,9 @@ __extend_last_switch(struct intel_guc *guc, u64 *prev_start, u32 new_start)
>  	*prev_start = ((u64)gt_stamp_hi << 32) | new_start;
>  }
>  
> +#define record_read(map_, field_) \
> +	iosys_map_rd_field(map_, 0, struct guc_engine_usage_record, field_)
> +
>  /*
>   * GuC updates shared memory and KMD reads it. Since this is not synchronized,
>   * we run into a race where the value read is inconsistent. Sometimes the
> @@ -1153,17 +1156,17 @@ __extend_last_switch(struct intel_guc *guc, u64 *prev_start, u32 new_start)
>  static void __get_engine_usage_record(struct intel_engine_cs *engine,
>  				      u32 *last_in, u32 *id, u32 *total)
>  {
> -	struct guc_engine_usage_record *rec = intel_guc_engine_usage(engine);
> +	struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine);
>  	int i = 0;
>  
>  	do {
> -		*last_in = READ_ONCE(rec->last_switch_in_stamp);
> -		*id = READ_ONCE(rec->current_context_index);
> -		*total = READ_ONCE(rec->total_runtime);
> +		*last_in = record_read(&rec_map, last_switch_in_stamp);
> +		*id = record_read(&rec_map, current_context_index);
> +		*total = record_read(&rec_map, total_runtime);
>  
> -		if (READ_ONCE(rec->last_switch_in_stamp) == *last_in &&
> -		    READ_ONCE(rec->current_context_index) == *id &&
> -		    READ_ONCE(rec->total_runtime) == *total)
> +		if (record_read(&rec_map, last_switch_in_stamp) == *last_in &&
> +		    record_read(&rec_map, current_context_index) == *id &&
> +		    record_read(&rec_map, total_runtime) == *total)
>  			break;
>  	} while (++i < 6);
>  }
> -- 
> 2.35.1
> 

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

end of thread, other threads:[~2022-02-15 23:29 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-08 10:45 [PATCH v2 00/18] drm/i915/guc: Refactor ADS access to use iosys_map Lucas De Marchi
2022-02-08 10:45 ` [Intel-gfx] " Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 01/18] iosys-map: Add offset to iosys_map_memcpy_to() Lucas De Marchi
2022-02-08 10:45   ` Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 02/18] iosys-map: Add a few more helpers Lucas De Marchi
2022-02-08 10:45   ` Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 22:53   ` Matt Atwood
2022-02-09  6:14   ` Mauro Carvalho Chehab
2022-02-09  6:14     ` Mauro Carvalho Chehab
2022-02-09  6:14     ` [Intel-gfx] " Mauro Carvalho Chehab
2022-02-09  6:23   ` Thomas Zimmermann
2022-02-09  6:23     ` [Intel-gfx] " Thomas Zimmermann
2022-02-09  6:43     ` Lucas De Marchi
2022-02-09  6:43       ` [Intel-gfx] " Lucas De Marchi
2022-02-09  6:43       ` Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 03/18] drm/i915/gt: Add helper for shmem copy to iosys_map Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 23:08   ` Matt Atwood
2022-02-08 10:45 ` [PATCH v2 04/18] drm/i915/guc: Keep iosys_map of ads_blob around Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-10 22:56   ` Matt Atwood
2022-02-08 10:45 ` [Intel-gfx] [PATCH v2 05/18] drm/i915/guc: Add read/write helpers for ADS blob Lucas De Marchi
2022-02-08 10:45   ` Lucas De Marchi
2022-02-10 23:00   ` [Intel-gfx] " Matt Atwood
2022-02-08 10:45 ` [PATCH v2 06/18] drm/i915/guc: Convert golden context init to iosys_map Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-10 23:07   ` Matt Atwood
2022-02-08 10:45 ` [PATCH v2 07/18] drm/i915/guc: Convert policies update " Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-10 23:56   ` Matt Atwood
2022-02-08 10:45 ` [PATCH v2 08/18] drm/i915/guc: Convert engine record " Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-15 23:28   ` Matt Atwood
2022-02-08 10:45 ` [PATCH v2 09/18] drm/i915/guc: Convert guc_ads_private_data_reset " Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 10/18] drm/i915/guc: Convert golden context prep " Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 11/18] drm/i915/guc: Replace check for golden context size Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 12/18] drm/i915/guc: Convert mapping table to iosys_map Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 13/18] drm/i915/guc: Convert capture list " Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 14/18] drm/i915/guc: Prepare for error propagation Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 15/18] drm/i915/guc: Use a single pass to calculate regset Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 10:45 ` [Intel-gfx] [PATCH v2 16/18] drm/i915/guc: Convert guc_mmio_reg_state_init to iosys_map Lucas De Marchi
2022-02-08 10:45   ` Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 17/18] drm/i915/guc: Convert __guc_ads_init " Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 10:45 ` [PATCH v2 18/18] drm/i915/guc: Remove plain ads_blob pointer Lucas De Marchi
2022-02-08 10:45   ` [Intel-gfx] " Lucas De Marchi
2022-02-08 11:18 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/guc: Refactor ADS access to use iosys_map (rev2) Patchwork
2022-02-08 11:20 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-02-08 11:50 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-02-08 13:07 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork

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.