On Tue, 4 Sep 2018, Jan Kiszka wrote: > On 2018-09-04 18:56, Daniel Bristot de Oliveira wrote: > > > > > > On 09/04/2018 06:25 PM, Ralf Ramsauer wrote: > >> > >> Hi Daniel, > >> > >> On 21/01/2016 19:08, Daniel Bristot de Oliveira wrote: > >>> Use the MSR/SMI counter on Intel's processor to detect/count SMIs. It is > >>> based on turbostat's implementation. > >>> > >>> SMI counting is enabled via --smi argument. When enabled, and additional > >>> field is added on both regular and verbose ouput. > >>> > >>> On the regular output, a SMI column shows how many SMIs occurred on > >>> each CPU during cyclictest's execution. For example: > >>> > >>> policy: fifo: loadavg: 0.09 0.05 0.02 1/194 2288 > >>> > >>> T: 0 ( 2285) P:80 I:1000 C: 9975 Min: 2 Act: 3 Avg: 4 Max: > >>> T: 20831 SMI: 2 > >>> T: 1 ( 2286) P:80 I:1500 C: 6650 Min: 2 Act: 2 Avg: 5 Max: > >>> T: 19910 SMI: 2 > >>> T: 2 ( 2287) P:80 I:2000 C: 4987 Min: 2 Act: 2 Avg: 6 Max: > >>> T: 20811 SMI: 2 > >>> T: 3 ( 2288) P:80 I:2500 C: 3990 Min: 2 Act: 3 Avg: 7 Max: > >>> T: 20322 SMI: 2 > >>> > >>> On verbose output, the last column shows how many SMIs occurred > >>> on each loop. For example: > >>> > >>> [ CPU | Loop | Lat | SMIs ] > >>> 0: 2156: 2 0 > >>> 0: 2157: 2 0 > >>> 0: 2158: 2 0 > >>> 0: 2159: 20981 2 > >>> 1: 1433: 2 0 > >>> 1: 1434: 2 0 > >>> 1: 1435: 2 0 > >>> 1: 1436: 3 0 > >>> 1: 1437: 2 0 > >>> 1: 1438: 2 0 > >>> 1: 1439: 20249 2 > >>> > >>> Signed-off-by: Daniel Bristot de Oliveira <bristot@xxxxxxxxxx> > >>> --- > >>> src/cyclictest/cyclictest.c | 229 > >>> ++++++++++++++++++++++++++++++++++++++++++-- > >>> 1 file changed, 219 insertions(+), 10 deletions(-) > >>> > >>> diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c > >>> index f5a67dc..df3db2a 100644 > >>> --- a/src/cyclictest/cyclictest.c > >>> +++ b/src/cyclictest/cyclictest.c > >>> @@ -111,6 +111,13 @@ extern int clock_nanosleep(clockid_t __clock_id, int > >>> __flags, > >>> #define KVARNAMELEN 32 > >>> #define KVALUELEN 32 > >>> > >>> +#if (defined(__i386__) || defined(__x86_64__)) > >>> +#define ARCH_HAS_SMI_COUNTER > >>> +#endif > >>> + > >>> +#define MSR_SMI_COUNT 0x00000034 > >>> +#define MSR_SMI_COUNT_MASK 0xFFFFFFFF > >>> + > >>> int enable_events; > >>> > >>> static char *policyname(int policy); > >>> @@ -143,6 +150,7 @@ struct thread_param { > >>> int cpu; > >>> int node; > >>> int tnum; > >>> + int msr_fd; > >>> }; > >>> > >>> /* Struct for statistics */ > >>> @@ -154,6 +162,7 @@ struct thread_stat { > >>> long act; > >>> double avg; > >>> long *values; > >>> + long *smis; > >>> long *hist_array; > >>> long *outliers; > >>> pthread_t thread; > >>> @@ -164,6 +173,7 @@ struct thread_stat { > >>> long cycleofmax; > >>> long hist_overflow; > >>> long num_outliers; > >>> + unsigned long smi_count; > >>> }; > >>> > >>> static pthread_mutex_t trigger_lock = PTHREAD_MUTEX_INITIALIZER; > >>> @@ -212,6 +222,12 @@ static pthread_t fifo_threadid; > >>> static int laptop = 0; > >>> static int use_histfile = 0; > >>> > >>> +#ifdef ARCH_HAS_SMI_COUNTER > >>> +static int smi = 0; > >>> +#else > >>> +#define smi 0 > >>> +#endif > >>> + > >>> static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER; > >>> static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER; > >>> > >>> @@ -772,6 +788,125 @@ try_again: > >>> return err; > >>> } > >>> > >>> +#ifdef ARCH_HAS_SMI_COUNTER > >>> +static int open_msr_file(int cpu) > >>> +{ > >>> + int fd; > >>> + char pathname[32]; > >>> + > >>> + /* SMI needs thread affinity */ > >>> + sprintf(pathname, "/dev/cpu/%d/msr", cpu); > >>> + fd = open(pathname, O_RDONLY); > >>> + if (fd < 0) > >>> + warn("%s open failed, try chown or chmod +r " > >>> + "/dev/cpu/*/msr, or run as root\n", pathname); > >>> + > >>> + return fd; > >>> +} > >>> + > >>> +static int get_msr(int fd, off_t offset, unsigned long long *msr) > >>> +{ > >>> + ssize_t retval; > >>> + > >>> + retval = pread(fd, msr, sizeof *msr, offset); > >>> + > >>> + if (retval != sizeof *msr) > >>> + return 1; > >>> + > >>> + return 0; > >>> +} > >>> + > >>> +static int get_smi_counter(int fd, unsigned long *counter) > >>> +{ > >>> + int retval; > >>> + unsigned long long msr; > >>> + > >>> + retval = get_msr(fd, MSR_SMI_COUNT, &msr); > >>> + if (retval) > >>> + return retval; > >>> + > >>> + *counter = (unsigned long) (msr & MSR_SMI_COUNT_MASK); > >>> + > >>> + return 0; > >>> +} > >>> + > >>> +#include <cpuid.h> > >>> + > >>> +/* Based on turbostat's check */ > >>> +static int has_smi_counter(void) > >>> +{ > >>> + unsigned int ebx, ecx, edx, max_level; > >>> + unsigned int fms, family, model; > >>> + > >>> + fms = family = model = ebx = ecx = edx = 0; > >>> + > >>> + __get_cpuid(0, &max_level, &ebx, &ecx, &edx); > >>> + > >>> + /* check genuine intel */ > >>> + if (!(ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)) > >>> + return 0; > >>> + > >>> + __get_cpuid(1, &fms, &ebx, &ecx, &edx); > >>> + family = (fms >> 8) & 0xf; > >>> + > >>> + if (family != 6) > >>> + return 0; > >>> + > >>> + /* no MSR */ > >>> + if (!(edx & (1 << 5))) > >>> + return 0; > >>> + > >>> + model = (((fms >> 16) & 0xf) << 4) + ((fms >> 4) & 0xf); > >>> + > >>> + switch (model) { > >>> + case 0x1A: /* Core i7, Xeon 5500 series - Bloomfield, Gainstown > >>> NHM-EP */ > >>> + case 0x1E: /* Core i7 and i5 Processor - Clarksfield, Lynnfield, > >>> Jasper Forest */ > >>> + case 0x1F: /* Core i7 and i5 Processor - Nehalem */ > >>> + case 0x25: /* Westmere Client - Clarkdale, Arrandale */ > >>> + case 0x2C: /* Westmere EP - Gulftown */ > >>> + case 0x2E: /* Nehalem-EX Xeon - Beckton */ > >>> + case 0x2F: /* Westmere-EX Xeon - Eagleton */ > >>> + case 0x2A: /* SNB */ > >>> + case 0x2D: /* SNB Xeon */ > >>> + case 0x3A: /* IVB */ > >>> + case 0x3E: /* IVB Xeon */ > >>> + case 0x3C: /* HSW */ > >>> + case 0x3F: /* HSX */ > >>> + case 0x45: /* HSW */ > >>> + case 0x46: /* HSW */ > >>> + case 0x3D: /* BDW */ > >>> + case 0x47: /* BDW */ > >>> + case 0x4F: /* BDX */ > >> > >> sorry for digging out this old patch. > >> > >> Are you sure that 0x4F has MSR_MSI_COUNT? I'm currently sitting in front > >> of such a box (Xeon E5-2683), and I doubt the value in this MSR is > >> correct for this model, it's way too high… > > > > This implementation is based in the turbostat.c (which is part of kernel): > > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/power/x86/turbostat/turbostat.c#n3139 > > > > So, other than doubting, do you have a list of CPU models that support > > it, saying this cpumodel is not supported? > > > > If so, report to turbostat.c developer and put me in Cc:. > > Our list is based on Intel SDM, Volume 4 (MSRs). In section 2.23, there is an > MSR index which associates MSRs with Family_Model IDs. But it may not be > complete as well, we already found at least one inconsistency (Xeon Phi is > 06_57h and 06_85h, but only the former was listed there). > > Jan > You guys are discussing a very old patch here, just want to make sure I didn't miss any updates, new patches? John