From: Vineet Gupta <Vineet.Gupta1@synopsys.com>
To: Peter Zijlstra <peterz@infradead.org>,
Alexey Brodkin <Alexey.Brodkin@synopsys.com>
Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
Vineet.Gupta1@synopsys.com, arc-linux-dev@synopsys.com,
arnd@arndb.de, Arnaldo Carvalho de Melo <acme@kernel.org>
Subject: perf documentation (was Re: [PATCH v3 3/6] ARCv2: perf: Support sampling events using overflow interrupts)
Date: Mon, 19 Oct 2015 15:31:51 +0530 [thread overview]
Message-ID: <5624BF8F.1050006@synopsys.com> (raw)
In-Reply-To: <20150826142547.GK18673@twins.programming.kicks-ass.net>
On Wednesday 26 August 2015 07:55 PM, Peter Zijlstra wrote:
> On Wed, Aug 26, 2015 at 03:12:25PM +0200, Peter Zijlstra wrote:
>> On Mon, Aug 24, 2015 at 05:20:20PM +0300, Alexey Brodkin wrote:
>>> @@ -295,6 +317,16 @@ static int arc_pmu_add(struct perf_event *event, int flags)
>>> }
>>>
>>> write_aux_reg(ARC_REG_PCT_INDEX, idx);
>>> +
>>> + arc_pmu->act_counter[idx] = event;
>>> +
>>> + if (is_sampling_event(event)) {
>>> + /* Mimic full counter overflow as other arches do */
>>> + write_aux_reg(ARC_REG_PCT_INT_CNTL, (u32)arc_pmu->max_period);
>>> + write_aux_reg(ARC_REG_PCT_INT_CNTH,
>>> + (arc_pmu->max_period >> 32));
>>> + }
>>> +
>>
>> pmu::add should call pmu::start when PERF_EF_START, without that it
>> should not start the counter, only schedule it.
>>
>> (although currently all pmu::add() calls will have EF_START set)
>>
>>> write_aux_reg(ARC_REG_PCT_CONFIG, 0);
>>> write_aux_reg(ARC_REG_PCT_COUNTL, 0);
>>> write_aux_reg(ARC_REG_PCT_COUNTH, 0);
>
> Does the below clarify things a bit? If there's still some uncertainty
> please say what/where and I'll try and expand.
Peter this is awesome documentation and would be a shame to get lost in lkml
archives. Can it please make it's way into git :-)
>
>
>
> ---
> include/linux/perf_event.h | 100 +++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 87 insertions(+), 13 deletions(-)
>
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 2027809433b3..8f78a0b7bfe5 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -140,27 +140,60 @@ struct hw_perf_event {
> };
> #endif
> };
> + /*
> + * If the event is a per task event, this will point to the task in
> + * question. See the comment in perf_event_alloc().
> + */
> struct task_struct *target;
> +
> +/*
> + * hw_perf_event::state flags; used to track the PERF_EF_* state.
> + */
> +#define PERF_HES_STOPPED 0x01 /* the counter is stopped */
> +#define PERF_HES_UPTODATE 0x02 /* event->count up-to-date */
> +#define PERF_HES_ARCH 0x04
> +
> int state;
> +
> + /*
> + * The last observed hardware counter value, updated with a
> + * local64_cmpxchg() such that pmu::read() can be called nested.
> + */
> local64_t prev_count;
> +
> + /*
> + * The period to start the next sample with.
> + */
> u64 sample_period;
> +
> + /*
> + * The period we started this sample with.
> + */
> u64 last_period;
> +
> + /*
> + * However much is left of the current period; note that this is
> + * a full 64bit value and allows for generation of periods longer
> + * than hardware might allow.
> + */
> local64_t period_left;
> +
> + /*
> + * State for throttling the event, see __perf_event_overflow() and
> + * perf_adjust_freq_unthr_context().
> + */
> u64 interrupts_seq;
> u64 interrupts;
>
> + /*
> + * State for freq target events, see __perf_event_overflow() and
> + * perf_adjust_freq_unthr_context().
> + */
> u64 freq_time_stamp;
> u64 freq_count_stamp;
> #endif
> };
>
> -/*
> - * hw_perf_event::state flags
> - */
> -#define PERF_HES_STOPPED 0x01 /* the counter is stopped */
> -#define PERF_HES_UPTODATE 0x02 /* event->count up-to-date */
> -#define PERF_HES_ARCH 0x04
> -
> struct perf_event;
>
> /*
> @@ -210,7 +243,19 @@ struct pmu {
>
> /*
> * Try and initialize the event for this PMU.
> - * Should return -ENOENT when the @event doesn't match this PMU.
> + *
> + * Returns:
> + * -ENOENT -- @event is not for this PMU
> + *
> + * -ENODEV -- @event is for this PMU but PMU not present
> + * -EBUSY -- @event is for this PMU but PMU temporarily unavailable
> + * -EINVAL -- @event is for this PMU but @event is not valid
> + * -EOPNOTSUPP -- @event is for this PMU, @event is valid, but not supported
> + * -EACCESS -- @event is for this PMU, @event is valid, but no privilidges
> + *
> + * 0 -- @event is for this PMU and valid
> + *
> + * Other error return values are allowed.
> */
> int (*event_init) (struct perf_event *event);
>
> @@ -221,27 +266,56 @@ struct pmu {
> void (*event_mapped) (struct perf_event *event); /*optional*/
> void (*event_unmapped) (struct perf_event *event); /*optional*/
>
> + /*
> + * Flags for ->add()/->del()/ ->start()/->stop(). There are
> + * matching hw_perf_event::state flags.
> + */
> #define PERF_EF_START 0x01 /* start the counter when adding */
> #define PERF_EF_RELOAD 0x02 /* reload the counter when starting */
> #define PERF_EF_UPDATE 0x04 /* update the counter when stopping */
>
> /*
> - * Adds/Removes a counter to/from the PMU, can be done inside
> - * a transaction, see the ->*_txn() methods.
> + * Adds/Removes a counter to/from the PMU, can be done inside a
> + * transaction, see the ->*_txn() methods.
> + *
> + * The add/del callbacks will reserve all hardware resources required
> + * to service the event, this includes any counter constraint
> + * scheduling etc.
> + *
> + * Called with IRQs disabled and the PMU disabled.
> + *
> + * ->add() called without PERF_EF_START should result in the same state
> + * as ->add() followed by ->stop().
> + *
> + * ->del() must always PERF_EF_UPDATE stop an event. If it calls
> + * ->stop() that must deal with already being stopped without
> + * PERF_EF_UPDATE.
> */
> int (*add) (struct perf_event *event, int flags);
> void (*del) (struct perf_event *event, int flags);
>
> /*
> - * Starts/Stops a counter present on the PMU. The PMI handler
> - * should stop the counter when perf_event_overflow() returns
> - * !0. ->start() will be used to continue.
> + * Starts/Stops a counter present on the PMU.
> + *
> + * The PMI handler should stop the counter when perf_event_overflow()
> + * returns !0. ->start() will be used to continue.
> + *
> + * Also used to change the sample period.
> + *
> + * ->stop() with PERF_EF_UPDATE will read the counter and update
> + * period/count values like ->read() would.
> + *
> + * ->start() with PERF_EF_RELOAD will reprogram the the counter
> + * value, must be preceded by a ->stop() with PERF_EF_UPDATE.
> */
> void (*start) (struct perf_event *event, int flags);
> void (*stop) (struct perf_event *event, int flags);
>
> /*
> * Updates the counter value of the event.
> + *
> + * For sampling capable PMUs this will also update the software period
> + * hw_perf_event::period_left field.
> */
> void (*read) (struct perf_event *event);
>
>
WARNING: multiple messages have this Message-ID (diff)
From: Vineet Gupta <Vineet.Gupta1@synopsys.com>
To: Peter Zijlstra <peterz@infradead.org>,
Alexey Brodkin <Alexey.Brodkin@synopsys.com>
Cc: <linux-arch@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<Vineet.Gupta1@synopsys.com>, <arc-linux-dev@synopsys.com>,
<arnd@arndb.de>, Arnaldo Carvalho de Melo <acme@kernel.org>
Subject: perf documentation (was Re: [PATCH v3 3/6] ARCv2: perf: Support sampling events using overflow interrupts)
Date: Mon, 19 Oct 2015 15:31:51 +0530 [thread overview]
Message-ID: <5624BF8F.1050006@synopsys.com> (raw)
In-Reply-To: <20150826142547.GK18673@twins.programming.kicks-ass.net>
On Wednesday 26 August 2015 07:55 PM, Peter Zijlstra wrote:
> On Wed, Aug 26, 2015 at 03:12:25PM +0200, Peter Zijlstra wrote:
>> On Mon, Aug 24, 2015 at 05:20:20PM +0300, Alexey Brodkin wrote:
>>> @@ -295,6 +317,16 @@ static int arc_pmu_add(struct perf_event *event, int flags)
>>> }
>>>
>>> write_aux_reg(ARC_REG_PCT_INDEX, idx);
>>> +
>>> + arc_pmu->act_counter[idx] = event;
>>> +
>>> + if (is_sampling_event(event)) {
>>> + /* Mimic full counter overflow as other arches do */
>>> + write_aux_reg(ARC_REG_PCT_INT_CNTL, (u32)arc_pmu->max_period);
>>> + write_aux_reg(ARC_REG_PCT_INT_CNTH,
>>> + (arc_pmu->max_period >> 32));
>>> + }
>>> +
>>
>> pmu::add should call pmu::start when PERF_EF_START, without that it
>> should not start the counter, only schedule it.
>>
>> (although currently all pmu::add() calls will have EF_START set)
>>
>>> write_aux_reg(ARC_REG_PCT_CONFIG, 0);
>>> write_aux_reg(ARC_REG_PCT_COUNTL, 0);
>>> write_aux_reg(ARC_REG_PCT_COUNTH, 0);
>
> Does the below clarify things a bit? If there's still some uncertainty
> please say what/where and I'll try and expand.
Peter this is awesome documentation and would be a shame to get lost in lkml
archives. Can it please make it's way into git :-)
>
>
>
> ---
> include/linux/perf_event.h | 100 +++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 87 insertions(+), 13 deletions(-)
>
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 2027809433b3..8f78a0b7bfe5 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -140,27 +140,60 @@ struct hw_perf_event {
> };
> #endif
> };
> + /*
> + * If the event is a per task event, this will point to the task in
> + * question. See the comment in perf_event_alloc().
> + */
> struct task_struct *target;
> +
> +/*
> + * hw_perf_event::state flags; used to track the PERF_EF_* state.
> + */
> +#define PERF_HES_STOPPED 0x01 /* the counter is stopped */
> +#define PERF_HES_UPTODATE 0x02 /* event->count up-to-date */
> +#define PERF_HES_ARCH 0x04
> +
> int state;
> +
> + /*
> + * The last observed hardware counter value, updated with a
> + * local64_cmpxchg() such that pmu::read() can be called nested.
> + */
> local64_t prev_count;
> +
> + /*
> + * The period to start the next sample with.
> + */
> u64 sample_period;
> +
> + /*
> + * The period we started this sample with.
> + */
> u64 last_period;
> +
> + /*
> + * However much is left of the current period; note that this is
> + * a full 64bit value and allows for generation of periods longer
> + * than hardware might allow.
> + */
> local64_t period_left;
> +
> + /*
> + * State for throttling the event, see __perf_event_overflow() and
> + * perf_adjust_freq_unthr_context().
> + */
> u64 interrupts_seq;
> u64 interrupts;
>
> + /*
> + * State for freq target events, see __perf_event_overflow() and
> + * perf_adjust_freq_unthr_context().
> + */
> u64 freq_time_stamp;
> u64 freq_count_stamp;
> #endif
> };
>
> -/*
> - * hw_perf_event::state flags
> - */
> -#define PERF_HES_STOPPED 0x01 /* the counter is stopped */
> -#define PERF_HES_UPTODATE 0x02 /* event->count up-to-date */
> -#define PERF_HES_ARCH 0x04
> -
> struct perf_event;
>
> /*
> @@ -210,7 +243,19 @@ struct pmu {
>
> /*
> * Try and initialize the event for this PMU.
> - * Should return -ENOENT when the @event doesn't match this PMU.
> + *
> + * Returns:
> + * -ENOENT -- @event is not for this PMU
> + *
> + * -ENODEV -- @event is for this PMU but PMU not present
> + * -EBUSY -- @event is for this PMU but PMU temporarily unavailable
> + * -EINVAL -- @event is for this PMU but @event is not valid
> + * -EOPNOTSUPP -- @event is for this PMU, @event is valid, but not supported
> + * -EACCESS -- @event is for this PMU, @event is valid, but no privilidges
> + *
> + * 0 -- @event is for this PMU and valid
> + *
> + * Other error return values are allowed.
> */
> int (*event_init) (struct perf_event *event);
>
> @@ -221,27 +266,56 @@ struct pmu {
> void (*event_mapped) (struct perf_event *event); /*optional*/
> void (*event_unmapped) (struct perf_event *event); /*optional*/
>
> + /*
> + * Flags for ->add()/->del()/ ->start()/->stop(). There are
> + * matching hw_perf_event::state flags.
> + */
> #define PERF_EF_START 0x01 /* start the counter when adding */
> #define PERF_EF_RELOAD 0x02 /* reload the counter when starting */
> #define PERF_EF_UPDATE 0x04 /* update the counter when stopping */
>
> /*
> - * Adds/Removes a counter to/from the PMU, can be done inside
> - * a transaction, see the ->*_txn() methods.
> + * Adds/Removes a counter to/from the PMU, can be done inside a
> + * transaction, see the ->*_txn() methods.
> + *
> + * The add/del callbacks will reserve all hardware resources required
> + * to service the event, this includes any counter constraint
> + * scheduling etc.
> + *
> + * Called with IRQs disabled and the PMU disabled.
> + *
> + * ->add() called without PERF_EF_START should result in the same state
> + * as ->add() followed by ->stop().
> + *
> + * ->del() must always PERF_EF_UPDATE stop an event. If it calls
> + * ->stop() that must deal with already being stopped without
> + * PERF_EF_UPDATE.
> */
> int (*add) (struct perf_event *event, int flags);
> void (*del) (struct perf_event *event, int flags);
>
> /*
> - * Starts/Stops a counter present on the PMU. The PMI handler
> - * should stop the counter when perf_event_overflow() returns
> - * !0. ->start() will be used to continue.
> + * Starts/Stops a counter present on the PMU.
> + *
> + * The PMI handler should stop the counter when perf_event_overflow()
> + * returns !0. ->start() will be used to continue.
> + *
> + * Also used to change the sample period.
> + *
> + * ->stop() with PERF_EF_UPDATE will read the counter and update
> + * period/count values like ->read() would.
> + *
> + * ->start() with PERF_EF_RELOAD will reprogram the the counter
> + * value, must be preceded by a ->stop() with PERF_EF_UPDATE.
> */
> void (*start) (struct perf_event *event, int flags);
> void (*stop) (struct perf_event *event, int flags);
>
> /*
> * Updates the counter value of the event.
> + *
> + * For sampling capable PMUs this will also update the software period
> + * hw_perf_event::period_left field.
> */
> void (*read) (struct perf_event *event);
>
>
next prev parent reply other threads:[~2015-10-19 10:02 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-24 14:20 [PATCH v3 0/6] ARCv2 port to Linux - (C) perf Alexey Brodkin
2015-08-24 14:20 ` [PATCH v3 1/6] ARC: perf: cap the number of counters to hardware max of 32 Alexey Brodkin
2015-08-24 14:20 ` [PATCH v3 2/6] ARCv2: perf: implement "event_set_period" Alexey Brodkin
2015-08-24 14:20 ` [PATCH v3 3/6] ARCv2: perf: Support sampling events using overflow interrupts Alexey Brodkin
2015-08-26 13:07 ` Peter Zijlstra
2015-08-26 13:17 ` Alexey Brodkin
2015-08-26 14:35 ` Peter Zijlstra
2015-08-26 14:42 ` [arc-linux-dev] " Alexey Brodkin
2015-08-26 13:12 ` Peter Zijlstra
2015-08-26 13:21 ` Alexey Brodkin
2015-08-26 14:32 ` Peter Zijlstra
2015-08-26 14:35 ` Alexey Brodkin
2015-08-26 14:25 ` Peter Zijlstra
2015-10-19 10:01 ` Vineet Gupta [this message]
2015-10-19 10:01 ` perf documentation (was Re: [PATCH v3 3/6] ARCv2: perf: Support sampling events using overflow interrupts) Vineet Gupta
2015-10-19 10:12 ` Peter Zijlstra
2015-08-24 14:20 ` [PATCH v3 4/6] ARCv2: perf: implement exclusion of event counting in user or kernel mode Alexey Brodkin
2015-08-24 14:30 ` Vineet Gupta
2015-08-24 16:38 ` Vineet Gupta
2015-08-24 14:20 ` [PATCH v3 5/6] ARCv2: perf: SMP support Alexey Brodkin
2015-08-24 14:20 ` [PATCH v3 6/6] ARCv2: perf: Finally introduce HS perf unit Alexey Brodkin
2015-08-26 12:07 ` [PATCH v3 0/6] ARCv2 port to Linux - (C) perf Alexey Brodkin
2015-08-27 6:58 ` [arc-linux-dev] " Alexey Brodkin
2015-08-27 7:14 ` Vineet Gupta
2015-08-27 9:18 ` Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5624BF8F.1050006@synopsys.com \
--to=vineet.gupta1@synopsys.com \
--cc=Alexey.Brodkin@synopsys.com \
--cc=acme@kernel.org \
--cc=arc-linux-dev@synopsys.com \
--cc=arnd@arndb.de \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.