From patchwork Thu Feb 28 05:06:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Song Liu X-Patchwork-Id: 1049260 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=fb.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=fb.com header.i=@fb.com header.b="ei5Rdm+w"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4490tK6vFgz9s6w for ; Thu, 28 Feb 2019 16:07:53 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731041AbfB1FHw (ORCPT ); Thu, 28 Feb 2019 00:07:52 -0500 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:45862 "EHLO mx0b-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730962AbfB1FHW (ORCPT ); Thu, 28 Feb 2019 00:07:22 -0500 Received: from pps.filterd (m0109332.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x1S540gB020629 for ; Wed, 27 Feb 2019 21:07:21 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=facebook; bh=ZodP6c/sisq3UbUd+SO8NMgA2CIeD9sdrF6Q32A6V+8=; b=ei5Rdm+wfMR+4RoVY12xdPtzJQAwfB2nwJzPVJ43CMpQjdngQ4yjSh2xmIMVt8rjak+e croETl1bUw6R/d/IM9rB3j9E0jLNMXZKyLy1/MXymTA/DatzKj2/yXaUuZg1KGhl3MIM jgotfggkxT63JIcyTiyiJEP17/ZhS5OS8jg= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0a-00082601.pphosted.com with ESMTP id 2qx6grrdxf-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Wed, 27 Feb 2019 21:07:21 -0800 Received: from mx-out.facebook.com (2620:10d:c081:10::13) by mail.thefacebook.com (2620:10d:c081:35::127) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) id 15.1.1531.3; Wed, 27 Feb 2019 21:07:20 -0800 Received: by devbig006.ftw2.facebook.com (Postfix, from userid 4523) id 5691062E2B27; Wed, 27 Feb 2019 21:07:18 -0800 (PST) Smtp-Origin-Hostprefix: devbig From: Song Liu Smtp-Origin-Hostname: devbig006.ftw2.facebook.com To: , CC: , , , , , , , Song Liu Smtp-Origin-Cluster: ftw2c04 Subject: [PATCH v5 perf,bpf 14/15] perf: introduce side band thread Date: Wed, 27 Feb 2019 21:06:42 -0800 Message-ID: <20190228050643.958685-15-songliubraving@fb.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190228050643.958685-1-songliubraving@fb.com> References: <20190228050643.958685-1-songliubraving@fb.com> X-FB-Internal: Safe MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-02-28_02:, , signatures=0 X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch introduces side band thread that captures extended information for events like PERF_RECORD_BPF_EVENT. This new thread uses its own evlist that uses ring buffer with very low watermark for lower latency. In the next patch, we uses this thread to handle PERF_RECORD_BPF_EVENT. Signed-off-by: Song Liu --- tools/perf/builtin-record.c | 7 +++ tools/perf/builtin-top.c | 7 +++ tools/perf/util/evlist.c | 100 ++++++++++++++++++++++++++++++++++++ tools/perf/util/evlist.h | 13 +++++ 4 files changed, 127 insertions(+) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 2355e0a9eda0..d10c1d5a9e89 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1106,6 +1106,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) struct perf_data *data = &rec->data; struct perf_session *session; bool disabled = false, draining = false; + struct perf_evlist_sb_poll_args poll_args; int fd; atexit(record__sig_exit); @@ -1206,6 +1207,10 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) goto out_child; } + poll_args.env = &session->header.env; + poll_args.done = &done; + perf_evlist__start_polling_thread(&rec->opts.target, &poll_args); + err = record__synthesize(rec, false); if (err < 0) goto out_child; @@ -1456,6 +1461,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) out_delete_session: perf_session__delete(session); + + perf_evlist__stop_polling_thread(); return status; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index ccdf5689452f..f41545445917 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1524,6 +1524,7 @@ int cmd_top(int argc, const char **argv) "number of thread to run event synthesize"), OPT_END() }; + struct perf_evlist_sb_poll_args poll_args; const char * const top_usage[] = { "perf top []", NULL @@ -1654,8 +1655,14 @@ int cmd_top(int argc, const char **argv) top.record_opts.bpf_event = !top.no_bpf_event; + poll_args.env = &perf_env; + poll_args.done = &done; + perf_evlist__start_polling_thread(target, &poll_args); + status = __cmd_top(&top); + perf_evlist__stop_polling_thread(); + out_delete_evlist: perf_evlist__delete(top.evlist); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 8c902276d4b4..61b87c8111e6 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -19,6 +19,7 @@ #include "debug.h" #include "units.h" #include "asm/bug.h" +#include "bpf-event.h" #include #include @@ -1841,3 +1842,102 @@ struct perf_evsel *perf_evlist__reset_weak_group(struct perf_evlist *evsel_list, } return leader; } + +static struct perf_evlist *sb_evlist; +pthread_t poll_thread; + +int perf_evlist__new_side_band_event(struct perf_event_attr *attr) +{ + struct perf_evsel *evsel; + + if (!sb_evlist) + sb_evlist = perf_evlist__new(); + + if (!sb_evlist) + return -1; + + evsel = perf_evsel__new_idx(attr, sb_evlist->nr_entries); + if (!evsel) + goto out_err; + + perf_evlist__add(sb_evlist, evsel); + return 0; + +out_err: + perf_evlist__delete(sb_evlist); + return -1; +} + +static void *perf_evlist__poll_thread(void *arg) +{ + struct perf_evlist_sb_poll_args *args = arg; + int i; + + while (!*(args->done)) { + perf_evlist__poll(sb_evlist, 1000); + + for (i = 0; i < sb_evlist->nr_mmaps; i++) { + struct perf_mmap *map = &sb_evlist->mmap[i]; + union perf_event *event; + + if (perf_mmap__read_init(map)) + continue; + while ((event = perf_mmap__read_event(map)) != NULL) { + pr_debug("processing vip event of type %d\n", + event->header.type); + switch (event->header.type) { + default: + break; + } + perf_mmap__consume(map); + } + perf_mmap__read_done(map); + } + } + return NULL; +} + +int perf_evlist__start_polling_thread(struct target *target, + struct perf_evlist_sb_poll_args *args) +{ + struct perf_evsel *counter; + + if (sb_evlist == NULL) + return 0; + + if (perf_evlist__create_maps(sb_evlist, target)) + goto out_delete_evlist; + + evlist__for_each_entry(sb_evlist, counter) { + if (perf_evsel__open(counter, sb_evlist->cpus, + sb_evlist->threads) < 0) + goto out_delete_evlist; + } + + if (perf_evlist__mmap(sb_evlist, UINT_MAX)) + goto out_delete_evlist; + + evlist__for_each_entry(sb_evlist, counter) { + if (perf_evsel__enable(counter)) + goto out_delete_evlist; + } + + if (pthread_create(&poll_thread, NULL, perf_evlist__poll_thread, args)) + goto out_delete_evlist; + + return 0; + +out_delete_evlist: + perf_evlist__delete(sb_evlist); + sb_evlist = NULL; + return -1; +} + +void perf_evlist__stop_polling_thread(void) +{ + if (!sb_evlist) + return; + pthread_join(poll_thread, NULL); + perf_evlist__exit(sb_evlist); + sb_evlist = NULL; +} diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 868294491194..4182e50659e0 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -58,6 +58,12 @@ struct perf_evsel_str_handler { void *handler; }; +struct perf_evlist_sb_poll_args { + struct perf_env *env; + + volatile int *done; +}; + struct perf_evlist *perf_evlist__new(void); struct perf_evlist *perf_evlist__new_default(void); struct perf_evlist *perf_evlist__new_dummy(void); @@ -84,6 +90,13 @@ int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, int perf_evlist__add_dummy(struct perf_evlist *evlist); +int perf_evlist__new_side_band_event(struct perf_event_attr *attr); + +int perf_evlist__start_polling_thread(struct target *target, + struct perf_evlist_sb_poll_args *args); + +void perf_evlist__stop_polling_thread(void); + int perf_evlist__add_newtp(struct perf_evlist *evlist, const char *sys, const char *name, void *handler);