Commit 320323d2 authored by Karol Wachowski's avatar Karol Wachowski Committed by Jacek Lawrynowicz
Browse files

accel/ivpu: Add debugfs interface for setting HWS priority bands



Add debugfs interface to modify following priority bands properties:
 * grace period
 * process grace period
 * process quantum

This allows for the adjustment of hardware scheduling algorithm parameters
for each existing priority band, facilitating validation and fine-tuning.

Reviewed-by: default avatarJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Signed-off-by: default avatarKarol Wachowski <karol.wachowski@intel.com>
Signed-off-by: default avatarJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250204084622.2422544-4-jacek.lawrynowicz@linux.intel.com
parent 7806bad7
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
@@ -398,6 +398,88 @@ static int dct_active_set(void *data, u64 active_percent)

DEFINE_DEBUGFS_ATTRIBUTE(ivpu_dct_fops, dct_active_get, dct_active_set, "%llu\n");

static int priority_bands_show(struct seq_file *s, void *v)
{
	struct ivpu_device *vdev = s->private;
	struct ivpu_hw_info *hw = vdev->hw;

	for (int band = VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE;
	     band < VPU_JOB_SCHEDULING_PRIORITY_BAND_COUNT; band++) {
		switch (band) {
		case VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE:
			seq_puts(s, "Idle:     ");
			break;

		case VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL:
			seq_puts(s, "Normal:   ");
			break;

		case VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS:
			seq_puts(s, "Focus:    ");
			break;

		case VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME:
			seq_puts(s, "Realtime: ");
			break;
		}

		seq_printf(s, "grace_period %9u process_grace_period %9u process_quantum %9u\n",
			   hw->hws.grace_period[band], hw->hws.process_grace_period[band],
			   hw->hws.process_quantum[band]);
	}

	return 0;
}

static int priority_bands_fops_open(struct inode *inode, struct file *file)
{
	return single_open(file, priority_bands_show, inode->i_private);
}

static ssize_t
priority_bands_fops_write(struct file *file, const char __user *user_buf, size_t size, loff_t *pos)
{
	struct seq_file *s = file->private_data;
	struct ivpu_device *vdev = s->private;
	char buf[64];
	u32 grace_period;
	u32 process_grace_period;
	u32 process_quantum;
	u32 band;
	int ret;

	if (size >= sizeof(buf))
		return -EINVAL;

	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, pos, user_buf, size);
	if (ret < 0)
		return ret;

	buf[size] = '\0';
	ret = sscanf(buf, "%u %u %u %u", &band, &grace_period, &process_grace_period,
		     &process_quantum);
	if (ret != 4)
		return -EINVAL;

	if (band >= VPU_JOB_SCHEDULING_PRIORITY_BAND_COUNT)
		return -EINVAL;

	vdev->hw->hws.grace_period[band] = grace_period;
	vdev->hw->hws.process_grace_period[band] = process_grace_period;
	vdev->hw->hws.process_quantum[band] = process_quantum;

	return size;
}

static const struct file_operations ivpu_hws_priority_bands_fops = {
	.owner = THIS_MODULE,
	.open = priority_bands_fops_open,
	.write = priority_bands_fops_write,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

void ivpu_debugfs_init(struct ivpu_device *vdev)
{
	struct dentry *debugfs_root = vdev->drm.debugfs_root;
@@ -420,6 +502,8 @@ void ivpu_debugfs_init(struct ivpu_device *vdev)
			    &fw_trace_hw_comp_mask_fops);
	debugfs_create_file("fw_trace_level", 0200, debugfs_root, vdev,
			    &fw_trace_level_fops);
	debugfs_create_file("hws_priority_bands", 0200, debugfs_root, vdev,
			    &ivpu_hws_priority_bands_fops);

	debugfs_create_file("reset_engine", 0200, debugfs_root, vdev,
			    &ivpu_reset_engine_fops);
+21 −0
Original line number Diff line number Diff line
@@ -113,6 +113,26 @@ static void timeouts_init(struct ivpu_device *vdev)
	}
}

