lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Wed, 28 Dec 2011 17:55:06 +0000
From:	Stephane Eranian <eranian@...gle.com>
To:	Peter Zijlstra <a.p.zijlstra@...llo.nl>
Cc:	mingo@...e.hu, William Cohen <wcohen@...hat.com>,
	linux-kernel@...r.kernel.org, Arun Sharma <asharma@...com>,
	Vince Weaver <vince@...ter.net>
Subject: Re: [RFC][PATCH 5/6] perf: Extend the mmap control page with time
 (TSC) fields

On Mon, Nov 21, 2011 at 2:51 PM, Peter Zijlstra <a.p.zijlstra@...llo.nl> wrote:
> Extend the mmap control page with fields so that userspace can compute
> time deltas relative to the provided time fields.
>
> Currently only implemented for x86 with constant and nonstop TSC.
>

It is not obvious to me how one would use time_mult, time_shift, time_offset
+ TSC to complement time_enabled/time_running to compute the correct
scaling factor. The patch does not include any example. Woud you mind
describing the method?

Thanks.


> Cc: Stephane Eranian <eranian@...gle.com>
> Cc: Arun Sharma <asharma@...com>
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@...llo.nl>
> ---
>  arch/x86/kernel/cpu/perf_event.c |   14 ++++++++++++++
>  include/linux/perf_event.h       |    4 +++-
>  kernel/events/core.c             |   21 ++++++++++++++-------
>  3 files changed, 31 insertions(+), 8 deletions(-)
> Index: linux-2.6/arch/x86/kernel/cpu/perf_event.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/kernel/cpu/perf_event.c
> +++ linux-2.6/arch/x86/kernel/cpu/perf_event.c
> @@ -32,6 +32,7 @@
>  #include <asm/compat.h>
>  #include <asm/smp.h>
>  #include <asm/alternative.h>
> +#include <asm/timer.h>
>
>  #include "perf_event.h"
>
> @@ -1621,6 +1622,19 @@ static struct pmu pmu = {
>        .event_idx      = x86_pmu_event_idx,
>  };
>
> +void perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now)
> +{
> +       if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
> +               return;
> +
> +       if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
> +               return;
> +
> +       userpg->time_mult = this_cpu_read(cyc2ns);
> +       userpg->time_shift = CYC2NS_SCALE_FACTOR;
> +       userpg->time_offset = this_cpu_read(cyc2ns_offset) - now;
> +}
> +
>  /*
>  * callchain support
>  */
> Index: linux-2.6/include/linux/perf_event.h
> ===================================================================
> --- linux-2.6.orig/include/linux/perf_event.h
> +++ linux-2.6/include/linux/perf_event.h
> @@ -290,12 +290,14 @@ struct perf_event_mmap_page {
>        __s64   offset;                 /* add to hardware event value */
>        __u64   time_enabled;           /* time event active */
>        __u64   time_running;           /* time event on cpu */
> +       __u32   time_mult, time_shift;
> +       __u64   time_offset;
>
>                /*
>                 * Hole for extension of the self monitor capabilities
>                 */
>
> -       __u64   __reserved[123];        /* align to 1k */
> +       __u64   __reserved[121];        /* align to 1k */
>
>        /*
>         * Control data for the mmap() data buffer.
> Index: linux-2.6/kernel/events/core.c
> ===================================================================
> --- linux-2.6.orig/kernel/events/core.c
> +++ linux-2.6/kernel/events/core.c
> @@ -3203,17 +3203,22 @@ static int perf_event_index(struct perf_
>  }
>
>  static void calc_timer_values(struct perf_event *event,
> +                               u64 *now,
>                                u64 *enabled,
>                                u64 *running)
>  {
> -       u64 now, ctx_time;
> +       u64 ctx_time;
>
> -       now = perf_clock();
> -       ctx_time = event->shadow_ctx_time + now;
> +       *now = perf_clock();
> +       ctx_time = event->shadow_ctx_time + *now;
>        *enabled = ctx_time - event->tstamp_enabled;
>        *running = ctx_time - event->tstamp_running;
>  }
>
> +void __weak perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now)
> +{
> +}
> +
>  /*
>  * Callers need to ensure there can be no nesting of this function, otherwise
>  * the seqlock logic goes bad. We can not serialize this because the arch
> @@ -3223,7 +3228,7 @@ void perf_event_update_userpage(struct p
>  {
>        struct perf_event_mmap_page *userpg;
>        struct ring_buffer *rb;
> -       u64 enabled, running;
> +       u64 enabled, running, now;
>
>        rcu_read_lock();
>        /*
> @@ -3235,7 +3240,7 @@ void perf_event_update_userpage(struct p
>         * because of locking issue as we can be called in
>         * NMI context
>         */
> -       calc_timer_values(event, &enabled, &running);
> +       calc_timer_values(event, &now, &enabled, &running);
>        rb = rcu_dereference(event->rb);
>        if (!rb)
>                goto unlock;
> @@ -3260,6 +3265,8 @@ void perf_event_update_userpage(struct p
>        userpg->time_running = running +
>                        atomic64_read(&event->child_total_time_running);
>
> +       perf_update_user_clock(userpg, now);
> +
>        barrier();
>        ++userpg->lock;
>        preempt_enable();
> @@ -3692,7 +3699,7 @@ static void perf_output_read_group(struc
>  static void perf_output_read(struct perf_output_handle *handle,
>                             struct perf_event *event)
>  {
> -       u64 enabled = 0, running = 0;
> +       u64 enabled = 0, running = 0, now;
>        u64 read_format = event->attr.read_format;
>
>        /*
> @@ -3705,7 +3712,7 @@ static void perf_output_read(struct perf
>         * NMI context
>         */
>        if (read_format & PERF_FORMAT_TOTAL_TIMES)
> -               calc_timer_values(event, &enabled, &running);
> +               calc_timer_values(event, &now, &enabled, &running);
>
>        if (event->attr.read_format & PERF_FORMAT_GROUP)
>                perf_output_read_group(handle, event, enabled, running);
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