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

Commit c3164d2f authored by Tal Gilboa's avatar Tal Gilboa Committed by Saeed Mahameed
Browse files

net/mlx5e: Added BW check for DIM decision mechanism



DIM (Dynamically-tuned Interrupt Moderation) is a mechanism designed for
changing the channel interrupt moderation values in order to reduce CPU
overhead for all traffic types.
Until now only interrupt and packet rate were sampled.
We found a scenario on which we get a false indication since a change in
DIM caused more aggregation and reduced packet rate while increasing BW.

We now regard a change as succesfull iff:
current_BW > (prev_BW + threshold) or
current_BW ~= prev_BW and current_PR > (prev_PR + threshold) or
current_BW ~= prev_BW and current_PR ~= prev_PR and
    current_IR < (prev_IR - threshold)
Where BW = Bandwidth, PR = Packet rate and IR = Interrupt rate

Improvements (ConnectX-4Lx 25GbE, single RX queue, LRO off)
    --------------------------------------------------
    packet size | before[Mb/s] | after[Mb/s] | gain  |
    2B          | 343.4        | 359.4       |  4.5% |
    16B         | 2739.7       | 2814.8      |  2.7% |
    64B         | 9739         | 10185.3     |  4.5% |

Fixes: cb3c7fd4 ("net/mlx5e: Support adaptive RX coalescing")
Signed-off-by: default avatarTal Gilboa <talgi@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent f729860a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -458,12 +458,14 @@ struct mlx5e_mpw_info {

struct mlx5e_rx_am_stats {
	int ppms; /* packets per msec */
	int bpms; /* bytes per msec */
	int epms; /* events per msec */
};

struct mlx5e_rx_am_sample {
	ktime_t		time;
	unsigned int	pkt_ctr;
	unsigned int    byte_ctr;
	u16		event_ctr;
};

+20 −17
Original line number Diff line number Diff line
@@ -183,27 +183,26 @@ static void mlx5e_am_exit_parking(struct mlx5e_rx_am *am)
	mlx5e_am_step(am);
}

#define IS_SIGNIFICANT_DIFF(val, ref) \
	(((100 * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */

static int mlx5e_am_stats_compare(struct mlx5e_rx_am_stats *curr,
				  struct mlx5e_rx_am_stats *prev)
{
	int diff;

	if (!prev->ppms)
		return curr->ppms ? MLX5E_AM_STATS_BETTER :
	if (!prev->bpms)
		return curr->bpms ? MLX5E_AM_STATS_BETTER :
				    MLX5E_AM_STATS_SAME;

	diff = curr->ppms - prev->ppms;
	if (((100 * abs(diff)) / prev->ppms) > 10) /* more than 10% diff */
		return (diff > 0) ? MLX5E_AM_STATS_BETTER :
	if (IS_SIGNIFICANT_DIFF(curr->bpms, prev->bpms))
		return (curr->bpms > prev->bpms) ? MLX5E_AM_STATS_BETTER :
						   MLX5E_AM_STATS_WORSE;

	if (!prev->epms)
		return curr->epms ? MLX5E_AM_STATS_WORSE :
				    MLX5E_AM_STATS_SAME;
	if (IS_SIGNIFICANT_DIFF(curr->ppms, prev->ppms))
		return (curr->ppms > prev->ppms) ? MLX5E_AM_STATS_BETTER :
						   MLX5E_AM_STATS_WORSE;

	diff = curr->epms - prev->epms;
	if (((100 * abs(diff)) / prev->epms) > 10) /* more than 10% diff */
		return (diff < 0) ? MLX5E_AM_STATS_BETTER :
	if (IS_SIGNIFICANT_DIFF(curr->epms, prev->epms))
		return (curr->epms < prev->epms) ? MLX5E_AM_STATS_BETTER :
						   MLX5E_AM_STATS_WORSE;

	return MLX5E_AM_STATS_SAME;
@@ -266,6 +265,7 @@ static void mlx5e_am_sample(struct mlx5e_rq *rq,
{
	s->time	     = ktime_get();
	s->pkt_ctr   = rq->stats.packets;
	s->byte_ctr  = rq->stats.bytes;
	s->event_ctr = rq->cq.event_ctr;
}

@@ -278,12 +278,15 @@ static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,
	/* u32 holds up to 71 minutes, should be enough */
	u32 delta_us = ktime_us_delta(end->time, start->time);
	unsigned int npkts = end->pkt_ctr - start->pkt_ctr;
	unsigned int nbytes = end->byte_ctr - start->byte_ctr;

	if (!delta_us)
		return;

	curr_stats->ppms =            (npkts * USEC_PER_MSEC) / delta_us;
	curr_stats->epms = (MLX5E_AM_NEVENTS * USEC_PER_MSEC) / delta_us;
	curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
	curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
	curr_stats->epms = DIV_ROUND_UP(MLX5E_AM_NEVENTS * USEC_PER_MSEC,
					delta_us);
}

void mlx5e_rx_am_work(struct work_struct *work)