All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Brost <matthew.brost@intel.com>
To: S Sebinraj <s.sebinraj@intel.com>
Cc: <intel-xe@lists.freedesktop.org>, <jeevaka.badrappan@intel.com>
Subject: Re: [PATCH v2] drm/xe: GPU frequency tracing support
Date: Mon, 11 Aug 2025 14:03:06 -0700	[thread overview]
Message-ID: <aJpairAgaJlpbs3N@lstrano-desk.jf.intel.com> (raw)
In-Reply-To: <aJpVQB3tYc6OUnae@lstrano-desk.jf.intel.com>

On Mon, Aug 11, 2025 at 01:40:32PM -0700, Matthew Brost wrote:
> On Mon, Aug 11, 2025 at 02:04:14PM +0530, S Sebinraj wrote:
> > A periodic GPU frequency monitoring and tracing program for the
> > Xe driver. The implementation provides periodic sampling of
> > GPU frequency through the Linux ftrace infrastructure.
> > 
> > Key features:
> > - Periodic GPU frequency sampling with configurable intervals
> > - Immediate frequency change reporting via tracepoints
> > - Integration with Linux ftrace subsystem under 'power' events
> > - Per-GT (Graphics Technology) monitoring support
> > - Dedicated workqueue for non-blocking frequency sampling
> > - Configurable via CONFIG_DRM_XE_GPUFREQTRACER kernel option
> > - The monitoring interval can be configured at runtime via the sysfs
> >   (default 5sec).
> > 
> > The sysfs entry is at:
> > /sys/module/xe/parameters/gpufreq_monitoring_interval_ms
> > 
> > The tracepoint is exposed at:
> > /sys/kernel/debug/tracing/events/power/gpu_frequency
> > 
> > Format: {unsigned int state, unsigned int gpu_id}
> > - state: GPU frequency in KHz
> > - gpu_id: GPU clock domain identifier
> > 
> > This enables userspace tools and system monitoring applications to track
> > GPU frequency changes for power management analysis, performance tuning,
> > and debugging purposes.
> > 
> > Signed-off-by: S Sebinraj <s.sebinraj@intel.com>
> > ---
> >  drivers/gpu/drm/xe/Kconfig                  |  22 ++
> >  drivers/gpu/drm/xe/Makefile                 |   3 +
> >  drivers/gpu/drm/xe/xe_device.c              |   7 +
> >  drivers/gpu/drm/xe/xe_device_types.h        |   4 +
> >  drivers/gpu/drm/xe/xe_gpufreqtracer.c       | 292 ++++++++++++++++++++
> >  drivers/gpu/drm/xe/xe_gpufreqtracer.h       |  30 ++
> >  drivers/gpu/drm/xe/xe_gpufreqtracer_trace.h |  48 ++++
> >  drivers/gpu/drm/xe/xe_module.c              |  12 +
> >  drivers/gpu/drm/xe/xe_module.h              |   3 +
> >  9 files changed, 421 insertions(+)
> >  create mode 100644 drivers/gpu/drm/xe/xe_gpufreqtracer.c
> >  create mode 100644 drivers/gpu/drm/xe/xe_gpufreqtracer.h
> >  create mode 100644 drivers/gpu/drm/xe/xe_gpufreqtracer_trace.h
> > 
> > diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig
> > index 714d5702dfd7..d9d07ec69875 100644
> > --- a/drivers/gpu/drm/xe/Kconfig
> > +++ b/drivers/gpu/drm/xe/Kconfig
> > @@ -129,6 +129,28 @@ config DRM_XE_FORCE_PROBE
> >  
> >  	  Use "!*" to block the probe of the driver for all known devices.
> >  
> > +config DRM_XE_GPUFREQTRACER
> > +	bool "Enable XE GPU frequency tracing"
> > +	depends on DRM_XE && FTRACE
> > +	default n
> > +	help
> > +	  Enable GPU frequency tracing support for Intel XE driver.
> > +	  This adds an ftrace tracepoint that reports GPU frequency changes
> > +	  at periodic boundaries (default 5 secs, configurable via the
> > +	  gpufreq_monitoring_interval_ms module parameter) and
> > +	  on direct frequency change events.
> > +
> > +	  The monitoring interval can be configured at runtime via the sysfs module parameter:
> > +	  /sys/module/xe/parameters/gpufreq_monitoring_interval_ms
> > +
> > +	  The tracepoint will be available at:
> > +	  /sys/kernel/debug/tracing/events/power/gpu_frequency
> > +
> > +	  Format: {unsigned int state, unsigned int gpu_id}
> > +	  Where state is the frequency in KHz and gpu_id is the GPU clock domain.
> > +
> > +	  If unsure, say N.
> > +
> >  menu "drm/Xe Debugging"
> >  depends on DRM_XE
> >  depends on EXPERT
> > diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
> > index 8e0c3412a757..61d46cc4dc25 100644
> > --- a/drivers/gpu/drm/xe/Makefile
> > +++ b/drivers/gpu/drm/xe/Makefile
> > @@ -170,6 +170,9 @@ xe-$(CONFIG_PCI_IOV) += \
> >  	xe_sriov_pf.o \
> >  	xe_sriov_pf_service.o
> >  
> > +# GPU frequency tracer
> > +xe-$(CONFIG_DRM_XE_GPUFREQTRACER) += xe_gpufreqtracer.o
> > +
> >  # include helpers for tests even when XE is built-in
> >  ifdef CONFIG_DRM_XE_KUNIT_TEST
> >  xe-y += tests/xe_kunit_helpers.o
> > diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
> > index 57edbc63da6f..88198ceb519b 100644
> > --- a/drivers/gpu/drm/xe/xe_device.c
> > +++ b/drivers/gpu/drm/xe/xe_device.c
> > @@ -34,6 +34,7 @@
> >  #include "xe_exec_queue.h"
> >  #include "xe_force_wake.h"
> >  #include "xe_ggtt.h"
> > +#include "xe_gpufreqtracer.h"
> >  #include "xe_gsc_proxy.h"
> >  #include "xe_gt.h"
> >  #include "xe_gt_mcr.h"
> > @@ -896,6 +897,12 @@ int xe_device_probe(struct xe_device *xe)
> >  	if (err)
> >  		return err;
> >  
> > +#if IS_ENABLED(CONFIG_DRM_XE_GPUFREQTRACER)
> > +	err = xe_gpufreqtracer_init(xe);
> > +	if (err)
> > +		return err;
> > +#endif
> > +
> >  	err = xe_oa_init(xe);
> >  	if (err)
> >  		return err;
> > diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
> > index 01e8fa0d2f9f..0634dbbbdc3f 100644
> > --- a/drivers/gpu/drm/xe/xe_device_types.h
> > +++ b/drivers/gpu/drm/xe/xe_device_types.h
> > @@ -35,6 +35,7 @@ struct dram_info;
> >  struct intel_display;
> >  struct intel_dg_nvm_dev;
> >  struct xe_ggtt;
> > +struct xe_gpufreqtracer_data;
> >  struct xe_i2c;
> >  struct xe_pat_ops;
> >  struct xe_pxp;
> > @@ -529,6 +530,9 @@ struct xe_device {
> >  	/** @oa: oa observation subsystem */
> >  	struct xe_oa oa;
> >  
> > +	/** @gpufreqtracer_data: GPU frequency tracer data */
> > +	struct xe_gpufreqtracer_data *gpufreqtracer_data;
> > +
> >  	/** @pxp: Encapsulate Protected Xe Path support */
> >  	struct xe_pxp *pxp;
> >  
> > diff --git a/drivers/gpu/drm/xe/xe_gpufreqtracer.c b/drivers/gpu/drm/xe/xe_gpufreqtracer.c
> > new file mode 100644
> > index 000000000000..07eedfb79e93
> > --- /dev/null
> > +++ b/drivers/gpu/drm/xe/xe_gpufreqtracer.c
> > @@ -0,0 +1,292 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright © 2025 Intel Corporation
> > + */
> > +
> > +#include "xe_gpufreqtracer.h"
> > +
> > +#include <linux/workqueue.h>
> > +#include <linux/slab.h>
> > +#include <linux/jiffies.h>
> > +#include <linux/kernel.h>
> > +#include <linux/moduleparam.h>
> > +#include <linux/types.h>
> > +#include <linux/container_of.h>
> > +#include <linux/gfp.h>
> > +#include <linux/atomic.h>
> > +#include <drm/drm_managed.h>
> > +
> > +#include "xe_device.h"
> > +#include "xe_gt.h"
> > +#include "xe_gt_types.h"
> > +#include "xe_guc_pc.h"
> > +#include "xe_module.h"
> > +
> > +/* GPU frequency monitoring interval constants (in milliseconds) */
> > +#define XE_GPUFREQ_MONITORING_MIN_INTERVAL_MS	100
> > +#define XE_GPUFREQ_MONITORING_MAX_INTERVAL_MS	10000
> > +#define XE_GPUFREQ_MONITORING_DEFAULT_INTERVAL_MS	5000
> > +
> > +#define CREATE_TRACE_POINTS
> > +#include "xe_gpufreqtracer_trace.h"
> > +
> > +/**
> > + * struct xe_gpufreqtracer_gt_data - Per-GT frequency monitoring data
> > + * @gt: Reference to the GT
> > + * @delayed_work: Delayed work for periodic monitoring
> > + * @last_frequency: Last reported frequency to avoid duplicate reports
> > + * @monitoring_active: Whether monitoring is currently active
> > + */
> > +struct xe_gpufreqtracer_gt_data {
> > +	struct xe_gt *gt;
> > +	struct delayed_work delayed_work;
> > +	atomic_t last_frequency;
> > +	atomic_t monitoring_active;
> > +};
> > +
> > +/**
> > + * struct xe_gpufreqtracer_data - Per-device frequency tracer data
> > + * @xe: Reference to the XE device
> > + * @gt_data: Array of per-GT monitoring data
> > + */
> > +struct xe_gpufreqtracer_data {
> > +	struct xe_device *xe;
> > +	struct xe_gpufreqtracer_gt_data *gt_data;
> > +};
> > +
> > +
> > +/**
> > + * xe_gpufreqtracer_sample_work - Worker function to sample GPU frequency.
> > + * @work: Pointer to the delayed_work_struct representing the scheduled work.
> > + *
> > + * This function is executed in a workqueue context to periodically sample
> > + * the GPU frequency and perform any necessary tracing or logging operations.
> > + * It reschedules itself for the next sampling interval.
> > + */
> > +static void xe_gpufreqtracer_sample_work(struct work_struct *work)
> > +{
> > +	struct xe_gpufreqtracer_gt_data *gt_data =
> > +		container_of(work, struct xe_gpufreqtracer_gt_data, delayed_work.work);
> > +	struct xe_gt *gt = gt_data->gt;
> > +	struct xe_guc_pc *pc = &gt->uc.guc.pc;
> > +	u32 current_freq, last_freq;
> > +
> > +	if (!atomic_read(&gt_data->monitoring_active)) {
> > +		drm_warn(&gt_to_xe(gt)->drm, "monitoring not active for GT%u, exiting",
> > +			 gt->info.id);
> > +		return;
> > +	}
> > +
> > +	current_freq = xe_guc_pc_get_act_freq(pc) * 1000; /* Convert MHz to KHz */
> 
> I missed this. The above function performs an MMIO read, which relies on
> a runtime PM reference being held. I think you will need a
> xe_pm_runtime_get_if_active to protect this function, and perhaps a
> drm_dev_enter to protect against hotplug as well.
> 
> With regard to power management, if the PM reference fails (and I don't
> think we want this worker waking the device), you can likely set
> current_freq to a known value. I suspect that if we don't have a PM
> reference, the GuC PC frequency is fixed at a (low) value, but I'm not
> 100% sure on that. You can check with a PM expert (perhaps Rodrigo or
> Vinay) to confirm.
> 
> It should probably look similar to xe_migrate_ulls_exit in this patch
> [1].
> 

You might also need a xe_force_wake_get of the XE_FW_GT domain too.

Matt

> Matt
> 
> [1] https://patchwork.freedesktop.org/patch/667257/?series=149888&rev=2
> 
> > +	last_freq = atomic_read(&gt_data->last_frequency);
> > +
> > +	/* Only report if frequency has changed or this is the first sample */
> > +	if (current_freq != last_freq) {
> > +		drm_dbg(&gt_to_xe(gt)->drm, "GT%u frequency changed, tracing %u KHz",
> > +			gt->info.id, current_freq);
> > +		trace_gpu_frequency(current_freq, gt->info.id);
> > +		atomic_set(&gt_data->last_frequency, current_freq);
> > +	}
> > +
> > +	/* Reschedule for the next sampling interval if monitoring is still active */
> > +	if (atomic_read(&gt_data->monitoring_active)) {
> > +		schedule_delayed_work(&gt_data->delayed_work,
> > +				      msecs_to_jiffies(xe_modparam.gpufreq_monitoring_interval_ms));
> > +	}
> > +}
> > +
> > +/**
> > + * xe_gpufreqtracer_start_monitoring - Start periodic frequency monitoring
> > + * @gt: The GT instance
> > + *
> > + * Starts periodic sampling of GPU frequency for the specified GT using the global
> > + * monitoring interval from module parameters.
> > + *
> > + * Return: 0 on success, negative error code on failure
> > + */
> > +static int xe_gpufreqtracer_start_monitoring(struct xe_gt *gt)
> > +{
> > +	struct xe_gpufreqtracer_data *tracer_data = gt_to_xe(gt)->gpufreqtracer_data;
> > +	struct xe_gpufreqtracer_gt_data *gt_data;
> > +
> > +	if (!tracer_data) {
> > +		drm_warn(&gt_to_xe(gt)->drm, "no tracer data for GT%u, not supported", gt->info.id);
> > +		return -EOPNOTSUPP;
> > +	}
> > +
> > +	if (gt->info.id >= gt_to_xe(gt)->info.gt_count) {
> > +		drm_err(&gt_to_xe(gt)->drm, "invalid GT ID %u, max supported is %u",
> > +			gt->info.id, gt_to_xe(gt)->info.gt_count - 1);
> > +		return -EINVAL;
> > +	}
> > +
> > +	gt_data = &tracer_data->gt_data[gt->info.id];
> > +
> > +	if (atomic_read(&gt_data->monitoring_active)) {
> > +		drm_warn(&gt_to_xe(gt)->drm, "monitoring already active for GT%u", gt->info.id);
> > +		return -EALREADY;
> > +	}
> > +
> > +	atomic_set(&gt_data->monitoring_active, 1);
> > +	atomic_set(&gt_data->last_frequency, 0);
> > +
> > +	/* Start the delayed work using global interval */
> > +	schedule_delayed_work(&gt_data->delayed_work,
> > +			      msecs_to_jiffies(xe_modparam.gpufreq_monitoring_interval_ms));
> > +
> > +	drm_dbg(&gt_to_xe(gt)->drm, "monitoring started for GT%u with interval %u ms",
> > +		 gt->info.id, xe_modparam.gpufreq_monitoring_interval_ms);
> > +
> > +	return 0;
> > +}
> > +
> > +/**
> > + * xe_gpufreqtracer_stop_monitoring - Stop periodic frequency monitoring
> > + * @gt: The GT instance
> > + *
> > + * Stops periodic sampling of GPU frequency for the specified GT.
> > + */
> > +static void xe_gpufreqtracer_stop_monitoring(struct xe_gt *gt)
> > +{
> > +	struct xe_gpufreqtracer_data *tracer_data = gt_to_xe(gt)->gpufreqtracer_data;
> > +	struct xe_gpufreqtracer_gt_data *gt_data;
> > +
> > +	if (!tracer_data || gt->info.id >= gt_to_xe(gt)->info.gt_count) {
> > +		drm_err(&gt_to_xe(gt)->drm, "invalid tracer data or GT ID %u for stop request",
> > +			gt->info.id);
> > +		return;
> > +	}
> > +
> > +	gt_data = &tracer_data->gt_data[gt->info.id];
> > +
> > +	if (!atomic_read(&gt_data->monitoring_active)) {
> > +		drm_warn(&gt_to_xe(gt)->drm, "monitoring not active for GT%u, nothing to stop",
> > +			 gt->info.id);
> > +		return;
> > +	}
> > +
> > +	atomic_set(&gt_data->monitoring_active, 0);
> > +
> > +	cancel_delayed_work_sync(&gt_data->delayed_work);
> > +}
> > +
> > +/**
> > + * xe_gpufreqtracer_validate_params - Validate GPU frequency monitoring parameters
> > + *
> > + * Validates and corrects the GPU frequency monitoring interval parameter.
> > + * If the parameter is out of range, it will be reset to the default value.
> > + */
> > +static void xe_gpufreqtracer_validate_params(void)
> > +{
> > +	if (xe_modparam.gpufreq_monitoring_interval_ms < XE_GPUFREQ_MONITORING_MIN_INTERVAL_MS ||
> > +	    xe_modparam.gpufreq_monitoring_interval_ms > XE_GPUFREQ_MONITORING_MAX_INTERVAL_MS) {
> > +		pr_warn("xe: gpufreq_monitoring_interval_ms %u out of range [%u, %u], using default %u ms\n",
> > +			xe_modparam.gpufreq_monitoring_interval_ms,
> > +			XE_GPUFREQ_MONITORING_MIN_INTERVAL_MS,
> > +			XE_GPUFREQ_MONITORING_MAX_INTERVAL_MS,
> > +			XE_GPUFREQ_MONITORING_DEFAULT_INTERVAL_MS);
> > +		xe_modparam.gpufreq_monitoring_interval_ms = XE_GPUFREQ_MONITORING_DEFAULT_INTERVAL_MS;
> > +	}
> > +}
> > +
> > +/**
> > + * xe_gpufreqtracer_cleanup_action - DRM managed cleanup action
> > + * @drm: DRM device
> > + * @ptr: Pointer to xe_device
> > + *
> > + * Cleanup function called automatically by DRM managed resource system.
> > + */
> > +static void xe_gpufreqtracer_cleanup_action(struct drm_device *drm, void *ptr)
> > +{
> > +	struct xe_device *xe = ptr;
> > +	struct xe_gpufreqtracer_data *tracer_data = xe->gpufreqtracer_data;
> > +	struct xe_gt *gt;
> > +	u8 tile_id;
> > +
> > +	if (!tracer_data) {
> > +		drm_warn(drm, "no tracer data found, nothing to cleanup");
> > +		return;
> > +	}
> > +
> > +	/* Stop all monitoring */
> > +	for_each_gt(gt, xe, tile_id) {
> > +		drm_dbg(drm, "stopping monitoring for GT%u", gt->info.id);
> > +		xe_gpufreqtracer_stop_monitoring(gt);
> > +	}
> > +
> > +	/* Memory is automatically freed by drmm - just clear the pointer */
> > +	xe->gpufreqtracer_data = NULL;
> > +}
> > +
> > +/**
> > + * xe_gpufreqtracer_init - Initialize GPU frequency tracer for a device
> > + * @xe: The XE device
> > + *
> > + * Sets up the frequency tracer infrastructure for all GTs in the device.
> > + *
> > + * Return: 0 on success, negative error code on failure
> > + */
> > +int xe_gpufreqtracer_init(struct xe_device *xe)
> > +{
> > +	struct xe_gpufreqtracer_data *tracer_data;
> > +	struct xe_gt *gt;
> > +	u8 tile_id;
> > +	int ret = 0;
> > +
> > +	/* Validate module parameters first */
> > +	xe_gpufreqtracer_validate_params();
> > +
> > +	tracer_data = drmm_kzalloc(&xe->drm, sizeof(*tracer_data), GFP_KERNEL);
> > +	if (!tracer_data)
> > +		return -ENOMEM;
> > +
> > +	tracer_data->xe = xe;
> > +
> > +	/* Allocate GT data array based on actual GT count */
> > +	tracer_data->gt_data = drmm_kcalloc(&xe->drm, xe->info.gt_count,
> > +				       sizeof(*tracer_data->gt_data),
> > +				       GFP_KERNEL);
> > +	if (!tracer_data->gt_data) {
> > +		ret = -ENOMEM;
> > +		goto err_free_tracer;
> > +	}
> > +
> > +	/* Initialize per-GT data */
> > +	for_each_gt(gt, xe, tile_id) {
> > +		struct xe_gpufreqtracer_gt_data *gt_data =
> > +			&tracer_data->gt_data[gt->info.id];
> > +
> > +		drm_dbg(&xe->drm, "initializing GT%u (tile %u)", gt->info.id, tile_id);
> > +
> > +		gt_data->gt = gt;
> > +		atomic_set(&gt_data->monitoring_active, 0);
> > +		atomic_set(&gt_data->last_frequency, 0);
> > +
> > +		INIT_DELAYED_WORK(&gt_data->delayed_work, xe_gpufreqtracer_sample_work);
> > +
> > +		drm_dbg(&xe->drm, "GT%u initialized with global interval=%u ms",
> > +			 gt->info.id, xe_modparam.gpufreq_monitoring_interval_ms);
> > +	}
> > +
> > +	xe->gpufreqtracer_data = tracer_data;
> > +
> > +	/* Start periodic monitoring on all GTs using global module parameter */
> > +	for_each_gt(gt, xe, tile_id) {
> > +		ret = xe_gpufreqtracer_start_monitoring(gt);
> > +		if (ret) {
> > +			drm_err(&xe->drm, "xe_gpufreqtracer: failed to start monitoring for GT%u, err=%d\n",
> > +				gt->info.id, ret);
> > +		}
> > +	}
> > +
> > +	/* Register cleanup action for proper work cancellation */
> > +	ret = drmm_add_action(&xe->drm, xe_gpufreqtracer_cleanup_action, xe);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +
> > +err_free_tracer:
> > +	drm_err(&xe->drm, "initialization failed, freeing tracer data");
> > +	return ret;
> > +}
> > diff --git a/drivers/gpu/drm/xe/xe_gpufreqtracer.h b/drivers/gpu/drm/xe/xe_gpufreqtracer.h
> > new file mode 100644
> > index 000000000000..561abe27b6e2
> > --- /dev/null
> > +++ b/drivers/gpu/drm/xe/xe_gpufreqtracer.h
> > @@ -0,0 +1,30 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright © 2025 Intel Corporation
> > + */
> > +
> > +#ifndef _XE_GPUFREQTRACER_H_
> > +#define _XE_GPUFREQTRACER_H_
> > +
> > +#include <linux/types.h>
> > +
> > +struct xe_device;
> > +struct xe_gt;
> > +
> > +#ifdef CONFIG_DRM_XE_GPUFREQTRACER
> > +
> > +/*
> > + * Initialize the GPU frequency tracer for a device
> > + */
> > +int xe_gpufreqtracer_init(struct xe_device *xe);
> > +
> > +#else /* CONFIG_DRM_XE_GPUFREQTRACER */
> > +
> > +static inline int xe_gpufreqtracer_init(struct xe_device *xe)
> > +{
> > +	return 0;
> > +}
> > +
> > +#endif /* CONFIG_DRM_XE_GPUFREQTRACER */
> > +
> > +#endif /* _XE_GPUFREQTRACER_H_ */
> > diff --git a/drivers/gpu/drm/xe/xe_gpufreqtracer_trace.h b/drivers/gpu/drm/xe/xe_gpufreqtracer_trace.h
> > new file mode 100644
> > index 000000000000..5664db62e3fb
> > --- /dev/null
> > +++ b/drivers/gpu/drm/xe/xe_gpufreqtracer_trace.h
> > @@ -0,0 +1,48 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright © 2025 Intel Corporation
> > + */
> > +
> > +#undef TRACE_SYSTEM
> > +#define TRACE_SYSTEM power
> > +
> > +#if !defined(_XE_GPUFREQTRACER_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
> > +#define _XE_GPUFREQTRACER_TRACE_H
> > +
> > +#include <linux/tracepoint.h>
> > +
> > +/*
> > + * Tracepoint for GPU frequency changes
> > + * This tracepoint is exposed at /sys/kernel/debug/tracing/events/power/gpu_frequency
> > + *
> > + * location: /d/events/power/gpu_frequency
> > + * format: {unsigned int state, unsigned int gpu_id}
> > + * where state holds the frequency(in Khz) and the gpu_id holds the GPU clock domain.
> > + */
> > +
> > +TRACE_EVENT(gpu_frequency,
> > +	TP_PROTO(unsigned int state, unsigned int gpu_id),
> > +
> > +	TP_ARGS(state, gpu_id),
> > +
> > +	TP_STRUCT__entry(
> > +		__field(unsigned int, state)
> > +		__field(unsigned int, gpu_id)
> > +	),
> > +
> > +	TP_fast_assign(
> > +		__entry->state = state;
> > +		__entry->gpu_id = gpu_id;
> > +	),
> > +
> > +	TP_printk("state=%u gpu_id=%u", __entry->state, __entry->gpu_id)
> > +);
> > +
> > +#endif /* _XE_GPUFREQTRACER_TRACE_H */
> > +
> > +/* This part must be outside protection */
> > +#undef TRACE_INCLUDE_PATH
> > +#undef TRACE_INCLUDE_FILE
> > +#define TRACE_INCLUDE_PATH .
> > +#define TRACE_INCLUDE_FILE xe_gpufreqtracer_trace
> > +#include <trace/define_trace.h>
> > diff --git a/drivers/gpu/drm/xe/xe_module.c b/drivers/gpu/drm/xe/xe_module.c
> > index d08338fc3bc1..f5d4f8bca61f 100644
> > --- a/drivers/gpu/drm/xe/xe_module.c
> > +++ b/drivers/gpu/drm/xe/xe_module.c
> > @@ -31,6 +31,7 @@
> >  #define DEFAULT_MAX_VFS_STR		"unlimited"
> >  #define DEFAULT_WEDGED_MODE		1
> >  #define DEFAULT_SVM_NOTIFIER_SIZE	512
> > +#define DEFAULT_GPUFREQ_MONITORING_INTERVAL_MS	5000
> >  
> >  struct xe_modparam xe_modparam = {
> >  	.probe_display =	DEFAULT_PROBE_DISPLAY,
> > @@ -41,6 +42,9 @@ struct xe_modparam xe_modparam = {
> >  #endif
> >  	.wedged_mode =		DEFAULT_WEDGED_MODE,
> >  	.svm_notifier_size =	DEFAULT_SVM_NOTIFIER_SIZE,
> > +#ifdef CONFIG_DRM_XE_GPUFREQTRACER
> > +	.gpufreq_monitoring_interval_ms = DEFAULT_GPUFREQ_MONITORING_INTERVAL_MS,
> > +#endif
> >  	/* the rest are 0 by default */
> >  };
> >  
> > @@ -93,6 +97,14 @@ MODULE_PARM_DESC(wedged_mode,
> >  		 "Module's default policy for the wedged mode (0=never, 1=upon-critical-errors, 2=upon-any-hang "
> >  		 "[default=" __stringify(DEFAULT_WEDGED_MODE) "])");
> >  
> > +#ifdef CONFIG_DRM_XE_GPUFREQTRACER
> > +module_param_named(gpufreq_monitoring_interval_ms,
> > +		   xe_modparam.gpufreq_monitoring_interval_ms, uint, 0644);
> > +MODULE_PARM_DESC(gpufreq_monitoring_interval_ms,
> > +		 "GPU frequency monitoring interval in milliseconds (100-10000, default: "
> > +		 __stringify(DEFAULT_GPUFREQ_MONITORING_INTERVAL_MS) ")");
> > +#endif
> > +
> >  static int xe_check_nomodeset(void)
> >  {
> >  	if (drm_firmware_drivers_only())
> > diff --git a/drivers/gpu/drm/xe/xe_module.h b/drivers/gpu/drm/xe/xe_module.h
> > index 5a3bfea8b7b4..fd60de38d24d 100644
> > --- a/drivers/gpu/drm/xe/xe_module.h
> > +++ b/drivers/gpu/drm/xe/xe_module.h
> > @@ -23,6 +23,9 @@ struct xe_modparam {
> >  #endif
> >  	int wedged_mode;
> >  	u32 svm_notifier_size;
> > +#ifdef CONFIG_DRM_XE_GPUFREQTRACER
> > +	u32 gpufreq_monitoring_interval_ms;
> > +#endif
> >  };
> >  
> >  extern struct xe_modparam xe_modparam;
> > -- 
> > 2.34.1
> > 

  reply	other threads:[~2025-08-11 21:03 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-11  8:34 [PATCH v2] drm/xe: GPU frequency tracing support S Sebinraj
2025-08-11  9:39 ` ✗ CI.checkpatch: warning for drm/xe: GPU frequency tracing support (rev2) Patchwork
2025-08-11  9:40 ` ✓ CI.KUnit: success " Patchwork
2025-08-11 10:42 ` ✓ Xe.CI.BAT: " Patchwork
2025-08-11 11:38 ` ✗ Xe.CI.Full: failure " Patchwork
2025-08-11 20:05 ` [PATCH v2] drm/xe: GPU frequency tracing support Matthew Brost
2025-08-11 20:40 ` Matthew Brost
2025-08-11 21:03   ` Matthew Brost [this message]
2025-08-11 21:13 ` Lucas De Marchi
2025-08-11 21:28   ` Matthew Brost
2025-08-20  4:25   ` Sebinraj, S
2025-08-22 19:30     ` Lucas De Marchi
2025-08-27  4:35       ` Matthew Brost
2025-09-03  5:54       ` Sebinraj, S
2025-08-22 20:58     ` Dixit, Ashutosh
2025-09-03  6:03       ` Sebinraj, S

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=aJpairAgaJlpbs3N@lstrano-desk.jf.intel.com \
    --to=matthew.brost@intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=jeevaka.badrappan@intel.com \
    --cc=s.sebinraj@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.