original: https://patchwork.freedesktop.org/series/99378/ v2: https://patchwork.freedesktop.org/series/99711/#rev1, https://patchwork.freedesktop.org/series/99711/#rev2
Main changes from previous version:
- Unrelated patches to iosys-map conversion have landed - Remove unecessary kernel.h include from iosys-map.h - Rebase on latest drm-tip
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 need 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/writing 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. [v3: the part unrelated to iosys-map has already landed]
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 (16): 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: 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 | 7 +- drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 233 ++++++++++-------- 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 | 218 +++++++++++++++- 9 files changed, 396 insertions(+), 121 deletions(-)
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 409d8dd7f868..d265a73313c9 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); }
/**
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 v3: - Drop kernel.h include as it's not needed anymore
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 Reviewed-by: Mauro Carvalho Chehab mchehab@kernel.org Reviewed-by: Matt Atwood matthew.s.atwood@intel.com --- include/linux/iosys-map.h | 201 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+)
diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h index edd730b1e899..e69a002d5aa4 100644 --- a/include/linux/iosys-map.h +++ b/include/linux/iosys-map.h @@ -120,6 +120,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(©, offset_); \ + copy; \ +}) + /** * iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory * @map: The iosys_map structure @@ -239,6 +278,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 +314,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__ */
Hi
Am 16.02.22 um 18:41 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
v3:
- Drop kernel.h include as it's not needed anymore
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 Reviewed-by: Mauro Carvalho Chehab mchehab@kernel.org Reviewed-by: Matt Atwood matthew.s.atwood@intel.com
Reviewed-by: Thomas Zimmermann tzimmermann@suse.de
include/linux/iosys-map.h | 201 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+)
diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h index edd730b1e899..e69a002d5aa4 100644 --- a/include/linux/iosys-map.h +++ b/include/linux/iosys-map.h @@ -120,6 +120,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(©, offset_); \
- copy; \
+})
- /**
- iosys_map_set_vaddr - Sets a iosys mapping structure to an address in system memory
- @map: The iosys_map structure
@@ -239,6 +278,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 +314,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__ */
On Thu, Feb 17, 2022 at 09:42:08AM +0100, Thomas Zimmermann wrote:
Hi
Am 16.02.22 um 18:41 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
v3:
- Drop kernel.h include as it's not needed anymore
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 Reviewed-by: Mauro Carvalho Chehab mchehab@kernel.org Reviewed-by: Matt Atwood matthew.s.atwood@intel.com
Reviewed-by: Thomas Zimmermann tzimmermann@suse.de
Thanks. I applied the first 2 patches to drm-intel-next.
The rest can't be applied as there are conflicts between drm-intel-next and drm-intel-gt-next. I should have merged the rename to drm-intel-gt-next since the guc patches need to be applied there. I guess the rest will have to wait some tree propagation.
Lucas De Marchi
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 Reviewed-by: Matt Atwood matthew.s.atwood@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);
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 Reviewed-by: Matt Atwood matthew.s.atwood@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 9d779de16613..f857e9190750 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; /** 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 7e41175618f5..4ea842752bbc 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -666,6 +666,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; @@ -687,6 +692,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); }
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 Reviewed-by: Matt Atwood matthew.s.atwood@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 4ea842752bbc..b645df7d46b6 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);
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 Reviewed-by: Matt Atwood matthew.s.atwood@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 b645df7d46b6..5c52bee516cf 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -512,18 +512,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(>->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 @@ -531,15 +529,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); @@ -550,18 +546,20 @@ static void guc_init_golden_context(struct intel_guc *guc) if (!engine) { drm_err(>->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);
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 Reviewed-by: Matt Atwood matthew.s.atwood@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 5c52bee516cf..7906a4df5a53 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(>->i915->runtime_pm, wakeref) - ret = guc_action_policies_update(guc, blob->ads.scheduler_policies); + ret = guc_action_policies_update(guc, scheduler_policies);
return ret; } @@ -593,7 +598,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);
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 Reviewed-by: Matt Atwoodmatthew.s.atwood@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 7906a4df5a53..c61648ef3920 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -738,18 +738,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); }
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 c61648ef3920..d924486490c1 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -714,8 +714,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); }
/**
On Wed, Feb 16, 2022 at 09:41:40AM -0800, Lucas De Marchi wrote:
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
Reviewed-by: Matthew Brost matthew.brost@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 c61648ef3920..d924486490c1 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -714,8 +714,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
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 d924486490c1..0077a63832ad 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); @@ -417,24 +423,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 @@ -448,14 +454,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) { @@ -464,14 +471,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;
/* @@ -485,12 +492,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); @@ -595,13 +605,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); @@ -617,7 +629,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);
@@ -663,7 +675,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;
On Wed, Feb 16, 2022 at 09:41:41AM -0800, Lucas De Marchi wrote:
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
Reviewed-by: Matthew Brost matthew.brost@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 d924486490c1..0077a63832ad 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); @@ -417,24 +423,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
@@ -448,14 +454,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,
} else { memset(&local_info, 0, sizeof(local_info));offsetof(struct __guc_ads_blob, system_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) {
@@ -464,14 +471,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;
/*
@@ -485,12 +492,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);
@@ -595,13 +605,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);
@@ -617,7 +629,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);
@@ -663,7 +675,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
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 0077a63832ad..b739781bd133 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -500,10 +500,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; }
On Wed, Feb 16, 2022 at 09:41:42AM -0800, Lucas De Marchi wrote:
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
Reviewed-by: Matthew Brost matthew.brost@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 0077a63832ad..b739781bd133 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -500,10 +500,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
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 b739781bd133..c3c31b679e79 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); } }
@@ -631,7 +631,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);
On Wed, Feb 16, 2022 at 09:41:43AM -0800, Lucas De Marchi wrote:
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
Reviewed-by: Matthew Brost matthew.brost@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 b739781bd133..c3c31b679e79 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);
}
@@ -631,7 +631,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
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 c3c31b679e79..ec0ccdf98dfa 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -580,7 +580,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; @@ -592,11 +592,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); } }
@@ -636,7 +636,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);
On Wed, Feb 16, 2022 at 09:41:44AM -0800, Lucas De Marchi wrote:
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
Reviewed-by: Matthew Brost matthew.brost@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 c3c31b679e79..ec0ccdf98dfa 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -580,7 +580,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; @@ -592,11 +592,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);
}
@@ -636,7 +636,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
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);
On Wed, Feb 16, 2022 at 09:41:45AM -0800, Lucas De Marchi wrote:
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
Reviewed-by: Matthew Brost matthew.brost@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
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); }
On Wed, Feb 16, 2022 at 09:41:46AM -0800, Lucas De Marchi wrote:
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
Reviewed-by: Matthew Brost matthew.brost@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
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); }
On Wed, Feb 16, 2022 at 09:41:47AM -0800, Lucas De Marchi wrote:
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
Reviewed-by: Matthew Brost matthew.brost@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);
elseiosys_map_set_vaddr_iomem(&guc->ads_map, (void __iomem *)ads_blob);
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
dri-devel@lists.freedesktop.org