drm/xe/pf: Improve VF control

Our initial VF control implementation was focused on providing
a very minimal support for the VF_STATE_NOTIFY events just to
meet GuC requirements, without tracking a VF state or doing any
expected actions (like cleanup in case of the FLR notification).

Try to improve this by defining set of VF state machines, each
responsible for processing one activity (PAUSE, RESUME, STOP or
FLR). All required steps defined by the VF state machine are then
executed by the PF worker from the dedicated workqueue.

Any external requests or notifications simply try to transition
between the states to trigger a work and then wait for that work
to finish. Some predefined default timeouts are used to avoid
changing existing API calls, but it should be easy to extend the
control API to also accept specific timeout values.

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Piotr Piórkowski <piotr.piorkowski@intel.com>
Reviewed-by: Piotr Piórkowski <piotr.piorkowski@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240828210809.1528-5-michal.wajdeczko@intel.com
This commit is contained in:
Michal Wajdeczko 2024-08-28 23:08:09 +02:00
parent d69300abc2
commit 2bd87f0fc2
5 changed files with 1305 additions and 15 deletions

View File

@ -9,6 +9,7 @@
#include "xe_gt_sriov_pf.h"
#include "xe_gt_sriov_pf_config.h"
#include "xe_gt_sriov_pf_control.h"
#include "xe_gt_sriov_pf_helpers.h"
#include "xe_gt_sriov_pf_service.h"
#include "xe_mmio.h"
@ -57,6 +58,10 @@ int xe_gt_sriov_pf_init_early(struct xe_gt *gt)
if (err)
return err;
err = xe_gt_sriov_pf_control_init(gt);
if (err)
return err;
return 0;
}
@ -93,4 +98,5 @@ void xe_gt_sriov_pf_init_hw(struct xe_gt *gt)
void xe_gt_sriov_pf_restart(struct xe_gt *gt)
{
xe_gt_sriov_pf_config_restart(gt);
xe_gt_sriov_pf_control_restart(gt);
}

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,9 @@
struct xe_gt;
int xe_gt_sriov_pf_control_init(struct xe_gt *gt);
void xe_gt_sriov_pf_control_restart(struct xe_gt *gt);
int xe_gt_sriov_pf_control_pause_vf(struct xe_gt *gt, unsigned int vfid);
int xe_gt_sriov_pf_control_resume_vf(struct xe_gt *gt, unsigned int vfid);
int xe_gt_sriov_pf_control_stop_vf(struct xe_gt *gt, unsigned int vfid);

View File

