Commit 1a4d8945 authored by Mun Chun Yep's avatar Mun Chun Yep Committed by Aichun Shi
Browse files

crypto: qat - update PFVF protocol for recovery

mainline inclusion
from mainline-v6.9-rc1
commit ec26f8e6c784ae391e69b19f4738d7196ed7794d
category: feature
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/I9A5BW
CVE: N/A
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ec26f8e6c784ae391e69b19f4738d7196ed7794d



-------------------------------------

Update the PFVF logic to handle restart and recovery. This adds the
following functions:

  * adf_pf2vf_notify_fatal_error(): allows the PF to notify VFs that the
    device detected a fatal error and requires a reset. This sends to
    VF the event `ADF_PF2VF_MSGTYPE_FATAL_ERROR`.
  * adf_pf2vf_wait_for_restarting_complete(): allows the PF to wait for
    `ADF_VF2PF_MSGTYPE_RESTARTING_COMPLETE` events from active VFs
    before proceeding with a reset.
  * adf_pf2vf_notify_restarted(): enables the PF to notify VFs with
    an `ADF_PF2VF_MSGTYPE_RESTARTED` event after recovery, indicating that
    the device is back to normal. This prompts VF drivers switch back to
    use the accelerator for workload processing.

These changes improve the communication and synchronization between PF
and VF drivers during system restart and recovery processes.

Intel-SIG: commit ec26f8e6c784 crypto: qat - update PFVF protocol for recovery
Backport to support QAT in-tree driver

Signed-off-by: default avatarMun Chun Yep <mun.chun.yep@intel.com>
Reviewed-by: default avatarAhsan Atta <ahsan.atta@intel.com>
Reviewed-by: default avatarMarkas Rapoportas <markas.rapoportas@intel.com>
Reviewed-by: default avatarGiovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
[ Aichun Shi: amend commit log ]
Signed-off-by: default avatarAichun Shi <aichun.shi@intel.com>
parent 6e0838b0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -332,6 +332,7 @@ struct adf_accel_vf_info {
	struct ratelimit_state vf2pf_ratelimit;
	u32 vf_nr;
	bool init;
	bool restarting;
	u8 vf_compat_ver;
};

+3 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <linux/delay.h>
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
#include "adf_pfvf_pf_msg.h"

struct adf_fatal_error_data {
	struct adf_accel_dev *accel_dev;
@@ -189,6 +190,8 @@ static void adf_notify_fatal_error_worker(struct work_struct *work)
		/* Disable arbitration to stop processing of new requests */
		if (hw_device->exit_arb)
			hw_device->exit_arb(accel_dev);
		if (accel_dev->pf.vf_info)
			adf_pf2vf_notify_fatal_error(accel_dev);
	}

	kfree(wq_data);
+6 −1
Original line number Diff line number Diff line
@@ -99,6 +99,8 @@ enum pf2vf_msgtype {
	ADF_PF2VF_MSGTYPE_RESTARTING		= 0x01,
	ADF_PF2VF_MSGTYPE_VERSION_RESP		= 0x02,
	ADF_PF2VF_MSGTYPE_BLKMSG_RESP		= 0x03,
	ADF_PF2VF_MSGTYPE_FATAL_ERROR		= 0x04,
	ADF_PF2VF_MSGTYPE_RESTARTED		= 0x05,
/* Values from 0x10 are Gen4 specific, message type is only 4 bits in Gen2 devices. */
	ADF_PF2VF_MSGTYPE_RP_RESET_RESP		= 0x10,
};
@@ -112,6 +114,7 @@ enum vf2pf_msgtype {
	ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ	= 0x07,
	ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ	= 0x08,
	ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ	= 0x09,
	ADF_VF2PF_MSGTYPE_RESTARTING_COMPLETE	= 0x0a,
/* Values from 0x10 are Gen4 specific, message type is only 4 bits in Gen2 devices. */
	ADF_VF2PF_MSGTYPE_RP_RESET		= 0x10,
};
@@ -124,8 +127,10 @@ enum pfvf_compatibility_version {
	ADF_PFVF_COMPAT_FAST_ACK		= 0x03,
	/* Ring to service mapping support for non-standard mappings */
	ADF_PFVF_COMPAT_RING_TO_SVC_MAP		= 0x04,
	/* Fallback compat */
	ADF_PFVF_COMPAT_FALLBACK		= 0x05,
	/* Reference to the latest version */
	ADF_PFVF_COMPAT_THIS_VERSION		= 0x04,
	ADF_PFVF_COMPAT_THIS_VERSION		= 0x05,
};

