From: will.deacon@arm.com (Will Deacon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM: perf: ensure counter delta is limited to 32-bits
Date: Fri, 2 Jul 2010 15:17:23 +0100 [thread overview]
Message-ID: <004501cb19f1$4a9a25a0$dfce70e0$@deacon@arm.com> (raw)
In-Reply-To: <20100702184848.GH2357@wear.picochip.com>
> > Performance counter stats for 'git status':
> >
> > 3650781413 cycles
> > 289950734 instructions # 0.079 IPC
> > 144882 context-switches
> > 13677 page-faults
> > 473580406 branches
> >
> > 82.426290000 seconds time elapsed
> >
> >
> > Which looks insane to me. The IPC is appalling and we've taken
> > more branches than we've executed instructions!
> No, that certainly doesn't look right. Referring back your earlier email, when
> we do the cmpxchng, shouldn't it get sign extended then? An atomic64_t should
> be signed, but looking at the arm implementation, we're using u64's. Could
> this have anything to do with it? The generic implementation in lib/atomic64.c
> uses 'long long's.
It's a 64-bit cmpxchg and we're passing in 64-bit arguments so I don't
think any sign-extension should occur. The real issue is that we're taking
the difference between two u32 quantities (prev_raw_count and new_raw_count)
but using s64s, so when the delta is shifted right we treat the u32s as signed
when they're not.
> Providing that the sign extension does work, I've had a quick play with some
> uint64_t's and int64_t's in userspace and I think the algorithm is ok. Is the
> assumption of atomic64_t's being signed wrong?
I don't think the signedness of atomic64_t actually matters because everything
is handled in assembly anyway.
If you do something like:
#include <stdio.h>
typedef unsigned long u32;
typedef signed long long s64;
typedef unsigned long long u64;
int main(void)
{
u64 x = 0xffffffff;
u64 y = 0x0fffffff;
s64 z = (x << 32) - (y << 32);
z >>= 32;
printf("0x%llx\n", z);
return 0;
}
You'll get the sign-extended number printed out. Actually, a much neater
fix to this problem is to make delta unsigned and leave everything else
as-is (although I'm not a massive fan of all the 64-bit shifting).
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index c457686..de12536 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -201,7 +201,7 @@ armpmu_event_update(struct perf_event *event,
{
int shift = 64 - 32;
s64 prev_raw_count, new_raw_count;
- s64 delta;
+ u64 delta;
again:
prev_raw_count = atomic64_read(&hwc->prev_count);
What do you think?
Will
next prev parent reply other threads:[~2010-07-02 14:17 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-02 12:44 [PATCH] ARM: perf: ensure counter delta is limited to 32-bits Will Deacon
2010-07-02 18:05 ` Jamie Iles
2010-07-02 13:22 ` Will Deacon
2010-07-02 13:38 ` Will Deacon
2010-07-02 18:48 ` Jamie Iles
2010-07-02 14:17 ` Will Deacon [this message]
2010-07-02 20:04 ` Jamie Iles
2010-07-02 15:36 ` Will Deacon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='004501cb19f1$4a9a25a0$dfce70e0$@deacon@arm.com' \
--to=will.deacon@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.