Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <asm/barrier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "synthetic-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "tsc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	u64 t, quot, rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	t = ns - tc->time_zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	quot = t / tc->time_mult;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	rem  = t % tc->time_mult;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	return (quot << tc->time_shift) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	       (rem << tc->time_shift) / tc->time_mult;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	u64 quot, rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	if (tc->cap_user_time_short)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		cyc = tc->time_cycles +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 			((cyc - tc->time_cycles) & tc->time_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	quot = cyc >> tc->time_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	rem  = cyc & (((u64)1 << tc->time_shift) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	return tc->time_zero + quot * tc->time_mult +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	       ((rem * tc->time_mult) >> tc->time_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 			     struct perf_tsc_conversion *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	u32 seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		seq = pc->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		tc->time_mult = pc->time_mult;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		tc->time_shift = pc->time_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		tc->time_zero = pc->time_zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		tc->time_cycles = pc->time_cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		tc->time_mask = pc->time_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		tc->cap_user_time_zero = pc->cap_user_time_zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		tc->cap_user_time_short	= pc->cap_user_time_short;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		if (pc->lock == seq && !(seq & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		if (++i > 10000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			pr_debug("failed to get perf_event_mmap_page lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (!tc->cap_user_time_zero)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) int perf_event__synth_time_conv(const struct perf_event_mmap_page *pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 				struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				perf_event__handler_t process,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 				struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	union perf_event event = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		.time_conv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			.header = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 				.type = PERF_RECORD_TIME_CONV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 				.size = sizeof(struct perf_record_time_conv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct perf_tsc_conversion tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (!pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	err = perf_read_tsc_conversion(pc, &tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (err == -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	pr_debug2("Synthesizing TSC conversion information\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	event.time_conv.time_mult  = tc.time_mult;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	event.time_conv.time_shift = tc.time_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	event.time_conv.time_zero  = tc.time_zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	event.time_conv.time_cycles = tc.time_cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	event.time_conv.time_mask = tc.time_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	event.time_conv.cap_user_time_zero = tc.cap_user_time_zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	event.time_conv.cap_user_time_short = tc.cap_user_time_short;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	return process(tool, &event, NULL, machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u64 __weak rdtsc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }