* [PATCH v2 1/5] drm/i915/fbdev: Add intel_fbdev_get_vaddr()
2024-12-03 8:50 [RFC PATCH v2 0/5] drm/i915: Add drm_panic support Jocelyn Falempe
@ 2024-12-03 8:50 ` Jocelyn Falempe
2024-12-04 14:03 ` kernel test robot
2024-12-03 8:50 ` [PATCH v2 2/5] drm/i915/display/i9xx: Add a disable_tiling() for i9xx planes Jocelyn Falempe
` (3 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Jocelyn Falempe @ 2024-12-03 8:50 UTC (permalink / raw)
To: Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
David Airlie, Simona Vetter, intel-gfx, intel-xe, dri-devel,
linux-kernel
Cc: Jocelyn Falempe
The vaddr of the fbdev framebuffer is private to the struct
intel_fbdev, so this function is needed to access it for drm_panic.
Also the struct i915_vma is different between i915 and xe, so it
requires a few functions to access fbdev->vma->iomap.
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
v2:
* Add intel_fb_get_vaddr() and i915_vma_get_iomap() to build with Xe driver.
drivers/gpu/drm/i915/display/intel_fb_pin.c | 5 +++++
drivers/gpu/drm/i915/display/intel_fb_pin.h | 1 +
drivers/gpu/drm/i915/display/intel_fbdev.c | 5 +++++
drivers/gpu/drm/i915/display/intel_fbdev.h | 6 ++++++
drivers/gpu/drm/i915/i915_vma.h | 5 +++++
drivers/gpu/drm/xe/display/xe_fb_pin.c | 5 +++++
6 files changed, 27 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index d3a86f9c6bc86..c44019c7ab56b 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -327,3 +327,8 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state)
intel_dpt_unpin_from_ggtt(fb->dpt_vm);
}
}
+
+void *intel_fb_get_vaddr(struct i915_vma *vma)
+{
+ return i915_vma_get_iomap(vma);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h
index ac0319b53af08..0141f5f2b1c7a 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.h
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h
@@ -25,5 +25,6 @@ void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags);
int intel_plane_pin_fb(struct intel_plane_state *plane_state);
void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state);
+void *intel_fb_get_vaddr(struct i915_vma *vma);
#endif
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 00852ff5b2470..1d12d1c047d02 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -695,3 +695,8 @@ struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev)
return to_intel_framebuffer(fbdev->helper.fb);
}
+
+void *intel_fbdev_get_vaddr(struct intel_fbdev *fbdev)
+{
+ return intel_fb_get_vaddr(fbdev->vma);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h
index 08de2d5b34338..f033d4f1efe96 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.h
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.h
@@ -17,6 +17,7 @@ struct intel_framebuffer;
void intel_fbdev_setup(struct drm_i915_private *dev_priv);
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous);
struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev);
+void *intel_fbdev_get_vaddr(struct intel_fbdev *fbdev);
#else
static inline void intel_fbdev_setup(struct drm_i915_private *dev_priv)
{
@@ -30,6 +31,11 @@ static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbd
{
return NULL;
}
+
+static inline void *intel_fbdev_get_vaddr(struct intel_fbdev *fbdev)
+{
+ return NULL;
+}
#endif
#endif /* __INTEL_FBDEV_H__ */
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 6a6be8048aa83..4ae610927fa77 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -353,6 +353,11 @@ static inline bool i915_node_color_differs(const struct drm_mm_node *node,
return drm_mm_node_allocated(node) && node->color != color;
}
+static inline void __iomem *i915_vma_get_iomap(struct i915_vma *vma)
+{
+ return READ_ONCE(vma->iomap);
+}
+
/**
* i915_vma_pin_iomap - calls ioremap_wc to map the GGTT VMA via the aperture
* @vma: VMA to iomap
diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c
index 761510ae06904..576b1e98f39cd 100644
--- a/drivers/gpu/drm/xe/display/xe_fb_pin.c
+++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c
@@ -421,3 +421,8 @@ u64 intel_dpt_offset(struct i915_vma *dpt_vma)
{
return 0;
}
+
+void *intel_fb_get_vaddr(struct i915_vma *vma)
+{
+ return NULL;
+}
--
2.47.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v2 1/5] drm/i915/fbdev: Add intel_fbdev_get_vaddr()
2024-12-03 8:50 ` [PATCH v2 1/5] drm/i915/fbdev: Add intel_fbdev_get_vaddr() Jocelyn Falempe
@ 2024-12-04 14:03 ` kernel test robot
0 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2024-12-04 14:03 UTC (permalink / raw)
To: Jocelyn Falempe, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, David Airlie, Simona Vetter, intel-gfx, intel-xe,
dri-devel, linux-kernel
Cc: oe-kbuild-all, Jocelyn Falempe
Hi Jocelyn,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 44cff6c5b0b17a78bc0b30372bcd816cf6dd282a]
url: https://github.com/intel-lab-lkp/linux/commits/Jocelyn-Falempe/drm-i915-fbdev-Add-intel_fbdev_get_vaddr/20241203-173213
base: 44cff6c5b0b17a78bc0b30372bcd816cf6dd282a
patch link: https://lore.kernel.org/r/20241203092836.426422-2-jfalempe%40redhat.com
patch subject: [PATCH v2 1/5] drm/i915/fbdev: Add intel_fbdev_get_vaddr()
config: i386-randconfig-062-20241204 (https://download.01.org/0day-ci/archive/20241204/202412042119.5ErpNlAU-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241204/202412042119.5ErpNlAU-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202412042119.5ErpNlAU-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> drivers/gpu/drm/i915/display/intel_fb_pin.c:333:34: sparse: sparse: incorrect type in return expression (different address spaces) @@ expected void * @@ got void [noderef] __iomem * @@
drivers/gpu/drm/i915/display/intel_fb_pin.c:333:34: sparse: expected void *
drivers/gpu/drm/i915/display/intel_fb_pin.c:333:34: sparse: got void [noderef] __iomem *
vim +333 drivers/gpu/drm/i915/display/intel_fb_pin.c
330
331 void *intel_fb_get_vaddr(struct i915_vma *vma)
332 {
> 333 return i915_vma_get_iomap(vma);
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 2/5] drm/i915/display/i9xx: Add a disable_tiling() for i9xx planes
2024-12-03 8:50 [RFC PATCH v2 0/5] drm/i915: Add drm_panic support Jocelyn Falempe
2024-12-03 8:50 ` [PATCH v2 1/5] drm/i915/fbdev: Add intel_fbdev_get_vaddr() Jocelyn Falempe
@ 2024-12-03 8:50 ` Jocelyn Falempe
2024-12-03 8:50 ` [PATCH v2 3/5] drm/i915/display: Add a disable_tiling() for skl planes Jocelyn Falempe
` (2 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Jocelyn Falempe @ 2024-12-03 8:50 UTC (permalink / raw)
To: Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
David Airlie, Simona Vetter, intel-gfx, intel-xe, dri-devel,
linux-kernel
Cc: Jocelyn Falempe
drm_panic draws in linear framebuffer, so it's easier to re-use the
current framebuffer, and disable tiling in the panic handler, to show
the panic screen.
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
drivers/gpu/drm/i915/display/i9xx_plane.c | 23 +++++++++++++++++++
.../drm/i915/display/intel_display_types.h | 2 ++
2 files changed, 25 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 17a1e3801a85c..671d3914585bf 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -848,6 +848,27 @@ static const struct drm_plane_funcs i8xx_plane_funcs = {
.format_mod_supported = i8xx_plane_format_mod_supported,
};
+static void i9xx_disable_tiling(struct intel_plane *plane)
+{
+ struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
+ u32 dspcntr;
+ u32 reg;
+
+ dspcntr = intel_de_read_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
+ dspcntr &= ~DISP_TILED;
+ intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
+
+ if (DISPLAY_VER(dev_priv) >= 4) {
+ reg = intel_de_read_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane));
+ intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), reg);
+
+ } else {
+ reg = intel_de_read_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane));
+ intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane), reg);
+ }
+}
+
struct intel_plane *
intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
{
@@ -973,6 +994,8 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
plane->disable_flip_done = ilk_primary_disable_flip_done;
}
+ plane->disable_tiling = i9xx_disable_tiling;
+
modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X);
if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 2bb1fa64da2f1..0559b02569e49 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1482,6 +1482,8 @@ struct intel_plane {
bool async_flip);
void (*enable_flip_done)(struct intel_plane *plane);
void (*disable_flip_done)(struct intel_plane *plane);
+ /* For drm_panic */
+ void (*disable_tiling)(struct intel_plane *plane);
};
#define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base)
--
2.47.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 3/5] drm/i915/display: Add a disable_tiling() for skl planes
2024-12-03 8:50 [RFC PATCH v2 0/5] drm/i915: Add drm_panic support Jocelyn Falempe
2024-12-03 8:50 ` [PATCH v2 1/5] drm/i915/fbdev: Add intel_fbdev_get_vaddr() Jocelyn Falempe
2024-12-03 8:50 ` [PATCH v2 2/5] drm/i915/display/i9xx: Add a disable_tiling() for i9xx planes Jocelyn Falempe
@ 2024-12-03 8:50 ` Jocelyn Falempe
2024-12-03 8:50 ` [PATCH v2 4/5] drm/i915/gem: Add i915_gem_object_panic_map() Jocelyn Falempe
2024-12-03 8:50 ` [PATCH v2 5/5] drm/i915: Add drm_panic support Jocelyn Falempe
4 siblings, 0 replies; 9+ messages in thread
From: Jocelyn Falempe @ 2024-12-03 8:50 UTC (permalink / raw)
To: Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
David Airlie, Simona Vetter, intel-gfx, intel-xe, dri-devel,
linux-kernel
Cc: Jocelyn Falempe
drm_panic draws in linear framebuffer, so it's easier to re-use the
current framebuffer, and disable tiling in the panic handler, to show
the panic screen.
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
.../drm/i915/display/skl_universal_plane.c | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index a0a7ed01415a5..62aa40b6e2347 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -2560,6 +2560,25 @@ static u8 skl_get_plane_caps(struct drm_i915_private *i915,
return caps;
}
+static void skl_disable_tiling(struct intel_plane *plane)
+{
+ u32 plane_ctl;
+ struct intel_plane_state *state = to_intel_plane_state(plane->base.state);
+ struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+ u32 stride = state->view.color_plane[0].scanout_stride / 64;
+
+ plane_ctl = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane->id));
+ plane_ctl &= ~PLANE_CTL_TILED_MASK;
+
+ intel_de_write_fw(dev_priv, PLANE_STRIDE(plane->pipe, plane->id),
+ PLANE_STRIDE_(stride));
+
+ intel_de_write_fw(dev_priv, PLANE_CTL(plane->pipe, plane->id), plane_ctl);
+
+ intel_de_write_fw(dev_priv, PLANE_SURF(plane->pipe, plane->id),
+ skl_plane_surf(state, 0));
+}
+
struct intel_plane *
skl_universal_plane_create(struct drm_i915_private *dev_priv,
enum pipe pipe, enum plane_id plane_id)
@@ -2601,6 +2620,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
plane->max_height = skl_plane_max_height;
plane->min_cdclk = skl_plane_min_cdclk;
}
+ plane->disable_tiling = skl_disable_tiling;
if (DISPLAY_VER(dev_priv) >= 13)
plane->max_stride = adl_plane_max_stride;
--
2.47.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 4/5] drm/i915/gem: Add i915_gem_object_panic_map()
2024-12-03 8:50 [RFC PATCH v2 0/5] drm/i915: Add drm_panic support Jocelyn Falempe
` (2 preceding siblings ...)
2024-12-03 8:50 ` [PATCH v2 3/5] drm/i915/display: Add a disable_tiling() for skl planes Jocelyn Falempe
@ 2024-12-03 8:50 ` Jocelyn Falempe
2024-12-03 8:50 ` [PATCH v2 5/5] drm/i915: Add drm_panic support Jocelyn Falempe
4 siblings, 0 replies; 9+ messages in thread
From: Jocelyn Falempe @ 2024-12-03 8:50 UTC (permalink / raw)
To: Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
David Airlie, Simona Vetter, intel-gfx, intel-xe, dri-devel,
linux-kernel
Cc: Jocelyn Falempe
Prepare the work for drm_panic support. This is used to map the
current framebuffer, so the CPU can overwrite it with the panic
message.
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
drivers/gpu/drm/i915/display/intel_bo.c | 10 +++++++++
drivers/gpu/drm/i915/display/intel_bo.h | 2 ++
drivers/gpu/drm/i915/gem/i915_gem_object.h | 2 ++
drivers/gpu/drm/i915/gem/i915_gem_pages.c | 25 ++++++++++++++++++++++
drivers/gpu/drm/xe/display/intel_bo.c | 11 ++++++++++
5 files changed, 50 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c
index fbd16d7b58d95..5eeb3ba827edf 100644
--- a/drivers/gpu/drm/i915/display/intel_bo.c
+++ b/drivers/gpu/drm/i915/display/intel_bo.c
@@ -22,6 +22,11 @@ bool intel_bo_is_shmem(struct drm_gem_object *obj)
return i915_gem_object_is_shmem(to_intel_bo(obj));
}
+bool intel_bo_has_iomem(struct drm_gem_object *obj)
+{
+ return i915_gem_object_has_iomem(to_intel_bo(obj));
+}
+
bool intel_bo_is_protected(struct drm_gem_object *obj)
{
return i915_gem_object_is_protected(to_intel_bo(obj));
@@ -57,3 +62,8 @@ void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj)
{
i915_debugfs_describe_obj(m, to_intel_bo(obj));
}
+
+void *intel_bo_panic_map(struct drm_gem_object *obj)
+{
+ return i915_gem_object_panic_map(to_intel_bo(obj));
+}
diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h
index ea7a2253aaa57..0eb084955e9af 100644
--- a/drivers/gpu/drm/i915/display/intel_bo.h
+++ b/drivers/gpu/drm/i915/display/intel_bo.h
@@ -13,6 +13,7 @@ struct vm_area_struct;
bool intel_bo_is_tiled(struct drm_gem_object *obj);
bool intel_bo_is_userptr(struct drm_gem_object *obj);
bool intel_bo_is_shmem(struct drm_gem_object *obj);
+bool intel_bo_has_iomem(struct drm_gem_object *obj);
bool intel_bo_is_protected(struct drm_gem_object *obj);
void intel_bo_flush_if_display(struct drm_gem_object *obj);
int intel_bo_fb_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
@@ -23,5 +24,6 @@ struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj,
struct intel_frontbuffer *front);
void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj);
+void *intel_bo_panic_map(struct drm_gem_object *obj);
#endif /* __INTEL_BO__ */
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 3dc61cbd2e11f..f85326a98aefc 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -694,6 +694,8 @@ i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
int i915_gem_object_truncate(struct drm_i915_gem_object *obj);
+void *i915_gem_object_panic_map(struct drm_i915_gem_object *obj);
+
/**
* i915_gem_object_pin_map - return a contiguous mapping of the entire object
* @obj: the object to map into kernel address space
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index 8780aa2431053..07c33169603c9 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -355,6 +355,31 @@ static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj,
return vaddr ?: ERR_PTR(-ENOMEM);
}
+/* Map the current framebuffer for CPU access. Called from panic handler, so no
+ * need to pin or cleanup.
+ */
+void *i915_gem_object_panic_map(struct drm_i915_gem_object *obj)
+{
+ enum i915_map_type has_type;
+ void *ptr;
+
+ ptr = page_unpack_bits(obj->mm.mapping, &has_type);
+
+ if (ptr)
+ return ptr;
+
+ if (i915_gem_object_has_struct_page(obj))
+ ptr = i915_gem_object_map_page(obj, I915_MAP_WB);
+ else
+ ptr = i915_gem_object_map_pfn(obj, I915_MAP_WB);
+
+ if (IS_ERR(ptr))
+ return NULL;
+
+ obj->mm.mapping = page_pack_bits(ptr, I915_MAP_WB);
+ return ptr;
+}
+
/* get, pin, and map the pages of the object into kernel space */
void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
enum i915_map_type type)
diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c
index 9f54fad0f1c0c..c05feeeec3806 100644
--- a/drivers/gpu/drm/xe/display/intel_bo.c
+++ b/drivers/gpu/drm/xe/display/intel_bo.c
@@ -23,6 +23,11 @@ bool intel_bo_is_shmem(struct drm_gem_object *obj)
return false;
}
+bool intel_bo_has_iomem(struct drm_gem_object *obj)
+{
+ return false;
+}
+
bool intel_bo_is_protected(struct drm_gem_object *obj)
{
return false;
@@ -82,3 +87,9 @@ void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj)
{
/* FIXME */
}
+
+void *intel_bo_panic_map(struct drm_gem_object *obj)
+{
+ /* TODO: map the object so CPU can write the panic screen to it */
+ return NULL;
+}
--
2.47.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 5/5] drm/i915: Add drm_panic support
2024-12-03 8:50 [RFC PATCH v2 0/5] drm/i915: Add drm_panic support Jocelyn Falempe
` (3 preceding siblings ...)
2024-12-03 8:50 ` [PATCH v2 4/5] drm/i915/gem: Add i915_gem_object_panic_map() Jocelyn Falempe
@ 2024-12-03 8:50 ` Jocelyn Falempe
2024-12-03 10:58 ` Maarten Lankhorst
4 siblings, 1 reply; 9+ messages in thread
From: Jocelyn Falempe @ 2024-12-03 8:50 UTC (permalink / raw)
To: Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
David Airlie, Simona Vetter, intel-gfx, intel-xe, dri-devel,
linux-kernel
Cc: Jocelyn Falempe
This adds drm_panic support for a wide range of Intel GPU. I've
tested it only on 3 laptops, haswell (with 128MB of eDRAM),
cometlake and alderlake.
* DPT: if I disable tiling on a framebuffer using DPT, then it
displays some other memory location. As DPT is enabled only for
tiled framebuffer, there might be some hardware limitations.
* fbdev: On my haswell laptop, the fbdev framebuffer is configured
with tiling enabled, but really it's linear, because fbcon don't
know about tiling, and the panic screen is perfect when it's drawn
as linear.
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
.../gpu/drm/i915/display/intel_atomic_plane.c | 85 ++++++++++++++++++-
1 file changed, 84 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index b7e462075ded3..58eb3b4c55fa5 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -33,16 +33,20 @@
#include <linux/dma-fence-chain.h>
#include <linux/dma-resv.h>
+#include <linux/iosys-map.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_blend.h>
+#include <drm/drm_cache.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem.h>
#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_panic.h>
#include "i915_config.h"
#include "i9xx_plane_regs.h"
#include "intel_atomic_plane.h"
+#include "intel_bo.h"
#include "intel_cdclk.h"
#include "intel_cursor.h"
#include "intel_display_rps.h"
@@ -50,6 +54,7 @@
#include "intel_display_types.h"
#include "intel_fb.h"
#include "intel_fb_pin.h"
+#include "intel_fbdev.h"
#include "skl_scaler.h"
#include "skl_watermark.h"
@@ -1198,14 +1203,92 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
intel_plane_unpin_fb(old_plane_state);
}
+/* Only used by drm_panic get_scanout_buffer() and panic_flush(), so it is
+ * protected by the drm panic spinlock
+ */
+static struct iosys_map panic_map;
+
+static void intel_panic_flush(struct drm_plane *plane)
+{
+ struct intel_plane_state *plane_state = to_intel_plane_state(plane->state);
+ struct drm_i915_private *dev_priv = to_i915(plane->dev);
+ struct drm_framebuffer *fb = plane_state->hw.fb;
+ struct intel_plane *iplane = to_intel_plane(plane);
+
+ /* Force a cache flush, otherwise the new pixels won't show up */
+ drm_clflush_virt_range(panic_map.vaddr, fb->height * fb->pitches[0]);
+
+ /* Don't disable tiling if it's the fbdev framebuffer.*/
+ if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev))
+ return;
+
+ if (fb->modifier && iplane->disable_tiling)
+ iplane->disable_tiling(iplane);
+}
+
+static int intel_get_scanout_buffer(struct drm_plane *plane,
+ struct drm_scanout_buffer *sb)
+{
+ struct intel_plane_state *plane_state;
+ struct drm_gem_object *obj;
+ struct drm_framebuffer *fb;
+ struct drm_i915_private *dev_priv = to_i915(plane->dev);
+ void *ptr;
+
+ if (!plane->state || !plane->state->fb || !plane->state->visible)
+ return -ENODEV;
+
+ plane_state = to_intel_plane_state(plane->state);
+ fb = plane_state->hw.fb;
+ obj = intel_fb_bo(fb);
+ if (!obj)
+ return -ENODEV;
+
+ if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev)) {
+ ptr = intel_fbdev_get_vaddr(dev_priv->display.fbdev.fbdev);
+ } else {
+ /* can't disable tiling if DPT is in use */
+ if (intel_bo_is_tiled(obj) && HAS_DPT(dev_priv))
+ return -EOPNOTSUPP;
+
+ ptr = intel_bo_panic_map(obj);
+ }
+
+ if (!ptr)
+ return -ENOMEM;
+
+ if (intel_bo_has_iomem(obj))
+ iosys_map_set_vaddr_iomem(&panic_map, ptr);
+ else
+ iosys_map_set_vaddr(&panic_map, ptr);
+
+ sb->map[0] = panic_map;
+ sb->width = fb->width;
+ sb->height = fb->height;
+ sb->format = fb->format;
+ sb->pitch[0] = fb->pitches[0];
+
+ return 0;
+}
+
static const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
.prepare_fb = intel_prepare_plane_fb,
.cleanup_fb = intel_cleanup_plane_fb,
};
+static const struct drm_plane_helper_funcs intel_primary_plane_helper_funcs = {
+ .prepare_fb = intel_prepare_plane_fb,
+ .cleanup_fb = intel_cleanup_plane_fb,
+ .get_scanout_buffer = intel_get_scanout_buffer,
+ .panic_flush = intel_panic_flush,
+};
+
void intel_plane_helper_add(struct intel_plane *plane)
{
- drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
+ if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
+ drm_plane_helper_add(&plane->base, &intel_primary_plane_helper_funcs);
+ else
+ drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
}
void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state,
--
2.47.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v2 5/5] drm/i915: Add drm_panic support
2024-12-03 8:50 ` [PATCH v2 5/5] drm/i915: Add drm_panic support Jocelyn Falempe
@ 2024-12-03 10:58 ` Maarten Lankhorst
2024-12-03 14:49 ` Jocelyn Falempe
0 siblings, 1 reply; 9+ messages in thread
From: Maarten Lankhorst @ 2024-12-03 10:58 UTC (permalink / raw)
To: Jocelyn Falempe, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, David Airlie, Simona Vetter, intel-gfx, intel-xe,
dri-devel, linux-kernel
Hey,
Den 2024-12-03 kl. 09:50, skrev Jocelyn Falempe:
> This adds drm_panic support for a wide range of Intel GPU. I've
> tested it only on 3 laptops, haswell (with 128MB of eDRAM),
> cometlake and alderlake.
>
> * DPT: if I disable tiling on a framebuffer using DPT, then it
> displays some other memory location. As DPT is enabled only for
> tiled framebuffer, there might be some hardware limitations.
This is because DPT points to the pagetable, when you disable tiling DPT is no longer used so the DPT is interpreted as a linear FB instead of a lookup table.
The lookup table is necessarily smaller than the real FB, so you would need to overwrite part of the GGTT and point it to linear FB.
I'm not sure what the fix is here as it would require a real GGTT mapping to fix, needing an allocation which might not succeed. Perhaps indicates a limitation to require a real pageflip to fbdev fb?
Have you tested rotated by any chance? Cursor enabled? Overlay?
I also think this may fail if there are flips queued. We should probably bite the bullet, reprogram the entire state into a known state, disable all overlay planes and cursor, reassign all watermarks for the primary and ensure any background work is killed where needed.
Cheers,
~Maarten
> * fbdev: On my haswell laptop, the fbdev framebuffer is configured
> with tiling enabled, but really it's linear, because fbcon don't
> know about tiling, and the panic screen is perfect when it's drawn
> as linear.
> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
> ---
> .../gpu/drm/i915/display/intel_atomic_plane.c | 85 ++++++++++++++++++-
> 1 file changed, 84 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index b7e462075ded3..58eb3b4c55fa5 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -33,16 +33,20 @@
>
> #include <linux/dma-fence-chain.h>
> #include <linux/dma-resv.h>
> +#include <linux/iosys-map.h>
>
> #include <drm/drm_atomic_helper.h>
> #include <drm/drm_blend.h>
> +#include <drm/drm_cache.h>
> #include <drm/drm_fourcc.h>
> #include <drm/drm_gem.h>
> #include <drm/drm_gem_atomic_helper.h>
> +#include <drm/drm_panic.h>
>
> #include "i915_config.h"
> #include "i9xx_plane_regs.h"
> #include "intel_atomic_plane.h"
> +#include "intel_bo.h"
> #include "intel_cdclk.h"
> #include "intel_cursor.h"
> #include "intel_display_rps.h"
> @@ -50,6 +54,7 @@
> #include "intel_display_types.h"
> #include "intel_fb.h"
> #include "intel_fb_pin.h"
> +#include "intel_fbdev.h"
> #include "skl_scaler.h"
> #include "skl_watermark.h"
>
> @@ -1198,14 +1203,92 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
> intel_plane_unpin_fb(old_plane_state);
> }
>
> +/* Only used by drm_panic get_scanout_buffer() and panic_flush(), so it is
> + * protected by the drm panic spinlock
> + */
> +static struct iosys_map panic_map;
> +
> +static void intel_panic_flush(struct drm_plane *plane)
> +{
> + struct intel_plane_state *plane_state = to_intel_plane_state(plane->state);
> + struct drm_i915_private *dev_priv = to_i915(plane->dev);
> + struct drm_framebuffer *fb = plane_state->hw.fb;
> + struct intel_plane *iplane = to_intel_plane(plane);
> +
> + /* Force a cache flush, otherwise the new pixels won't show up */
> + drm_clflush_virt_range(panic_map.vaddr, fb->height * fb->pitches[0]);
> +
> + /* Don't disable tiling if it's the fbdev framebuffer.*/
> + if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev))
> + return;
> +
> + if (fb->modifier && iplane->disable_tiling)
> + iplane->disable_tiling(iplane);
> +}
> +
> +static int intel_get_scanout_buffer(struct drm_plane *plane,
> + struct drm_scanout_buffer *sb)
> +{
> + struct intel_plane_state *plane_state;
> + struct drm_gem_object *obj;
> + struct drm_framebuffer *fb;
> + struct drm_i915_private *dev_priv = to_i915(plane->dev);
> + void *ptr;
> +
> + if (!plane->state || !plane->state->fb || !plane->state->visible)
> + return -ENODEV;
> +
> + plane_state = to_intel_plane_state(plane->state);
> + fb = plane_state->hw.fb;
> + obj = intel_fb_bo(fb);
> + if (!obj)
> + return -ENODEV;
> +
> + if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev)) {
> + ptr = intel_fbdev_get_vaddr(dev_priv->display.fbdev.fbdev);
> + } else {
> + /* can't disable tiling if DPT is in use */
> + if (intel_bo_is_tiled(obj) && HAS_DPT(dev_priv))
> + return -EOPNOTSUPP;
> +
> + ptr = intel_bo_panic_map(obj);
> + }
> +
> + if (!ptr)
> + return -ENOMEM;
> +
> + if (intel_bo_has_iomem(obj))
> + iosys_map_set_vaddr_iomem(&panic_map, ptr);
> + else
> + iosys_map_set_vaddr(&panic_map, ptr);
> +
> + sb->map[0] = panic_map;
> + sb->width = fb->width;
> + sb->height = fb->height;
> + sb->format = fb->format;
> + sb->pitch[0] = fb->pitches[0];
> +
> + return 0;
> +}
> +
> static const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
> .prepare_fb = intel_prepare_plane_fb,
> .cleanup_fb = intel_cleanup_plane_fb,
> };
>
> +static const struct drm_plane_helper_funcs intel_primary_plane_helper_funcs = {
> + .prepare_fb = intel_prepare_plane_fb,
> + .cleanup_fb = intel_cleanup_plane_fb,
> + .get_scanout_buffer = intel_get_scanout_buffer,
> + .panic_flush = intel_panic_flush,
> +};
> +
> void intel_plane_helper_add(struct intel_plane *plane)
> {
> - drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
> + if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
> + drm_plane_helper_add(&plane->base, &intel_primary_plane_helper_funcs);
> + else
> + drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
> }
>
> void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state,
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH v2 5/5] drm/i915: Add drm_panic support
2024-12-03 10:58 ` Maarten Lankhorst
@ 2024-12-03 14:49 ` Jocelyn Falempe
0 siblings, 0 replies; 9+ messages in thread
From: Jocelyn Falempe @ 2024-12-03 14:49 UTC (permalink / raw)
To: Maarten Lankhorst, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
Tvrtko Ursulin, David Airlie, Simona Vetter, intel-gfx, intel-xe,
dri-devel, linux-kernel
On 03/12/2024 11:58, Maarten Lankhorst wrote:
> Hey,
>
> Den 2024-12-03 kl. 09:50, skrev Jocelyn Falempe:
>> This adds drm_panic support for a wide range of Intel GPU. I've
>> tested it only on 3 laptops, haswell (with 128MB of eDRAM),
>> cometlake and alderlake.
>>
>> * DPT: if I disable tiling on a framebuffer using DPT, then it
>> displays some other memory location. As DPT is enabled only for
>> tiled framebuffer, there might be some hardware limitations.
> This is because DPT points to the pagetable, when you disable tiling DPT is no longer used so the DPT is interpreted as a linear FB instead of a lookup table.
Thanks for the explanation, I was a bit puzzled by this.
>
> The lookup table is necessarily smaller than the real FB, so you would need to overwrite part of the GGTT and point it to linear FB.
>
> I'm not sure what the fix is here as it would require a real GGTT mapping to fix, needing an allocation which might not succeed. Perhaps indicates a limitation to require a real pageflip to fbdev fb?
fbdev is not always present, (and drm_panic is there to help disable it,
so I would prefer that it doesn't rely on it).
The other solution is to draw tiled. When I tested, TILED_X looked
simple, and is the default when using gnome desktop, so I can start to
implement that.
>
> Have you tested rotated by any chance? Cursor enabled? Overlay?
No, not yet. But even a rotated panic screen is better than a hard
freeze. When I test, I have sometime the mouse cursor on top of the
panic screen, but that's not really a problem. Even if it hides a part
of the QR code, there are enough ECC to decode it.
drm_panic is a best effort mode, it's not a problem if it doesn't cover
all use cases.
As a side note regarding rotation, there are a lot of pictures of
Crowdstrike's BSOD, that doesn't respect the rotation of the screen.
>
> I also think this may fail if there are flips queued. We should probably bite the bullet, reprogram the entire state into a known state, disable all overlay planes and cursor, reassign all watermarks for the primary and ensure any background work is killed where needed.
This has been discussed when I started drm_panic, and restarting the
full graphic pipeline is complex to do in a panic handler.
It would also require much more work than this.
In a panic handler, there shouldn't be any background work going on the
CPU (all CPU are shutdown except the panic CPU). On the other hand, the
GPU can continue his work freely.
Also there is a mode_config->panic_lock, so that we don't try to draw a
panic screen, if we are in the middle of a page flip:
https://elixir.bootlin.com/linux/v6.12.1/source/drivers/gpu/drm/drm_atomic_helper.c#L3102
Best regards,
--
Jocelyn
>
> Cheers,
> ~Maarten
>
>> * fbdev: On my haswell laptop, the fbdev framebuffer is configured
>> with tiling enabled, but really it's linear, because fbcon don't
>> know about tiling, and the panic screen is perfect when it's drawn
>> as linear.
>> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
>> ---
>> .../gpu/drm/i915/display/intel_atomic_plane.c | 85 ++++++++++++++++++-
>> 1 file changed, 84 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>> index b7e462075ded3..58eb3b4c55fa5 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>> @@ -33,16 +33,20 @@
>>
>> #include <linux/dma-fence-chain.h>
>> #include <linux/dma-resv.h>
>> +#include <linux/iosys-map.h>
>>
>> #include <drm/drm_atomic_helper.h>
>> #include <drm/drm_blend.h>
>> +#include <drm/drm_cache.h>
>> #include <drm/drm_fourcc.h>
>> #include <drm/drm_gem.h>
>> #include <drm/drm_gem_atomic_helper.h>
>> +#include <drm/drm_panic.h>
>>
>> #include "i915_config.h"
>> #include "i9xx_plane_regs.h"
>> #include "intel_atomic_plane.h"
>> +#include "intel_bo.h"
>> #include "intel_cdclk.h"
>> #include "intel_cursor.h"
>> #include "intel_display_rps.h"
>> @@ -50,6 +54,7 @@
>> #include "intel_display_types.h"
>> #include "intel_fb.h"
>> #include "intel_fb_pin.h"
>> +#include "intel_fbdev.h"
>> #include "skl_scaler.h"
>> #include "skl_watermark.h"
>>
>> @@ -1198,14 +1203,92 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>> intel_plane_unpin_fb(old_plane_state);
>> }
>>
>> +/* Only used by drm_panic get_scanout_buffer() and panic_flush(), so it is
>> + * protected by the drm panic spinlock
>> + */
>> +static struct iosys_map panic_map;
>> +
>> +static void intel_panic_flush(struct drm_plane *plane)
>> +{
>> + struct intel_plane_state *plane_state = to_intel_plane_state(plane->state);
>> + struct drm_i915_private *dev_priv = to_i915(plane->dev);
>> + struct drm_framebuffer *fb = plane_state->hw.fb;
>> + struct intel_plane *iplane = to_intel_plane(plane);
>> +
>> + /* Force a cache flush, otherwise the new pixels won't show up */
>> + drm_clflush_virt_range(panic_map.vaddr, fb->height * fb->pitches[0]);
>> +
>> + /* Don't disable tiling if it's the fbdev framebuffer.*/
>> + if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev))
>> + return;
>> +
>> + if (fb->modifier && iplane->disable_tiling)
>> + iplane->disable_tiling(iplane);
>> +}
>> +
>> +static int intel_get_scanout_buffer(struct drm_plane *plane,
>> + struct drm_scanout_buffer *sb)
>> +{
>> + struct intel_plane_state *plane_state;
>> + struct drm_gem_object *obj;
>> + struct drm_framebuffer *fb;
>> + struct drm_i915_private *dev_priv = to_i915(plane->dev);
>> + void *ptr;
>> +
>> + if (!plane->state || !plane->state->fb || !plane->state->visible)
>> + return -ENODEV;
>> +
>> + plane_state = to_intel_plane_state(plane->state);
>> + fb = plane_state->hw.fb;
>> + obj = intel_fb_bo(fb);
>> + if (!obj)
>> + return -ENODEV;
>> +
>> + if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev)) {
>> + ptr = intel_fbdev_get_vaddr(dev_priv->display.fbdev.fbdev);
>> + } else {
>> + /* can't disable tiling if DPT is in use */
>> + if (intel_bo_is_tiled(obj) && HAS_DPT(dev_priv))
>> + return -EOPNOTSUPP;
>> +
>> + ptr = intel_bo_panic_map(obj);
>> + }
>> +
>> + if (!ptr)
>> + return -ENOMEM;
>> +
>> + if (intel_bo_has_iomem(obj))
>> + iosys_map_set_vaddr_iomem(&panic_map, ptr);
>> + else
>> + iosys_map_set_vaddr(&panic_map, ptr);
>> +
>> + sb->map[0] = panic_map;
>> + sb->width = fb->width;
>> + sb->height = fb->height;
>> + sb->format = fb->format;
>> + sb->pitch[0] = fb->pitches[0];
>> +
>> + return 0;
>> +}
>> +
>> static const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
>> .prepare_fb = intel_prepare_plane_fb,
>> .cleanup_fb = intel_cleanup_plane_fb,
>> };
>>
>> +static const struct drm_plane_helper_funcs intel_primary_plane_helper_funcs = {
>> + .prepare_fb = intel_prepare_plane_fb,
>> + .cleanup_fb = intel_cleanup_plane_fb,
>> + .get_scanout_buffer = intel_get_scanout_buffer,
>> + .panic_flush = intel_panic_flush,
>> +};
>> +
>> void intel_plane_helper_add(struct intel_plane *plane)
>> {
>> - drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
>> + if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
>> + drm_plane_helper_add(&plane->base, &intel_primary_plane_helper_funcs);
>> + else
>> + drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
>> }
>>
>> void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state,
>
^ permalink raw reply [flat|nested] 9+ messages in thread