@ -0,0 +1,107 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2024 Intel Corporation
*/
#ifndef _XE_GT_SRIOV_PF_CONTROL_TYPES_H_
#define _XE_GT_SRIOV_PF_CONTROL_TYPES_H_
#include <linux/completion.h>
#include <linux/spinlock.h>
#include <linux/workqueue_types.h>
/**
* enum xe_gt_sriov_control_bits - Various bits used by the PF to represent a VF state
*
* @XE_GT_SRIOV_STATE_WIP: indicates that some operations are in progress.
* @XE_GT_SRIOV_STATE_FLR_WIP: indicates that a VF FLR is in progress.
* @XE_GT_SRIOV_STATE_FLR_SEND_START: indicates that the PF wants to send a FLR START command.
* @XE_GT_SRIOV_STATE_FLR_WAIT_GUC: indicates that the PF awaits for a response from the GuC.
* @XE_GT_SRIOV_STATE_FLR_GUC_DONE: indicates that the PF has received a response from the GuC.
* @XE_GT_SRIOV_STATE_FLR_RESET_CONFIG: indicates that the PF needs to clear VF's resources.
* @XE_GT_SRIOV_STATE_FLR_RESET_DATA: indicates that the PF needs to clear VF's data.
* @XE_GT_SRIOV_STATE_FLR_RESET_MMIO: indicates that the PF needs to reset VF's registers.
* @XE_GT_SRIOV_STATE_FLR_SEND_FINISH: indicates that the PF wants to send a FLR FINISH message.
* @XE_GT_SRIOV_STATE_FLR_FAILED: indicates that VF FLR sequence failed.
* @XE_GT_SRIOV_STATE_PAUSE_WIP: indicates that a VF pause operation is in progress.
* @XE_GT_SRIOV_STATE_PAUSE_SEND_PAUSE: indicates that the PF is about to send a PAUSE command.
* @XE_GT_SRIOV_STATE_PAUSE_WAIT_GUC: indicates that the PF awaits for a response from the GuC.
* @XE_GT_SRIOV_STATE_PAUSE_GUC_DONE: indicates that the PF has received a response from the GuC.
* @XE_GT_SRIOV_STATE_PAUSE_FAILED: indicates that a VF pause operation has failed.
* @XE_GT_SRIOV_STATE_PAUSED: indicates that the VF is paused.
* @XE_GT_SRIOV_STATE_RESUME_WIP: indicates the a VF resume operation is in progress.
* @XE_GT_SRIOV_STATE_RESUME_SEND_RESUME: indicates that the PF is about to send RESUME command.
* @XE_GT_SRIOV_STATE_RESUME_FAILED: indicates that a VF resume operation has failed.
* @XE_GT_SRIOV_STATE_RESUMED: indicates that the VF was resumed.
* @XE_GT_SRIOV_STATE_STOP_WIP: indicates that a VF stop operation is in progress.
* @XE_GT_SRIOV_STATE_STOP_SEND_STOP: indicates that the PF wants to send a STOP command.
* @XE_GT_SRIOV_STATE_STOP_FAILED: indicates that the VF stop operation has failed
* @XE_GT_SRIOV_STATE_STOPPED: indicates that the VF was stopped.
* @XE_GT_SRIOV_STATE_MISMATCH: indicates that the PF has detected a VF state mismatch.
*/
enum xe_gt_sriov_control_bits {
XE_GT_SRIOV_STATE_WIP = 1,
XE_GT_SRIOV_STATE_FLR_WIP,
XE_GT_SRIOV_STATE_FLR_SEND_START,
XE_GT_SRIOV_STATE_FLR_WAIT_GUC,
XE_GT_SRIOV_STATE_FLR_GUC_DONE,
XE_GT_SRIOV_STATE_FLR_RESET_CONFIG,
XE_GT_SRIOV_STATE_FLR_RESET_DATA,
XE_GT_SRIOV_STATE_FLR_RESET_MMIO,
XE_GT_SRIOV_STATE_FLR_SEND_FINISH,
XE_GT_SRIOV_STATE_FLR_FAILED,
XE_GT_SRIOV_STATE_PAUSE_WIP,
XE_GT_SRIOV_STATE_PAUSE_SEND_PAUSE,
XE_GT_SRIOV_STATE_PAUSE_WAIT_GUC,
XE_GT_SRIOV_STATE_PAUSE_GUC_DONE,
XE_GT_SRIOV_STATE_PAUSE_FAILED,
XE_GT_SRIOV_STATE_PAUSED,
XE_GT_SRIOV_STATE_RESUME_WIP,
XE_GT_SRIOV_STATE_RESUME_SEND_RESUME,
XE_GT_SRIOV_STATE_RESUME_FAILED,
XE_GT_SRIOV_STATE_RESUMED,
XE_GT_SRIOV_STATE_STOP_WIP,
XE_GT_SRIOV_STATE_STOP_SEND_STOP,
XE_GT_SRIOV_STATE_STOP_FAILED,
XE_GT_SRIOV_STATE_STOPPED,
XE_GT_SRIOV_STATE_MISMATCH = BITS_PER_LONG - 1,
};
/**
* struct xe_gt_sriov_control_state - GT-level per-VF control state.
*
* Used by the PF driver to maintain per-VF control data.
*/
struct xe_gt_sriov_control_state {
/** @state: VF state bits */
unsigned long state;
/** @done: completion of async operations */
struct completion done;
/** @link: link into worker list */
struct list_head link;
};
/**
* struct xe_gt_sriov_pf_control - GT-level control data.
*
* Used by the PF driver to maintain its data.
*/
struct xe_gt_sriov_pf_control {
/** @worker: worker that executes a VF operations */
struct work_struct worker;
/** @list: list of VF entries that have a pending work */
struct list_head list;
/** @lock: protects VF pending list */
spinlock_t lock;
};
#endif

View File

@ -9,6 +9,7 @@
#include <linux/types.h>
#include "xe_gt_sriov_pf_config_types.h"
#include "xe_gt_sriov_pf_control_types.h"
#include "xe_gt_sriov_pf_monitor_types.h"
#include "xe_gt_sriov_pf_policy_types.h"
#include "xe_gt_sriov_pf_service_types.h"
@ -23,6 +24,9 @@ struct xe_gt_sriov_metadata {
/** @monitor: per-VF monitoring data. */
struct xe_gt_sriov_monitor monitor;
/** @control: per-VF control data. */
struct xe_gt_sriov_control_state control;
/** @version: negotiated VF/PF ABI version */
struct xe_gt_sriov_pf_service_version version;
};
@ -30,12 +34,14 @@ struct xe_gt_sriov_metadata {
/**
* struct xe_gt_sriov_pf - GT level PF virtualization data.
* @service: service data.
* @control: control data.
* @policy: policy data.
* @spare: PF-only provisioning configuration.
* @vfs: metadata for all VFs.
*/
struct xe_gt_sriov_pf {
struct xe_gt_sriov_pf_service service;
struct xe_gt_sriov_pf_control control;
struct xe_gt_sriov_pf_policy policy;
struct xe_gt_sriov_spare_config spare;
struct xe_gt_sriov_metadata *vfs;