lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 17 Jul 2012 03:09:17 -0700
From:	Jeff Kirsher <jeffrey.t.kirsher@...el.com>
To:	davem@...emloft.net
Cc:	Alexander Duyck <alexander.h.duyck@...el.com>,
	netdev@...r.kernel.org, gospo@...hat.com, sassmann@...hat.com,
	Greg Rose <gregory.v.rose@...el.com>,
	Jeff Kirsher <jeffrey.t.kirsher@...el.com>
Subject: [net-next 6/8] ixgbevf: Update q_vector to contain ring pointers instead of bitmaps

From: Alexander Duyck <alexander.h.duyck@...el.com>

For most cases the ixgbevf driver will only ever contain a single Tx and
single Rx queue.  In order to track that it makes more sense to use a
pointer instead of using a bitmap which must be search in order to locate
the ring on an adapter index.  As such I am changing the code to use
pointers and an iterator to access all rings on a given q_vector.

Signed-off-by: Alexander Duyck <alexander.h.duyck@...el.com>
Signed-off-by: Greg Rose <gregory.v.rose@...el.com>
Tested-by: Sibai Li <sibai.li@...el.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@...el.com>
---
 drivers/net/ethernet/intel/ixgbevf/ixgbevf.h      |   18 ++-
 drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c |  152 +++++++--------------
 2 files changed, 65 insertions(+), 105 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index c62caba..8cae4ff 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -55,6 +55,7 @@ struct ixgbevf_rx_buffer {
 };
 
 struct ixgbevf_ring {
+	struct ixgbevf_ring *next;
 	struct ixgbevf_adapter *adapter;  /* backlink */
 	void *desc;			/* descriptor ring memory */
 	dma_addr_t dma;			/* phys. address of descriptor ring */
@@ -120,18 +121,23 @@ struct ixgbevf_ring {
 #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK	0x0000e000
 #define IXGBE_TX_FLAGS_VLAN_SHIFT	16
 
+struct ixgbevf_ring_container {
+	struct ixgbevf_ring *ring;	/* pointer to linked list of rings */
+	u8 count;			/* total number of rings in vector */
+	u8 itr;				/* current ITR setting for ring */
+};
+
+/* iterator for handling rings in ring container */
+#define ixgbevf_for_each_ring(pos, head) \
+	for (pos = (head).ring; pos != NULL; pos = pos->next)
+
 /* MAX_MSIX_Q_VECTORS of these are allocated,
  * but we only use one per queue-specific vector.
  */
 struct ixgbevf_q_vector {
 	struct ixgbevf_adapter *adapter;
 	struct napi_struct napi;
-	DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */
-	DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */
-	u8 rxr_count;     /* Rx ring count assigned to this vector */
-	u8 txr_count;     /* Tx ring count assigned to this vector */
-	u8 tx_itr;
-	u8 rx_itr;
+	struct ixgbevf_ring_container rx, tx;
 	u32 eitr;
 	int v_idx;	  /* vector index in list */
 };
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 855bb21..744a026 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -526,14 +526,9 @@ static int ixgbevf_clean_rxonly(struct napi_struct *napi, int budget)
 	struct ixgbevf_q_vector *q_vector =
 		container_of(napi, struct ixgbevf_q_vector, napi);
 	struct ixgbevf_adapter *adapter = q_vector->adapter;
-	struct ixgbevf_ring *rx_ring = NULL;
 	int work_done = 0;
-	long r_idx;
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	rx_ring = &(adapter->rx_ring[r_idx]);
-
-	ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
+	ixgbevf_clean_rx_irq(q_vector, q_vector->rx.ring, &work_done, budget);
 
 	/* If all Rx work done, exit the polling mode */
 	if (work_done < budget) {
@@ -541,7 +536,8 @@ static int ixgbevf_clean_rxonly(struct napi_struct *napi, int budget)
 		if (adapter->itr_setting & 1)
 			ixgbevf_set_itr_msix(q_vector);
 		if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
-			ixgbevf_irq_enable_queues(adapter, rx_ring->v_idx);
+			ixgbevf_irq_enable_queues(adapter,
+						  1 << q_vector->v_idx);
 	}
 
 	return work_done;
@@ -560,26 +556,16 @@ static int ixgbevf_clean_rxonly_many(struct napi_struct *napi, int budget)
 	struct ixgbevf_q_vector *q_vector =
 		container_of(napi, struct ixgbevf_q_vector, napi);
 	struct ixgbevf_adapter *adapter = q_vector->adapter;
-	struct ixgbevf_ring *rx_ring = NULL;
-	int work_done = 0, i;
-	long r_idx;
-	u64 enable_mask = 0;
+	struct ixgbevf_ring *rx_ring;
+	int work_done = 0;
 
 	/* attempt to distribute budget to each queue fairly, but don't allow
 	 * the budget to go below 1 because we'll exit polling */
-	budget /= (q_vector->rxr_count ?: 1);
+	budget /= (q_vector->rx.count ?: 1);
 	budget = max(budget, 1);
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	for (i = 0; i < q_vector->rxr_count; i++) {
-		rx_ring = &(adapter->rx_ring[r_idx]);
-		ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
-		enable_mask |= rx_ring->v_idx;
-		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
-				      r_idx + 1);
-	}
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	rx_ring = &(adapter->rx_ring[r_idx]);
+	ixgbevf_for_each_ring(rx_ring, q_vector->rx)
+		ixgbevf_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
 
 	/* If all Rx work done, exit the polling mode */
 	if (work_done < budget) {
@@ -587,7 +573,8 @@ static int ixgbevf_clean_rxonly_many(struct napi_struct *napi, int budget)
 		if (adapter->itr_setting & 1)
 			ixgbevf_set_itr_msix(q_vector);
 		if (!test_bit(__IXGBEVF_DOWN, &adapter->state))
-			ixgbevf_irq_enable_queues(adapter, enable_mask);
+			ixgbevf_irq_enable_queues(adapter,
+						  1 << q_vector->v_idx);
 	}
 
 	return work_done;
@@ -605,7 +592,7 @@ static void ixgbevf_configure_msix(struct ixgbevf_adapter *adapter)
 {
 	struct ixgbevf_q_vector *q_vector;
 	struct ixgbe_hw *hw = &adapter->hw;
-	int i, j, q_vectors, v_idx, r_idx;
+	int q_vectors, v_idx;
 	u32 mask;
 
 	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
@@ -615,33 +602,19 @@ static void ixgbevf_configure_msix(struct ixgbevf_adapter *adapter)
 	 * corresponding register.
 	 */
 	for (v_idx = 0; v_idx < q_vectors; v_idx++) {
+		struct ixgbevf_ring *ring;
 		q_vector = adapter->q_vector[v_idx];
-		/* XXX for_each_set_bit(...) */
-		r_idx = find_first_bit(q_vector->rxr_idx,
-				       adapter->num_rx_queues);
-
-		for (i = 0; i < q_vector->rxr_count; i++) {
-			j = adapter->rx_ring[r_idx].reg_idx;
-			ixgbevf_set_ivar(adapter, 0, j, v_idx);
-			r_idx = find_next_bit(q_vector->rxr_idx,
-					      adapter->num_rx_queues,
-					      r_idx + 1);
-		}
-		r_idx = find_first_bit(q_vector->txr_idx,
-				       adapter->num_tx_queues);
-
-		for (i = 0; i < q_vector->txr_count; i++) {
-			j = adapter->tx_ring[r_idx].reg_idx;
-			ixgbevf_set_ivar(adapter, 1, j, v_idx);
-			r_idx = find_next_bit(q_vector->txr_idx,
-					      adapter->num_tx_queues,
-					      r_idx + 1);
-		}
+
+		ixgbevf_for_each_ring(ring, q_vector->rx)
+			ixgbevf_set_ivar(adapter, 0, ring->reg_idx, v_idx);
+
+		ixgbevf_for_each_ring(ring, q_vector->tx)
+			ixgbevf_set_ivar(adapter, 1, ring->reg_idx, v_idx);
 
 		/* if this is a tx only vector halve the interrupt rate */
-		if (q_vector->txr_count && !q_vector->rxr_count)
+		if (q_vector->tx.ring && !q_vector->rx.ring)
 			q_vector->eitr = (adapter->eitr_param >> 1);
-		else if (q_vector->rxr_count)
+		else if (q_vector->rx.ring)
 			/* rx only */
 			q_vector->eitr = adapter->eitr_param;
 
@@ -752,40 +725,32 @@ static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector)
 	struct ixgbevf_adapter *adapter = q_vector->adapter;
 	u32 new_itr;
 	u8 current_itr, ret_itr;
-	int i, r_idx, v_idx = q_vector->v_idx;
+	int v_idx = q_vector->v_idx;
 	struct ixgbevf_ring *rx_ring, *tx_ring;
 
-	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
-	for (i = 0; i < q_vector->txr_count; i++) {
-		tx_ring = &(adapter->tx_ring[r_idx]);
+	ixgbevf_for_each_ring(tx_ring, q_vector->tx) {
 		ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr,
-					     q_vector->tx_itr,
+					     q_vector->tx.itr,
 					     tx_ring->total_packets,
 					     tx_ring->total_bytes);
 		/* if the result for this queue would decrease interrupt
 		 * rate for this vector then use that result */
-		q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ?
-				    q_vector->tx_itr - 1 : ret_itr);
-		r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
-				      r_idx + 1);
+		q_vector->tx.itr = ((q_vector->tx.itr > ret_itr) ?
+				    q_vector->tx.itr - 1 : ret_itr);
 	}
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	for (i = 0; i < q_vector->rxr_count; i++) {
-		rx_ring = &(adapter->rx_ring[r_idx]);
+	ixgbevf_for_each_ring(rx_ring, q_vector->rx) {
 		ret_itr = ixgbevf_update_itr(adapter, q_vector->eitr,
-					     q_vector->rx_itr,
+					     q_vector->rx.itr,
 					     rx_ring->total_packets,
 					     rx_ring->total_bytes);
 		/* if the result for this queue would decrease interrupt
 		 * rate for this vector then use that result */
-		q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ?
-				    q_vector->rx_itr - 1 : ret_itr);
-		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
-				      r_idx + 1);
+		q_vector->rx.itr = ((q_vector->rx.itr > ret_itr) ?
+				    q_vector->rx.itr - 1 : ret_itr);
 	}
 
