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-next>] [day] [month] [year] [list]
Message-ID: <7c86c4470908111504i3a1e83b9k140fdaa717584a30@mail.gmail.com>
Date:	Wed, 12 Aug 2009 00:04:09 +0200
From:	stephane eranian <eranian@...glemail.com>
To:	Peter Zijlstra <a.p.zijlstra@...llo.nl>
Cc:	Ingo Molnar <mingo@...e.hu>, 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: perf_counters issue remapped count

Hi,

I am trying to use the remapped counter feature
on Intel Core. It does not work as expected.

Well, in fact, it segfaults immediately, but that's because
you have not enabled PCE in cr4. But assume you have
for a moment. Them there are still several problems.

1/ hdr->index does not work with fixed counters

    On Intel, RDPMC supports fixed counters, however, you
    have to add an offset 0x40000000 to the index (see Intel
    Vol 2b RDPMC description).

    From what I can see in:

    static int perf_counter_index(struct perf_counter *counter)
    {
        if (counter->state != PERF_COUNTER_STATE_ACTIVE)
                return 0;

        return counter->hw.idx + 1 - PERF_COUNTER_INDEX_OFFSET;
    }

    It  cannot be made to work for both generic and fixed counters.
    I think this function has to go in arch-specific code or become
    more complicated.


2/ rdpmc() + offset returns bogus counts

    Suppose you are using a generic counter, RDPMC returns the live
    40-bit value of the counter. Then, my understanding is that you are
    supposed to addr hdr->offset to that value to reconstruct the full
    64-bit value.

    It appears this is not quite working. Here is small example counting
    PERF_COUNT_HW_BRANCH_INSTRUCTIONS.

   RDPMC RAW hdr->offset
                34a1 offset=0x0
                3bac offset=0x0
                40e4 offset=0x0
                461c offset=0x0
                4b54 offset=0x0
                508c offset=0x0
                55c4 offset=0x0
                5afc offset=0x0
                6034 offset=0x0
                656c offset=0x0
                6aa4 offset=0x0
                6fdc offset=0x0
                7514 offset=0x0
                7a4c offset=0x0
                7f84 offset=0x0
                84bc offset=0x0
                89f4 offset=0x0
                8f2c offset=0x0
                9464 offset=0x0
                999c offset=0x0
                9ed4 offset=0x0
                ac20 offset=0x0
          ff8000bbe9 offset=0x7fffffff
          ff8000bf15 offset=0x7fffffff
          ff8000c241 offset=0x7fffffff
          ff8000c56d offset=0x7fffffff
          ff8000c899 offset=0x7fffffff
          ff8000cbc5 offset=0x7fffffff
          ff8000cef1 offset=0x7fffffff
          ff8000d21d offset=0x7fffffff
          ff8000d549 offset=0x7fffffff

It appears at some point, the live value of the counter is changed and suddenly
you set bit 31 (bit32-39 are sign extension). Don't think it is because of PMU
interrupt, I suspect something wrong during context switching.

The core of my loop is as follows:

        for(;;) {
                for (i=0; i < num; i++) {
                        uint64_t offset = 0;
                        uint64_t values[3];
                        do {
                                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;
                                } else {
                                        ret = read(fd, values, sizeof(values));
                                        break;
                                }
                                barrier();
                        } while (hdr->lock != seq);

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

                        printf("%20"PRIx64" offset=0x%"PRIx64"\n",
                                values[0],
                                offset);
                }
                fib(10);
        }
--
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