Commit 34c21fa8 authored by Alan Brady's avatar Alan Brady Committed by Tony Nguyen
Browse files

idpf: implement virtchnl transaction manager



This starts refactoring how virtchnl messages are handled by adding a
transaction manager (idpf_vc_xn_manager).

There are two primary motivations here which are to enable handling of
multiple messages at once and to make it more robust in general. As it
is right now, the driver may only have one pending message at a time and
there's no guarantee that the response we receive was actually intended
for the message we sent prior.

This works by utilizing a "cookie" field of the message descriptor. It
is arbitrary what data we put in the cookie and the response is required
to have the same cookie the original message was sent with. Then using a
"transaction" abstraction that uses the completion API to pair responses
to the message it belongs to.

The cookie works such that the first half is the index to the
transaction in our array, and the second half is a "salt" that gets
incremented every message. This enables quick lookups into the array and
also ensuring we have the correct message. The salt is necessary because
after, for example, a message times out and we deem the response was
lost for some reason, we could theoretically reuse the same index but
using a different salt ensures that when we do actually get a response
it's not the old message that timed out previously finally coming in.
Since the number of transactions allocated is U8_MAX and the salt is 8
bits, we can never have a conflict because we can't roll over the salt
without using more transactions than we have available.

This starts by only converting the VIRTCHNL2_OP_VERSION message to use
this new transaction API. Follow up patches will convert all virtchnl
messages to use the API.

Tested-by: default avatarAlexander Lobakin <aleksander.lobakin@intel.com>
Reviewed-by: default avatarPrzemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: default avatarIgor Bagnucki <igor.bagnucki@intel.com>
Co-developed-by: default avatarJoshua Hay <joshua.a.hay@intel.com>
Signed-off-by: default avatarJoshua Hay <joshua.a.hay@intel.com>
Signed-off-by: default avatarAlan Brady <alan.brady@intel.com>
Tested-by: default avatarKrishneil Singh <krishneil.k.singh@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 5dc283fa
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -66,14 +66,12 @@ struct idpf_mac_filter {

/**
 * enum idpf_state - State machine to handle bring up
 * @__IDPF_STARTUP: Start the state machine
 * @__IDPF_VER_CHECK: Negotiate virtchnl version
 * @__IDPF_GET_CAPS: Negotiate capabilities
 * @__IDPF_INIT_SW: Init based on given capabilities
 * @__IDPF_STATE_LAST: Must be last, used to determine size
 */
enum idpf_state {
	__IDPF_STARTUP,
	__IDPF_VER_CHECK,
	__IDPF_GET_CAPS,
	__IDPF_INIT_SW,
@@ -560,6 +558,8 @@ struct idpf_vport_config {
	DECLARE_BITMAP(flags, IDPF_VPORT_CONFIG_FLAGS_NBITS);
};

struct idpf_vc_xn_manager;

/**
 * struct idpf_adapter - Device data struct generated on probe
 * @pdev: PCI device struct given on probe
@@ -604,6 +604,7 @@ struct idpf_vport_config {
 * @vchnl_wq: Wait queue for virtchnl messages
 * @vc_state: Virtchnl message state
 * @vc_msg: Virtchnl message buffer
 * @vcxn_mngr: Virtchnl transaction manager
 * @dev_ops: See idpf_dev_ops
 * @num_vfs: Number of allocated VFs through sysfs. PF does not directly talk
 *	     to VFs but is used to initialize them
@@ -663,6 +664,7 @@ struct idpf_adapter {
	wait_queue_head_t vchnl_wq;
	DECLARE_BITMAP(vc_state, IDPF_VC_NBITS);
	char vc_msg[IDPF_CTLQ_MAX_BUF_LEN];
	struct idpf_vc_xn_manager *vcxn_mngr;
	struct idpf_dev_ops dev_ops;
	int num_vfs;
	bool crc_enable;
+5 −0
Original line number Diff line number Diff line
@@ -69,6 +69,11 @@ struct idpf_ctlq_msg {
			u8 context[IDPF_INDIRECT_CTX_SIZE];
			struct idpf_dma_mem *payload;
		} indirect;
		struct {
			u32 rsvd;
			u16 data;
			u16 flags;
		} sw_cookie;
	} ctx;
};

+2 −0
Original line number Diff line number Diff line
@@ -1824,6 +1824,8 @@ static int idpf_init_hard_reset(struct idpf_adapter *adapter)
		goto unlock_mutex;
	}

	queue_delayed_work(adapter->mbx_wq, &adapter->mbx_task, 0);

	/* Initialize the state machine, also allocate memory and request
	 * resources
	 */
+3 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ static void idpf_remove(struct pci_dev *pdev)
		idpf_sriov_configure(pdev, 0);

	idpf_vc_core_deinit(adapter);

	/* Be a good citizen and leave the device clean on exit */
	adapter->dev_ops.reg_ops.trigger_reset(adapter, IDPF_HR_FUNC_RESET);
	idpf_deinit_dflt_mbx(adapter);
@@ -67,6 +68,8 @@ static void idpf_remove(struct pci_dev *pdev)
	adapter->vport_config = NULL;
	kfree(adapter->netdevs);
	adapter->netdevs = NULL;
	kfree(adapter->vcxn_mngr);
	adapter->vcxn_mngr = NULL;

	mutex_destroy(&adapter->vport_ctrl_lock);
	mutex_destroy(&adapter->vector_lock);
+1 −1
Original line number Diff line number Diff line
@@ -138,7 +138,7 @@ static void idpf_vf_trigger_reset(struct idpf_adapter *adapter,
	/* Do not send VIRTCHNL2_OP_RESET_VF message on driver unload */
	if (trig_cause == IDPF_HR_FUNC_RESET &&
	    !test_bit(IDPF_REMOVE_IN_PROG, adapter->flags))
		idpf_send_mb_msg(adapter, VIRTCHNL2_OP_RESET_VF, 0, NULL);
		idpf_send_mb_msg(adapter, VIRTCHNL2_OP_RESET_VF, 0, NULL, 0);
}

/**
Loading