mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
drm/xe/pf: Allow to view and replace VF GuC state over debugfs
For feature enabling and testing purposes, allow to view saved VF GuC state and to replace it, but only under strict debug config. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Michał Winiarski <michal.winiarski@intel.com> Cc: Tomasz Lis <tomasz.lis@intel.com> Reviewed-by: Michał Winiarski <michal.winiarski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240912203817.1880-6-michal.wajdeczko@intel.com
This commit is contained in:
parent
14423f08c3
commit
d620448fb5
|
|
@ -17,6 +17,7 @@
|
|||
#include "xe_gt_sriov_pf_control.h"
|
||||
#include "xe_gt_sriov_pf_debugfs.h"
|
||||
#include "xe_gt_sriov_pf_helpers.h"
|
||||
#include "xe_gt_sriov_pf_migration.h"
|
||||
#include "xe_gt_sriov_pf_monitor.h"
|
||||
#include "xe_gt_sriov_pf_policy.h"
|
||||
#include "xe_gt_sriov_pf_service.h"
|
||||
|
|
@ -375,6 +376,44 @@ static const struct file_operations control_ops = {
|
|||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
/*
|
||||
* /sys/kernel/debug/dri/0/
|
||||
* ├── gt0
|
||||
* │ ├── vf1
|
||||
* │ │ ├── guc_state
|
||||
*/
|
||||
static ssize_t guc_state_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct dentry *dent = file_dentry(file);
|
||||
struct dentry *parent = dent->d_parent;
|
||||
struct xe_gt *gt = extract_gt(parent);
|
||||
unsigned int vfid = extract_vfid(parent);
|
||||
|
||||
return xe_gt_sriov_pf_migration_read_guc_state(gt, vfid, buf, count, pos);
|
||||
}
|
||||
|
||||
static ssize_t guc_state_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct dentry *dent = file_dentry(file);
|
||||
struct dentry *parent = dent->d_parent;
|
||||
struct xe_gt *gt = extract_gt(parent);
|
||||
unsigned int vfid = extract_vfid(parent);
|
||||
|
||||
if (*pos)
|
||||
return -EINVAL;
|
||||
|
||||
return xe_gt_sriov_pf_migration_write_guc_state(gt, vfid, buf, count);
|
||||
}
|
||||
|
||||
static const struct file_operations guc_state_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = guc_state_read,
|
||||
.write = guc_state_write,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
/**
|
||||
* xe_gt_sriov_pf_debugfs_register - Register SR-IOV PF specific entries in GT debugfs.
|
||||
* @gt: the &xe_gt to register
|
||||
|
|
@ -423,5 +462,12 @@ void xe_gt_sriov_pf_debugfs_register(struct xe_gt *gt, struct dentry *root)
|
|||
|
||||
pf_add_config_attrs(gt, vfdentry, VFID(n));
|
||||
debugfs_create_file("control", 0600, vfdentry, NULL, &control_ops);
|
||||
|
||||
/* for testing/debugging purposes only! */
|
||||
if (IS_ENABLED(CONFIG_DRM_XE_DEBUG)) {
|
||||
debugfs_create_file("guc_state",
|
||||
IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV) ? 0600 : 0400,
|
||||
vfdentry, NULL, &guc_state_ops);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,6 +297,91 @@ int xe_gt_sriov_pf_migration_restore_guc_state(struct xe_gt *gt, unsigned int vf
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
/**
|
||||
* xe_gt_sriov_pf_migration_read_guc_state() - Read a GuC VF state.
|
||||
* @gt: the &xe_gt
|
||||
* @vfid: the VF identifier
|
||||
* @buf: the user space buffer to read to
|
||||
* @count: the maximum number of bytes to read
|
||||
* @pos: the current position in the buffer
|
||||
*
|
||||
* This function is for PF only.
|
||||
*
|
||||
* This function reads up to @count bytes from the saved VF GuC state buffer
|
||||
* at offset @pos into the user space address starting at @buf.
|
||||
*
|
||||
* Return: the number of bytes read or a negative error code on failure.
|
||||
*/
|
||||
ssize_t xe_gt_sriov_pf_migration_read_guc_state(struct xe_gt *gt, unsigned int vfid,
|
||||
char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
struct xe_gt_sriov_state_snapshot *snapshot;
|
||||
ssize_t ret;
|
||||
|
||||
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
|
||||
xe_gt_assert(gt, vfid != PFID);
|
||||
xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
|
||||
|
||||
if (!pf_migration_supported(gt))
|
||||
return -ENOPKG;
|
||||
|
||||
mutex_lock(pf_migration_mutex(gt));
|
||||
snapshot = pf_pick_vf_snapshot(gt, vfid);
|
||||
if (snapshot->guc.size)
|
||||
ret = simple_read_from_buffer(buf, count, pos, snapshot->guc.buff,
|
||||
snapshot->guc.size);
|
||||
else
|
||||
ret = -ENODATA;
|
||||
mutex_unlock(pf_migration_mutex(gt));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_gt_sriov_pf_migration_write_guc_state() - Write a GuC VF state.
|
||||
* @gt: the &xe_gt
|
||||
* @vfid: the VF identifier
|
||||
* @buf: the user space buffer with GuC VF state
|
||||
* @size: the size of GuC VF state (in bytes)
|
||||
*
|
||||
* This function is for PF only.
|
||||
*
|
||||
* This function reads @size bytes of the VF GuC state stored at user space
|
||||
* address @buf and writes it into a internal VF state buffer.
|
||||
*
|
||||
* Return: the number of bytes used or a negative error code on failure.
|
||||
*/
|
||||
ssize_t xe_gt_sriov_pf_migration_write_guc_state(struct xe_gt *gt, unsigned int vfid,
|
||||
const char __user *buf, size_t size)
|
||||
{
|
||||
struct xe_gt_sriov_state_snapshot *snapshot;
|
||||
loff_t pos = 0;
|
||||
ssize_t ret;
|
||||
|
||||
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
|
||||
xe_gt_assert(gt, vfid != PFID);
|
||||
xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
|
||||
|
||||
if (!pf_migration_supported(gt))
|
||||
return -ENOPKG;
|
||||
|
||||
mutex_lock(pf_migration_mutex(gt));
|
||||
snapshot = pf_pick_vf_snapshot(gt, vfid);
|
||||
ret = pf_alloc_guc_state(gt, snapshot, size);
|
||||
if (!ret) {
|
||||
ret = simple_write_to_buffer(snapshot->guc.buff, size, &pos, buf, size);
|
||||
if (ret < 0)
|
||||
pf_free_guc_state(gt, snapshot);
|
||||
else
|
||||
pf_dump_guc_state(gt, snapshot);
|
||||
}
|
||||
mutex_unlock(pf_migration_mutex(gt));
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
static bool pf_check_migration_support(struct xe_gt *gt)
|
||||
{
|
||||
/* GuC 70.25 with save/restore v2 is required */
|
||||
|
|
|
|||
|
|
@ -14,4 +14,11 @@ int xe_gt_sriov_pf_migration_init(struct xe_gt *gt);
|
|||
int xe_gt_sriov_pf_migration_save_guc_state(struct xe_gt *gt, unsigned int vfid);
|
||||
int xe_gt_sriov_pf_migration_restore_guc_state(struct xe_gt *gt, unsigned int vfid);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
ssize_t xe_gt_sriov_pf_migration_read_guc_state(struct xe_gt *gt, unsigned int vfid,
|
||||
char __user *buf, size_t count, loff_t *pos);
|
||||
ssize_t xe_gt_sriov_pf_migration_write_guc_state(struct xe_gt *gt, unsigned int vfid,
|
||||
const char __user *buf, size_t count);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user