-	current_itr = max(q_vector->rx_itr, q_vector->tx_itr);
+	current_itr = max(q_vector->rx.itr, q_vector->tx.itr);
 
 	switch (current_itr) {
 	/* counts and packets in update_itr are dependent on these numbers */
@@ -861,19 +826,14 @@ static irqreturn_t ixgbevf_msix_clean_tx(int irq, void *data)
 	struct ixgbevf_q_vector *q_vector = data;
 	struct ixgbevf_adapter  *adapter = q_vector->adapter;
 	struct ixgbevf_ring     *tx_ring;
-	int i, r_idx;
 
-	if (!q_vector->txr_count)
+	if (!q_vector->tx.ring)
 		return IRQ_HANDLED;
 
-	r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
-	for (i = 0; i < q_vector->txr_count; i++) {
-		tx_ring = &(adapter->tx_ring[r_idx]);
+	ixgbevf_for_each_ring(tx_ring, q_vector->tx) {
 		tx_ring->total_bytes = 0;
 		tx_ring->total_packets = 0;
 		ixgbevf_clean_tx_irq(adapter, tx_ring);
-		r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
-				      r_idx + 1);
 	}
 
 	if (adapter->itr_setting & 1)
@@ -893,25 +853,17 @@ static irqreturn_t ixgbevf_msix_clean_rx(int irq, void *data)
 	struct ixgbevf_adapter  *adapter = q_vector->adapter;
 	struct ixgbe_hw *hw = &adapter->hw;
 	struct ixgbevf_ring  *rx_ring;
-	int r_idx;
-	int i;
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	for (i = 0; i < q_vector->rxr_count; i++) {
-		rx_ring = &(adapter->rx_ring[r_idx]);
+	ixgbevf_for_each_ring(rx_ring, q_vector->rx) {
 		rx_ring->total_bytes = 0;
 		rx_ring->total_packets = 0;
-		r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
-				      r_idx + 1);
 	}
 
-	if (!q_vector->rxr_count)
+	if (!q_vector->rx.ring)
 		return IRQ_HANDLED;
 
-	r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-	rx_ring = &(adapter->rx_ring[r_idx]);
 	/* disable interrupts on this vector only */
-	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, rx_ring->v_idx);
+	IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, 1 << q_vector->v_idx);
 	napi_schedule(&q_vector->napi);
 
 
