Commit eab866bf authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge tag 'linux-cpupower-6.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux

Pull cpupower utility fixes for 6.4-rc3 from Shuah Khan:

"This cpupower fixes update for Linux 67.4-rc3 consists of:

- a resource leak fix
- fix drift in C0 percentage calculation due to System-wide TSC read.
  To lower this drift read TSC per CPU and also just after mperf read.
  This technique improves C0 percentage calculation in Mperf monitor"

* tag 'linux-cpupower-6.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux:
  cpupower: Make TSC read per CPU for Mperf monitor
  cpupower:Fix resource leaks in sysfs_get_enabled()
parents f1fcbaa1 c2adb187
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -40,25 +40,34 @@ static int sysfs_get_enabled(char *path, int *mode)
{
	int fd;
	char yes_no;
	int ret = 0;

	*mode = 0;

	fd = open(path, O_RDONLY);
	if (fd == -1)
		return -1;
	if (fd == -1) {
		ret = -1;
		goto out;
	}

	if (read(fd, &yes_no, 1) != 1) {
		close(fd);
		return -1;
		ret = -1;
		goto out_close;
	}

	if (yes_no == '1') {
		*mode = 1;
		return 0;
		goto out_close;
	} else if (yes_no == '0') {
		return 0;
		goto out_close;
	} else {
		ret = -1;
		goto out_close;
	}
	return -1;
out_close:
	close(fd);
out:
	return ret;
}

int powercap_get_enabled(int *mode)
+14 −17
Original line number Diff line number Diff line
@@ -70,8 +70,8 @@ static int max_freq_mode;
 */
static unsigned long max_frequency;

static unsigned long long tsc_at_measure_start;
static unsigned long long tsc_at_measure_end;
static unsigned long long *tsc_at_measure_start;
static unsigned long long *tsc_at_measure_end;
static unsigned long long *mperf_previous_count;
static unsigned long long *aperf_previous_count;
static unsigned long long *mperf_current_count;
@@ -169,7 +169,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent,
	aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];

	if (max_freq_mode == MAX_FREQ_TSC_REF) {
		tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
		tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
		*percent = 100.0 * mperf_diff / tsc_diff;
		dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
		       mperf_cstates[id].name, mperf_diff, tsc_diff);
@@ -206,7 +206,7 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,

	if (max_freq_mode == MAX_FREQ_TSC_REF) {
		/* Calculate max_freq from TSC count */
		tsc_diff = tsc_at_measure_end - tsc_at_measure_start;
		tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
		time_diff = timespec_diff_us(time_start, time_end);
		max_frequency = tsc_diff / time_diff;
	}
@@ -225,33 +225,27 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
static int mperf_start(void)
{
	int cpu;
	unsigned long long dbg;

	clock_gettime(CLOCK_REALTIME, &time_start);
	mperf_get_tsc(&tsc_at_measure_start);

	for (cpu = 0; cpu < cpu_count; cpu++)
	for (cpu = 0; cpu < cpu_count; cpu++) {
		mperf_get_tsc(&tsc_at_measure_start[cpu]);
		mperf_init_stats(cpu);
	}

	mperf_get_tsc(&dbg);
	dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start);
	return 0;
}

static int mperf_stop(void)
{
	unsigned long long dbg;
	int cpu;

	for (cpu = 0; cpu < cpu_count; cpu++)
	for (cpu = 0; cpu < cpu_count; cpu++) {
		mperf_measure_stats(cpu);
		mperf_get_tsc(&tsc_at_measure_end[cpu]);
	}

	mperf_get_tsc(&tsc_at_measure_end);
	clock_gettime(CLOCK_REALTIME, &time_end);

	mperf_get_tsc(&dbg);
	dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end);

	return 0;
}

@@ -353,7 +347,8 @@ struct cpuidle_monitor *mperf_register(void)
	aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long));
	mperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
	aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));

	tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long));
	tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long));
	mperf_monitor.name_len = strlen(mperf_monitor.name);
	return &mperf_monitor;
}
@@ -364,6 +359,8 @@ void mperf_unregister(void)
	free(aperf_previous_count);
	free(mperf_current_count);
	free(aperf_current_count);
	free(tsc_at_measure_start);
	free(tsc_at_measure_end);
	free(is_valid);
}