1. 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
  2. 14 1月, 2009 2 次提交
    • 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
    • P
      powerpc/perf_counter: Make sure PMU gets enabled properly · 01d0287f
      Paul Mackerras 提交于
      This makes sure that we call the platform-specific ppc_md.enable_pmcs
      function on each CPU before we try to use the PMU on that CPU.  If the
      CPU goes off-line and then on-line, we need to do the enable_pmcs call
      again, so we use the hw_perf_counter_setup hook to ensure that.  It gets
      called as each CPU comes online, but it isn't called on the CPU that is
      coming up, so this adds the CPU number as an argument to it (there were
      no non-empty instances of hw_perf_counter_setup before).
      
      This also arranges to set the pmcregs_in_use field of the lppaca (data
      structure shared with the hypervisor) on each CPU when we are using the
      PMU and clear it when we are not.  This allows the hypervisor to optimize
      partition switches by not saving/restoring the PMU registers when we
      aren't using the PMU.
      Signed-off-by: NPaul Mackerras <paulus@samba.org>
      01d0287f
  3. 12 1月, 2009 1 次提交
    • P
      perf_counter: Always schedule all software counters in · dd0e6ba2
      Paul Mackerras 提交于
      Software counters aren't subject to the limitations imposed by the
      fixed number of hardware counter registers, so there is no reason not
      to enable them all in __perf_counter_sched_in.  Previously we used to
      break out of the loop when we got to a group that wouldn't fit on the
      PMU; with this we continue through the list but only schedule in
      software counters (or groups containing only software counters) from
      there on.
      Signed-off-by: NPaul Mackerras <paulus@samba.org>
      dd0e6ba2
  4. 11 1月, 2009 6 次提交
  5. 10 1月, 2009 30 次提交