@@ -931,8 +883,9 @@ static inline void map_vector_to_rxq(struct ixgbevf_adapter *a, int v_idx,
 {
 	struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx];
 
-	set_bit(r_idx, q_vector->rxr_idx);
-	q_vector->rxr_count++;
+	a->rx_ring[r_idx].next = q_vector->rx.ring;
+	q_vector->rx.ring = &a->rx_ring[r_idx];
+	q_vector->rx.count++;
 	a->rx_ring[r_idx].v_idx = 1 << v_idx;
 }
 
@@ -941,8 +894,9 @@ static inline void map_vector_to_txq(struct ixgbevf_adapter *a, int v_idx,
 {
 	struct ixgbevf_q_vector *q_vector = a->q_vector[v_idx];
 
-	set_bit(t_idx, q_vector->txr_idx);
-	q_vector->txr_count++;
+	a->tx_ring[t_idx].next = q_vector->tx.ring;
+	q_vector->tx.ring = &a->tx_ring[t_idx];
+	q_vector->tx.count++;
 	a->tx_ring[t_idx].v_idx = 1 << v_idx;
 }
 
@@ -1026,10 +980,10 @@ static int ixgbevf_request_msix_irqs(struct ixgbevf_adapter *adapter)
 	/* Decrement for Other and TCP Timer vectors */
 	q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
 
-#define SET_HANDLER(_v) (((_v)->rxr_count && (_v)->txr_count)          \
-					  ? &ixgbevf_msix_clean_many : \
-			  (_v)->rxr_count ? &ixgbevf_msix_clean_rx   : \
-			  (_v)->txr_count ? &ixgbevf_msix_clean_tx   : \
+#define SET_HANDLER(_v) (((_v)->rx.ring && (_v)->tx.ring)          \
+					? &ixgbevf_msix_clean_many : \
+			  (_v)->rx.ring ? &ixgbevf_msix_clean_rx   : \
+			  (_v)->tx.ring ? &ixgbevf_msix_clean_tx   : \
 			  NULL)
 	for (vector = 0; vector < q_vectors; vector++) {
 		handler = SET_HANDLER(adapter->q_vector[vector]);
@@ -1085,10 +1039,10 @@ static inline void ixgbevf_reset_q_vectors(struct ixgbevf_adapter *adapter)
 
 	for (i = 0; i < q_vectors; i++) {
 		struct ixgbevf_q_vector *q_vector = adapter->q_vector[i];
-		bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES);
-		bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES);
-		q_vector->rxr_count = 0;
-		q_vector->txr_count = 0;
+		q_vector->rx.ring = NULL;
+		q_vector->tx.ring = NULL;
+		q_vector->rx.count = 0;
+		q_vector->tx.count = 0;
 		q_vector->eitr = adapter->eitr_param;
 	}
 }
