Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09c1c68f authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller
Browse files

be2net: fix erx->rx_drops_no_frags wrap around



The rx_drops_no_frags HW counter for RSS rings is 16bits in HW and can
wraparound often. Maintain a 32-bit accumulator in the driver to prevent
frequent wraparound.

Also, incorporated Eric's feedback to use ACCESS_ONCE() for the accumulator
write.

Signed-off-by: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent db3ea781
Loading
Loading
Loading
Loading
+19 −3
Original line number Original line Diff line number Diff line
@@ -378,6 +378,18 @@ static void populate_lancer_stats(struct be_adapter *adapter)
				pport_stats->rx_drops_too_many_frags_lo;
				pport_stats->rx_drops_too_many_frags_lo;
}
}


static void accumulate_16bit_val(u32 *acc, u16 val)
{
#define lo(x)			(x & 0xFFFF)
#define hi(x)			(x & 0xFFFF0000)
	bool wrapped = val < lo(*acc);
	u32 newacc = hi(*acc) + val;

	if (wrapped)
		newacc += 65536;
	ACCESS_ONCE(*acc) = newacc;
}

void be_parse_stats(struct be_adapter *adapter)
void be_parse_stats(struct be_adapter *adapter)
{
{
	struct be_erx_stats_v1 *erx = be_erx_stats_from_cmd(adapter);
	struct be_erx_stats_v1 *erx = be_erx_stats_from_cmd(adapter);
@@ -394,9 +406,13 @@ void be_parse_stats(struct be_adapter *adapter)
	}
	}


	/* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */
	/* as erx_v1 is longer than v0, ok to use v1 defn for v0 access */
	for_all_rx_queues(adapter, rxo, i)
	for_all_rx_queues(adapter, rxo, i) {
		rx_stats(rxo)->rx_drops_no_frags =
		/* below erx HW counter can actually wrap around after
			erx->rx_drops_no_fragments[rxo->q.id];
		 * 65535. Driver accumulates a 32-bit value
		 */
		accumulate_16bit_val(&rx_stats(rxo)->rx_drops_no_frags,
				(u16)erx->rx_drops_no_fragments[rxo->q.id]);
	}
}
}


static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,
static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,