brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 88f7794 Raw
110 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB2/*3 * Copyright (c) 2019, Mellanox Technologies inc.  All rights reserved.4 */5 6#include <linux/dim.h>7 8static int rdma_dim_step(struct dim *dim)9{10	if (dim->tune_state == DIM_GOING_RIGHT) {11		if (dim->profile_ix == (RDMA_DIM_PARAMS_NUM_PROFILES - 1))12			return DIM_ON_EDGE;13		dim->profile_ix++;14		dim->steps_right++;15	}16	if (dim->tune_state == DIM_GOING_LEFT) {17		if (dim->profile_ix == 0)18			return DIM_ON_EDGE;19		dim->profile_ix--;20		dim->steps_left++;21	}22 23	return DIM_STEPPED;24}25 26static int rdma_dim_stats_compare(struct dim_stats *curr,27				  struct dim_stats *prev)28{29	/* first stat */30	if (!prev->cpms)31		return DIM_STATS_SAME;32 33	if (IS_SIGNIFICANT_DIFF(curr->cpms, prev->cpms))34		return (curr->cpms > prev->cpms) ? DIM_STATS_BETTER :35						DIM_STATS_WORSE;36 37	if (IS_SIGNIFICANT_DIFF(curr->cpe_ratio, prev->cpe_ratio))38		return (curr->cpe_ratio > prev->cpe_ratio) ? DIM_STATS_BETTER :39						DIM_STATS_WORSE;40 41	return DIM_STATS_SAME;42}43 44static bool rdma_dim_decision(struct dim_stats *curr_stats, struct dim *dim)45{46	int prev_ix = dim->profile_ix;47	u8 state = dim->tune_state;48	int stats_res;49	int step_res;50 51	if (state != DIM_PARKING_ON_TOP && state != DIM_PARKING_TIRED) {52		stats_res = rdma_dim_stats_compare(curr_stats,53						   &dim->prev_stats);54 55		switch (stats_res) {56		case DIM_STATS_SAME:57			if (curr_stats->cpe_ratio <= 50 * prev_ix)58				dim->profile_ix = 0;59			break;60		case DIM_STATS_WORSE:61			dim_turn(dim);62			fallthrough;63		case DIM_STATS_BETTER:64			step_res = rdma_dim_step(dim);65			if (step_res == DIM_ON_EDGE)66				dim_turn(dim);67			break;68		}69	}70 71	dim->prev_stats = *curr_stats;72 73	return dim->profile_ix != prev_ix;74}75 76void rdma_dim(struct dim *dim, u64 completions)77{78	struct dim_sample *curr_sample = &dim->measuring_sample;79	struct dim_stats curr_stats;80	u32 nevents;81 82	dim_update_sample_with_comps(curr_sample->event_ctr + 1, 0, 0,83				     curr_sample->comp_ctr + completions,84				     &dim->measuring_sample);85 86	switch (dim->state) {87	case DIM_MEASURE_IN_PROGRESS:88		nevents = curr_sample->event_ctr - dim->start_sample.event_ctr;89		if (nevents < DIM_NEVENTS)90			break;91		if (!dim_calc_stats(&dim->start_sample, curr_sample, &curr_stats))92			break;93		if (rdma_dim_decision(&curr_stats, dim)) {94			dim->state = DIM_APPLY_NEW_PROFILE;95			schedule_work(&dim->work);96			break;97		}98		fallthrough;99	case DIM_START_MEASURE:100		dim->state = DIM_MEASURE_IN_PROGRESS;101		dim_update_sample_with_comps(curr_sample->event_ctr, 0, 0,102					     curr_sample->comp_ctr,103					     &dim->start_sample);104		break;105	case DIM_APPLY_NEW_PROFILE:106		break;107	}108}109EXPORT_SYMBOL(rdma_dim);110