@@ -1365,10 +1319,10 @@ static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
 	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
 		struct napi_struct *napi;
 		q_vector = adapter->q_vector[q_idx];
-		if (!q_vector->rxr_count)
+		if (!q_vector->rx.ring)
 			continue;
 		napi = &q_vector->napi;
-		if (q_vector->rxr_count > 1)
+		if (q_vector->rx.count > 1)
 			napi->poll = &ixgbevf_clean_rxonly_many;
 
 		napi_enable(napi);
@@ -1383,7 +1337,7 @@ static void ixgbevf_napi_disable_all(struct ixgbevf_adapter *adapter)
 
 	for (q_idx = 0; q_idx < q_vectors; q_idx++) {
 		q_vector = adapter->q_vector[q_idx];
-		if (!q_vector->rxr_count)
+		if (!q_vector->rx.ring)
 			continue;
 		napi_disable(&q_vector->napi);
 	}
@@ -2144,7 +2098,7 @@ static void ixgbevf_watchdog(unsigned long data)
 	/* get one bit for every active tx/rx interrupt vector */
 	for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
 		struct ixgbevf_q_vector *qv = adapter->q_vector[i];
-		if (qv->rxr_count || qv->txr_count)
+		if (qv->rx.ring || qv->tx.ring)
 			eics |= (1 << i);
 	}
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