• Frederic Weisbecker's avatar
    hw-breakpoints: Arbitrate access to pmu following registers constraints · ba1c813a
    Frederic Weisbecker authored
    Allow or refuse to build a counter using the breakpoints pmu following
    given constraints.
    
    We keep track of the pmu users by using three per cpu variables:
    
    - nr_cpu_bp_pinned stores the number of pinned cpu breakpoints counters
      in the given cpu
    
    - nr_bp_flexible stores the number of non-pinned breakpoints counters
      in the given cpu.
    
    - task_bp_pinned stores the number of pinned task breakpoints in a cpu
    
    The latter is not a simple counter but gathers the number of tasks that
    have n pinned breakpoints.
    Considering HBP_NUM the number of available breakpoint address
    registers:
       task_bp_pinned[0] is the number of tasks having 1 breakpoint
       task_bp_pinned[1] is the number of tasks having 2 breakpoints
       [...]
       task_bp_pinned[HBP_NUM - 1] is the number of tasks having the
       maximum number of registers (HBP_NUM).
    
    When a breakpoint counter is created and wants an access to the pmu,
    we evaluate the following constraints:
    
    == Non-pinned counter ==
    
    - If attached to a single cpu, check:
    
        (per_cpu(nr_bp_flexible, cpu) || (per_cpu(nr_cpu_bp_pinned, cpu)
             + max(per_cpu(task_bp_pinned, cpu)))) < HBP_NUM
    
           -> If there are already non-pinned counters in this cpu, it
              means there is already a free slot for them.
              Otherwise, we check that the maximum number of per task
              breakpoints (for this cpu) plus the number of per cpu
              breakpoint (for this cpu) doesn't cover every registers.
    
    - If attached to every cpus, check:
    
        (per_cpu(nr_bp_flexible, *) || (max(per_cpu(nr_cpu_bp_pinned, *))
               + max(per_cpu(task_bp_pinned, *)))) < HBP_NUM
    
           -> This is roughly the same, except we check the number of per
              cpu bp for every cpu and we keep the max one. Same for the
              per tasks breakpoints.
    
    == Pinned counter ==
    
    - If attached to a single cpu, check:
    
           ((per_cpu(nr_bp_flexible, cpu) > 1)
                + per_cpu(nr_cpu_bp_pinned, cpu)
                + max(per_cpu(task_bp_pinned, cpu))) < HBP_NUM
    
           -> Same checks as before. But now the nr_bp_flexible, if any,
              must keep one register at least (or flexible breakpoints will
              never be be fed).
    
    - If attached to every cpus, check:
    
          ((per_cpu(nr_bp_flexible, *) > 1)
               + max(per_cpu(nr_cpu_bp_pinned, *))
               + max(per_cpu(task_bp_pinned, *))) < HBP_NUM
    
    Changes in v2:
    
    - Counter -> event rename
    
    Changes in v5:
    
    - Fix unreleased non-pinned task-bound-only counters. We only released
      it in the first cpu. (Thanks to Paul Mackerras for reporting that)
    
    Changes in v6:
    
    - Currently, events scheduling are done in this order: cpu context
      pinned + cpu context non-pinned + task context pinned + task context
      non-pinned events. Then our current constraints are right theoretically
      but not in practice, because non-pinned counters may be scheduled
      before we can apply every possible pinned counters. So consider
      non-pinned counters as pinned for now.
    Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
    Cc: Prasad <prasad@linux.vnet.ibm.com>
    Cc: Alan Stern <stern@rowland.harvard.edu>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Jan Kiszka <jan.kiszka@web.de>
    Cc: Jiri Slaby <jirislaby@gmail.com>
    Cc: Li Zefan <lizf@cn.fujitsu.com>
    Cc: Avi Kivity <avi@redhat.com>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Mike Galbraith <efault@gmx.de>
    Cc: Masami Hiramatsu <mhiramat@redhat.com>
    Cc: Paul Mundt <lethal@linux-sh.org>
    ba1c813a
hw_breakpoint.c 12.3 KB