Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jani Nikula <jani.nikula@linux.intel.com>
To: "Jocelyn Falempe" <jfalempe@redhat.com>,
	"Rodrigo Vivi" <rodrigo.vivi@intel.com>,
	"Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>,
	"Tvrtko Ursulin" <tursulin@ursulin.net>,
	"Ville Syrjälä" <ville.syrjala@linux.intel.com>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Christian Koenig" <christian.koenig@amd.com>,
	"Huang Rui" <ray.huang@amd.com>,
	"Matthew Auld" <matthew.auld@intel.com>,
	"Matthew Brost" <matthew.brost@intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org
Cc: Jocelyn Falempe <jfalempe@redhat.com>
Subject: Re: [PATCH v8 5/9] drm/i915: Add intel_bo_panic_setup and intel_bo_panic_finish
Date: Fri, 06 Jun 2025 16:24:43 +0300	[thread overview]
Message-ID: <5e5014e3f1cbc9c91d2d6e4a3258c775a468bf46@intel.com> (raw)
In-Reply-To: <20250606120519.753928-6-jfalempe@redhat.com>

On Fri, 06 Jun 2025, Jocelyn Falempe <jfalempe@redhat.com> wrote:
> Implement both functions for i915 and xe, they prepare the work for
> drm_panic support.
> They both use kmap_try_from_panic(), and map one page at a time, to
> write the panic screen on the framebuffer.
>
> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
> ---
>
>
> v5:
>  * Use iosys_map for intel_bo_panic_map().
>
> v7:
>  * Return int for i915_gem_object_panic_map() (Ville Syrjälä)
>
> v8:
>  * Complete rewrite, to use kmap_try_from_panic() which is safe
>    to call from a panic handler
>
>  drivers/gpu/drm/i915/display/intel_bo.c    | 11 +++
>  drivers/gpu/drm/i915/display/intel_bo.h    |  3 +
>  drivers/gpu/drm/i915/gem/i915_gem_object.h |  4 +
>  drivers/gpu/drm/i915/gem/i915_gem_pages.c  | 92 ++++++++++++++++++++++
>  drivers/gpu/drm/xe/display/intel_bo.c      | 55 +++++++++++++
>  5 files changed, 165 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c
> index fbd16d7b58d9..83dbd8ae16fe 100644
> --- a/drivers/gpu/drm/i915/display/intel_bo.c
> +++ b/drivers/gpu/drm/i915/display/intel_bo.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: MIT
>  /* Copyright © 2024 Intel Corporation */
>  
> +#include <drm/drm_panic.h>
>  #include "gem/i915_gem_mman.h"
>  #include "gem/i915_gem_object.h"
>  #include "gem/i915_gem_object_frontbuffer.h"
> @@ -57,3 +58,13 @@ void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj)
>  {
>  	i915_debugfs_describe_obj(m, to_intel_bo(obj));
>  }
> +
> +int intel_bo_panic_setup(struct drm_gem_object *obj, struct drm_scanout_buffer *sb)
> +{
> +	return i915_gem_object_panic_setup(to_intel_bo(obj), sb);
> +}
> +
> +void intel_bo_panic_finish(struct drm_gem_object *obj)
> +{
> +	return i915_gem_object_panic_finish(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 ea7a2253aaa5..9ac087ea275d 100644
> --- a/drivers/gpu/drm/i915/display/intel_bo.h
> +++ b/drivers/gpu/drm/i915/display/intel_bo.h
> @@ -4,6 +4,7 @@
>  #ifndef __INTEL_BO__
>  #define __INTEL_BO__
>  
> +#include <drm/drm_panic.h>
>  #include <linux/types.h>
>  
>  struct drm_gem_object;
> @@ -23,5 +24,7 @@ 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);
> +int intel_bo_panic_setup(struct drm_gem_object *obj, struct drm_scanout_buffer *sb);
> +void intel_bo_panic_finish(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 c34f41605b46..9a0c1019dcad 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> @@ -9,6 +9,7 @@
>  #include <drm/drm_gem.h>
>  #include <drm/drm_file.h>
>  #include <drm/drm_device.h>
> +#include <drm/drm_panic.h>
>  
>  #include "intel_memory_region.h"
>  #include "i915_gem_object_types.h"
> @@ -691,6 +692,9 @@ 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);
>  
> +int i915_gem_object_panic_setup(struct drm_i915_gem_object *obj, struct drm_scanout_buffer *sb);
> +void i915_gem_object_panic_finish(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 7f83f8bdc8fb..9bdbac3d9433 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> @@ -3,6 +3,7 @@
>   * Copyright © 2014-2016 Intel Corporation
>   */
>  
> +#include <drm/drm_panic.h>
>  #include <drm/drm_cache.h>
>  #include <linux/vmalloc.h>
>  
> @@ -354,6 +355,97 @@ static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj,
>  	return vaddr ?: ERR_PTR(-ENOMEM);
>  }
>  
> +static struct page **i915_panic_pages;
> +static int i915_panic_page = -1;
> +static void *i915_panic_vaddr;

How do the per module variables work when you have multiple devices?

BR,
Jani.

> +
> +static void i915_panic_kunmap(void)
> +{
> +	if (i915_panic_vaddr) {
> +		drm_clflush_virt_range(i915_panic_vaddr, PAGE_SIZE);
> +		kunmap_local(i915_panic_vaddr);
> +		i915_panic_vaddr = NULL;
> +	}
> +}
> +
> +static struct page **i915_gem_object_panic_pages(struct drm_i915_gem_object *obj)
> +{
> +	unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i;
> +	struct page *page;
> +	struct page **pages;
> +	struct sgt_iter iter;
> +
> +	pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_ATOMIC);
> +	if (!pages)
> +		return NULL;
> +
> +	i = 0;
> +	for_each_sgt_page(page, iter, obj->mm.pages)
> +		pages[i++] = page;
> +	return pages;
> +}
> +
> +/*
> + * The scanout buffer pages are not mapped, so for each pixel,
> + * use kmap_local_page_try_from_panic() to map the page, and write the pixel.
> + * Try to keep the map from the previous pixel, to avoid too much map/unmap.
> + */
> +static void i915_gem_object_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int x,
> +						 unsigned int y, u32 color)
> +{
> +	unsigned int new_page;
> +	unsigned int offset;
> +
> +	offset = y * sb->pitch[0] + x * sb->format->cpp[0];
> +
> +	new_page = offset >> PAGE_SHIFT;
> +	offset = offset % PAGE_SIZE;
> +	if (new_page != i915_panic_page) {
> +		i915_panic_kunmap();
> +		i915_panic_page = new_page;
> +		i915_panic_vaddr = kmap_local_page_try_from_panic(
> +				   i915_panic_pages[i915_panic_page]);
> +	}
> +	if (i915_panic_vaddr) {
> +		u32 *pix = i915_panic_vaddr + offset;
> +		*pix = color;
> +	}
> +}
> +
> +/*
> + * Setup the gem framebuffer for drm_panic access.
> + * Use current vaddr if it exists, or setup a list of pages.
> + * pfn is not supported yet.
> + */
> +int i915_gem_object_panic_setup(struct drm_i915_gem_object *obj, struct drm_scanout_buffer *sb)
> +{
> +	enum i915_map_type has_type;
> +	void *ptr;
> +
> +	ptr = page_unpack_bits(obj->mm.mapping, &has_type);
> +	if (ptr) {
> +		if (i915_gem_object_has_iomem(obj))
> +			iosys_map_set_vaddr_iomem(&sb->map[0], (void __iomem *)ptr);
> +		else
> +			iosys_map_set_vaddr(&sb->map[0], ptr);
> +
> +		return 0;
> +	}
> +	if (i915_gem_object_has_struct_page(obj)) {
> +		i915_panic_pages = i915_gem_object_panic_pages(obj);
> +		sb->set_pixel = i915_gem_object_panic_page_set_pixel;
> +		i915_panic_page = -1;
> +		return 0;
> +	}
> +	return -EOPNOTSUPP;
> +}
> +
> +void i915_gem_object_panic_finish(struct drm_i915_gem_object *obj)
> +{
> +	i915_panic_kunmap();
> +	i915_panic_page = -1;
> +}
> +
>  /* 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 27437c22bd70..eb9a3400c110 100644
> --- a/drivers/gpu/drm/xe/display/intel_bo.c
> +++ b/drivers/gpu/drm/xe/display/intel_bo.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: MIT
>  /* Copyright © 2024 Intel Corporation */
>  
> +#include <drm/drm_cache.h>
>  #include <drm/drm_gem.h>
>  
>  #include "xe_bo.h"
> @@ -59,3 +60,57 @@ void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj)
>  {
>  	/* FIXME */
>  }
> +
> +static int xe_panic_page = -1;
> +static void *xe_panic_vaddr;
> +static struct xe_bo *xe_panic_bo;
> +
> +static void xe_panic_kunmap(void)
> +{
> +	if (xe_panic_vaddr) {
> +		drm_clflush_virt_range(xe_panic_vaddr, PAGE_SIZE);
> +		kunmap_local(xe_panic_vaddr);
> +		xe_panic_vaddr = NULL;
> +	}
> +}
> +/*
> + * The scanout buffer pages are not mapped, so for each pixel,
> + * use kmap_local_page_try_from_panic() to map the page, and write the pixel.
> + * Try to keep the map from the previous pixel, to avoid too much map/unmap.
> + */
> +static void xe_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int x,
> +				    unsigned int y, u32 color)
> +{
> +	unsigned int new_page;
> +	unsigned int offset;
> +
> +	offset = y * sb->pitch[0] + x * sb->format->cpp[0];
> +
> +	new_page = offset >> PAGE_SHIFT;
> +	offset = offset % PAGE_SIZE;
> +	if (new_page != xe_panic_page) {
> +		xe_panic_kunmap();
> +		xe_panic_page = new_page;
> +		xe_panic_vaddr = ttm_bo_kmap_try_from_panic(&xe_panic_bo->ttm,
> +							    xe_panic_page);
> +	}
> +	if (xe_panic_vaddr) {
> +		u32 *pix = xe_panic_vaddr + offset;
> +		*pix = color;
> +	}
> +}
> +
> +int intel_bo_panic_setup(struct drm_gem_object *obj, struct drm_scanout_buffer *sb)
> +{
> +	struct xe_bo *bo = gem_to_xe_bo(obj);
> +
> +	xe_panic_bo = bo;
> +	sb->set_pixel = xe_panic_page_set_pixel;
> +	return 0;
> +}
> +
> +void intel_bo_panic_finish(struct drm_gem_object *obj)
> +{
> +	xe_panic_kunmap();
> +	xe_panic_page = -1;
> +}

