From patchwork Thu Nov 6 16:51:58 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pawel Moll X-Patchwork-Id: 40357 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f70.google.com (mail-la0-f70.google.com [209.85.215.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id A99DB24687 for ; Thu, 6 Nov 2014 16:53:02 +0000 (UTC) Received: by mail-la0-f70.google.com with SMTP id ge10sf2018442lab.9 for ; Thu, 06 Nov 2014 08:53:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=5bgYMAv0ipSxiY5cqdzHvQVWoAiMRRPqABXyC+fioZE=; b=haRRXBOHjnG+8o3U9kD1MipaWz+FRNl1EbIKtn5SA8hKVY8Ec3Bl0W88Cxf/5QGry5 7GHEdYi1i25IN8aTpbrN3SCsqw8zkbIDzs2Wa7k5pyTjBzv0SQ4QSzOivLiJDBb+6Lvt +Ki4l0Dz8cjwAzbpofJe9R6PNLg5aE0hWiXOqH49R30RFfHOm5Kwo0/qLcO2R8W90zsK Sam5XW0ebnmlMe6bCJVSXvLPYO8aaA4Z3OCe/LrSmnc6dPFZ0NiOb4ktQjwc1SSkl1DG gQSKTC153EmuG7KkgXrh+DQXJKzDHo0rEgmcY+zogQ78DFRcEw8NktQn2PJm/ZoowuAi 4M8Q== X-Gm-Message-State: ALoCoQl4bJArwxKk0Fv8d95nN7hxCzq3nWdfZMd8mIZnaBF/8a/zkBiNDRajVWwPsAuPd8WhhOm4 X-Received: by 10.180.94.3 with SMTP id cy3mr303504wib.7.1415292781415; Thu, 06 Nov 2014 08:53:01 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.27.168 with SMTP id u8ls98725lag.103.gmail; Thu, 06 Nov 2014 08:53:01 -0800 (PST) X-Received: by 10.112.64.66 with SMTP id m2mr6212641lbs.53.1415292781017; Thu, 06 Nov 2014 08:53:01 -0800 (PST) Received: from mail-la0-f43.google.com (mail-la0-f43.google.com. [209.85.215.43]) by mx.google.com with ESMTPS id at1si12221598lbc.2.2014.11.06.08.53.00 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 06 Nov 2014 08:53:00 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.43 as permitted sender) client-ip=209.85.215.43; Received: by mail-la0-f43.google.com with SMTP id ge10so2961770lab.2 for ; Thu, 06 Nov 2014 08:53:00 -0800 (PST) X-Received: by 10.112.202.104 with SMTP id kh8mr6272925lbc.46.1415292780820; Thu, 06 Nov 2014 08:53:00 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.184.201 with SMTP id ew9csp74543lbc; Thu, 6 Nov 2014 08:52:59 -0800 (PST) X-Received: by 10.66.151.202 with SMTP id us10mr5761118pab.78.1415292779040; Thu, 06 Nov 2014 08:52:59 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id fc5si6481734pdb.29.2014.11.06.08.52.58 for ; Thu, 06 Nov 2014 08:52:59 -0800 (PST) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752874AbaKFQw4 (ORCPT + 25 others); Thu, 6 Nov 2014 11:52:56 -0500 Received: from foss-mx-na.foss.arm.com ([217.140.108.86]:54078 "EHLO foss-mx-na.foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752846AbaKFQwQ (ORCPT ); Thu, 6 Nov 2014 11:52:16 -0500 Received: from foss-smtp-na-1.foss.arm.com (unknown [10.80.61.8]) by foss-mx-na.foss.arm.com (Postfix) with ESMTP id 9D0B24E1; Thu, 6 Nov 2014 10:52:12 -0600 (CST) Received: from collaborate-mta1.arm.com (highbank-bc01-b06.austin.arm.com [10.112.81.134]) by foss-smtp-na-1.foss.arm.com (Postfix) with ESMTP id 4F6EF5FAD7; Thu, 6 Nov 2014 10:52:10 -0600 (CST) Received: from hornet.Cambridge.Arm.com (hornet.cambridge.arm.com [10.2.201.42]) by collaborate-mta1.arm.com (Postfix) with ESMTP id 1766213F697; Thu, 6 Nov 2014 10:52:07 -0600 (CST) From: Pawel Moll To: Richard Cochran , Steven Rostedt , Ingo Molnar , Peter Zijlstra , Paul Mackerras , Arnaldo Carvalho de Melo , John Stultz , Masami Hiramatsu , Christopher Covington , Namhyung Kim , David Ahern , Thomas Gleixner , Tomeu Vizoso Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, Pawel Moll Subject: [PATCH v4 3/3] perf: Sample additional clock value Date: Thu, 6 Nov 2014 16:51:58 +0000 Message-Id: <1415292718-19785-4-git-send-email-pawel.moll@arm.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1415292718-19785-1-git-send-email-pawel.moll@arm.com> References: <1415292718-19785-1-git-send-email-pawel.moll@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: pawel.moll@arm.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.43 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This patch adds an option to sample value of an additional clock with any perf event, with the the aim of allowing time correlation between data coming from perf and other sources like hardware trace which is timestamped with an external clock. The idea is to generate periodic perf record containing timestamps from two different sources, sampled as close to each other as possible. This allows performing simple linear approximation: other event -----O--------------+-------------O------> t_other : | : : V : -----O----------------------------O------> t_perf perf event User can request such samples for any standard perf event, with the most obvious examples of cpu-clock (hrtimer) at selected frequency or other periodic events like sched:sched_switch. In order to do this, PERF_SAMPLE_CLOCK has to be set in struct perf_event_attr.sample_type and a type of the clock to be sampled selected by setting perf_event_attr.clock to a value corresponding to a POSIX clock clk_id (see "man 2 clock_gettime") Currently three clocks are implemented: CLOCK_REALITME = 0, CLOCK_MONOTONIC = 1 and CLOCK_MONOTONIC_RAW = 2. The clock field is 5 bits wide to allow for future extension to custom, non-POSIX clock sources(MAX_CLOCK for those is 16, see include/uapi/linux/time.h) like ARM CoreSight (hardware trace) timestamp generator. Signed-off-by: Pawel Moll --- Changes since v3: - none include/linux/perf_event.h | 2 ++ include/uapi/linux/perf_event.h | 16 ++++++++++++++-- kernel/events/core.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 680767d..b690a0d 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -607,6 +607,8 @@ struct perf_sample_data { * Transaction flags for abort events: */ u64 txn; + /* Clock value (additional timestamp for time correlation) */ + u64 clock; }; /* default value for data source */ diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index 9a64eb1..53a7a72 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -137,8 +137,9 @@ enum perf_event_sample_format { PERF_SAMPLE_DATA_SRC = 1U << 15, PERF_SAMPLE_IDENTIFIER = 1U << 16, PERF_SAMPLE_TRANSACTION = 1U << 17, + PERF_SAMPLE_CLOCK = 1U << 18, - PERF_SAMPLE_MAX = 1U << 18, /* non-ABI */ + PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */ }; /* @@ -304,7 +305,16 @@ struct perf_event_attr { mmap2 : 1, /* include mmap with inode data */ comm_exec : 1, /* flag comm events that are due to an exec */ uevents : 1, /* allow uevents into the buffer */ - __reserved_1 : 38; + + /* + * clock: one of the POSIX clock IDs: + * + * 0 - CLOCK_REALTIME + * 1 - CLOCK_MONOTONIC + * 4 - CLOCK_MONOTONIC_RAW + */ + clock : 5, /* clock type */ + __reserved_1 : 33; union { __u32 wakeup_events; /* wakeup every n events */ @@ -544,6 +554,7 @@ enum perf_event_type { * { u64 id; } && PERF_SAMPLE_ID * { u64 stream_id;} && PERF_SAMPLE_STREAM_ID * { u32 cpu, res; } && PERF_SAMPLE_CPU + * { u64 clock; } && PERF_SAMPLE_CLOCK * { u64 id; } && PERF_SAMPLE_IDENTIFIER * } && perf_event_attr::sample_id_all * @@ -687,6 +698,7 @@ enum perf_event_type { * { u64 weight; } && PERF_SAMPLE_WEIGHT * { u64 data_src; } && PERF_SAMPLE_DATA_SRC * { u64 transaction; } && PERF_SAMPLE_TRANSACTION + * { u64 clock; } && PERF_SAMPLE_CLOCK * }; */ PERF_RECORD_SAMPLE = 9, diff --git a/kernel/events/core.c b/kernel/events/core.c index 9a2d082..816baa6 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1264,6 +1264,9 @@ static void perf_event__header_size(struct perf_event *event) if (sample_type & PERF_SAMPLE_TRANSACTION) size += sizeof(data->txn); + if (sample_type & PERF_SAMPLE_CLOCK) + size += sizeof(data->clock); + event->header_size = size; } @@ -1291,6 +1294,9 @@ static void perf_event__id_header_size(struct perf_event *event) if (sample_type & PERF_SAMPLE_CPU) size += sizeof(data->cpu_entry); + if (sample_type & PERF_SAMPLE_CLOCK) + size += sizeof(data->clock); + event->id_header_size = size; } @@ -4631,6 +4637,24 @@ static void __perf_event_header__init_id(struct perf_event_header *header, data->cpu_entry.cpu = raw_smp_processor_id(); data->cpu_entry.reserved = 0; } + + if (sample_type & PERF_SAMPLE_CLOCK) { + switch (event->attr.clock) { + case CLOCK_REALTIME: + data->clock = ktime_get_real_ns(); + break; + case CLOCK_MONOTONIC: + data->clock = ktime_get_mono_fast_ns(); + break; + case CLOCK_MONOTONIC_RAW: + data->clock = ktime_get_raw_ns(); + break; + default: + data->clock = 0; + break; + } + } + } void perf_event_header__init_id(struct perf_event_header *header, @@ -4661,6 +4685,9 @@ static void __perf_event__output_id_sample(struct perf_output_handle *handle, if (sample_type & PERF_SAMPLE_CPU) perf_output_put(handle, data->cpu_entry); + if (sample_type & PERF_SAMPLE_CLOCK) + perf_output_put(handle, data->clock); + if (sample_type & PERF_SAMPLE_IDENTIFIER) perf_output_put(handle, data->id); } @@ -4889,6 +4916,9 @@ void perf_output_sample(struct perf_output_handle *handle, if (sample_type & PERF_SAMPLE_TRANSACTION) perf_output_put(handle, data->txn); + if (sample_type & PERF_SAMPLE_CLOCK) + perf_output_put(handle, data->clock); + if (!event->attr.watermark) { int wakeup_events = event->attr.wakeup_events;