static void priority_bands_init(struct ivpu_device *vdev)
{
	/* Idle */
	vdev->hw->hws.grace_period[VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE] = 0;
	vdev->hw->hws.process_grace_period[VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE] = 50000;
	vdev->hw->hws.process_quantum[VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE] = 160000;
	/* Normal */
	vdev->hw->hws.grace_period[VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL] = 50000;
	vdev->hw->hws.process_grace_period[VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL] = 50000;
	vdev->hw->hws.process_quantum[VPU_JOB_SCHEDULING_PRIORITY_BAND_NORMAL] = 300000;
	/* Focus */
	vdev->hw->hws.grace_period[VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS] = 50000;
	vdev->hw->hws.process_grace_period[VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS] = 50000;
	vdev->hw->hws.process_quantum[VPU_JOB_SCHEDULING_PRIORITY_BAND_FOCUS] = 200000;
	/* Realtime */
	vdev->hw->hws.grace_period[VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME] = 0;
	vdev->hw->hws.process_grace_period[VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME] = 50000;
	vdev->hw->hws.process_quantum[VPU_JOB_SCHEDULING_PRIORITY_BAND_REALTIME] = 200000;
}

static void memory_ranges_init(struct ivpu_device *vdev)
{
	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
@@ -251,6 +271,7 @@ int ivpu_hw_init(struct ivpu_device *vdev)
{
	ivpu_hw_btrs_info_init(vdev);
	ivpu_hw_btrs_freq_ratios_init(vdev);
	priority_bands_init(vdev);
	memory_ranges_init(vdev);
	platform_init(vdev);
	wa_init(vdev);
+5 −0
Original line number Diff line number Diff line
@@ -36,6 +36,11 @@ struct ivpu_hw_info {
		u8 pn_ratio;
		u32 profiling_freq;
	} pll;
	struct {
		u32 grace_period[VPU_HWS_NUM_PRIORITY_BANDS];
		u32 process_quantum[VPU_HWS_NUM_PRIORITY_BANDS];
		u32 process_grace_period[VPU_HWS_NUM_PRIORITY_BANDS];
	} hws;
	u32 tile_fuse;
	u32 sku;
	u16 config;
+11 −18
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include "ivpu_hw.h"
#include "ivpu_ipc.h"
#include "ivpu_jsm_msg.h"
#include "vpu_jsm_api.h"

const char *ivpu_jsm_msg_type_to_str(enum vpu_ipc_msg_type type)
{
@@ -407,26 +408,18 @@ int ivpu_jsm_hws_setup_priority_bands(struct ivpu_device *vdev)
{
	struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP };
	struct vpu_jsm_msg resp;
	struct ivpu_hw_info *hw = vdev->hw;
	struct vpu_ipc_msg_payload_hws_priority_band_setup *setup =
		&req.payload.hws_priority_band_setup;
	int ret;

	/* Idle */
	req.payload.hws_priority_band_setup.grace_period[0] = 0;
	req.payload.hws_priority_band_setup.process_grace_period[0] = 50000;
	req.payload.hws_priority_band_setup.process_quantum[0] = 160000;
	/* Normal */
	req.payload.hws_priority_band_setup.grace_period[1] = 50000;
	req.payload.hws_priority_band_setup.process_grace_period[1] = 50000;
	req.payload.hws_priority_band_setup.process_quantum[1] = 300000;
	/* Focus */
	req.payload.hws_priority_band_setup.grace_period[2] = 50000;
	req.payload.hws_priority_band_setup.process_grace_period[2] = 50000;
	req.payload.hws_priority_band_setup.process_quantum[2] = 200000;
	/* Realtime */
	req.payload.hws_priority_band_setup.grace_period[3] = 0;
	req.payload.hws_priority_band_setup.process_grace_period[3] = 50000;
	req.payload.hws_priority_band_setup.process_quantum[3] = 200000;

	req.payload.hws_priority_band_setup.normal_band_percentage = 10;
	for (int band = VPU_JOB_SCHEDULING_PRIORITY_BAND_IDLE;
	     band < VPU_JOB_SCHEDULING_PRIORITY_BAND_COUNT; band++) {
		setup->grace_period[band] = hw->hws.grace_period[band];
		setup->process_grace_period[band] = hw->hws.process_grace_period[band];
		setup->process_quantum[band] = hw->hws.process_quantum[band];
	}
	setup->normal_band_percentage = 10;

	ret = ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_SET_PRIORITY_BAND_SETUP_RSP,
					     &resp, VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);