lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Thu, 13 Aug 2009 13:14:59 +0200
From:	stephane eranian <eranian@...glemail.com>
To:	Ingo Molnar <mingo@...e.hu>
Cc:	Peter Zijlstra <a.p.zijlstra@...llo.nl>,
	LKML <linux-kernel@...r.kernel.org>,
	Andrew Morton <akpm@...ux-foundation.org>,
	Thomas Gleixner <tglx@...utronix.de>,
	Robert Richter <robert.richter@....com>,
	Paul Mackerras <paulus@...ba.org>,
	Andi Kleen <andi@...stfloor.org>,
	Maynard Johnson <mpjohn@...ibm.com>,
	Carl Love <cel@...ibm.com>,
	Corey J Ashford <cjashfor@...ibm.com>,
	Philip Mucci <mucci@...s.utk.edu>,
	Dan Terpstra <terpstra@...s.utk.edu>,
	perfmon2-devel <perfmon2-devel@...ts.sourceforge.net>
Subject: Re: perf_counters issue remapped count

On Thu, Aug 13, 2009 at 11:56 AM, Ingo Molnar<mingo@...e.hu> wrote:
>
> * stephane eranian <eranian@...glemail.com> wrote:
>
>> Hi,
>>
>> I am trying to use the remapped counter feature
>> on Intel Core. It does not work as expected.
>
> it would be highly useful if you posted the .c files you used to
> test it.
>
Here it is. It assumes you have enabled PCE in CR4 on all your CPUs.
I used BRANCH to ensure it would not use a fixed counter given the
hdr->index is wrong for those.

#include <sys/types.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/mman.h>
#include <err.h>

#include <perf_counter.h>

#ifdef __x86_64__
#define DECLARE_ARGS(val, low, high)    unsigned low, high
#define EAX_EDX_VAL(val, low, high)     ((low) | ((uint64_t )(high) << 32))
#define EAX_EDX_ARGS(val, low, high)    "a" (low), "d" (high)
#define EAX_EDX_RET(val, low, high)     "=a" (low), "=d" (high)
#else
#define DECLARE_ARGS(val, low, high)    unsigned long long val
#define EAX_EDX_VAL(val, low, high)     (val)
#define EAX_EDX_ARGS(val, low, high)    "A" (val)
#define EAX_EDX_RET(val, low, high)     "=A" (val)
#endif

#define barrier() __asm__ __volatile__("": : :"memory")

static inline unsigned long long rdpmc(int counter)
{
       unsigned low, high;

       asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
       return EAX_EDX_VAL(val, low, high);
}

static volatile int quit;
void sig_handler(int n)
{
       quit = 1;
}

/*
 * our test code (function cannot be made static otherwise it is optimized away)
 */
unsigned long
fib(unsigned long n)
{
       if (n == 0)
               return 0;
       if (n == 1)
               return 2;
       return fib(n-1)+fib(n-2);
}

int
main(int argc, char **argv)
{
       struct perf_counter_mmap_page *hdr;
       struct perf_counter_attr hw;
       char *name;
       uint64_t values[3];
       int ret, fd, src;
       unsigned int seq;

       memset(&hw, 0, sizeof(hw));

       /* make sure we do not use a fixed counter event */
       name = "PERF_COUNT_HW_BRANCH_INSTRUCTIONS";
       hw.type = PERF_TYPE_HARDWARE;
       hw.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
       hw.read_format =
PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING;
       hw.disabled = 0;

       fd = perf_counter_open(&hw, 0, -1, -1, 0);
       if (fd == -1)
               err(1, "cannot open event");

       hdr = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, fd, 0);
       if (hdr == MAP_FAILED)
               err(1, "cannot mmap page");

       signal(SIGALRM, sig_handler);

       ioctl(fd, PERF_COUNTER_IOC_ENABLE, 0);

       alarm(10);

       for(;quit == 0;) {
               uint64_t offset = 0;
               unsigned long loop;

               /* generate branches */
               fib(10);

               loop = 0;
               do {
                       loop++;
                       seq = hdr->lock;
                       barrier();
                       if (hdr->index > 0) {
                               values[0] = rdpmc(hdr->index-1);
                               offset = hdr->offset;
                               values[0] += offset;
                               values[1] = hdr->time_enabled;
                               values[2] = hdr->time_running;
                               src = 0;
                       } else {
                               ret = read(fd, values, sizeof(values));
                               src =1;
                               break;
                       }
                       barrier();
               } while (hdr->lock != seq);

               if (values[2])
                       values[0]= (uint64_t)((double)values[0] *
values[1]/values[2]);

               printf("%20"PRIx64" %s %s offset=0x%"PRIx64" src=%s loop=%lu\n",
                       values[0],
                       name,
                       values[1] != values[2] ? "(scaled)" : "",
                       offset, src ? "read" : "rdpmc",
                       loop);
       }
       ioctl(fd, PERF_COUNTER_IOC_DISABLE, 0);
       close(fd);
       return 0;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