1. 06 4月, 2009 6 次提交
  2. 05 3月, 2009 1 次提交
  3. 04 3月, 2009 1 次提交
    • P
      perfcounters: provide expansion room in the ABI · 2743a5b0
      Paul Mackerras 提交于
      Impact: ABI change
      
      This expands several fields in the perf_counter_hw_event struct and adds
      a "flags" argument to the perf_counter_open system call, in order that
      features can be added in future without ABI changes.
      
      In particular the record_type field is expanded to 64 bits, and the
      space for flag bits has been expanded from 32 to 64 bits.
      
      This also adds some new fields:
      
      * read_format (64 bits) is intended to provide a way to specify what
        userspace wants to get back when it does a read() on a simple
        (non-interrupting) counter;
      
      * exclude_idle (1 bit) provides a way for userspace to ask that events
        that occur when the cpu is idle be excluded;
      
      * extra_config_len will provide a way for userspace to supply an
        arbitrary amount of extra machine-specific PMU configuration data
        immediately following the perf_counter_hw_event struct, to allow
        sophisticated users to program things such as instruction matching
        CAMs and address range registers;
      
      * __reserved_3 and __reserved_4 provide space for future expansion.
      Signed-off-by: NPaul Mackerras <paulus@samba.org>
      2743a5b0
  4. 26 2月, 2009 1 次提交
    • P
      perfcounters: fix a few minor cleanliness issues · f3dfd265
      Paul Mackerras 提交于
      This fixes three issues noticed by Arnd Bergmann:
      
      - Add #ifdef __KERNEL__ and move some things around in perf_counter.h
        to make sure only the bits that userspace needs are exported to
        userspace.
      
      - Use __u64, __s64, __u32 types in the structs exported to userspace
        rather than u64, s64, u32.
      
      - Make the sys_perf_counter_open syscall available to the SPUs on
        Cell platforms.
      
      And one issue that I noticed in looking at the code again:
      
      - Wrap the perf_counter_open syscall with SYSCALL_DEFINE4 so we get
        the proper handling of int arguments on ppc64 (and some other 64-bit
        architectures).
      Reported-by: NArnd Bergmann <arnd@arndb.de>
      Signed-off-by: NPaul Mackerras <paulus@samba.org>
      f3dfd265
  5. 13 2月, 2009 1 次提交
    • P
      perfcounters: make context switch and migration software counters work again · c07c99b6
      Paul Mackerras 提交于
      Jaswinder Singh Rajput reported that commit 23a185ca caused the
      context switch and migration software counters to report zero always.
      With that commit, the software counters only count events that occur
      between sched-in and sched-out for a task.  This is necessary for the
      counter enable/disable prctls and ioctls to work.  However, the
      context switch and migration counts are incremented after sched-out
      for one task and before sched-in for the next.  Since the increment
      doesn't occur while a task is scheduled in (as far as the software
      counters are concerned) it doesn't count towards any counter.
      
      Thus the context switch and migration counters need to count events
      that occur at any time, provided the counter is enabled, not just
      those that occur while the task is scheduled in (from the perf_counter
      subsystem's point of view).  The problem though is that the software
      counter code can't tell the difference between being enabled and being
      scheduled in, and between being disabled and being scheduled out,
      since we use the one pair of enable/disable entry points for both.
      That is, the high-level disable operation simply arranges for the
      counter to not be scheduled in any more, and the high-level enable
      operation arranges for it to be scheduled in again.
      
      One way to solve this would be to have sched_in/out operations in the
      hw_perf_counter_ops struct as well as enable/disable.  However, this
      takes a simpler approach: it adds a 'prev_state' field to the
      perf_counter struct that allows a counter's enable method to know
      whether the counter was previously disabled or just inactive
      (scheduled out), and therefore whether the enable method is being
      called as a result of a high-level enable or a schedule-in operation.
      
      This then allows the context switch, migration and page fault counters
      to reset their hw.prev_count value in their enable functions only if
      they are called as a result of a high-level enable operation.
      Although page faults would normally only occur while the counter is
      scheduled in, this changes the page fault counter code too in case
      there are ever circumstances where page faults get counted against a
      task while its counters are not scheduled in.
      Reported-by: NJaswinder Singh Rajput <jaswinder@kernel.org>
      Signed-off-by: NPaul Mackerras <paulus@samba.org>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      c07c99b6
  6. 11 2月, 2009 1 次提交
    • P
      perf_counters: allow users to count user, kernel and/or hypervisor events · 0475f9ea
      Paul Mackerras 提交于
      Impact: new perf_counter feature
      
      This extends the perf_counter_hw_event struct with bits that specify
      that events in user, kernel and/or hypervisor mode should not be
      counted (i.e. should be excluded), and adds code to program the PMU
      mode selection bits accordingly on x86 and powerpc.
      
      For software counters, we don't currently have the infrastructure to
      distinguish which mode an event occurs in, so we currently fail the
      counter initialization if the setting of the hw_event.exclude_* bits
      would require us to distinguish.  Context switches and CPU migrations
      are currently considered to occur in kernel mode.
      
      On x86, this changes the previous policy that only root can count
      kernel events.  Now non-root users can count kernel events or exclude
      them.  Non-root users still can't use NMI events, though.  On x86 we
      don't appear to have any way to control whether hypervisor events are
      counted or not, so hw_event.exclude_hv is ignored.
      
      On powerpc, the selection of whether to count events in user, kernel
      and/or hypervisor mode is PMU-wide, not per-counter, so this adds a
      check that the hw_event.exclude_* settings are the same as other events
      on the PMU.  Counters being added to a group have to have the same
      settings as the other hardware counters in the group.  Counters and
      groups can only be enabled in hw_perf_group_sched_in or power_perf_enable
      if they have the same settings as any other counters already on the
      PMU.  If we are not running on a hypervisor, the exclude_hv setting
      is ignored (by forcing it to 0) since we can't ever get any
      hypervisor events.
      Signed-off-by: NPaul Mackerras <paulus@samba.org>
      0475f9ea
  7. 23 1月, 2009 2 次提交
  8. 17 1月, 2009 1 次提交
    • P
      perf_counter: Add counter enable/disable ioctls · d859e29f
      Paul Mackerras 提交于
      Impact: New perf_counter features
      
      This primarily adds a way for perf_counter users to enable and disable
      counters and groups.  Enabling or disabling a counter or group also
      enables or disables all of the child counters that have been cloned
      from it to monitor children of the task monitored by the top-level
      counter.  The userspace interface to enable/disable counters is via
      ioctl on the counter file descriptor.
      
      Along the way this extends the code that handles child counters to
      handle child counter groups properly.  A group with multiple counters
      will be cloned to child tasks if and only if the group leader has the
      hw_event.inherit bit set - if it is set the whole group is cloned as a
      group in the child task.
      
      In order to be able to enable or disable all child counters of a given
      top-level counter, we need a way to find them all.  Hence I have added
      a child_list field to struct perf_counter, which is the head of the
      list of children for a top-level counter, or the link in that list for
      a child counter.  That list is protected by the perf_counter.mutex
      field.
      
      This also adds a mutex to the perf_counter_context struct.  Previously
      the list of counters was protected just by the lock field in the
      context, which meant that perf_counter_init_task had to take that lock
      and then take whatever lock/mutex protects the top-level counter's
      child_list.  But the counter enable/disable functions need to take
      that lock in order to traverse the list, then for each counter take
      the lock in that counter's context in order to change the counter's
      state safely, which will lead to a deadlock.
      
      To solve this, we now have both a mutex and a spinlock in the context,
      and taking either is sufficient to ensure the list of counters can't
      change - you have to take both before changing the list.  Now
      perf_counter_init_task takes the mutex instead of the lock (which
      incidentally means that inherit_counter can use GFP_KERNEL instead of
      GFP_ATOMIC) and thus avoids the possible deadlock.  Similarly the new
      enable/disable functions can take the mutex while traversing the list
      of child counters without incurring a possible deadlock when the
      counter manipulation code locks the context for a child counter.
      
      We also had an misfeature that the first counter added to a context
      would possibly not go on until the next sched-in, because we were
      using ctx->nr_active to detect if the context was running on a CPU.
      But nr_active is the number of active counters, and if that was zero
      (because the context didn't have any counters yet) it would look like
      the context wasn't running on a cpu and so the retry code in
      __perf_install_in_context wouldn't retry.  So this adds an 'is_active'
      field that is set when the context is on a CPU, even if it has no
      counters.  The is_active field is only used for task contexts, not for
      per-cpu contexts.
      
      If we enable a subsidiary counter in a group that is active on a CPU,
      and the arch code can't enable the counter, then we have to pull the
      whole group off the CPU.  We do this with group_sched_out, which gets
      moved up in the file so it comes before all its callers.  This also
      adds similar logic to __perf_install_in_context so that the "all on,
      or none" invariant of groups is preserved when adding a new counter to
      a group.
      Signed-off-by: NPaul Mackerras <paulus@samba.org>
      d859e29f
  9. 14 1月, 2009 1 次提交
    • P
      perf_counter: Add support for pinned and exclusive counter groups · 3b6f9e5c
      Paul Mackerras 提交于
      Impact: New perf_counter features
      
      A pinned counter group is one that the user wants to have on the CPU
      whenever possible, i.e. whenever the associated task is running, for
      a per-task group, or always for a per-cpu group.  If the system
      cannot satisfy that, it puts the group into an error state where
      it is not scheduled any more and reads from it return EOF (i.e. 0
      bytes read).  The group can be released from error state and made
      readable again using prctl(PR_TASK_PERF_COUNTERS_ENABLE).  When we
      have finer-grained enable/disable controls on counters we'll be able
      to reset the error state on individual groups.
      
      An exclusive group is one that the user wants to be the only group
      using the CPU performance monitor hardware whenever it is on.  The
      counter group scheduler will not schedule an exclusive group if there
      are already other groups on the CPU and will not schedule other groups
      onto the CPU if there is an exclusive group scheduled (that statement
      does not apply to groups containing only software counters, which can
      always go on and which do not prevent an exclusive group from going on).
      With an exclusive group, we will be able to let users program PMU
      registers at a low level without the concern that those settings will
      perturb other measurements.
      
      Along the way this reorganizes things a little:
      - is_software_counter() is moved to perf_counter.h.
      - cpuctx->active_oncpu now records the number of hardware counters on
        the CPU, i.e. it now excludes software counters.  Nothing was reading
        cpuctx->active_oncpu before, so this change is harmless.
      - A new cpuctx->exclusive field records whether we currently have an
        exclusive group on the CPU.
      - counter_sched_out moves higher up in perf_counter.c and gets called
        from __perf_counter_remove_from_context and __perf_counter_exit_task,
        where we used to have essentially the same code.
      - __perf_counter_sched_in now goes through the counter list twice, doing
        the pinned counters in the first loop and the non-pinned counters in
        the second loop, in order to give the pinned counters the best chance
        to be scheduled in.
      
      Note that only a group leader can be exclusive or pinned, and that
      attribute applies to the whole group.  This avoids some awkwardness in
      some corner cases (e.g. where a group leader is closed and the other
      group members get added to the context list).  If we want to relax that
      restriction later, we can, and it is easier to relax a restriction than
      to apply a new one.
      
      This doesn't yet handle the case where a pinned counter is inherited
      and goes into error state in the child - the error state is not
      propagated up to the parent when the child exits, and arguably it
      should.
      Signed-off-by: NPaul Mackerras <paulus@samba.org>
      3b6f9e5c
  10. 09 1月, 2009 1 次提交
    • P
      perf_counter: Add optional hw_perf_group_sched_in arch function · 3cbed429
      Paul Mackerras 提交于
      Impact: extend perf_counter infrastructure
      
      This adds an optional hw_perf_group_sched_in() arch function that enables
      a whole group of counters in one go.  It returns 1 if it added the group
      successfully, 0 if it did nothing (and therefore the core needs to add
      the counters individually), or a negative number if an error occurred.
      It should add all the counters and enable any software counters in the
      group, or else add none of them and return an error.
      
      There are a couple of related changes/improvements in the group handling
      here:
      
      * As an optimization, group_sched_out() and group_sched_in() now check the
        state of the group leader, and do nothing if the leader is not active
        or disabled.
      
      * We now call hw_perf_save_disable/hw_perf_restore around the complete
        set of counter enable/disable calls in __perf_counter_sched_in/out,
        to give the arch code the opportunity to defer updating the hardware
        state until the hw_perf_restore call if it wants.
      
      * We no longer stop adding groups after we get to a group that has more
        than one counter.  We will ultimately add an option for a group to be
        exclusive.  The current code doesn't really implement exclusive groups
        anyway, since a group could end up going on with other counters that
        get added before it.
      Signed-off-by: NPaul Mackerras <paulus@samba.org>
      3cbed429
  11. 25 12月, 2008 1 次提交
  12. 23 12月, 2008 6 次提交
  13. 15 12月, 2008 4 次提交
    • I
      perfcounters: add task migrations counter · 6c594c21
      Ingo Molnar 提交于
      Impact: add new feature, new sw counter
      
      Add a counter that counts the number of cross-CPU migrations a
      task is suffering.
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      6c594c21
    • I
      perfcounters: add context switch counter · 5d6a27d8
      Ingo Molnar 提交于
      Impact: add new feature, new sw counter
      
      Add a counter that counts the number of context-switches a task
      is doing.
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      5d6a27d8
    • I
      perfcounters: implement "counter inheritance" · 9b51f66d
      Ingo Molnar 提交于
      Impact: implement new performance feature
      
      Counter inheritance can be used to run performance counters in a workload,
      transparently - and pipe back the counter results to the parent counter.
      
      Inheritance for performance counters works the following way: when creating
      a counter it can be marked with the .inherit=1 flag. Such counters are then
      'inherited' by all child tasks (be they fork()-ed or clone()-ed). These
      counters get inherited through exec() boundaries as well (except through
      setuid boundaries).
      
      The counter values get added back to the parent counter(s) when the child
      task(s) exit - much like stime/utime statistics are gathered. So inherited
      counters are ideal to gather summary statistics about an application's
      behavior via shell commands, without having to modify that application.
      
      The timec.c command utilizes counter inheritance:
      
        http://redhat.com/~mingo/perfcounters/timec.c
      
      Sample output:
      
         $ ./timec -e 1 -e 3 -e 5 ls -lR /usr/include/ >/dev/null
      
         Performance counter stats for 'ls':
      
                 163516953 instructions
                      2295 cache-misses
                   2855182 branch-misses
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      9b51f66d
    • I
      perfcounters: restructure x86 counter math · ee06094f
      Ingo Molnar 提交于
      Impact: restructure code
      
      Change counter math from absolute values to clear delta logic.
      
      We try to extract elapsed deltas from the raw hw counter - and put
      that into the generic counter.
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      ee06094f
  14. 11 12月, 2008 11 次提交
    • I
      perf counters: clean up state transitions · 6a930700
      Ingo Molnar 提交于
      Impact: cleanup
      
      Introduce a proper enum for the 3 states of a counter:
      
      	PERF_COUNTER_STATE_OFF		= -1
      	PERF_COUNTER_STATE_INACTIVE	=  0
      	PERF_COUNTER_STATE_ACTIVE	=  1
      
      and rename counter->active to counter->state and propagate the
      changes everywhere.
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      6a930700
    • I
      perf counters: add prctl interface to disable/enable counters · 1d1c7ddb
      Ingo Molnar 提交于
      Add a way for self-monitoring tasks to disable/enable counters summarily,
      via a prctl:
      
      	PR_TASK_PERF_COUNTERS_DISABLE		31
      	PR_TASK_PERF_COUNTERS_ENABLE		32
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      1d1c7ddb
    • I
      perf counters: implement PERF_COUNT_TASK_CLOCK · bae43c99
      Ingo Molnar 提交于
      Impact: add new perf-counter type
      
      The 'task clock' counter counts the amount of time a task is executing,
      in nanoseconds. It stops ticking when a task is scheduled out either due
      to it blocking, sleeping or it being preempted.
      
      This counter type is a Linux kernel based abstraction, it is available
      even if the hardware does not support native hardware performance counters.
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      bae43c99
    • I
      perf counters: consolidate hw_perf save/restore APIs · 01b2838c
      Ingo Molnar 提交于
      Impact: cleanup
      
      Rename them to better match up the usual IRQ disable/enable APIs:
      
       hw_perf_disable_all()  => hw_perf_save_disable()
       hw_perf_restore_ctrl() => hw_perf_restore()
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      01b2838c
    • I
      perf counters: implement PERF_COUNT_CPU_CLOCK · 5c92d124
      Ingo Molnar 提交于
      Impact: add new perf-counter type
      
      The 'CPU clock' counter counts the amount of CPU clock time that is
      elapsing, in nanoseconds. (regardless of how much of it the task is
      spending on a CPU executing)
      
      This counter type is a Linux kernel based abstraction, it is available
      even if the hardware does not support native hardware performance counters.
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      5c92d124
    • I
      perf counters: hw driver API · 621a01ea
      Ingo Molnar 提交于
      Impact: restructure code, introduce hw_ops driver abstraction
      
      Introduce this abstraction to handle counter details:
      
       struct hw_perf_counter_ops {
      	void (*hw_perf_counter_enable)	(struct perf_counter *counter);
      	void (*hw_perf_counter_disable)	(struct perf_counter *counter);
      	void (*hw_perf_counter_read)	(struct perf_counter *counter);
       };
      
      This will be useful to support assymetric hw details, and it will also
      be useful to implement "software counters". (Counters that count kernel
      managed sw events such as pagefaults, context-switches, wall-clock time
      or task-local time.)
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      621a01ea
    • I
      perf counters: add support for group counters · 04289bb9
      Ingo Molnar 提交于
      Impact: add group counters
      
      This patch adds the "counter groups" abstraction.
      
      Groups of counters behave much like normal 'single' counters, with a
      few semantic and behavioral extensions on top of that.
      
      A counter group is created by creating a new counter with the open()
      syscall's group-leader group_fd file descriptor parameter pointing
      to another, already existing counter.
      
      Groups of counters are scheduled in and out in one atomic group, and
      they are also roundrobin-scheduled atomically.
      
      Counters that are member of a group can also record events with an
      (atomic) extended timestamp that extends to all members of the group,
      if the record type is set to PERF_RECORD_GROUP.
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      04289bb9
    • I
      perf counters: restructure the API · 9f66a381
      Ingo Molnar 提交于
      Impact: clean up new API
      
      Thorough cleanup of the new perf counters API, we now get clean separation
      of the various concepts:
      
       - introduce perf_counter_hw_event to separate out the event source details
      
       - move special type flags into separate attributes: PERF_COUNT_NMI,
         PERF_COUNT_RAW
      
       - extend the type to u64 and reserve it fully to the architecture in the
         raw type case.
      
      And make use of all these changes in the core and x86 perfcounters code.
      
      Also change the syscall signature to:
      
        asmlinkage int sys_perf_counter_open(
      
      	struct perf_counter_hw_event	*hw_event_uptr		__user,
      	pid_t				pid,
      	int				cpu,
      	int				group_fd);
      
      ( Note that group_fd is unused for now - it's reserved for the counter
        groups abstraction. )
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      9f66a381
    • T
      perf counters: expand use of counter->event · dfa7c899
      Thomas Gleixner 提交于
      Impact: change syscall, cleanup
      
      Make use of the new perf_counters event type.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      dfa7c899
    • T
      perf counters: clean up 'raw' type API · eab656ae
      Thomas Gleixner 提交于
      Impact: cleanup
      
      Introduce a separate hw_event type.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      eab656ae
    • T
      perf counters: protect them against CSTATE transitions · 4ac13294
      Thomas Gleixner 提交于
      Impact: fix rare lost events problem
      
      There are CPUs whose performance counters misbehave on CSTATE transitions,
      so provide a way to just disable/enable them around deep idle methods.
      
      (hw_perf_enable_all() is cheap on x86.)
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      4ac13294
  15. 08 12月, 2008 1 次提交
    • T
      performance counters: core code · 0793a61d
      Thomas Gleixner 提交于
      Implement the core kernel bits of Performance Counters subsystem.
      
      The Linux Performance Counter subsystem provides an abstraction of
      performance counter hardware capabilities. It provides per task and per
      CPU counters, and it provides event capabilities on top of those.
      
      Performance counters are accessed via special file descriptors.
      There's one file descriptor per virtual counter used.
      
      The special file descriptor is opened via the perf_counter_open()
      system call:
      
       int
       perf_counter_open(u32 hw_event_type,
                         u32 hw_event_period,
                         u32 record_type,
                         pid_t pid,
                         int cpu);
      
      The syscall returns the new fd. The fd can be used via the normal
      VFS system calls: read() can be used to read the counter, fcntl()
      can be used to set the blocking mode, etc.
      
      Multiple counters can be kept open at a time, and the counters
      can be poll()ed.
      
      See more details in Documentation/perf-counters.txt.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NIngo Molnar <mingo@elte.hu>
      0793a61d