/* PF->VF Version Response */
+63 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2015 - 2021 Intel Corporation */
#include <linux/delay.h>
#include <linux/pci.h>
#include "adf_accel_devices.h"
#include "adf_pfvf_msg.h"
#include "adf_pfvf_pf_msg.h"
#include "adf_pfvf_pf_proto.h"

#define ADF_PF_WAIT_RESTARTING_COMPLETE_DELAY	100
#define ADF_VF_SHUTDOWN_RETRY			100

void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev)
{
	struct adf_accel_vf_info *vf;
	struct pfvf_message msg = { .type = ADF_PF2VF_MSGTYPE_RESTARTING };
	int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));

	dev_dbg(&GET_DEV(accel_dev), "pf2vf notify restarting\n");
	for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) {
		if (vf->init && adf_send_pf2vf_msg(accel_dev, i, msg))
		vf->restarting = false;
		if (!vf->init)
			continue;
		if (adf_send_pf2vf_msg(accel_dev, i, msg))
			dev_err(&GET_DEV(accel_dev),
				"Failed to send restarting msg to VF%d\n", i);
		else if (vf->vf_compat_ver >= ADF_PFVF_COMPAT_FALLBACK)
			vf->restarting = true;
	}
}

void adf_pf2vf_wait_for_restarting_complete(struct adf_accel_dev *accel_dev)
{
	int num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));
	int i, retries = ADF_VF_SHUTDOWN_RETRY;
	struct adf_accel_vf_info *vf;
	bool vf_running;

	dev_dbg(&GET_DEV(accel_dev), "pf2vf wait for restarting complete\n");
	do {
		vf_running = false;
		for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++)
			if (vf->restarting)
				vf_running = true;
		if (!vf_running)
			break;
		msleep(ADF_PF_WAIT_RESTARTING_COMPLETE_DELAY);
	} while (--retries);

	if (vf_running)
		dev_warn(&GET_DEV(accel_dev), "Some VFs are still running\n");
}

void adf_pf2vf_notify_restarted(struct adf_accel_dev *accel_dev)
{
	struct pfvf_message msg = { .type = ADF_PF2VF_MSGTYPE_RESTARTED };
	int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));
	struct adf_accel_vf_info *vf;

	dev_dbg(&GET_DEV(accel_dev), "pf2vf notify restarted\n");
	for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) {
		if (vf->init && vf->vf_compat_ver >= ADF_PFVF_COMPAT_FALLBACK &&
		    adf_send_pf2vf_msg(accel_dev, i, msg))
			dev_err(&GET_DEV(accel_dev),
				"Failed to send restarted msg to VF%d\n", i);
	}
}

void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev)
{
	struct pfvf_message msg = { .type = ADF_PF2VF_MSGTYPE_FATAL_ERROR };
	int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));
	struct adf_accel_vf_info *vf;

	dev_dbg(&GET_DEV(accel_dev), "pf2vf notify fatal error\n");
	for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) {
		if (vf->init && vf->vf_compat_ver >= ADF_PFVF_COMPAT_FALLBACK &&
		    adf_send_pf2vf_msg(accel_dev, i, msg))
			dev_err(&GET_DEV(accel_dev),
				"Failed to send fatal error msg to VF%d\n", i);
	}
}

+21 −0
Original line number Diff line number Diff line
@@ -5,7 +5,28 @@

#include "adf_accel_devices.h"

#if defined(CONFIG_PCI_IOV)
void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev);
void adf_pf2vf_wait_for_restarting_complete(struct adf_accel_dev *accel_dev);
void adf_pf2vf_notify_restarted(struct adf_accel_dev *accel_dev);
void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev);
#else
static inline void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev)
{
}

static inline void adf_pf2vf_wait_for_restarting_complete(struct adf_accel_dev *accel_dev)
{
}

static inline void adf_pf2vf_notify_restarted(struct adf_accel_dev *accel_dev)
{
}

static inline void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev)
{
}
#endif

typedef int (*adf_pf2vf_blkmsg_provider)(struct adf_accel_dev *accel_dev,
					 u8 *buffer, u8 compat);
Loading