Commit a0c60b07 authored by Alexander Lobakin's avatar Alexander Lobakin Committed by Tony Nguyen
Browse files

idpf: add support for nointerrupt queues



Currently, queues are associated 1:1 with interrupt vectors as it's
assumed queues are always interrupt-driven. For XDP, we want to use
Tx queues without interrupts and only do "lazy" cleaning when the number
of free elements is <= threshold (closest pow-2 to 1/4 of the ring).
In order to use a queue without an interrupt, idpf still needs to have
a vector assigned to it to flush descriptors. This vector can be global
and only one for the whole vport to handle all its noirq queues.
Always request one excessive vector and configure it in non-interrupt
mode right away when creating vport, so that it can be used later by
queues when needed (not only XDP ones).

Co-developed-by: default avatarMichal Kubiak <michal.kubiak@intel.com>
Signed-off-by: default avatarMichal Kubiak <michal.kubiak@intel.com>
Signed-off-by: default avatarAlexander Lobakin <aleksander.lobakin@intel.com>
Tested-by: default avatarRamu R <ramu.r@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 9d394470
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -312,6 +312,9 @@ struct idpf_fsteer_fltr {
 * @num_q_vectors: Number of IRQ vectors allocated
 * @q_vectors: Array of queue vectors
 * @q_vector_idxs: Starting index of queue vectors
 * @noirq_dyn_ctl: register to enable/disable the vector for NOIRQ queues
 * @noirq_dyn_ctl_ena: value to write to the above to enable it
 * @noirq_v_idx: ID of the NOIRQ vector
 * @max_mtu: device given max possible MTU
 * @default_mac_addr: device will give a default MAC to use
 * @rx_itr_profile: RX profiles for Dynamic Interrupt Moderation
@@ -358,6 +361,11 @@ struct idpf_vport {
	u16 num_q_vectors;
	struct idpf_q_vector *q_vectors;
	u16 *q_vector_idxs;

	void __iomem *noirq_dyn_ctl;
	u32 noirq_dyn_ctl_ena;
	u16 noirq_v_idx;

	u16 max_mtu;
	u8 default_mac_addr[ETH_ALEN];
	u16 rx_itr_profile[IDPF_DIM_PROFILE_SLOTS];
+10 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ static int idpf_intr_reg_init(struct idpf_vport *vport)
	int num_vecs = vport->num_q_vectors;
	struct idpf_vec_regs *reg_vals;
	int num_regs, i, err = 0;
	u32 rx_itr, tx_itr;
	u32 rx_itr, tx_itr, val;
	u16 total_vecs;

	total_vecs = idpf_get_reserved_vecs(vport->adapter);
@@ -121,6 +121,15 @@ static int idpf_intr_reg_init(struct idpf_vport *vport)
		intr->tx_itr = idpf_get_reg_addr(adapter, tx_itr);
	}

	/* Data vector for NOIRQ queues */

	val = reg_vals[vport->q_vector_idxs[i] - IDPF_MBX_Q_VEC].dyn_ctl_reg;
	vport->noirq_dyn_ctl = idpf_get_reg_addr(adapter, val);

	val = PF_GLINT_DYN_CTL_WB_ON_ITR_M | PF_GLINT_DYN_CTL_INTENA_MSK_M |
	      FIELD_PREP(PF_GLINT_DYN_CTL_ITR_INDX_M, IDPF_NO_ITR_UPDATE_IDX);
	vport->noirq_dyn_ctl_ena = val;

free_reg_vals:
	kfree(reg_vals);

+1 −1
Original line number Diff line number Diff line
@@ -1142,7 +1142,7 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter,
	if (!vport)
		return vport;

	num_max_q = max(max_q->max_txq, max_q->max_rxq);
	num_max_q = max(max_q->max_txq, max_q->max_rxq) + IDPF_RESERVED_VECS;
	if (!adapter->vport_config[idx]) {
		struct idpf_vport_config *vport_config;
		struct idpf_q_coalesce *q_coal;
+8 −0
Original line number Diff line number Diff line
@@ -3507,6 +3507,8 @@ static void idpf_vport_intr_dis_irq_all(struct idpf_vport *vport)
	struct idpf_q_vector *q_vector = vport->q_vectors;
	int q_idx;

	writel(0, vport->noirq_dyn_ctl);

	for (q_idx = 0; q_idx < vport->num_q_vectors; q_idx++)
		writel(0, q_vector[q_idx].intr_reg.dyn_ctl);
}
@@ -3750,6 +3752,8 @@ static void idpf_vport_intr_ena_irq_all(struct idpf_vport *vport)
		if (qv->num_txq || qv->num_rxq)
			idpf_vport_intr_update_itr_ena_irq(qv);
	}

	writel(vport->noirq_dyn_ctl_ena, vport->noirq_dyn_ctl);
}

/**
@@ -4061,6 +4065,8 @@ static int idpf_vport_intr_init_vec_idx(struct idpf_vport *vport)
		for (i = 0; i < vport->num_q_vectors; i++)
			vport->q_vectors[i].v_idx = vport->q_vector_idxs[i];

		vport->noirq_v_idx = vport->q_vector_idxs[i];

		return 0;
	}

@@ -4074,6 +4080,8 @@ static int idpf_vport_intr_init_vec_idx(struct idpf_vport *vport)
	for (i = 0; i < vport->num_q_vectors; i++)
		vport->q_vectors[i].v_idx = vecids[vport->q_vector_idxs[i]];

	vport->noirq_v_idx = vecids[vport->q_vector_idxs[i]];

	kfree(vecids);

	return 0;
+4 −0
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@
#define IDPF_MBX_Q_VEC		1
#define IDPF_MIN_Q_VEC		1
#define IDPF_MIN_RDMA_VEC	2
/* Data vector for NOIRQ queues */
#define IDPF_RESERVED_VECS			1

#define IDPF_DFLT_TX_Q_DESC_COUNT		512
#define IDPF_DFLT_TX_COMPLQ_DESC_COUNT		512
@@ -279,6 +281,7 @@ struct idpf_ptype_state {
 * @__IDPF_Q_HSPLIT_EN: enable header split on Rx (splitq)
 * @__IDPF_Q_PTP: indicates whether the Rx timestamping is enabled for the
 *		  queue
 * @__IDPF_Q_NOIRQ: queue is polling-driven and has no interrupt
 * @__IDPF_Q_FLAGS_NBITS: Must be last
 */
enum idpf_queue_flags_t {
@@ -289,6 +292,7 @@ enum idpf_queue_flags_t {
	__IDPF_Q_CRC_EN,
	__IDPF_Q_HSPLIT_EN,
	__IDPF_Q_PTP,
	__IDPF_Q_NOIRQ,

	__IDPF_Q_FLAGS_NBITS,
};
Loading