License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 22:07:57 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
/* Performance event support for sparc64.
|
2009-09-10 21:28:20 +08:00
|
|
|
*
|
2010-01-19 16:26:13 +08:00
|
|
|
* Copyright (C) 2009, 2010 David S. Miller <davem@davemloft.net>
|
2009-09-10 21:28:20 +08:00
|
|
|
*
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
* This code is based almost entirely upon the x86 perf event
|
2009-09-10 21:28:20 +08:00
|
|
|
* code, which is:
|
|
|
|
*
|
|
|
|
* Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
|
|
|
|
* Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
|
|
|
|
* Copyright (C) 2009 Jaswinder Singh Rajput
|
|
|
|
* Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
|
2015-11-16 18:08:45 +08:00
|
|
|
* Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra
|
2009-09-10 21:28:20 +08:00
|
|
|
*/
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
#include <linux/perf_event.h>
|
2009-09-10 21:28:20 +08:00
|
|
|
#include <linux/kprobes.h>
|
2010-04-21 18:08:11 +08:00
|
|
|
#include <linux/ftrace.h>
|
2009-09-10 21:28:20 +08:00
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/kdebug.h>
|
|
|
|
#include <linux/mutex.h>
|
|
|
|
|
2010-01-19 16:26:13 +08:00
|
|
|
#include <asm/stacktrace.h>
|
2009-09-10 21:28:20 +08:00
|
|
|
#include <asm/cpudata.h>
|
2015-06-16 04:15:43 +08:00
|
|
|
#include <linux/uaccess.h>
|
2011-07-27 07:09:06 +08:00
|
|
|
#include <linux/atomic.h>
|
2009-09-10 21:28:20 +08:00
|
|
|
#include <asm/nmi.h>
|
|
|
|
#include <asm/pcr.h>
|
2012-03-29 01:30:03 +08:00
|
|
|
#include <asm/cacheflush.h>
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2011-04-22 06:45:45 +08:00
|
|
|
#include "kernel.h"
|
2010-01-19 16:26:13 +08:00
|
|
|
#include "kstack.h"
|
|
|
|
|
2012-08-19 14:17:38 +08:00
|
|
|
/* Two classes of sparc64 chips currently exist. All of which have
|
|
|
|
* 32-bit counters which can generate overflow interrupts on the
|
|
|
|
* transition from 0xffffffff to 0.
|
2009-09-10 21:28:20 +08:00
|
|
|
*
|
2012-08-19 14:17:38 +08:00
|
|
|
* All chips upto and including SPARC-T3 have two performance
|
|
|
|
* counters. The two 32-bit counters are accessed in one go using a
|
|
|
|
* single 64-bit register.
|
2009-09-10 21:28:20 +08:00
|
|
|
*
|
2012-08-19 14:17:38 +08:00
|
|
|
* On these older chips both counters are controlled using a single
|
|
|
|
* control register. The only way to stop all sampling is to clear
|
|
|
|
* all of the context (user, supervisor, hypervisor) sampling enable
|
|
|
|
* bits. But these bits apply to both counters, thus the two counters
|
|
|
|
* can't be enabled/disabled individually.
|
|
|
|
*
|
|
|
|
* Furthermore, the control register on these older chips have two
|
|
|
|
* event fields, one for each of the two counters. It's thus nearly
|
|
|
|
* impossible to have one counter going while keeping the other one
|
|
|
|
* stopped. Therefore it is possible to get overflow interrupts for
|
|
|
|
* counters not currently "in use" and that condition must be checked
|
|
|
|
* in the overflow interrupt handler.
|
2009-09-10 21:28:20 +08:00
|
|
|
*
|
|
|
|
* So we use a hack, in that we program inactive counters with the
|
|
|
|
* "sw_count0" and "sw_count1" events. These count how many times
|
|
|
|
* the instruction "sethi %hi(0xfc000), %g0" is executed. It's an
|
|
|
|
* unusual way to encode a NOP and therefore will not trigger in
|
|
|
|
* normal code.
|
2012-08-19 14:17:38 +08:00
|
|
|
*
|
|
|
|
* Starting with SPARC-T4 we have one control register per counter.
|
|
|
|
* And the counters are stored in individual registers. The registers
|
|
|
|
* for the counters are 64-bit but only a 32-bit counter is
|
|
|
|
* implemented. The event selections on SPARC-T4 lack any
|
|
|
|
* restrictions, therefore we can elide all of the complicated
|
|
|
|
* conflict resolution code we have for SPARC-T3 and earlier chips.
|
2009-09-10 21:28:20 +08:00
|
|
|
*/
|
|
|
|
|
2012-08-18 14:06:09 +08:00
|
|
|
#define MAX_HWEVENTS 4
|
|
|
|
#define MAX_PCRS 4
|
2009-09-10 21:28:20 +08:00
|
|
|
#define MAX_PERIOD ((1UL << 32) - 1)
|
|
|
|
|
|
|
|
#define PIC_UPPER_INDEX 0
|
|
|
|
#define PIC_LOWER_INDEX 1
|
2010-01-20 18:59:47 +08:00
|
|
|
#define PIC_NO_INDEX -1
|
2009-09-10 21:28:20 +08:00
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
struct cpu_hw_events {
|
2010-01-20 18:59:47 +08:00
|
|
|
/* Number of events currently scheduled onto this cpu.
|
|
|
|
* This tells how many entries in the arrays below
|
|
|
|
* are valid.
|
|
|
|
*/
|
|
|
|
int n_events;
|
|
|
|
|
|
|
|
/* Number of new events added since the last hw_perf_disable().
|
|
|
|
* This works because the perf event layer always adds new
|
|
|
|
* events inside of a perf_{disable,enable}() sequence.
|
|
|
|
*/
|
|
|
|
int n_added;
|
|
|
|
|
|
|
|
/* Array of events current scheduled on this cpu. */
|
|
|
|
struct perf_event *event[MAX_HWEVENTS];
|
|
|
|
|
|
|
|
/* Array of encoded longs, specifying the %pcr register
|
|
|
|
* encoding and the mask of PIC counters this even can
|
|
|
|
* be scheduled on. See perf_event_encode() et al.
|
|
|
|
*/
|
|
|
|
unsigned long events[MAX_HWEVENTS];
|
|
|
|
|
|
|
|
/* The current counter index assigned to an event. When the
|
|
|
|
* event hasn't been programmed into the cpu yet, this will
|
|
|
|
* hold PIC_NO_INDEX. The event->hw.idx value tells us where
|
|
|
|
* we ought to schedule the event.
|
|
|
|
*/
|
|
|
|
int current_idx[MAX_HWEVENTS];
|
|
|
|
|
2012-08-17 17:51:21 +08:00
|
|
|
/* Software copy of %pcr register(s) on this cpu. */
|
|
|
|
u64 pcr[MAX_HWEVENTS];
|
2010-01-20 18:59:47 +08:00
|
|
|
|
|
|
|
/* Enabled/disable state. */
|
2009-09-30 12:27:06 +08:00
|
|
|
int enabled;
|
2010-04-23 13:56:33 +08:00
|
|
|
|
2015-09-04 11:07:45 +08:00
|
|
|
unsigned int txn_flags;
|
2009-09-10 21:28:20 +08:00
|
|
|
};
|
2014-05-17 05:26:04 +08:00
|
|
|
static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
/* An event map describes the characteristics of a performance
|
|
|
|
* counter event. In particular it gives the encoding as well as
|
|
|
|
* a mask telling which counters the event can be measured on.
|
2012-08-19 14:17:38 +08:00
|
|
|
*
|
|
|
|
* The mask is unused on SPARC-T4 and later.
|
2010-01-20 18:59:47 +08:00
|
|
|
*/
|
2009-09-10 21:28:20 +08:00
|
|
|
struct perf_event_map {
|
|
|
|
u16 encoding;
|
|
|
|
u8 pic_mask;
|
|
|
|
#define PIC_NONE 0x00
|
|
|
|
#define PIC_UPPER 0x01
|
|
|
|
#define PIC_LOWER 0x02
|
|
|
|
};
|
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
/* Encode a perf_event_map entry into a long. */
|
2009-09-29 08:35:20 +08:00
|
|
|
static unsigned long perf_event_encode(const struct perf_event_map *pmap)
|
|
|
|
{
|
|
|
|
return ((unsigned long) pmap->encoding << 16) | pmap->pic_mask;
|
|
|
|
}
|
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
static u8 perf_event_get_msk(unsigned long val)
|
|
|
|
{
|
|
|
|
return val & 0xff;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u64 perf_event_get_enc(unsigned long val)
|
2009-09-29 08:35:20 +08:00
|
|
|
{
|
2010-01-20 18:59:47 +08:00
|
|
|
return val >> 16;
|
2009-09-29 08:35:20 +08:00
|
|
|
}
|
|
|
|
|
2009-09-27 11:42:10 +08:00
|
|
|
#define C(x) PERF_COUNT_HW_CACHE_##x
|
|
|
|
|
|
|
|
#define CACHE_OP_UNSUPPORTED 0xfffe
|
|
|
|
#define CACHE_OP_NONSENSE 0xffff
|
|
|
|
|
|
|
|
typedef struct perf_event_map cache_map_t
|
|
|
|
[PERF_COUNT_HW_CACHE_MAX]
|
|
|
|
[PERF_COUNT_HW_CACHE_OP_MAX]
|
|
|
|
[PERF_COUNT_HW_CACHE_RESULT_MAX];
|
|
|
|
|
2009-09-10 21:28:20 +08:00
|
|
|
struct sparc_pmu {
|
|
|
|
const struct perf_event_map *(*event_map)(int);
|
2009-09-27 11:42:10 +08:00
|
|
|
const cache_map_t *cache_map;
|
2009-09-10 21:28:20 +08:00
|
|
|
int max_events;
|
2012-08-17 17:37:06 +08:00
|
|
|
u32 (*read_pmc)(int);
|
|
|
|
void (*write_pmc)(int, u64);
|
2009-09-10 21:28:20 +08:00
|
|
|
int upper_shift;
|
|
|
|
int lower_shift;
|
|
|
|
int event_mask;
|
2012-08-17 17:41:32 +08:00
|
|
|
int user_bit;
|
|
|
|
int priv_bit;
|
2009-09-10 22:09:06 +08:00
|
|
|
int hv_bit;
|
2009-09-10 22:10:59 +08:00
|
|
|
int irq_bit;
|
2009-09-10 22:13:26 +08:00
|
|
|
int upper_nop;
|
|
|
|
int lower_nop;
|
2012-08-17 17:31:10 +08:00
|
|
|
unsigned int flags;
|
|
|
|
#define SPARC_PMU_ALL_EXCLUDES_SAME 0x00000001
|
|
|
|
#define SPARC_PMU_HAS_CONFLICTS 0x00000002
|
2012-08-17 17:33:44 +08:00
|
|
|
int max_hw_events;
|
2012-08-17 17:51:21 +08:00
|
|
|
int num_pcrs;
|
|
|
|
int num_pic_regs;
|
2009-09-10 21:28:20 +08:00
|
|
|
};
|
|
|
|
|
2012-08-17 17:37:06 +08:00
|
|
|
static u32 sparc_default_read_pmc(int idx)
|
|
|
|
{
|
|
|
|
u64 val;
|
|
|
|
|
|
|
|
val = pcr_ops->read_pic(0);
|
|
|
|
if (idx == PIC_UPPER_INDEX)
|
|
|
|
val >>= 32;
|
|
|
|
|
|
|
|
return val & 0xffffffff;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sparc_default_write_pmc(int idx, u64 val)
|
|
|
|
{
|
|
|
|
u64 shift, mask, pic;
|
|
|
|
|
|
|
|
shift = 0;
|
|
|
|
if (idx == PIC_UPPER_INDEX)
|
|
|
|
shift = 32;
|
|
|
|
|
|
|
|
mask = ((u64) 0xffffffff) << shift;
|
|
|
|
val <<= shift;
|
|
|
|
|
|
|
|
pic = pcr_ops->read_pic(0);
|
|
|
|
pic &= ~mask;
|
|
|
|
pic |= val;
|
|
|
|
pcr_ops->write_pic(0, pic);
|
|
|
|
}
|
|
|
|
|
2009-09-27 11:54:22 +08:00
|
|
|
static const struct perf_event_map ultra3_perfmon_event_map[] = {
|
2009-09-10 21:28:20 +08:00
|
|
|
[PERF_COUNT_HW_CPU_CYCLES] = { 0x0000, PIC_UPPER | PIC_LOWER },
|
|
|
|
[PERF_COUNT_HW_INSTRUCTIONS] = { 0x0001, PIC_UPPER | PIC_LOWER },
|
|
|
|
[PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0009, PIC_LOWER },
|
|
|
|
[PERF_COUNT_HW_CACHE_MISSES] = { 0x0009, PIC_UPPER },
|
|
|
|
};
|
|
|
|
|
2009-09-27 11:54:22 +08:00
|
|
|
static const struct perf_event_map *ultra3_event_map(int event_id)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
2009-09-27 11:54:22 +08:00
|
|
|
return &ultra3_perfmon_event_map[event_id];
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
2009-09-27 11:54:22 +08:00
|
|
|
static const cache_map_t ultra3_cache_map = {
|
2009-09-27 11:42:10 +08:00
|
|
|
[C(L1D)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x09, PIC_LOWER, },
|
|
|
|
[C(RESULT_MISS)] = { 0x09, PIC_UPPER, },
|
|
|
|
},
|
|
|
|
[C(OP_WRITE)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x0a, PIC_LOWER },
|
|
|
|
[C(RESULT_MISS)] = { 0x0a, PIC_UPPER },
|
|
|
|
},
|
|
|
|
[C(OP_PREFETCH)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(L1I)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x09, PIC_LOWER, },
|
|
|
|
[C(RESULT_MISS)] = { 0x09, PIC_UPPER, },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(LL)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x0c, PIC_LOWER, },
|
|
|
|
[C(RESULT_MISS)] = { 0x0c, PIC_UPPER, },
|
|
|
|
},
|
|
|
|
[C(OP_WRITE)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x0c, PIC_LOWER },
|
|
|
|
[C(RESULT_MISS)] = { 0x0c, PIC_UPPER },
|
|
|
|
},
|
|
|
|
[C(OP_PREFETCH)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(DTLB)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { 0x12, PIC_UPPER, },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(ITLB)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { 0x11, PIC_UPPER, },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(BPU)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
2011-04-23 05:37:06 +08:00
|
|
|
[C(NODE)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
2009-09-27 11:42:10 +08:00
|
|
|
};
|
|
|
|
|
2009-09-27 11:54:22 +08:00
|
|
|
static const struct sparc_pmu ultra3_pmu = {
|
|
|
|
.event_map = ultra3_event_map,
|
|
|
|
.cache_map = &ultra3_cache_map,
|
|
|
|
.max_events = ARRAY_SIZE(ultra3_perfmon_event_map),
|
2012-08-17 17:37:06 +08:00
|
|
|
.read_pmc = sparc_default_read_pmc,
|
|
|
|
.write_pmc = sparc_default_write_pmc,
|
2009-09-10 21:28:20 +08:00
|
|
|
.upper_shift = 11,
|
|
|
|
.lower_shift = 4,
|
|
|
|
.event_mask = 0x3f,
|
2012-08-17 17:41:32 +08:00
|
|
|
.user_bit = PCR_UTRACE,
|
|
|
|
.priv_bit = PCR_STRACE,
|
2009-09-10 22:13:26 +08:00
|
|
|
.upper_nop = 0x1c,
|
|
|
|
.lower_nop = 0x14,
|
2012-08-17 17:31:10 +08:00
|
|
|
.flags = (SPARC_PMU_ALL_EXCLUDES_SAME |
|
|
|
|
SPARC_PMU_HAS_CONFLICTS),
|
2012-08-17 17:33:44 +08:00
|
|
|
.max_hw_events = 2,
|
2012-08-17 17:51:21 +08:00
|
|
|
.num_pcrs = 1,
|
|
|
|
.num_pic_regs = 1,
|
2009-09-10 21:28:20 +08:00
|
|
|
};
|
|
|
|
|
2009-09-27 12:23:41 +08:00
|
|
|
/* Niagara1 is very limited. The upper PIC is hard-locked to count
|
|
|
|
* only instructions, so it is free running which creates all kinds of
|
2009-09-30 06:10:23 +08:00
|
|
|
* problems. Some hardware designs make one wonder if the creator
|
2009-09-27 12:23:41 +08:00
|
|
|
* even looked at how this stuff gets used by software.
|
|
|
|
*/
|
|
|
|
static const struct perf_event_map niagara1_perfmon_event_map[] = {
|
|
|
|
[PERF_COUNT_HW_CPU_CYCLES] = { 0x00, PIC_UPPER },
|
|
|
|
[PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, PIC_UPPER },
|
|
|
|
[PERF_COUNT_HW_CACHE_REFERENCES] = { 0, PIC_NONE },
|
|
|
|
[PERF_COUNT_HW_CACHE_MISSES] = { 0x03, PIC_LOWER },
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct perf_event_map *niagara1_event_map(int event_id)
|
|
|
|
{
|
|
|
|
return &niagara1_perfmon_event_map[event_id];
|
|
|
|
}
|
|
|
|
|
|
|
|
static const cache_map_t niagara1_cache_map = {
|
|
|
|
[C(L1D)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { 0x03, PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[C(OP_WRITE)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { 0x03, PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[C(OP_PREFETCH)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(L1I)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x00, PIC_UPPER },
|
|
|
|
[C(RESULT_MISS)] = { 0x02, PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(LL)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { 0x07, PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[C(OP_WRITE)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { 0x07, PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[C(OP_PREFETCH)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(DTLB)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { 0x05, PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(ITLB)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { 0x04, PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(BPU)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
2011-04-23 05:37:06 +08:00
|
|
|
[C(NODE)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
2009-09-27 12:23:41 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct sparc_pmu niagara1_pmu = {
|
|
|
|
.event_map = niagara1_event_map,
|
|
|
|
.cache_map = &niagara1_cache_map,
|
|
|
|
.max_events = ARRAY_SIZE(niagara1_perfmon_event_map),
|
2012-08-17 17:37:06 +08:00
|
|
|
.read_pmc = sparc_default_read_pmc,
|
|
|
|
.write_pmc = sparc_default_write_pmc,
|
2009-09-27 12:23:41 +08:00
|
|
|
.upper_shift = 0,
|
|
|
|
.lower_shift = 4,
|
|
|
|
.event_mask = 0x7,
|
2012-08-17 17:41:32 +08:00
|
|
|
.user_bit = PCR_UTRACE,
|
|
|
|
.priv_bit = PCR_STRACE,
|
2009-09-27 12:23:41 +08:00
|
|
|
.upper_nop = 0x0,
|
|
|
|
.lower_nop = 0x0,
|
2012-08-17 17:31:10 +08:00
|
|
|
.flags = (SPARC_PMU_ALL_EXCLUDES_SAME |
|
|
|
|
SPARC_PMU_HAS_CONFLICTS),
|
2012-08-17 17:33:44 +08:00
|
|
|
.max_hw_events = 2,
|
2012-08-17 17:51:21 +08:00
|
|
|
.num_pcrs = 1,
|
|
|
|
.num_pic_regs = 1,
|
2009-09-27 12:23:41 +08:00
|
|
|
};
|
|
|
|
|
2009-09-10 22:22:18 +08:00
|
|
|
static const struct perf_event_map niagara2_perfmon_event_map[] = {
|
|
|
|
[PERF_COUNT_HW_CPU_CYCLES] = { 0x02ff, PIC_UPPER | PIC_LOWER },
|
|
|
|
[PERF_COUNT_HW_INSTRUCTIONS] = { 0x02ff, PIC_UPPER | PIC_LOWER },
|
|
|
|
[PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0208, PIC_UPPER | PIC_LOWER },
|
|
|
|
[PERF_COUNT_HW_CACHE_MISSES] = { 0x0302, PIC_UPPER | PIC_LOWER },
|
|
|
|
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x0201, PIC_UPPER | PIC_LOWER },
|
|
|
|
[PERF_COUNT_HW_BRANCH_MISSES] = { 0x0202, PIC_UPPER | PIC_LOWER },
|
|
|
|
};
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
static const struct perf_event_map *niagara2_event_map(int event_id)
|
2009-09-10 22:22:18 +08:00
|
|
|
{
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
return &niagara2_perfmon_event_map[event_id];
|
2009-09-10 22:22:18 +08:00
|
|
|
}
|
|
|
|
|
2009-09-27 12:04:16 +08:00
|
|
|
static const cache_map_t niagara2_cache_map = {
|
|
|
|
[C(L1D)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x0208, PIC_UPPER | PIC_LOWER, },
|
|
|
|
[C(RESULT_MISS)] = { 0x0302, PIC_UPPER | PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[C(OP_WRITE)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x0210, PIC_UPPER | PIC_LOWER, },
|
|
|
|
[C(RESULT_MISS)] = { 0x0302, PIC_UPPER | PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[C(OP_PREFETCH)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(L1I)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x02ff, PIC_UPPER | PIC_LOWER, },
|
|
|
|
[C(RESULT_MISS)] = { 0x0301, PIC_UPPER | PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(LL)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x0208, PIC_UPPER | PIC_LOWER, },
|
|
|
|
[C(RESULT_MISS)] = { 0x0330, PIC_UPPER | PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[C(OP_WRITE)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { 0x0210, PIC_UPPER | PIC_LOWER, },
|
|
|
|
[C(RESULT_MISS)] = { 0x0320, PIC_UPPER | PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[C(OP_PREFETCH)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(DTLB)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { 0x0b08, PIC_UPPER | PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(ITLB)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { 0xb04, PIC_UPPER | PIC_LOWER, },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(BPU)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
2011-04-23 05:37:06 +08:00
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(NODE)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
2009-09-27 12:04:16 +08:00
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2009-09-10 22:22:18 +08:00
|
|
|
static const struct sparc_pmu niagara2_pmu = {
|
|
|
|
.event_map = niagara2_event_map,
|
2009-09-27 12:04:16 +08:00
|
|
|
.cache_map = &niagara2_cache_map,
|
2009-09-10 22:22:18 +08:00
|
|
|
.max_events = ARRAY_SIZE(niagara2_perfmon_event_map),
|
2012-08-17 17:37:06 +08:00
|
|
|
.read_pmc = sparc_default_read_pmc,
|
|
|
|
.write_pmc = sparc_default_write_pmc,
|
2009-09-10 22:22:18 +08:00
|
|
|
.upper_shift = 19,
|
|
|
|
.lower_shift = 6,
|
|
|
|
.event_mask = 0xfff,
|
2012-08-17 17:41:32 +08:00
|
|
|
.user_bit = PCR_UTRACE,
|
|
|
|
.priv_bit = PCR_STRACE,
|
|
|
|
.hv_bit = PCR_N2_HTRACE,
|
2009-10-09 15:42:40 +08:00
|
|
|
.irq_bit = 0x30,
|
2009-09-10 22:22:18 +08:00
|
|
|
.upper_nop = 0x220,
|
|
|
|
.lower_nop = 0x220,
|
2012-08-17 17:31:10 +08:00
|
|
|
.flags = (SPARC_PMU_ALL_EXCLUDES_SAME |
|
|
|
|
SPARC_PMU_HAS_CONFLICTS),
|
2012-08-17 17:33:44 +08:00
|
|
|
.max_hw_events = 2,
|
2012-08-17 17:51:21 +08:00
|
|
|
.num_pcrs = 1,
|
|
|
|
.num_pic_regs = 1,
|
2009-09-10 22:22:18 +08:00
|
|
|
};
|
|
|
|
|
2012-08-18 14:06:09 +08:00
|
|
|
static const struct perf_event_map niagara4_perfmon_event_map[] = {
|
|
|
|
[PERF_COUNT_HW_CPU_CYCLES] = { (26 << 6) },
|
|
|
|
[PERF_COUNT_HW_INSTRUCTIONS] = { (3 << 6) | 0x3f },
|
|
|
|
[PERF_COUNT_HW_CACHE_REFERENCES] = { (3 << 6) | 0x04 },
|
|
|
|
[PERF_COUNT_HW_CACHE_MISSES] = { (16 << 6) | 0x07 },
|
|
|
|
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { (4 << 6) | 0x01 },
|
|
|
|
[PERF_COUNT_HW_BRANCH_MISSES] = { (25 << 6) | 0x0f },
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct perf_event_map *niagara4_event_map(int event_id)
|
|
|
|
{
|
|
|
|
return &niagara4_perfmon_event_map[event_id];
|
|
|
|
}
|
|
|
|
|
|
|
|
static const cache_map_t niagara4_cache_map = {
|
|
|
|
[C(L1D)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { (3 << 6) | 0x04 },
|
|
|
|
[C(RESULT_MISS)] = { (16 << 6) | 0x07 },
|
|
|
|
},
|
|
|
|
[C(OP_WRITE)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { (3 << 6) | 0x08 },
|
|
|
|
[C(RESULT_MISS)] = { (16 << 6) | 0x07 },
|
|
|
|
},
|
|
|
|
[C(OP_PREFETCH)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(L1I)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { (3 << 6) | 0x3f },
|
|
|
|
[C(RESULT_MISS)] = { (11 << 6) | 0x03 },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(LL)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { (3 << 6) | 0x04 },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[C(OP_WRITE)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { (3 << 6) | 0x08 },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[C(OP_PREFETCH)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(DTLB)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { (17 << 6) | 0x3f },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(ITLB)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { (6 << 6) | 0x3f },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(BPU)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[C(NODE)] = {
|
|
|
|
[C(OP_READ)] = {
|
|
|
|
[C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_WRITE) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
[ C(OP_PREFETCH) ] = {
|
|
|
|
[ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
[ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static u32 sparc_vt_read_pmc(int idx)
|
|
|
|
{
|
|
|
|
u64 val = pcr_ops->read_pic(idx);
|
|
|
|
|
|
|
|
return val & 0xffffffff;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sparc_vt_write_pmc(int idx, u64 val)
|
|
|
|
{
|
|
|
|
u64 pcr;
|
|
|
|
|
|
|
|
pcr = pcr_ops->read_pcr(idx);
|
2015-04-22 04:14:53 +08:00
|
|
|
/* ensure ov and ntc are reset */
|
|
|
|
pcr &= ~(PCR_N4_OV | PCR_N4_NTC);
|
2012-08-18 14:06:09 +08:00
|
|
|
|
|
|
|
pcr_ops->write_pic(idx, val & 0xffffffff);
|
|
|
|
|
|
|
|
pcr_ops->write_pcr(idx, pcr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct sparc_pmu niagara4_pmu = {
|
|
|
|
.event_map = niagara4_event_map,
|
|
|
|
.cache_map = &niagara4_cache_map,
|
|
|
|
.max_events = ARRAY_SIZE(niagara4_perfmon_event_map),
|
|
|
|
.read_pmc = sparc_vt_read_pmc,
|
|
|
|
.write_pmc = sparc_vt_write_pmc,
|
|
|
|
.upper_shift = 5,
|
|
|
|
.lower_shift = 5,
|
|
|
|
.event_mask = 0x7ff,
|
|
|
|
.user_bit = PCR_N4_UTRACE,
|
|
|
|
.priv_bit = PCR_N4_STRACE,
|
|
|
|
|
|
|
|
/* We explicitly don't support hypervisor tracing. The T4
|
|
|
|
* generates the overflow event for precise events via a trap
|
|
|
|
* which will not be generated (ie. it's completely lost) if
|
|
|
|
* we happen to be in the hypervisor when the event triggers.
|
|
|
|
* Essentially, the overflow event reporting is completely
|
|
|
|
* unusable when you have hypervisor mode tracing enabled.
|
|
|
|
*/
|
|
|
|
.hv_bit = 0,
|
|
|
|
|
|
|
|
.irq_bit = PCR_N4_TOE,
|
|
|
|
.upper_nop = 0,
|
|
|
|
.lower_nop = 0,
|
|
|
|
.flags = 0,
|
|
|
|
.max_hw_events = 4,
|
|
|
|
.num_pcrs = 4,
|
|
|
|
.num_pic_regs = 4,
|
|
|
|
};
|
|
|
|
|
2015-03-20 04:06:37 +08:00
|
|
|
static const struct sparc_pmu sparc_m7_pmu = {
|
|
|
|
.event_map = niagara4_event_map,
|
|
|
|
.cache_map = &niagara4_cache_map,
|
|
|
|
.max_events = ARRAY_SIZE(niagara4_perfmon_event_map),
|
|
|
|
.read_pmc = sparc_vt_read_pmc,
|
2015-04-22 04:14:53 +08:00
|
|
|
.write_pmc = sparc_vt_write_pmc,
|
2015-03-20 04:06:37 +08:00
|
|
|
.upper_shift = 5,
|
|
|
|
.lower_shift = 5,
|
|
|
|
.event_mask = 0x7ff,
|
|
|
|
.user_bit = PCR_N4_UTRACE,
|
|
|
|
.priv_bit = PCR_N4_STRACE,
|
|
|
|
|
|
|
|
/* We explicitly don't support hypervisor tracing. */
|
|
|
|
.hv_bit = 0,
|
|
|
|
|
|
|
|
.irq_bit = PCR_N4_TOE,
|
|
|
|
.upper_nop = 0,
|
|
|
|
.lower_nop = 0,
|
|
|
|
.flags = 0,
|
|
|
|
.max_hw_events = 4,
|
|
|
|
.num_pcrs = 4,
|
|
|
|
.num_pic_regs = 4,
|
|
|
|
};
|
2009-09-10 21:28:20 +08:00
|
|
|
static const struct sparc_pmu *sparc_pmu __read_mostly;
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
static u64 event_encoding(u64 event_id, int idx)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
|
|
|
if (idx == PIC_UPPER_INDEX)
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
event_id <<= sparc_pmu->upper_shift;
|
2009-09-10 21:28:20 +08:00
|
|
|
else
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
event_id <<= sparc_pmu->lower_shift;
|
|
|
|
return event_id;
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static u64 mask_for_index(int idx)
|
|
|
|
{
|
|
|
|
return event_encoding(sparc_pmu->event_mask, idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static u64 nop_for_index(int idx)
|
|
|
|
{
|
|
|
|
return event_encoding(idx == PIC_UPPER_INDEX ?
|
2009-09-10 22:13:26 +08:00
|
|
|
sparc_pmu->upper_nop :
|
|
|
|
sparc_pmu->lower_nop, idx);
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
2009-09-30 12:27:06 +08:00
|
|
|
static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
2012-10-17 04:05:25 +08:00
|
|
|
u64 enc, val, mask = mask_for_index(idx);
|
2012-08-17 18:14:01 +08:00
|
|
|
int pcr_index = 0;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2012-08-17 18:14:01 +08:00
|
|
|
if (sparc_pmu->num_pcrs > 1)
|
|
|
|
pcr_index = idx;
|
|
|
|
|
2012-10-17 04:05:25 +08:00
|
|
|
enc = perf_event_get_enc(cpuc->events[idx]);
|
|
|
|
|
2012-08-17 18:14:01 +08:00
|
|
|
val = cpuc->pcr[pcr_index];
|
2009-09-30 12:27:06 +08:00
|
|
|
val &= ~mask;
|
2012-10-17 04:05:25 +08:00
|
|
|
val |= event_encoding(enc, idx);
|
2012-08-17 18:14:01 +08:00
|
|
|
cpuc->pcr[pcr_index] = val;
|
2009-09-30 12:27:06 +08:00
|
|
|
|
2012-08-17 18:14:01 +08:00
|
|
|
pcr_ops->write_pcr(pcr_index, cpuc->pcr[pcr_index]);
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
2009-09-30 12:27:06 +08:00
|
|
|
static inline void sparc_pmu_disable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
|
|
|
u64 mask = mask_for_index(idx);
|
|
|
|
u64 nop = nop_for_index(idx);
|
2012-08-17 18:14:01 +08:00
|
|
|
int pcr_index = 0;
|
2009-09-30 12:27:06 +08:00
|
|
|
u64 val;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2012-08-17 18:14:01 +08:00
|
|
|
if (sparc_pmu->num_pcrs > 1)
|
|
|
|
pcr_index = idx;
|
|
|
|
|
|
|
|
val = cpuc->pcr[pcr_index];
|
2009-09-30 12:27:06 +08:00
|
|
|
val &= ~mask;
|
|
|
|
val |= nop;
|
2012-08-17 18:14:01 +08:00
|
|
|
cpuc->pcr[pcr_index] = val;
|
2009-09-30 12:27:06 +08:00
|
|
|
|
2012-08-17 18:14:01 +08:00
|
|
|
pcr_ops->write_pcr(pcr_index, cpuc->pcr[pcr_index]);
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
static u64 sparc_perf_event_update(struct perf_event *event,
|
|
|
|
struct hw_perf_event *hwc, int idx)
|
|
|
|
{
|
|
|
|
int shift = 64 - 32;
|
|
|
|
u64 prev_raw_count, new_raw_count;
|
|
|
|
s64 delta;
|
|
|
|
|
|
|
|
again:
|
2010-05-21 20:43:08 +08:00
|
|
|
prev_raw_count = local64_read(&hwc->prev_count);
|
2012-08-17 17:37:06 +08:00
|
|
|
new_raw_count = sparc_pmu->read_pmc(idx);
|
2010-01-20 18:59:47 +08:00
|
|
|
|
2010-05-21 20:43:08 +08:00
|
|
|
if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
|
2010-01-20 18:59:47 +08:00
|
|
|
new_raw_count) != prev_raw_count)
|
|
|
|
goto again;
|
|
|
|
|
|
|
|
delta = (new_raw_count << shift) - (prev_raw_count << shift);
|
|
|
|
delta >>= shift;
|
|
|
|
|
2010-05-21 20:43:08 +08:00
|
|
|
local64_add(delta, &event->count);
|
|
|
|
local64_sub(delta, &hwc->period_left);
|
2010-01-20 18:59:47 +08:00
|
|
|
|
|
|
|
return new_raw_count;
|
|
|
|
}
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
static int sparc_perf_event_set_period(struct perf_event *event,
|
2009-09-29 08:37:12 +08:00
|
|
|
struct hw_perf_event *hwc, int idx)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
2010-05-21 20:43:08 +08:00
|
|
|
s64 left = local64_read(&hwc->period_left);
|
2009-09-10 21:28:20 +08:00
|
|
|
s64 period = hwc->sample_period;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (unlikely(left <= -period)) {
|
|
|
|
left = period;
|
2010-05-21 20:43:08 +08:00
|
|
|
local64_set(&hwc->period_left, left);
|
2009-09-10 21:28:20 +08:00
|
|
|
hwc->last_period = period;
|
|
|
|
ret = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unlikely(left <= 0)) {
|
|
|
|
left += period;
|
2010-05-21 20:43:08 +08:00
|
|
|
local64_set(&hwc->period_left, left);
|
2009-09-10 21:28:20 +08:00
|
|
|
hwc->last_period = period;
|
|
|
|
ret = 1;
|
|
|
|
}
|
|
|
|
if (left > MAX_PERIOD)
|
|
|
|
left = MAX_PERIOD;
|
|
|
|
|
2010-05-21 20:43:08 +08:00
|
|
|
local64_set(&hwc->prev_count, (u64)-left);
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2012-08-17 17:37:06 +08:00
|
|
|
sparc_pmu->write_pmc(idx, (u64)(-left) & 0xffffffff);
|
2009-09-10 21:28:20 +08:00
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
perf_event_update_userpage(event);
|
2009-09-10 21:28:20 +08:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-08-17 18:29:05 +08:00
|
|
|
static void read_in_all_counters(struct cpu_hw_events *cpuc)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
2010-01-20 18:59:47 +08:00
|
|
|
int i;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
for (i = 0; i < cpuc->n_events; i++) {
|
|
|
|
struct perf_event *cp = cpuc->event[i];
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
if (cpuc->current_idx[i] != PIC_NO_INDEX &&
|
|
|
|
cpuc->current_idx[i] != cp->hw.idx) {
|
|
|
|
sparc_perf_event_update(cp, &cp->hw,
|
|
|
|
cpuc->current_idx[i]);
|
|
|
|
cpuc->current_idx[i] = PIC_NO_INDEX;
|
|
|
|
}
|
|
|
|
}
|
2012-08-17 18:29:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* On this PMU all PICs are programmed using a single PCR. Calculate
|
|
|
|
* the combined control register value.
|
|
|
|
*
|
|
|
|
* For such chips we require that all of the events have the same
|
|
|
|
* configuration, so just fetch the settings from the first entry.
|
|
|
|
*/
|
|
|
|
static void calculate_single_pcr(struct cpu_hw_events *cpuc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!cpuc->n_added)
|
|
|
|
goto out;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
/* Assign to counters all unassigned events. */
|
|
|
|
for (i = 0; i < cpuc->n_events; i++) {
|
|
|
|
struct perf_event *cp = cpuc->event[i];
|
|
|
|
struct hw_perf_event *hwc = &cp->hw;
|
|
|
|
int idx = hwc->idx;
|
|
|
|
u64 enc;
|
|
|
|
|
|
|
|
if (cpuc->current_idx[i] != PIC_NO_INDEX)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
sparc_perf_event_set_period(cp, hwc, idx);
|
|
|
|
cpuc->current_idx[i] = idx;
|
|
|
|
|
|
|
|
enc = perf_event_get_enc(cpuc->events[i]);
|
2012-08-17 18:29:05 +08:00
|
|
|
cpuc->pcr[0] &= ~mask_for_index(idx);
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
if (hwc->state & PERF_HES_STOPPED)
|
2012-08-17 18:29:05 +08:00
|
|
|
cpuc->pcr[0] |= nop_for_index(idx);
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
else
|
2012-08-17 18:29:05 +08:00
|
|
|
cpuc->pcr[0] |= event_encoding(enc, idx);
|
2010-01-20 18:59:47 +08:00
|
|
|
}
|
|
|
|
out:
|
2012-08-17 18:29:05 +08:00
|
|
|
cpuc->pcr[0] |= cpuc->event[0]->hw.config_base;
|
|
|
|
}
|
|
|
|
|
2015-03-20 04:06:17 +08:00
|
|
|
static void sparc_pmu_start(struct perf_event *event, int flags);
|
|
|
|
|
2012-08-17 18:29:05 +08:00
|
|
|
/* On this PMU each PIC has it's own PCR control register. */
|
|
|
|
static void calculate_multiple_pcrs(struct cpu_hw_events *cpuc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!cpuc->n_added)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
for (i = 0; i < cpuc->n_events; i++) {
|
|
|
|
struct perf_event *cp = cpuc->event[i];
|
|
|
|
struct hw_perf_event *hwc = &cp->hw;
|
|
|
|
int idx = hwc->idx;
|
|
|
|
|
|
|
|
if (cpuc->current_idx[i] != PIC_NO_INDEX)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
cpuc->current_idx[i] = idx;
|
|
|
|
|
2015-03-20 04:06:17 +08:00
|
|
|
sparc_pmu_start(cp, PERF_EF_RELOAD);
|
2012-08-17 18:29:05 +08:00
|
|
|
}
|
|
|
|
out:
|
|
|
|
for (i = 0; i < cpuc->n_events; i++) {
|
|
|
|
struct perf_event *cp = cpuc->event[i];
|
|
|
|
int idx = cp->hw.idx;
|
|
|
|
|
|
|
|
cpuc->pcr[idx] |= cp->hw.config_base;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If performance event entries have been added, move existing events
|
|
|
|
* around (if necessary) and then assign new entries to counters.
|
|
|
|
*/
|
|
|
|
static void update_pcrs_for_enable(struct cpu_hw_events *cpuc)
|
|
|
|
{
|
|
|
|
if (cpuc->n_added)
|
|
|
|
read_in_all_counters(cpuc);
|
|
|
|
|
|
|
|
if (sparc_pmu->num_pcrs == 1) {
|
|
|
|
calculate_single_pcr(cpuc);
|
|
|
|
} else {
|
|
|
|
calculate_multiple_pcrs(cpuc);
|
|
|
|
}
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
static void sparc_pmu_enable(struct pmu *pmu)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
2012-08-17 18:29:05 +08:00
|
|
|
int i;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
if (cpuc->enabled)
|
|
|
|
return;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
cpuc->enabled = 1;
|
|
|
|
barrier();
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2012-08-17 18:29:05 +08:00
|
|
|
if (cpuc->n_events)
|
|
|
|
update_pcrs_for_enable(cpuc);
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2012-08-17 18:29:05 +08:00
|
|
|
for (i = 0; i < sparc_pmu->num_pcrs; i++)
|
|
|
|
pcr_ops->write_pcr(i, cpuc->pcr[i]);
|
2010-01-20 18:59:47 +08:00
|
|
|
}
|
|
|
|
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
static void sparc_pmu_disable(struct pmu *pmu)
|
2010-01-20 18:59:47 +08:00
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
2012-08-17 17:51:21 +08:00
|
|
|
int i;
|
2010-01-20 18:59:47 +08:00
|
|
|
|
|
|
|
if (!cpuc->enabled)
|
|
|
|
return;
|
|
|
|
|
|
|
|
cpuc->enabled = 0;
|
|
|
|
cpuc->n_added = 0;
|
|
|
|
|
2012-08-17 17:51:21 +08:00
|
|
|
for (i = 0; i < sparc_pmu->num_pcrs; i++) {
|
|
|
|
u64 val = cpuc->pcr[i];
|
2010-01-20 18:59:47 +08:00
|
|
|
|
2012-08-17 17:51:21 +08:00
|
|
|
val &= ~(sparc_pmu->user_bit | sparc_pmu->priv_bit |
|
|
|
|
sparc_pmu->hv_bit | sparc_pmu->irq_bit);
|
|
|
|
cpuc->pcr[i] = val;
|
|
|
|
pcr_ops->write_pcr(i, cpuc->pcr[i]);
|
|
|
|
}
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
static int active_event_index(struct cpu_hw_events *cpuc,
|
|
|
|
struct perf_event *event)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < cpuc->n_events; i++) {
|
|
|
|
if (cpuc->event[i] == event)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
BUG_ON(i == cpuc->n_events);
|
|
|
|
return cpuc->current_idx[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sparc_pmu_start(struct perf_event *event, int flags)
|
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
int idx = active_event_index(cpuc, event);
|
|
|
|
|
|
|
|
if (flags & PERF_EF_RELOAD) {
|
|
|
|
WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
|
|
|
|
sparc_perf_event_set_period(event, &event->hw, idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
event->hw.state = 0;
|
|
|
|
|
|
|
|
sparc_pmu_enable_event(cpuc, &event->hw, idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sparc_pmu_stop(struct perf_event *event, int flags)
|
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
int idx = active_event_index(cpuc, event);
|
|
|
|
|
|
|
|
if (!(event->hw.state & PERF_HES_STOPPED)) {
|
|
|
|
sparc_pmu_disable_event(cpuc, &event->hw, idx);
|
|
|
|
event->hw.state |= PERF_HES_STOPPED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(event->hw.state & PERF_HES_UPTODATE) && (flags & PERF_EF_UPDATE)) {
|
|
|
|
sparc_perf_event_update(event, &event->hw, idx);
|
|
|
|
event->hw.state |= PERF_HES_UPTODATE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sparc_pmu_del(struct perf_event *event, int _flags)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
2010-01-20 18:59:47 +08:00
|
|
|
unsigned long flags;
|
|
|
|
int i;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
local_irq_save(flags);
|
|
|
|
|
|
|
|
for (i = 0; i < cpuc->n_events; i++) {
|
|
|
|
if (event == cpuc->event[i]) {
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
/* Absorb the final count and turn off the
|
|
|
|
* event.
|
|
|
|
*/
|
|
|
|
sparc_pmu_stop(event, PERF_EF_UPDATE);
|
2010-01-20 18:59:47 +08:00
|
|
|
|
|
|
|
/* Shift remaining entries down into
|
|
|
|
* the existing slot.
|
|
|
|
*/
|
|
|
|
while (++i < cpuc->n_events) {
|
|
|
|
cpuc->event[i - 1] = cpuc->event[i];
|
|
|
|
cpuc->events[i - 1] = cpuc->events[i];
|
|
|
|
cpuc->current_idx[i - 1] =
|
|
|
|
cpuc->current_idx[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
perf_event_update_userpage(event);
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
cpuc->n_events--;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
local_irq_restore(flags);
|
|
|
|
}
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
static void sparc_pmu_read(struct perf_event *event)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
2010-01-20 18:59:47 +08:00
|
|
|
int idx = active_event_index(cpuc, event);
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
struct hw_perf_event *hwc = &event->hw;
|
2009-09-30 12:27:06 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
sparc_perf_event_update(event, hwc, idx);
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
static atomic_t active_events = ATOMIC_INIT(0);
|
2009-09-10 21:28:20 +08:00
|
|
|
static DEFINE_MUTEX(pmc_grab_mutex);
|
|
|
|
|
2009-09-30 12:27:06 +08:00
|
|
|
static void perf_stop_nmi_watchdog(void *unused)
|
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
2012-08-17 17:51:21 +08:00
|
|
|
int i;
|
2009-09-30 12:27:06 +08:00
|
|
|
|
|
|
|
stop_nmi_watchdog(NULL);
|
2012-08-17 17:51:21 +08:00
|
|
|
for (i = 0; i < sparc_pmu->num_pcrs; i++)
|
|
|
|
cpuc->pcr[i] = pcr_ops->read_pcr(i);
|
2009-09-30 12:27:06 +08:00
|
|
|
}
|
|
|
|
|
2014-05-17 05:26:04 +08:00
|
|
|
static void perf_event_grab_pmc(void)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
if (atomic_inc_not_zero(&active_events))
|
2009-09-10 21:28:20 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
mutex_lock(&pmc_grab_mutex);
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
if (atomic_read(&active_events) == 0) {
|
2009-09-10 21:28:20 +08:00
|
|
|
if (atomic_read(&nmi_active) > 0) {
|
2009-09-30 12:27:06 +08:00
|
|
|
on_each_cpu(perf_stop_nmi_watchdog, NULL, 1);
|
2009-09-10 21:28:20 +08:00
|
|
|
BUG_ON(atomic_read(&nmi_active) != 0);
|
|
|
|
}
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
atomic_inc(&active_events);
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
mutex_unlock(&pmc_grab_mutex);
|
|
|
|
}
|
|
|
|
|
2014-05-17 05:26:04 +08:00
|
|
|
static void perf_event_release_pmc(void)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
if (atomic_dec_and_mutex_lock(&active_events, &pmc_grab_mutex)) {
|
2009-09-10 21:28:20 +08:00
|
|
|
if (atomic_read(&nmi_active) == 0)
|
|
|
|
on_each_cpu(start_nmi_watchdog, NULL, 1);
|
|
|
|
mutex_unlock(&pmc_grab_mutex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-27 11:42:10 +08:00
|
|
|
static const struct perf_event_map *sparc_map_cache_event(u64 config)
|
|
|
|
{
|
|
|
|
unsigned int cache_type, cache_op, cache_result;
|
|
|
|
const struct perf_event_map *pmap;
|
|
|
|
|
|
|
|
if (!sparc_pmu->cache_map)
|
|
|
|
return ERR_PTR(-ENOENT);
|
|
|
|
|
|
|
|
cache_type = (config >> 0) & 0xff;
|
|
|
|
if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
|
|
|
|
cache_op = (config >> 8) & 0xff;
|
|
|
|
if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
|
|
|
|
cache_result = (config >> 16) & 0xff;
|
|
|
|
if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
|
|
|
|
pmap = &((*sparc_pmu->cache_map)[cache_type][cache_op][cache_result]);
|
|
|
|
|
|
|
|
if (pmap->encoding == CACHE_OP_UNSUPPORTED)
|
|
|
|
return ERR_PTR(-ENOENT);
|
|
|
|
|
|
|
|
if (pmap->encoding == CACHE_OP_NONSENSE)
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
|
|
|
|
return pmap;
|
|
|
|
}
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
static void hw_perf_event_destroy(struct perf_event *event)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
perf_event_release_pmc();
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
2009-09-29 08:35:20 +08:00
|
|
|
/* Make sure all events can be scheduled into the hardware at
|
|
|
|
* the same time. This is simplified by the fact that we only
|
|
|
|
* need to support 2 simultaneous HW events.
|
2010-01-20 18:59:47 +08:00
|
|
|
*
|
|
|
|
* As a side effect, the evts[]->hw.idx values will be assigned
|
|
|
|
* on success. These are pending indexes. When the events are
|
|
|
|
* actually programmed into the chip, these values will propagate
|
|
|
|
* to the per-cpu cpuc->current_idx[] slots, see the code in
|
|
|
|
* maybe_change_configuration() for details.
|
2009-09-29 08:35:20 +08:00
|
|
|
*/
|
2010-01-20 18:59:47 +08:00
|
|
|
static int sparc_check_constraints(struct perf_event **evts,
|
|
|
|
unsigned long *events, int n_ev)
|
2009-09-29 08:35:20 +08:00
|
|
|
{
|
2010-01-20 18:59:47 +08:00
|
|
|
u8 msk0 = 0, msk1 = 0;
|
|
|
|
int idx0 = 0;
|
|
|
|
|
|
|
|
/* This case is possible when we are invoked from
|
|
|
|
* hw_perf_group_sched_in().
|
|
|
|
*/
|
|
|
|
if (!n_ev)
|
|
|
|
return 0;
|
|
|
|
|
2012-08-17 17:33:44 +08:00
|
|
|
if (n_ev > sparc_pmu->max_hw_events)
|
2010-01-20 18:59:47 +08:00
|
|
|
return -1;
|
|
|
|
|
2012-08-17 17:31:10 +08:00
|
|
|
if (!(sparc_pmu->flags & SPARC_PMU_HAS_CONFLICTS)) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < n_ev; i++)
|
|
|
|
evts[i]->hw.idx = i;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
msk0 = perf_event_get_msk(events[0]);
|
|
|
|
if (n_ev == 1) {
|
|
|
|
if (msk0 & PIC_LOWER)
|
|
|
|
idx0 = 1;
|
|
|
|
goto success;
|
|
|
|
}
|
|
|
|
BUG_ON(n_ev != 2);
|
|
|
|
msk1 = perf_event_get_msk(events[1]);
|
|
|
|
|
|
|
|
/* If both events can go on any counter, OK. */
|
|
|
|
if (msk0 == (PIC_UPPER | PIC_LOWER) &&
|
|
|
|
msk1 == (PIC_UPPER | PIC_LOWER))
|
|
|
|
goto success;
|
|
|
|
|
|
|
|
/* If one event is limited to a specific counter,
|
|
|
|
* and the other can go on both, OK.
|
|
|
|
*/
|
|
|
|
if ((msk0 == PIC_UPPER || msk0 == PIC_LOWER) &&
|
|
|
|
msk1 == (PIC_UPPER | PIC_LOWER)) {
|
|
|
|
if (msk0 & PIC_LOWER)
|
|
|
|
idx0 = 1;
|
|
|
|
goto success;
|
2009-09-29 08:35:20 +08:00
|
|
|
}
|
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) &&
|
|
|
|
msk0 == (PIC_UPPER | PIC_LOWER)) {
|
|
|
|
if (msk1 & PIC_UPPER)
|
|
|
|
idx0 = 1;
|
|
|
|
goto success;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If the events are fixed to different counters, OK. */
|
|
|
|
if ((msk0 == PIC_UPPER && msk1 == PIC_LOWER) ||
|
|
|
|
(msk0 == PIC_LOWER && msk1 == PIC_UPPER)) {
|
|
|
|
if (msk0 & PIC_LOWER)
|
|
|
|
idx0 = 1;
|
|
|
|
goto success;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, there is a conflict. */
|
2009-09-29 08:35:20 +08:00
|
|
|
return -1;
|
2010-01-20 18:59:47 +08:00
|
|
|
|
|
|
|
success:
|
|
|
|
evts[0]->hw.idx = idx0;
|
|
|
|
if (n_ev == 2)
|
|
|
|
evts[1]->hw.idx = idx0 ^ 1;
|
|
|
|
return 0;
|
2009-09-29 08:35:20 +08:00
|
|
|
}
|
|
|
|
|
2009-09-28 11:43:07 +08:00
|
|
|
static int check_excludes(struct perf_event **evts, int n_prev, int n_new)
|
|
|
|
{
|
|
|
|
int eu = 0, ek = 0, eh = 0;
|
|
|
|
struct perf_event *event;
|
|
|
|
int i, n, first;
|
|
|
|
|
2012-08-17 17:31:10 +08:00
|
|
|
if (!(sparc_pmu->flags & SPARC_PMU_ALL_EXCLUDES_SAME))
|
|
|
|
return 0;
|
|
|
|
|
2009-09-28 11:43:07 +08:00
|
|
|
n = n_prev + n_new;
|
|
|
|
if (n <= 1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
first = 1;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
event = evts[i];
|
|
|
|
if (first) {
|
|
|
|
eu = event->attr.exclude_user;
|
|
|
|
ek = event->attr.exclude_kernel;
|
|
|
|
eh = event->attr.exclude_hv;
|
|
|
|
first = 0;
|
|
|
|
} else if (event->attr.exclude_user != eu ||
|
|
|
|
event->attr.exclude_kernel != ek ||
|
|
|
|
event->attr.exclude_hv != eh) {
|
|
|
|
return -EAGAIN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int collect_events(struct perf_event *group, int max_count,
|
2010-01-20 18:59:47 +08:00
|
|
|
struct perf_event *evts[], unsigned long *events,
|
|
|
|
int *current_idx)
|
2009-09-28 11:43:07 +08:00
|
|
|
{
|
|
|
|
struct perf_event *event;
|
|
|
|
int n = 0;
|
|
|
|
|
|
|
|
if (!is_software_event(group)) {
|
|
|
|
if (n >= max_count)
|
|
|
|
return -1;
|
|
|
|
evts[n] = group;
|
2010-01-20 18:59:47 +08:00
|
|
|
events[n] = group->hw.event_base;
|
|
|
|
current_idx[n++] = PIC_NO_INDEX;
|
2009-09-28 11:43:07 +08:00
|
|
|
}
|
|
|
|
list_for_each_entry(event, &group->sibling_list, group_entry) {
|
|
|
|
if (!is_software_event(event) &&
|
|
|
|
event->state != PERF_EVENT_STATE_OFF) {
|
|
|
|
if (n >= max_count)
|
|
|
|
return -1;
|
|
|
|
evts[n] = event;
|
2010-01-20 18:59:47 +08:00
|
|
|
events[n] = event->hw.event_base;
|
|
|
|
current_idx[n++] = PIC_NO_INDEX;
|
2009-09-28 11:43:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
static int sparc_pmu_add(struct perf_event *event, int ef_flags)
|
2010-01-20 18:59:47 +08:00
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
2010-01-20 18:59:47 +08:00
|
|
|
int n0, ret = -EAGAIN;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
local_irq_save(flags);
|
|
|
|
|
|
|
|
n0 = cpuc->n_events;
|
2012-08-17 17:33:44 +08:00
|
|
|
if (n0 >= sparc_pmu->max_hw_events)
|
2010-01-20 18:59:47 +08:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
cpuc->event[n0] = event;
|
|
|
|
cpuc->events[n0] = event->hw.event_base;
|
|
|
|
cpuc->current_idx[n0] = PIC_NO_INDEX;
|
|
|
|
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
event->hw.state = PERF_HES_UPTODATE;
|
|
|
|
if (!(ef_flags & PERF_EF_START))
|
|
|
|
event->hw.state |= PERF_HES_STOPPED;
|
|
|
|
|
2010-04-23 13:56:33 +08:00
|
|
|
/*
|
|
|
|
* If group events scheduling transaction was started,
|
2011-03-31 09:57:33 +08:00
|
|
|
* skip the schedulability test here, it will be performed
|
2010-04-23 13:56:33 +08:00
|
|
|
* at commit time(->commit_txn) as a whole
|
|
|
|
*/
|
2015-09-04 11:07:53 +08:00
|
|
|
if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
|
2010-04-23 13:56:33 +08:00
|
|
|
goto nocheck;
|
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
if (check_excludes(cpuc->event, n0, 1))
|
|
|
|
goto out;
|
|
|
|
if (sparc_check_constraints(cpuc->event, cpuc->events, n0 + 1))
|
|
|
|
goto out;
|
|
|
|
|
2010-04-23 13:56:33 +08:00
|
|
|
nocheck:
|
2010-01-20 18:59:47 +08:00
|
|
|
cpuc->n_events++;
|
|
|
|
cpuc->n_added++;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
out:
|
|
|
|
local_irq_restore(flags);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-06-11 19:35:08 +08:00
|
|
|
static int sparc_pmu_event_init(struct perf_event *event)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
struct perf_event_attr *attr = &event->attr;
|
2009-09-28 11:43:07 +08:00
|
|
|
struct perf_event *evts[MAX_HWEVENTS];
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
struct hw_perf_event *hwc = &event->hw;
|
2009-09-29 08:35:20 +08:00
|
|
|
unsigned long events[MAX_HWEVENTS];
|
2010-01-20 18:59:47 +08:00
|
|
|
int current_idx_dmy[MAX_HWEVENTS];
|
2009-09-10 21:28:20 +08:00
|
|
|
const struct perf_event_map *pmap;
|
2009-09-28 11:43:07 +08:00
|
|
|
int n;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
|
|
|
if (atomic_read(&nmi_active) < 0)
|
|
|
|
return -ENODEV;
|
|
|
|
|
2012-02-10 06:20:59 +08:00
|
|
|
/* does not support taken branch sampling */
|
|
|
|
if (has_branch_stack(event))
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
2010-06-11 19:35:08 +08:00
|
|
|
switch (attr->type) {
|
|
|
|
case PERF_TYPE_HARDWARE:
|
2009-09-27 11:42:10 +08:00
|
|
|
if (attr->config >= sparc_pmu->max_events)
|
|
|
|
return -EINVAL;
|
|
|
|
pmap = sparc_pmu->event_map(attr->config);
|
2010-06-11 19:35:08 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PERF_TYPE_HW_CACHE:
|
2009-09-27 11:42:10 +08:00
|
|
|
pmap = sparc_map_cache_event(attr->config);
|
|
|
|
if (IS_ERR(pmap))
|
|
|
|
return PTR_ERR(pmap);
|
2010-06-11 19:35:08 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PERF_TYPE_RAW:
|
2010-09-23 14:02:09 +08:00
|
|
|
pmap = NULL;
|
|
|
|
break;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2010-06-11 19:35:08 +08:00
|
|
|
default:
|
|
|
|
return -ENOENT;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-09-13 08:20:24 +08:00
|
|
|
if (pmap) {
|
|
|
|
hwc->event_base = perf_event_encode(pmap);
|
|
|
|
} else {
|
2010-09-23 14:02:09 +08:00
|
|
|
/*
|
|
|
|
* User gives us "(encoding << 16) | pic_mask" for
|
2010-09-13 08:20:24 +08:00
|
|
|
* PERF_TYPE_RAW events.
|
|
|
|
*/
|
|
|
|
hwc->event_base = attr->config;
|
|
|
|
}
|
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
/* We save the enable bits in the config_base. */
|
2009-09-10 22:10:59 +08:00
|
|
|
hwc->config_base = sparc_pmu->irq_bit;
|
2009-09-10 21:28:20 +08:00
|
|
|
if (!attr->exclude_user)
|
2012-08-17 17:41:32 +08:00
|
|
|
hwc->config_base |= sparc_pmu->user_bit;
|
2009-09-10 21:28:20 +08:00
|
|
|
if (!attr->exclude_kernel)
|
2012-08-17 17:41:32 +08:00
|
|
|
hwc->config_base |= sparc_pmu->priv_bit;
|
2009-09-10 22:09:06 +08:00
|
|
|
if (!attr->exclude_hv)
|
|
|
|
hwc->config_base |= sparc_pmu->hv_bit;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2009-09-28 11:43:07 +08:00
|
|
|
n = 0;
|
|
|
|
if (event->group_leader != event) {
|
|
|
|
n = collect_events(event->group_leader,
|
2012-08-17 17:33:44 +08:00
|
|
|
sparc_pmu->max_hw_events - 1,
|
2010-01-20 18:59:47 +08:00
|
|
|
evts, events, current_idx_dmy);
|
2009-09-28 11:43:07 +08:00
|
|
|
if (n < 0)
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2009-09-29 08:35:20 +08:00
|
|
|
events[n] = hwc->event_base;
|
2009-09-28 11:43:07 +08:00
|
|
|
evts[n] = event;
|
|
|
|
|
|
|
|
if (check_excludes(evts, n, 1))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
if (sparc_check_constraints(evts, events, n + 1))
|
2009-09-29 08:35:20 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
hwc->idx = PIC_NO_INDEX;
|
|
|
|
|
2009-09-28 11:43:07 +08:00
|
|
|
/* Try to do all error checking before this point, as unwinding
|
|
|
|
* state after grabbing the PMC is difficult.
|
|
|
|
*/
|
|
|
|
perf_event_grab_pmc();
|
|
|
|
event->destroy = hw_perf_event_destroy;
|
|
|
|
|
2009-09-10 21:28:20 +08:00
|
|
|
if (!hwc->sample_period) {
|
|
|
|
hwc->sample_period = MAX_PERIOD;
|
|
|
|
hwc->last_period = hwc->sample_period;
|
2010-05-21 20:43:08 +08:00
|
|
|
local64_set(&hwc->period_left, hwc->sample_period);
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-04-23 13:56:33 +08:00
|
|
|
/*
|
|
|
|
* Start group events scheduling transaction
|
|
|
|
* Set the flag to make pmu::enable() not perform the
|
|
|
|
* schedulability test, it will be performed at commit time
|
|
|
|
*/
|
2015-09-04 11:07:45 +08:00
|
|
|
static void sparc_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
|
2010-04-23 13:56:33 +08:00
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
|
2010-04-23 13:56:33 +08:00
|
|
|
|
2015-09-04 11:07:45 +08:00
|
|
|
WARN_ON_ONCE(cpuhw->txn_flags); /* txn already in flight */
|
|
|
|
|
|
|
|
cpuhw->txn_flags = txn_flags;
|
|
|
|
if (txn_flags & ~PERF_PMU_TXN_ADD)
|
|
|
|
return;
|
|
|
|
|
2010-06-14 14:49:00 +08:00
|
|
|
perf_pmu_disable(pmu);
|
2010-04-23 13:56:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Stop group events scheduling transaction
|
|
|
|
* Clear the flag and pmu::enable() will perform the
|
|
|
|
* schedulability test.
|
|
|
|
*/
|
2010-06-11 19:35:57 +08:00
|
|
|
static void sparc_pmu_cancel_txn(struct pmu *pmu)
|
2010-04-23 13:56:33 +08:00
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
|
2015-09-04 11:07:45 +08:00
|
|
|
unsigned int txn_flags;
|
|
|
|
|
|
|
|
WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
|
|
|
|
|
|
|
|
txn_flags = cpuhw->txn_flags;
|
|
|
|
cpuhw->txn_flags = 0;
|
|
|
|
if (txn_flags & ~PERF_PMU_TXN_ADD)
|
|
|
|
return;
|
2010-04-23 13:56:33 +08:00
|
|
|
|
2010-06-14 14:49:00 +08:00
|
|
|
perf_pmu_enable(pmu);
|
2010-04-23 13:56:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Commit group events scheduling transaction
|
|
|
|
* Perform the group schedulability test as a whole
|
|
|
|
* Return 0 if success
|
|
|
|
*/
|
2010-06-11 19:35:57 +08:00
|
|
|
static int sparc_pmu_commit_txn(struct pmu *pmu)
|
2010-04-23 13:56:33 +08:00
|
|
|
{
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
2010-04-23 13:56:33 +08:00
|
|
|
int n;
|
|
|
|
|
|
|
|
if (!sparc_pmu)
|
|
|
|
return -EINVAL;
|
|
|
|
|
2015-09-04 11:07:45 +08:00
|
|
|
WARN_ON_ONCE(!cpuc->txn_flags); /* no txn in flight */
|
|
|
|
|
|
|
|
if (cpuc->txn_flags & ~PERF_PMU_TXN_ADD) {
|
|
|
|
cpuc->txn_flags = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-04-23 13:56:33 +08:00
|
|
|
n = cpuc->n_events;
|
|
|
|
if (check_excludes(cpuc->event, 0, n))
|
|
|
|
return -EINVAL;
|
|
|
|
if (sparc_check_constraints(cpuc->event, cpuc->events, n))
|
|
|
|
return -EAGAIN;
|
|
|
|
|
2015-09-04 11:07:45 +08:00
|
|
|
cpuc->txn_flags = 0;
|
2010-06-14 14:49:00 +08:00
|
|
|
perf_pmu_enable(pmu);
|
2010-04-23 13:56:33 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-11 19:35:57 +08:00
|
|
|
static struct pmu pmu = {
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
.pmu_enable = sparc_pmu_enable,
|
|
|
|
.pmu_disable = sparc_pmu_disable,
|
2010-06-11 19:35:08 +08:00
|
|
|
.event_init = sparc_pmu_event_init,
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
.add = sparc_pmu_add,
|
|
|
|
.del = sparc_pmu_del,
|
|
|
|
.start = sparc_pmu_start,
|
|
|
|
.stop = sparc_pmu_stop,
|
2009-09-10 21:28:20 +08:00
|
|
|
.read = sparc_pmu_read,
|
2010-04-23 13:56:33 +08:00
|
|
|
.start_txn = sparc_pmu_start_txn,
|
|
|
|
.cancel_txn = sparc_pmu_cancel_txn,
|
|
|
|
.commit_txn = sparc_pmu_commit_txn,
|
2009-09-10 21:28:20 +08:00
|
|
|
};
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
void perf_event_print_debug(void)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2012-08-17 17:51:21 +08:00
|
|
|
int cpu, i;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
|
|
|
if (!sparc_pmu)
|
|
|
|
return;
|
|
|
|
|
|
|
|
local_irq_save(flags);
|
|
|
|
|
|
|
|
cpu = smp_processor_id();
|
|
|
|
|
|
|
|
pr_info("\n");
|
2012-08-17 17:51:21 +08:00
|
|
|
for (i = 0; i < sparc_pmu->num_pcrs; i++)
|
|
|
|
pr_info("CPU#%d: PCR%d[%016llx]\n",
|
|
|
|
cpu, i, pcr_ops->read_pcr(i));
|
|
|
|
for (i = 0; i < sparc_pmu->num_pic_regs; i++)
|
|
|
|
pr_info("CPU#%d: PIC%d[%016llx]\n",
|
|
|
|
cpu, i, pcr_ops->read_pic(i));
|
2009-09-10 21:28:20 +08:00
|
|
|
|
|
|
|
local_irq_restore(flags);
|
|
|
|
}
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
|
2009-09-29 08:37:12 +08:00
|
|
|
unsigned long cmd, void *__args)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
|
|
|
struct die_args *args = __args;
|
|
|
|
struct perf_sample_data data;
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
struct cpu_hw_events *cpuc;
|
2009-09-10 21:28:20 +08:00
|
|
|
struct pt_regs *regs;
|
2010-01-20 18:59:47 +08:00
|
|
|
int i;
|
2009-09-10 21:28:20 +08:00
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
if (!atomic_read(&active_events))
|
2009-09-10 21:28:20 +08:00
|
|
|
return NOTIFY_DONE;
|
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
case DIE_NMI:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return NOTIFY_DONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
regs = args->regs;
|
|
|
|
|
sparc: Replace __get_cpu_var uses
__get_cpu_var() is used for multiple purposes in the kernel source. One of
them is address calculation via the form &__get_cpu_var(x). This calculates
the address for the instance of the percpu variable of the current processor
based on an offset.
Other use cases are for storing and retrieving data from the current
processors percpu area. __get_cpu_var() can be used as an lvalue when
writing data or on the right side of an assignment.
__get_cpu_var() is defined as :
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
__get_cpu_var() always only does an address determination. However, store
and retrieve operations could use a segment prefix (or global register on
other platforms) to avoid the address calculation.
this_cpu_write() and this_cpu_read() can directly take an offset into a
percpu area and use optimized assembly code to read and write per cpu
variables.
This patch converts __get_cpu_var into either an explicit address
calculation using this_cpu_ptr() or into a use of this_cpu operations that
use the offset. Thereby address calculations are avoided and less registers
are used when code is generated.
At the end of the patch set all uses of __get_cpu_var have been removed so
the macro is removed too.
The patch set includes passes over all arches as well. Once these operations
are used throughout then specialized macros can be defined in non -x86
arches as well in order to optimize per cpu access by f.e. using a global
register that may be set to the per cpu base.
Transformations done to __get_cpu_var()
1. Determine the address of the percpu instance of the current processor.
DEFINE_PER_CPU(int, y);
int *x = &__get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(&y);
2. Same as #1 but this time an array structure is involved.
DEFINE_PER_CPU(int, y[20]);
int *x = __get_cpu_var(y);
Converts to
int *x = this_cpu_ptr(y);
3. Retrieve the content of the current processors instance of a per cpu
variable.
DEFINE_PER_CPU(int, y);
int x = __get_cpu_var(y)
Converts to
int x = __this_cpu_read(y);
4. Retrieve the content of a percpu struct
DEFINE_PER_CPU(struct mystruct, y);
struct mystruct x = __get_cpu_var(y);
Converts to
memcpy(&x, this_cpu_ptr(&y), sizeof(x));
5. Assignment to a per cpu variable
DEFINE_PER_CPU(int, y)
__get_cpu_var(y) = x;
Converts to
__this_cpu_write(y, x);
6. Increment/Decrement etc of a per cpu variable
DEFINE_PER_CPU(int, y);
__get_cpu_var(y)++
Converts to
__this_cpu_inc(y)
Cc: sparclinux@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2014-08-18 01:30:54 +08:00
|
|
|
cpuc = this_cpu_ptr(&cpu_hw_events);
|
2010-01-05 15:16:03 +08:00
|
|
|
|
|
|
|
/* If the PMU has the TOE IRQ enable bits, we need to do a
|
|
|
|
* dummy write to the %pcr to clear the overflow bits and thus
|
|
|
|
* the interrupt.
|
|
|
|
*
|
|
|
|
* Do this before we peek at the counters to determine
|
|
|
|
* overflow so we don't lose any events.
|
|
|
|
*/
|
2012-08-17 17:51:21 +08:00
|
|
|
if (sparc_pmu->irq_bit &&
|
|
|
|
sparc_pmu->num_pcrs == 1)
|
|
|
|
pcr_ops->write_pcr(0, cpuc->pcr[0]);
|
2010-01-05 15:16:03 +08:00
|
|
|
|
2010-01-20 18:59:47 +08:00
|
|
|
for (i = 0; i < cpuc->n_events; i++) {
|
|
|
|
struct perf_event *event = cpuc->event[i];
|
|
|
|
int idx = cpuc->current_idx[i];
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
struct hw_perf_event *hwc;
|
2009-09-10 21:28:20 +08:00
|
|
|
u64 val;
|
|
|
|
|
2012-08-17 17:51:21 +08:00
|
|
|
if (sparc_pmu->irq_bit &&
|
|
|
|
sparc_pmu->num_pcrs > 1)
|
|
|
|
pcr_ops->write_pcr(idx, cpuc->pcr[idx]);
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
hwc = &event->hw;
|
|
|
|
val = sparc_perf_event_update(event, hwc, idx);
|
2009-09-10 21:28:20 +08:00
|
|
|
if (val & (1ULL << 31))
|
|
|
|
continue;
|
|
|
|
|
2012-04-03 02:19:08 +08:00
|
|
|
perf_sample_data_init(&data, 0, hwc->last_period);
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
if (!sparc_perf_event_set_period(event, hwc, idx))
|
2009-09-10 21:28:20 +08:00
|
|
|
continue;
|
|
|
|
|
2011-06-27 20:41:57 +08:00
|
|
|
if (perf_event_overflow(event, &data, regs))
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
sparc_pmu_stop(event, 0);
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return NOTIFY_STOP;
|
|
|
|
}
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
static __read_mostly struct notifier_block perf_event_nmi_notifier = {
|
|
|
|
.notifier_call = perf_event_nmi_handler,
|
2009-09-10 21:28:20 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static bool __init supported_pmu(void)
|
|
|
|
{
|
2009-09-27 11:54:22 +08:00
|
|
|
if (!strcmp(sparc_pmu_type, "ultra3") ||
|
|
|
|
!strcmp(sparc_pmu_type, "ultra3+") ||
|
|
|
|
!strcmp(sparc_pmu_type, "ultra3i") ||
|
|
|
|
!strcmp(sparc_pmu_type, "ultra4+")) {
|
|
|
|
sparc_pmu = &ultra3_pmu;
|
2009-09-10 21:28:20 +08:00
|
|
|
return true;
|
|
|
|
}
|
2009-09-27 12:23:41 +08:00
|
|
|
if (!strcmp(sparc_pmu_type, "niagara")) {
|
|
|
|
sparc_pmu = &niagara1_pmu;
|
|
|
|
return true;
|
|
|
|
}
|
sparc: Detect and handle UltraSPARC-T3 cpu types.
The cpu compatible string we look for is "SPARC-T3".
As far as memset/memcpy optimizations go, we treat this chip the same
as Niagara-T2/T2+. Use cache initializing stores for memset, and use
perfetch, FPU block loads, cache initializing stores, and block stores
for copies.
We use the Niagara-T2 perf support, since T3 is a close relative in
this regard. Later we'll add support for the new events T3 can
report, plus enable T3's new "sample" mode.
For now I haven't added any new ELF hwcap flags. We probably need
to add a couple, for example:
T2 and T3 both support the population count instruction in hardware.
T3 supports VIS3 instructions, including support (finally) for
partitioned shift. One can also now move directly between float
and integer registers.
T3 supports instructions meant to help with Galois Field and other HPC
calculations, such as XOR multiply. Also there are "OP and negate"
instructions, for example "fnmul" which is multiply-and-negate.
T3 recognizes the transactional memory opcodes, however since
transactional memory isn't supported: 1) 'commit' behaves as a NOP and
2) 'chkpt' always branches 3) 'rdcps' returns all zeros and 4) 'wrcps'
behaves as a NOP.
So we'll need about 3 new elf capability flags in the end to represent
all of these things.
Signed-off-by: David S. Miller <davem@davemloft.net>
2011-07-28 12:06:16 +08:00
|
|
|
if (!strcmp(sparc_pmu_type, "niagara2") ||
|
|
|
|
!strcmp(sparc_pmu_type, "niagara3")) {
|
2009-09-10 22:22:18 +08:00
|
|
|
sparc_pmu = &niagara2_pmu;
|
|
|
|
return true;
|
|
|
|
}
|
2014-09-16 22:09:06 +08:00
|
|
|
if (!strcmp(sparc_pmu_type, "niagara4") ||
|
|
|
|
!strcmp(sparc_pmu_type, "niagara5")) {
|
2012-08-18 14:06:09 +08:00
|
|
|
sparc_pmu = &niagara4_pmu;
|
|
|
|
return true;
|
|
|
|
}
|
2015-03-20 04:06:37 +08:00
|
|
|
if (!strcmp(sparc_pmu_type, "sparc-m7")) {
|
|
|
|
sparc_pmu = &sparc_m7_pmu;
|
|
|
|
return true;
|
|
|
|
}
|
2009-09-10 21:28:20 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-05-17 05:26:04 +08:00
|
|
|
static int __init init_hw_perf_events(void)
|
2009-09-10 21:28:20 +08:00
|
|
|
{
|
2014-08-12 06:38:46 +08:00
|
|
|
int err;
|
|
|
|
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
pr_info("Performance events: ");
|
2009-09-10 21:28:20 +08:00
|
|
|
|
2014-08-12 06:38:46 +08:00
|
|
|
err = pcr_arch_init();
|
|
|
|
if (err || !supported_pmu()) {
|
2009-09-10 21:28:20 +08:00
|
|
|
pr_cont("No support for PMU type '%s'\n", sparc_pmu_type);
|
2010-11-26 01:38:29 +08:00
|
|
|
return 0;
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type);
|
|
|
|
|
2010-11-18 06:17:36 +08:00
|
|
|
perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
|
perf: Do the big rename: Performance Counters -> Performance Events
Bye-bye Performance Counters, welcome Performance Events!
In the past few months the perfcounters subsystem has grown out its
initial role of counting hardware events, and has become (and is
becoming) a much broader generic event enumeration, reporting, logging,
monitoring, analysis facility.
Naming its core object 'perf_counter' and naming the subsystem
'perfcounters' has become more and more of a misnomer. With pending
code like hw-breakpoints support the 'counter' name is less and
less appropriate.
All in one, we've decided to rename the subsystem to 'performance
events' and to propagate this rename through all fields, variables
and API names. (in an ABI compatible fashion)
The word 'event' is also a bit shorter than 'counter' - which makes
it slightly more convenient to write/handle as well.
Thanks goes to Stephane Eranian who first observed this misnomer and
suggested a rename.
User-space tooling and ABI compatibility is not affected - this patch
should be function-invariant. (Also, defconfigs were not touched to
keep the size down.)
This patch has been generated via the following script:
FILES=$(find * -type f | grep -vE 'oprofile|[^K]config')
sed -i \
-e 's/PERF_EVENT_/PERF_RECORD_/g' \
-e 's/PERF_COUNTER/PERF_EVENT/g' \
-e 's/perf_counter/perf_event/g' \
-e 's/nb_counters/nb_events/g' \
-e 's/swcounter/swevent/g' \
-e 's/tpcounter_event/tp_event/g' \
$FILES
for N in $(find . -name perf_counter.[ch]); do
M=$(echo $N | sed 's/perf_counter/perf_event/g')
mv $N $M
done
FILES=$(find . -name perf_event.*)
sed -i \
-e 's/COUNTER_MASK/REG_MASK/g' \
-e 's/COUNTER/EVENT/g' \
-e 's/\<event\>/event_id/g' \
-e 's/counter/event/g' \
-e 's/Counter/Event/g' \
$FILES
... to keep it as correct as possible. This script can also be
used by anyone who has pending perfcounters patches - it converts
a Linux kernel tree over to the new naming. We tried to time this
change to the point in time where the amount of pending patches
is the smallest: the end of the merge window.
Namespace clashes were fixed up in a preparatory patch - and some
stylistic fallout will be fixed up in a subsequent patch.
( NOTE: 'counters' are still the proper terminology when we deal
with hardware registers - and these sed scripts are a bit
over-eager in renaming them. I've undone some of that, but
in case there's something left where 'counter' would be
better than 'event' we can undo that on an individual basis
instead of touching an otherwise nicely automated patch. )
Suggested-by: Stephane Eranian <eranian@google.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Paul Mackerras <paulus@samba.org>
Reviewed-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-09-21 18:02:48 +08:00
|
|
|
register_die_notifier(&perf_event_nmi_notifier);
|
2010-11-26 01:38:29 +08:00
|
|
|
|
|
|
|
return 0;
|
2009-09-10 21:28:20 +08:00
|
|
|
}
|
2014-08-12 06:38:46 +08:00
|
|
|
pure_initcall(init_hw_perf_events);
|
2010-01-19 16:26:13 +08:00
|
|
|
|
2016-04-28 23:30:53 +08:00
|
|
|
void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
|
2010-07-01 05:03:51 +08:00
|
|
|
struct pt_regs *regs)
|
2010-01-19 16:26:13 +08:00
|
|
|
{
|
|
|
|
unsigned long ksp, fp;
|
2010-04-21 18:08:11 +08:00
|
|
|
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
|
|
|
int graph = 0;
|
|
|
|
#endif
|
2010-01-19 16:26:13 +08:00
|
|
|
|
2010-07-01 05:03:51 +08:00
|
|
|
stack_trace_flush();
|
|
|
|
|
2010-06-30 01:34:05 +08:00
|
|
|
perf_callchain_store(entry, regs->tpc);
|
2010-01-19 16:26:13 +08:00
|
|
|
|
|
|
|
ksp = regs->u_regs[UREG_I6];
|
|
|
|
fp = ksp + STACK_BIAS;
|
|
|
|
do {
|
|
|
|
struct sparc_stackf *sf;
|
|
|
|
struct pt_regs *regs;
|
|
|
|
unsigned long pc;
|
|
|
|
|
|
|
|
if (!kstack_valid(current_thread_info(), fp))
|
|
|
|
break;
|
|
|
|
|
|
|
|
sf = (struct sparc_stackf *) fp;
|
|
|
|
regs = (struct pt_regs *) (sf + 1);
|
|
|
|
|
|
|
|
if (kstack_is_trap_frame(current_thread_info(), regs)) {
|
|
|
|
if (user_mode(regs))
|
|
|
|
break;
|
|
|
|
pc = regs->tpc;
|
|
|
|
fp = regs->u_regs[UREG_I6] + STACK_BIAS;
|
|
|
|
} else {
|
|
|
|
pc = sf->callers_pc;
|
|
|
|
fp = (unsigned long)sf->fp + STACK_BIAS;
|
|
|
|
}
|
2010-06-30 01:34:05 +08:00
|
|
|
perf_callchain_store(entry, pc);
|
2010-04-21 18:08:11 +08:00
|
|
|
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
|
|
|
if ((pc + 8UL) == (unsigned long) &return_to_handler) {
|
|
|
|
int index = current->curr_ret_stack;
|
|
|
|
if (current->ret_stack && index >= graph) {
|
|
|
|
pc = current->ret_stack[index - graph].ret;
|
2010-06-30 01:34:05 +08:00
|
|
|
perf_callchain_store(entry, pc);
|
2010-04-21 18:08:11 +08:00
|
|
|
graph++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
perf core: Add a 'nr' field to perf_event_callchain_context
We will use it to count how many addresses are in the entry->ip[] array,
excluding PERF_CONTEXT_{KERNEL,USER,etc} entries, so that we can really
return the number of entries specified by the user via the relevant
sysctl, kernel.perf_event_max_contexts, or via the per event
perf_event_attr.sample_max_stack knob.
This way we keep the perf_sample->ip_callchain->nr meaning, that is the
number of entries, be it real addresses or PERF_CONTEXT_ entries, while
honouring the max_stack knobs, i.e. the end result will be max_stack
entries if we have at least that many entries in a given stack trace.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/n/tip-s8teto51tdqvlfhefndtat9r@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-11 05:08:32 +08:00
|
|
|
} while (entry->nr < entry->max_stack);
|
2010-01-19 16:26:13 +08:00
|
|
|
}
|
|
|
|
|
2015-06-16 04:15:45 +08:00
|
|
|
static inline int
|
|
|
|
valid_user_frame(const void __user *fp, unsigned long size)
|
|
|
|
{
|
|
|
|
/* addresses should be at least 4-byte aligned */
|
|
|
|
if (((unsigned long) fp) & 3)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return (__range_not_ok(fp, size, TASK_SIZE) == 0);
|
|
|
|
}
|
|
|
|
|
2016-04-28 23:30:53 +08:00
|
|
|
static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
|
2010-07-01 05:03:51 +08:00
|
|
|
struct pt_regs *regs)
|
2010-01-19 16:26:13 +08:00
|
|
|
{
|
|
|
|
unsigned long ufp;
|
|
|
|
|
2015-06-16 04:15:46 +08:00
|
|
|
ufp = regs->u_regs[UREG_FP] + STACK_BIAS;
|
2010-01-19 16:26:13 +08:00
|
|
|
do {
|
2014-05-17 05:26:04 +08:00
|
|
|
struct sparc_stackf __user *usf;
|
|
|
|
struct sparc_stackf sf;
|
2010-01-19 16:26:13 +08:00
|
|
|
unsigned long pc;
|
|
|
|
|
2014-05-17 05:26:04 +08:00
|
|
|
usf = (struct sparc_stackf __user *)ufp;
|
2015-06-16 04:15:45 +08:00
|
|
|
if (!valid_user_frame(usf, sizeof(sf)))
|
|
|
|
break;
|
|
|
|
|
2010-01-19 16:26:13 +08:00
|
|
|
if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
|
|
|
|
break;
|
|
|
|
|
|
|
|
pc = sf.callers_pc;
|
|
|
|
ufp = (unsigned long)sf.fp + STACK_BIAS;
|
2010-06-30 01:34:05 +08:00
|
|
|
perf_callchain_store(entry, pc);
|
perf core: Add a 'nr' field to perf_event_callchain_context
We will use it to count how many addresses are in the entry->ip[] array,
excluding PERF_CONTEXT_{KERNEL,USER,etc} entries, so that we can really
return the number of entries specified by the user via the relevant
sysctl, kernel.perf_event_max_contexts, or via the per event
perf_event_attr.sample_max_stack knob.
This way we keep the perf_sample->ip_callchain->nr meaning, that is the
number of entries, be it real addresses or PERF_CONTEXT_ entries, while
honouring the max_stack knobs, i.e. the end result will be max_stack
entries if we have at least that many entries in a given stack trace.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/n/tip-s8teto51tdqvlfhefndtat9r@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-11 05:08:32 +08:00
|
|
|
} while (entry->nr < entry->max_stack);
|
2010-01-19 16:26:13 +08:00
|
|
|
}
|
|
|
|
|
2016-04-28 23:30:53 +08:00
|
|
|
static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
|
2010-07-01 05:03:51 +08:00
|
|
|
struct pt_regs *regs)
|
2010-01-19 16:26:13 +08:00
|
|
|
{
|
|
|
|
unsigned long ufp;
|
|
|
|
|
2015-06-16 04:15:46 +08:00
|
|
|
ufp = regs->u_regs[UREG_FP] & 0xffffffffUL;
|
2010-01-19 16:26:13 +08:00
|
|
|
do {
|
|
|
|
unsigned long pc;
|
|
|
|
|
sparc64: Make montmul/montsqr/mpmul usable in 32-bit threads.
The Montgomery Multiply, Montgomery Square, and Multiple-Precision
Multiply instructions work by loading a combination of the floating
point and multiple register windows worth of integer registers
with the inputs.
These values are 64-bit. But for 32-bit userland processes we only
save the low 32-bits of each integer register during a register spill.
This is because the register window save area is in the user stack and
has a fixed layout.
Therefore, the only way to use these instruction in 32-bit mode is to
perform the following sequence:
1) Load the top-32bits of a choosen integer register with a sentinel,
say "-1". This will be in the outer-most register window.
The idea is that we're trying to see if the outer-most register
window gets spilled, and thus the 64-bit values were truncated.
2) Load all the inputs for the montmul/montsqr/mpmul instruction,
down to the inner-most register window.
3) Execute the opcode.
4) Traverse back up to the outer-most register window.
5) Check the sentinel, if it's still "-1" store the results.
Otherwise retry the entire sequence.
This retry is extremely troublesome. If you're just unlucky and an
interrupt or other trap happens, it'll push that outer-most window to
the stack and clear the sentinel when we restore it.
We could retry forever and never make forward progress if interrupts
arrive at a fast enough rate (consider perf events as one example).
So we have do limited retries and fallback to software which is
extremely non-deterministic.
Luckily it's very straightforward to provide a mechanism to let
32-bit applications use a 64-bit stack. Stacks in 64-bit mode are
biased by 2047 bytes, which means that the lowest bit is set in the
actual %sp register value.
So if we see bit zero set in a 32-bit application's stack we treat
it like a 64-bit stack.
Runtime detection of such a facility is tricky, and cumbersome at
best. For example, just trying to use a biased stack and seeing if it
works is hard to recover from (the signal handler will need to use an
alt stack, plus something along the lines of longjmp). Therefore, we
add a system call to report a bitmask of arch specific features like
this in a cheap and less hairy way.
With help from Andy Polyakov.
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-10-27 06:18:37 +08:00
|
|
|
if (thread32_stack_is_64bit(ufp)) {
|
2014-05-17 05:26:04 +08:00
|
|
|
struct sparc_stackf __user *usf;
|
|
|
|
struct sparc_stackf sf;
|
2010-01-19 16:26:13 +08:00
|
|
|
|
sparc64: Make montmul/montsqr/mpmul usable in 32-bit threads.
The Montgomery Multiply, Montgomery Square, and Multiple-Precision
Multiply instructions work by loading a combination of the floating
point and multiple register windows worth of integer registers
with the inputs.
These values are 64-bit. But for 32-bit userland processes we only
save the low 32-bits of each integer register during a register spill.
This is because the register window save area is in the user stack and
has a fixed layout.
Therefore, the only way to use these instruction in 32-bit mode is to
perform the following sequence:
1) Load the top-32bits of a choosen integer register with a sentinel,
say "-1". This will be in the outer-most register window.
The idea is that we're trying to see if the outer-most register
window gets spilled, and thus the 64-bit values were truncated.
2) Load all the inputs for the montmul/montsqr/mpmul instruction,
down to the inner-most register window.
3) Execute the opcode.
4) Traverse back up to the outer-most register window.
5) Check the sentinel, if it's still "-1" store the results.
Otherwise retry the entire sequence.
This retry is extremely troublesome. If you're just unlucky and an
interrupt or other trap happens, it'll push that outer-most window to
the stack and clear the sentinel when we restore it.
We could retry forever and never make forward progress if interrupts
arrive at a fast enough rate (consider perf events as one example).
So we have do limited retries and fallback to software which is
extremely non-deterministic.
Luckily it's very straightforward to provide a mechanism to let
32-bit applications use a 64-bit stack. Stacks in 64-bit mode are
biased by 2047 bytes, which means that the lowest bit is set in the
actual %sp register value.
So if we see bit zero set in a 32-bit application's stack we treat
it like a 64-bit stack.
Runtime detection of such a facility is tricky, and cumbersome at
best. For example, just trying to use a biased stack and seeing if it
works is hard to recover from (the signal handler will need to use an
alt stack, plus something along the lines of longjmp). Therefore, we
add a system call to report a bitmask of arch specific features like
this in a cheap and less hairy way.
With help from Andy Polyakov.
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-10-27 06:18:37 +08:00
|
|
|
ufp += STACK_BIAS;
|
2014-05-17 05:26:04 +08:00
|
|
|
usf = (struct sparc_stackf __user *)ufp;
|
sparc64: Make montmul/montsqr/mpmul usable in 32-bit threads.
The Montgomery Multiply, Montgomery Square, and Multiple-Precision
Multiply instructions work by loading a combination of the floating
point and multiple register windows worth of integer registers
with the inputs.
These values are 64-bit. But for 32-bit userland processes we only
save the low 32-bits of each integer register during a register spill.
This is because the register window save area is in the user stack and
has a fixed layout.
Therefore, the only way to use these instruction in 32-bit mode is to
perform the following sequence:
1) Load the top-32bits of a choosen integer register with a sentinel,
say "-1". This will be in the outer-most register window.
The idea is that we're trying to see if the outer-most register
window gets spilled, and thus the 64-bit values were truncated.
2) Load all the inputs for the montmul/montsqr/mpmul instruction,
down to the inner-most register window.
3) Execute the opcode.
4) Traverse back up to the outer-most register window.
5) Check the sentinel, if it's still "-1" store the results.
Otherwise retry the entire sequence.
This retry is extremely troublesome. If you're just unlucky and an
interrupt or other trap happens, it'll push that outer-most window to
the stack and clear the sentinel when we restore it.
We could retry forever and never make forward progress if interrupts
arrive at a fast enough rate (consider perf events as one example).
So we have do limited retries and fallback to software which is
extremely non-deterministic.
Luckily it's very straightforward to provide a mechanism to let
32-bit applications use a 64-bit stack. Stacks in 64-bit mode are
biased by 2047 bytes, which means that the lowest bit is set in the
actual %sp register value.
So if we see bit zero set in a 32-bit application's stack we treat
it like a 64-bit stack.
Runtime detection of such a facility is tricky, and cumbersome at
best. For example, just trying to use a biased stack and seeing if it
works is hard to recover from (the signal handler will need to use an
alt stack, plus something along the lines of longjmp). Therefore, we
add a system call to report a bitmask of arch specific features like
this in a cheap and less hairy way.
With help from Andy Polyakov.
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-10-27 06:18:37 +08:00
|
|
|
if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
|
|
|
|
break;
|
|
|
|
pc = sf.callers_pc & 0xffffffff;
|
|
|
|
ufp = ((unsigned long) sf.fp) & 0xffffffff;
|
|
|
|
} else {
|
2014-05-17 05:26:04 +08:00
|
|
|
struct sparc_stackf32 __user *usf;
|
|
|
|
struct sparc_stackf32 sf;
|
|
|
|
usf = (struct sparc_stackf32 __user *)ufp;
|
sparc64: Make montmul/montsqr/mpmul usable in 32-bit threads.
The Montgomery Multiply, Montgomery Square, and Multiple-Precision
Multiply instructions work by loading a combination of the floating
point and multiple register windows worth of integer registers
with the inputs.
These values are 64-bit. But for 32-bit userland processes we only
save the low 32-bits of each integer register during a register spill.
This is because the register window save area is in the user stack and
has a fixed layout.
Therefore, the only way to use these instruction in 32-bit mode is to
perform the following sequence:
1) Load the top-32bits of a choosen integer register with a sentinel,
say "-1". This will be in the outer-most register window.
The idea is that we're trying to see if the outer-most register
window gets spilled, and thus the 64-bit values were truncated.
2) Load all the inputs for the montmul/montsqr/mpmul instruction,
down to the inner-most register window.
3) Execute the opcode.
4) Traverse back up to the outer-most register window.
5) Check the sentinel, if it's still "-1" store the results.
Otherwise retry the entire sequence.
This retry is extremely troublesome. If you're just unlucky and an
interrupt or other trap happens, it'll push that outer-most window to
the stack and clear the sentinel when we restore it.
We could retry forever and never make forward progress if interrupts
arrive at a fast enough rate (consider perf events as one example).
So we have do limited retries and fallback to software which is
extremely non-deterministic.
Luckily it's very straightforward to provide a mechanism to let
32-bit applications use a 64-bit stack. Stacks in 64-bit mode are
biased by 2047 bytes, which means that the lowest bit is set in the
actual %sp register value.
So if we see bit zero set in a 32-bit application's stack we treat
it like a 64-bit stack.
Runtime detection of such a facility is tricky, and cumbersome at
best. For example, just trying to use a biased stack and seeing if it
works is hard to recover from (the signal handler will need to use an
alt stack, plus something along the lines of longjmp). Therefore, we
add a system call to report a bitmask of arch specific features like
this in a cheap and less hairy way.
With help from Andy Polyakov.
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-10-27 06:18:37 +08:00
|
|
|
if (__copy_from_user_inatomic(&sf, usf, sizeof(sf)))
|
|
|
|
break;
|
|
|
|
pc = sf.callers_pc;
|
|
|
|
ufp = (unsigned long)sf.fp;
|
|
|
|
}
|
2010-06-30 01:34:05 +08:00
|
|
|
perf_callchain_store(entry, pc);
|
perf core: Add a 'nr' field to perf_event_callchain_context
We will use it to count how many addresses are in the entry->ip[] array,
excluding PERF_CONTEXT_{KERNEL,USER,etc} entries, so that we can really
return the number of entries specified by the user via the relevant
sysctl, kernel.perf_event_max_contexts, or via the per event
perf_event_attr.sample_max_stack knob.
This way we keep the perf_sample->ip_callchain->nr meaning, that is the
number of entries, be it real addresses or PERF_CONTEXT_ entries, while
honouring the max_stack knobs, i.e. the end result will be max_stack
entries if we have at least that many entries in a given stack trace.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/n/tip-s8teto51tdqvlfhefndtat9r@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-11 05:08:32 +08:00
|
|
|
} while (entry->nr < entry->max_stack);
|
2010-01-19 16:26:13 +08:00
|
|
|
}
|
|
|
|
|
2010-07-01 05:03:51 +08:00
|
|
|
void
|
2016-04-28 23:30:53 +08:00
|
|
|
perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
|
2010-01-19 16:26:13 +08:00
|
|
|
{
|
2015-12-23 12:16:07 +08:00
|
|
|
u64 saved_fault_address = current_thread_info()->fault_address;
|
|
|
|
u8 saved_fault_code = get_thread_fault_code();
|
2015-12-23 12:16:06 +08:00
|
|
|
mm_segment_t old_fs;
|
|
|
|
|
2012-10-15 08:59:40 +08:00
|
|
|
perf_callchain_store(entry, regs->tpc);
|
|
|
|
|
|
|
|
if (!current->mm)
|
|
|
|
return;
|
|
|
|
|
2015-12-23 12:16:06 +08:00
|
|
|
old_fs = get_fs();
|
|
|
|
set_fs(USER_DS);
|
|
|
|
|
2010-07-01 05:03:51 +08:00
|
|
|
flushw_user();
|
2015-06-16 04:15:43 +08:00
|
|
|
|
|
|
|
pagefault_disable();
|
|
|
|
|
2010-07-01 05:03:51 +08:00
|
|
|
if (test_thread_flag(TIF_32BIT))
|
|
|
|
perf_callchain_user_32(entry, regs);
|
|
|
|
else
|
|
|
|
perf_callchain_user_64(entry, regs);
|
2015-06-16 04:15:43 +08:00
|
|
|
|
|
|
|
pagefault_enable();
|
2015-12-23 12:16:06 +08:00
|
|
|
|
|
|
|
set_fs(old_fs);
|
2015-12-23 12:16:07 +08:00
|
|
|
set_thread_fault_code(saved_fault_code);
|
|
|
|
current_thread_info()->fault_address = saved_fault_address;
|
2010-01-19 16:26:13 +08:00
|
|
|
}
|