-- 
Jani Nikula, Intel

  reply	other threads:[~2025-06-06 13:24 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-06 11:48 [PATCH v8 0/9] drm/i915: Add drm_panic support Jocelyn Falempe
2025-06-06 11:48 ` [PATCH v8 1/9] drm/i915/fbdev: Add intel_fbdev_get_map() Jocelyn Falempe
2025-06-06 11:48 ` [PATCH v8 2/9] drm/i915/display/i9xx: Add a disable_tiling() for i9xx planes Jocelyn Falempe
2025-06-06 11:48 ` [PATCH v8 3/9] drm/i915/display: Add a disable_tiling() for skl planes Jocelyn Falempe
2025-06-06 11:48 ` [PATCH v8 4/9] drm/ttm: Add ttm_bo_kmap_try_from_panic() Jocelyn Falempe
2025-06-06 12:28   ` Christian König
2025-06-06 13:14     ` Jocelyn Falempe
2025-06-06 14:57       ` Christian König
2025-06-06 19:46   ` kernel test robot
2025-06-06 11:48 ` [PATCH v8 5/9] drm/i915: Add intel_bo_panic_setup and intel_bo_panic_finish Jocelyn Falempe
2025-06-06 13:24   ` Jani Nikula [this message]
2025-06-06 11:48 ` [PATCH v8 6/9] drm/i915/display: Add drm_panic support Jocelyn Falempe
2025-06-06 11:48 ` [PATCH v8 7/9] drm/i915/display: Add drm_panic support for Y-tiling with DPT Jocelyn Falempe
2025-06-06 11:48 ` [PATCH v8 8/9] drm/i915/display: Add drm_panic support for 4-tiling " Jocelyn Falempe
2025-06-06 11:48 ` [PATCH v8 9/9] drm/i915/psr: Add intel_psr2_panic_force_full_update Jocelyn Falempe
2025-06-06 13:07 ` ✓ CI.Patch_applied: success for drm/i915: Add drm_panic support (rev8) Patchwork
2025-06-06 13:08 ` ✗ CI.checkpatch: warning " Patchwork
2025-06-06 13:10 ` ✓ CI.KUnit: success " Patchwork
2025-06-06 13:22 ` ✓ CI.Build: " Patchwork
2025-06-06 13:25 ` ✓ CI.Hooks: " Patchwork
2025-06-06 13:27 ` ✗ CI.checksparse: warning " Patchwork
2025-06-06 14:12 ` ✓ Xe.CI.BAT: success " Patchwork
2025-06-08 16:36 ` ✗ Xe.CI.Full: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5e5014e3f1cbc9c91d2d6e4a3258c775a468bf46@intel.com \
    --to=jani.nikula@linux.intel.com \
    --cc=airlied@gmail.com \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=jfalempe@redhat.com \
    --cc=joonas.lahtinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matthew.auld@intel.com \
    --cc=matthew.brost@intel.com \
    --cc=mripard@kernel.org \
    --cc=ray.huang@amd.com \
    --cc=rodrigo.vivi@intel.com \
    --cc=simona@ffwll.ch \
    --cc=tursulin@ursulin.net \
    --cc=tzimmermann@suse.de \
    --cc=ville.syrjala@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox