From nobody Thu Dec 18 18:43:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01D84C77B6E for ; Fri, 14 Apr 2023 08:23:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230183AbjDNIXd (ORCPT ); Fri, 14 Apr 2023 04:23:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33002 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230110AbjDNIXZ (ORCPT ); Fri, 14 Apr 2023 04:23:25 -0400 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E408E30FD; Fri, 14 Apr 2023 01:23:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1681460603; x=1712996603; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lKhCyQDrP3SWVP+Mn5U2yqr9K7pd2gf6DvLZAJNWAYw=; b=C3us+nhnfk6/hNhlG/JKbd6WhQY7SlftA2qG84jea3PzKO6PBZOro3t7 CTpxnRp0Myxx28XiTcFjz8AeHDjB1Iit49Ar4GNCBHzjxeADod5FNVWK/ JrSV3q754ooJ03E5CuqxCUnwZZwauXiw9uOXgZt4MQeW2a4v5WhlnpUP7 d759Twsp25xR73lwo8kBGU5DNXNbEdwwPSXULeA/sIE2C8Exxev+zPTxA dUA4JAcDqBxOaM+U/4S/WErqZ+XZSmlUGgnLcTl811De0HR6e9sprLE97 6tR4YleFLbvHkZ1xw8914v9Mp8GLqXD0AafSD4Nec2qW7RUa0GlKCeDkN A==; X-IronPort-AV: E=McAfee;i="6600,9927,10679"; a="430708091" X-IronPort-AV: E=Sophos;i="5.99,195,1677571200"; d="scan'208";a="430708091" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2023 01:23:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10679"; a="683267456" X-IronPort-AV: E=Sophos;i="5.99,195,1677571200"; d="scan'208";a="683267456" Received: from ahunter6-mobl1.ger.corp.intel.com (HELO ahunter-VirtualBox.home\044ger.corp.intel.com) ([10.249.34.252]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2023 01:23:20 -0700 From: Adrian Hunter To: Peter Zijlstra Cc: Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RFC 1/5] perf: Add ioctl to emit sideband events Date: Fri, 14 Apr 2023 11:22:56 +0300 Message-Id: <20230414082300.34798-2-adrian.hunter@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230414082300.34798-1-adrian.hunter@intel.com> References: <20230414082300.34798-1-adrian.hunter@intel.com> MIME-Version: 1.0 Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" perf tools currently read /proc to get this information, but that races with changes made by the kernel. Add an ioctl to output status-only sideband events for a currently active event on the current CPU. Using timestamps, these status-only sideband events will be correctly ordered with respect to "real" sideband events. The assumption is a user will: - open and enable a dummy event to track sideband events - call the new ioctl to get sideband information for currently running processes as needed - enable the remaining selected events The initial sideband events to be supported will be: fork, namespaces, comm and mmap. Add a new misc flag PERF_RECORD_MISC_STATUS_ONLY to differentiate "real" sideband events from status-only sideband events. The limitation that the event must be active is significant. The ioctl caller must either: i) For a CPU context, set CPU affinity to the correct CPU. Note, obviously that would not need to be done for system-wide tracing on all CPUs. It would also only need to be done for the period of tracing when the ioctl is to be used. ii) Use an event opened for the current process on all CPUs. Note, if such an additional event is needed, it would also use additional memory from the user's perf_event_mlock_kb / RLIMIT_MEMLOCK limit. Signed-off-by: Adrian Hunter --- include/uapi/linux/perf_event.h | 19 ++++++- kernel/events/core.c | 87 ++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 3 deletions(-) diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_even= t.h index 37675437b768..d44fb0f65484 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -541,6 +541,18 @@ struct perf_event_query_bpf { __u32 ids[]; }; =20 +enum perf_event_emit_flag { + PERF_EVENT_EMIT_FORK =3D 1U << 0, + PERF_EVENT_EMIT_NAMESPACES =3D 1U << 1, + PERF_EVENT_EMIT_COMM =3D 1U << 2, + PERF_EVENT_EMIT_MMAP =3D 1U << 3, +}; + +struct perf_event_pid_sb { + __u32 pid; + __u32 emit_flags; /* Refer perf_event_emit_flag */ +}; + /* * Ioctls that can be done on a perf event fd: */ @@ -556,6 +568,7 @@ struct perf_event_query_bpf { #define PERF_EVENT_IOC_PAUSE_OUTPUT _IOW('$', 9, __u32) #define PERF_EVENT_IOC_QUERY_BPF _IOWR('$', 10, struct perf_event_query_b= pf *) #define PERF_EVENT_IOC_MODIFY_ATTRIBUTES _IOW('$', 11, struct perf_event_a= ttr *) +#define PERF_EVENT_IOC_EMIT_SIDEBAND _IOW('$', 12, struct perf_event_pid_= sb *) =20 enum perf_event_ioc_flags { PERF_IOC_FLAG_GROUP =3D 1U << 0, @@ -743,12 +756,13 @@ struct perf_event_mmap_page { * The current state of perf_event_header::misc bits usage: * ('|' used bit, '-' unused bit) * - * 012 CDEF - * |||---------|||| + * 012 BCDEF + * |||--------||||| * * Where: * 0-2 CPUMODE_MASK * + * B STATUS_ONLY * C PROC_MAP_PARSE_TIMEOUT * D MMAP_DATA / COMM_EXEC / FORK_EXEC / SWITCH_OUT * E MMAP_BUILD_ID / EXACT_IP / SCHED_OUT_PREEMPT @@ -763,6 +777,7 @@ struct perf_event_mmap_page { #define PERF_RECORD_MISC_GUEST_KERNEL (4 << 0) #define PERF_RECORD_MISC_GUEST_USER (5 << 0) =20 +#define PERF_RECORD_MISC_STATUS_ONLY (1 << 11) /* * Indicates that /proc/PID/maps parsing are truncated by time out. */ diff --git a/kernel/events/core.c b/kernel/events/core.c index fb3e436bcd4a..5cbcc6851587 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5797,6 +5797,7 @@ static int perf_event_set_output(struct perf_event *e= vent, static int perf_event_set_filter(struct perf_event *event, void __user *ar= g); static int perf_copy_attr(struct perf_event_attr __user *uattr, struct perf_event_attr *attr); +static int perf_event_emit_sideband(struct perf_event *event, void __user = *arg); =20 static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsign= ed long arg) { @@ -5924,6 +5925,9 @@ static long perf_ioctl(struct file *file, unsigned in= t cmd, unsigned long arg) if (ret) return ret; =20 + if (cmd =3D=3D PERF_EVENT_IOC_EMIT_SIDEBAND) + return perf_event_emit_sideband(event, (void __user *)arg); + ctx =3D perf_event_ctx_lock(event); ret =3D _perf_ioctl(event, cmd, arg); perf_event_ctx_unlock(event, ctx); @@ -5940,6 +5944,7 @@ static long perf_compat_ioctl(struct file *file, unsi= gned int cmd, case _IOC_NR(PERF_EVENT_IOC_ID): case _IOC_NR(PERF_EVENT_IOC_QUERY_BPF): case _IOC_NR(PERF_EVENT_IOC_MODIFY_ATTRIBUTES): + case _IOC_NR(PERF_EVENT_IOC_EMIT_SIDEBAND): /* Fix up pointer size (usually 4 -> 8 in 32-on-64-bit case */ if (_IOC_SIZE(cmd) =3D=3D sizeof(compat_uptr_t)) { cmd &=3D ~IOCSIZE_MASK; @@ -12277,7 +12282,7 @@ perf_check_permission(struct perf_event_attr *attr,= struct task_struct *task) unsigned int ptrace_mode =3D PTRACE_MODE_READ_REALCREDS; bool is_capable =3D perfmon_capable(); =20 - if (attr->sigtrap) { + if (attr && attr->sigtrap) { /* * perf_event_attr::sigtrap sends signals to the other task. * Require the current task to also have CAP_KILL. @@ -12810,6 +12815,86 @@ perf_event_create_kernel_counter(struct perf_event= _attr *attr, int cpu, } EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter); =20 +static int perf_event_emit_fork(struct perf_event *event, struct task_stru= ct *task) +{ + return -EINVAL; +} + +static int perf_event_emit_namespaces(struct perf_event *event, struct tas= k_struct *task) +{ + return -EINVAL; +} + +static int perf_event_emit_comm(struct perf_event *event, struct task_stru= ct *task) +{ + return -EINVAL; +} + +static int perf_event_emit_mmap(struct perf_event *event, struct task_stru= ct *task) +{ + return -EINVAL; +} + +static int perf_event_emit_sideband(struct perf_event *event, void __user = *arg) +{ + struct perf_event_pid_sb pid_sb; + struct perf_event_context *ctx; + struct task_struct *task; + int err; + + if (copy_from_user(&pid_sb, arg, sizeof(pid_sb))) + return -EFAULT; + + if (pid_sb.emit_flags & ~(PERF_EVENT_EMIT_FORK | + PERF_EVENT_EMIT_NAMESPACES | + PERF_EVENT_EMIT_COMM | + PERF_EVENT_EMIT_MMAP)) + return -EINVAL; + + task =3D find_lively_task_by_vpid(pid_sb.pid); + if (IS_ERR(task)) + return PTR_ERR(task); + + err =3D down_read_interruptible(&task->signal->exec_update_lock); + if (err) + goto out_put_task; + + /* Validate access to pid (same as perf_event_open) */ + err =3D -EACCES; + if (!perf_check_permission(NULL, task)) + goto out_cred; + + ctx =3D perf_event_ctx_lock(event); + + if (pid_sb.emit_flags & PERF_EVENT_EMIT_FORK) { + err =3D perf_event_emit_fork(event, task); + if (err) + goto out_ctx; + } + if (pid_sb.emit_flags & PERF_EVENT_EMIT_NAMESPACES) { + err =3D perf_event_emit_namespaces(event, task); + if (err) + goto out_ctx; + } + if (pid_sb.emit_flags & PERF_EVENT_EMIT_COMM) { + err =3D perf_event_emit_comm(event, task); + if (err) + goto out_ctx; + } + if (pid_sb.emit_flags & PERF_EVENT_EMIT_MMAP) { + err =3D perf_event_emit_mmap(event, task); + if (err) + goto out_ctx; + } +out_ctx: + perf_event_ctx_unlock(event, ctx); +out_cred: + up_read(&task->signal->exec_update_lock); +out_put_task: + put_task_struct(task); + return err; +} + static void __perf_pmu_remove(struct perf_event_context *ctx, int cpu, struct pmu *pmu, struct perf_event_groups *groups, --=20 2.34.1 From nobody Thu Dec 18 18:43:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 13F7BC77B6E for ; Fri, 14 Apr 2023 08:23:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230194AbjDNIXl (ORCPT ); Fri, 14 Apr 2023 04:23:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32998 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230003AbjDNIX2 (ORCPT ); Fri, 14 Apr 2023 04:23:28 -0400 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6EF6B6E9D; Fri, 14 Apr 2023 01:23:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1681460607; x=1712996607; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Xhw2PFI44xhxatWgOY9IkkDtUpBt0VWfQQBb/Lx2E8k=; b=ahgM5qkA4p9/HBmOgo2SAuiCLd3kduResrfoGooNywsBgx5l1JM8Q9i1 xjQyu2bcqAUEQO8YfujHtZ7omMlZNBB/l+43gAv7mww2ICgi8nA49vh4a D3bQWHbdWm2SWI02cjBeVq2e3jnnPDFyFBOGk18P8jjrQ72/jr32sYIHi HhRZP5SjH3DAg8l0UOuPc+loFyRXBfX3DzdVTHXyZOsz00VzywDwKCkWR mrHGFH84mR167vx+mm5WhcqDOHZGDaqTaZwYLkigygkxH101+cZ6RINcr uGPJ7jXBSkWjw8s8A/iID5IwkabT0UAwOjIqRbk+6pGBN2JiUCEorDUV6 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10679"; a="430708106" X-IronPort-AV: E=Sophos;i="5.99,195,1677571200"; d="scan'208";a="430708106" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2023 01:23:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10679"; a="683267482" X-IronPort-AV: E=Sophos;i="5.99,195,1677571200"; d="scan'208";a="683267482" Received: from ahunter6-mobl1.ger.corp.intel.com (HELO ahunter-VirtualBox.home\044ger.corp.intel.com) ([10.249.34.252]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2023 01:23:23 -0700 From: Adrian Hunter To: Peter Zijlstra Cc: Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RFC 2/5] perf: Add fork to the sideband ioctl Date: Fri, 14 Apr 2023 11:22:57 +0300 Message-Id: <20230414082300.34798-3-adrian.hunter@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230414082300.34798-1-adrian.hunter@intel.com> References: <20230414082300.34798-1-adrian.hunter@intel.com> MIME-Version: 1.0 Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Support the case of output to an active event, and return an error if output is not possible in that case. Set PERF_RECORD_MISC_STATUS_ONLY to differentiate the ioctl status-only sideband event from a "real" sideband event. Set the fork parent pid/tid to the real parent for a thread group leader, or to the thread group leader otherwise. Signed-off-by: Adrian Hunter --- kernel/events/core.c | 88 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 5cbcc6851587..4e76596d3bfb 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -7948,6 +7948,54 @@ perf_iterate_sb(perf_iterate_f output, void *data, rcu_read_unlock(); } =20 +typedef int (perf_output_f)(struct perf_event *event, void *data); + +static int perf_event_output_sb(struct perf_event *event, perf_output_f ou= tput, void *data) +{ + int err =3D -ENOENT; + + preempt_disable(); + + if (event->state !=3D PERF_EVENT_STATE_ACTIVE || + !event_filter_match(event) || + READ_ONCE(event->oncpu) !=3D smp_processor_id()) + goto out; + + err =3D output(event, data); +out: + preempt_enable(); + return err; +} + +struct perf_output_f_data { + perf_output_f *func; + void *data; +}; + +void perf_output_f_wrapper(struct perf_event *event, void *data) +{ + struct perf_output_f_data *f_data =3D data; + + f_data->func(event, f_data->data); +} + +static int perf_output_sb(perf_output_f output, void *data, + struct perf_event_context *task_ctx, + struct perf_event *event) +{ + struct perf_output_f_data f_data =3D { + .func =3D output, + .data =3D data, + }; + + if (event) + return perf_event_output_sb(event, output, data); + + perf_iterate_sb(perf_output_f_wrapper, &f_data, task_ctx); + + return 0; +} + /* * Clear all file-based filters at exec, they'll have to be * re-instated when/if these objects are mmapped again. @@ -8107,8 +8155,7 @@ static int perf_event_task_match(struct perf_event *e= vent) event->attr.task; } =20 -static void perf_event_task_output(struct perf_event *event, - void *data) +static int perf_event_task_output(struct perf_event *event, void *data) { struct perf_task_event *task_event =3D data; struct perf_output_handle handle; @@ -8117,7 +8164,7 @@ static void perf_event_task_output(struct perf_event = *event, int ret, size =3D task_event->event_id.header.size; =20 if (!perf_event_task_match(event)) - return; + return -ENOENT; =20 perf_event_header__init_id(&task_event->event_id.header, &sample, event); =20 @@ -8134,6 +8181,14 @@ static void perf_event_task_output(struct perf_event= *event, task->real_parent); task_event->event_id.ptid =3D perf_event_pid(event, task->real_parent); + } else if (task_event->event_id.header.misc & PERF_RECORD_MISC_STATUS_ONL= Y) { + if (thread_group_leader(task)) { + task_event->event_id.ppid =3D perf_event_pid(event, task->real_parent); + task_event->event_id.ptid =3D perf_event_tid(event, task->real_parent); + } else { + task_event->event_id.ppid =3D perf_event_pid(event, task); + task_event->event_id.ptid =3D perf_event_pid(event, task); + } } else { /* PERF_RECORD_FORK */ task_event->event_id.ppid =3D perf_event_pid(event, current); task_event->event_id.ptid =3D perf_event_tid(event, current); @@ -8148,18 +8203,19 @@ static void perf_event_task_output(struct perf_even= t *event, perf_output_end(&handle); out: task_event->event_id.header.size =3D size; + return ret; } =20 -static void perf_event_task(struct task_struct *task, - struct perf_event_context *task_ctx, - int new) +static int perf_event_task(struct task_struct *task, + struct perf_event_context *task_ctx, + int new, struct perf_event *event) { struct perf_task_event task_event; =20 if (!atomic_read(&nr_comm_events) && !atomic_read(&nr_mmap_events) && !atomic_read(&nr_task_events)) - return; + return -ENOENT; =20 task_event =3D (struct perf_task_event){ .task =3D task, @@ -8167,7 +8223,7 @@ static void perf_event_task(struct task_struct *task, .event_id =3D { .header =3D { .type =3D new ? PERF_RECORD_FORK : PERF_RECORD_EXIT, - .misc =3D 0, + .misc =3D event ? PERF_RECORD_MISC_STATUS_ONLY : 0, .size =3D sizeof(task_event.event_id), }, /* .pid */ @@ -8178,14 +8234,12 @@ static void perf_event_task(struct task_struct *tas= k, }, }; =20 - perf_iterate_sb(perf_event_task_output, - &task_event, - task_ctx); + return perf_output_sb(perf_event_task_output, &task_event, task_ctx, even= t); } =20 void perf_event_fork(struct task_struct *task) { - perf_event_task(task, NULL, 1); + perf_event_task(task, NULL, 1, NULL); perf_event_namespaces(task); } =20 @@ -12817,7 +12871,11 @@ EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter= ); =20 static int perf_event_emit_fork(struct perf_event *event, struct task_stru= ct *task) { - return -EINVAL; + if (!event->attr.comm && !event->attr.mmap && !event->attr.mmap2 && + !event->attr.mmap_data && !event->attr.task) + return -EINVAL; + + return perf_event_task(task, NULL, 1, event); } =20 static int perf_event_emit_namespaces(struct perf_event *event, struct tas= k_struct *task) @@ -13115,7 +13173,7 @@ static void perf_event_exit_task_context(struct tas= k_struct *child) * won't get any samples after PERF_RECORD_EXIT. We can however still * get a few PERF_RECORD_READ events. */ - perf_event_task(child, child_ctx, 0); + perf_event_task(child, child_ctx, 0, NULL); =20 list_for_each_entry_safe(child_event, next, &child_ctx->event_list, event= _entry) perf_event_exit_event(child_event, child_ctx); @@ -13157,7 +13215,7 @@ void perf_event_exit_task(struct task_struct *child) * child contexts and sets child->perf_event_ctxp[] to NULL. * At this point we need to send EXIT events to cpu contexts. */ - perf_event_task(child, NULL, 0); + perf_event_task(child, NULL, 0, NULL); } =20 static void perf_free_event(struct perf_event *event, --=20 2.34.1 From nobody Thu Dec 18 18:43:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5F4E1C77B71 for ; Fri, 14 Apr 2023 08:23:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229732AbjDNIXy (ORCPT ); Fri, 14 Apr 2023 04:23:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33900 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230200AbjDNIXr (ORCPT ); Fri, 14 Apr 2023 04:23:47 -0400 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 38EB78F; Fri, 14 Apr 2023 01:23:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1681460611; x=1712996611; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=k9xICirPTs+XLNZnMSTUNHHk49e/SSv9s64WeLS7yIQ=; b=nXPByUpyyio0vmdQQDD/xoorBkijXOofEqiFlchUd+d7oB/vbHItpkr/ dL9M7252bMA2lCSt4dc+ZacK4OYyiifgTiLBRdz1iTm+swkAspdHcYsdT bpH5h5RLNM1/JUO650C60fQlzqRHUwc3WmyPhgoc+JySyOS79T7u26YiK ynR1ClorVNFEqgvh+hZOddvfGJPPiXllnrqGbPkbcz2k7jO+cqk6HZBuN 3Nnhwv+kYRPcP8khjYjv+sjnd/H2PS8tsLhZwjqLVX8sj2O9fEA6kPqjB 2iiLE+qfAPD7VtgW8RefJsBd5H2dtkB5gPAogw8xZaT9lYQr10w886GsN Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10679"; a="430708125" X-IronPort-AV: E=Sophos;i="5.99,195,1677571200"; d="scan'208";a="430708125" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2023 01:23:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10679"; a="683267520" X-IronPort-AV: E=Sophos;i="5.99,195,1677571200"; d="scan'208";a="683267520" Received: from ahunter6-mobl1.ger.corp.intel.com (HELO ahunter-VirtualBox.home\044ger.corp.intel.com) ([10.249.34.252]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2023 01:23:27 -0700 From: Adrian Hunter To: Peter Zijlstra Cc: Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RFC 3/5] perf: Add namespaces to the sideband ioctl Date: Fri, 14 Apr 2023 11:22:58 +0300 Message-Id: <20230414082300.34798-4-adrian.hunter@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230414082300.34798-1-adrian.hunter@intel.com> References: <20230414082300.34798-1-adrian.hunter@intel.com> MIME-Version: 1.0 Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Support the case of output to an active event, and return an error if output is not possible in that case. Set PERF_RECORD_MISC_STATUS_ONLY to differentiate the ioctl status-only sideband event from a "real" sideband event. Signed-off-by: Adrian Hunter --- kernel/events/core.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 4e76596d3bfb..ed4af231853a 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8364,8 +8364,7 @@ static int perf_event_namespaces_match(struct perf_ev= ent *event) return event->attr.namespaces; } =20 -static void perf_event_namespaces_output(struct perf_event *event, - void *data) +static int perf_event_namespaces_output(struct perf_event *event, void *da= ta) { struct perf_namespaces_event *namespaces_event =3D data; struct perf_output_handle handle; @@ -8374,7 +8373,7 @@ static void perf_event_namespaces_output(struct perf_= event *event, int ret; =20 if (!perf_event_namespaces_match(event)) - return; + return -ENOENT; =20 perf_event_header__init_id(&namespaces_event->event_id.header, &sample, event); @@ -8395,6 +8394,7 @@ static void perf_event_namespaces_output(struct perf_= event *event, perf_output_end(&handle); out: namespaces_event->event_id.header.size =3D header_size; + return ret; } =20 static void perf_fill_ns_link_info(struct perf_ns_link_info *ns_link_info, @@ -8414,20 +8414,20 @@ static void perf_fill_ns_link_info(struct perf_ns_l= ink_info *ns_link_info, } } =20 -void perf_event_namespaces(struct task_struct *task) +static int __perf_event_namespaces(struct task_struct *task, struct perf_e= vent *event) { struct perf_namespaces_event namespaces_event; struct perf_ns_link_info *ns_link_info; =20 if (!atomic_read(&nr_namespaces_events)) - return; + return -ENOENT; =20 namespaces_event =3D (struct perf_namespaces_event){ .task =3D task, .event_id =3D { .header =3D { .type =3D PERF_RECORD_NAMESPACES, - .misc =3D 0, + .misc =3D event ? PERF_RECORD_MISC_STATUS_ONLY : 0, .size =3D sizeof(namespaces_event.event_id), }, /* .pid */ @@ -8467,9 +8467,12 @@ void perf_event_namespaces(struct task_struct *task) task, &cgroupns_operations); #endif =20 - perf_iterate_sb(perf_event_namespaces_output, - &namespaces_event, - NULL); + return perf_output_sb(perf_event_namespaces_output, &namespaces_event, NU= LL, event); +} + +void perf_event_namespaces(struct task_struct *task) +{ + __perf_event_namespaces(task, NULL); } =20 /* @@ -12880,7 +12883,10 @@ static int perf_event_emit_fork(struct perf_event = *event, struct task_struct *ta =20 static int perf_event_emit_namespaces(struct perf_event *event, struct tas= k_struct *task) { - return -EINVAL; + if (!event->attr.namespaces) + return -EINVAL; + + return __perf_event_namespaces(task, event); } =20 static int perf_event_emit_comm(struct perf_event *event, struct task_stru= ct *task) --=20 2.34.1 From nobody Thu Dec 18 18:43:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 193F8C77B71 for ; Fri, 14 Apr 2023 08:24:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229553AbjDNIYA (ORCPT ); Fri, 14 Apr 2023 04:24:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230220AbjDNIXt (ORCPT ); Fri, 14 Apr 2023 04:23:49 -0400 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AFECF7EF5; Fri, 14 Apr 2023 01:23:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1681460614; x=1712996614; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3nHcjAW5hAXD3jrHcmKICBKZPcBY+tB2vS9Jj26IxgQ=; b=dglHk3STL+XoTEAcBm1p7GlojlLHnTIFjlP3TzcNoD4YIrk5PVTglCaZ SwruLGdz3Hu7q6wALVUpVLYliszc61pmLDesKZI7Pm1wQ+ekgNYYANhhn ySRb9EbGuXDjW1OMjH1Ehw8IfOc9vINvTkfs72oyoDiY269wpvFR0JPFX JCquoLQOybIx4JVDHz6YquGmWZhKnJiX2z7np+a3fpTs53UY2ZkZyXjir fhYkfwE6L0C4179o5b249s8pKg19hGBJmN/jCUGYsGxoxUlSgqUomXSgL nOR3O0QuFWfpeMAfV5dF5hcqk/kp1j7ZCVYjRM36YPbkI+DSxtdsvEMKf Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10679"; a="430708139" X-IronPort-AV: E=Sophos;i="5.99,195,1677571200"; d="scan'208";a="430708139" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2023 01:23:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10679"; a="683267542" X-IronPort-AV: E=Sophos;i="5.99,195,1677571200"; d="scan'208";a="683267542" Received: from ahunter6-mobl1.ger.corp.intel.com (HELO ahunter-VirtualBox.home\044ger.corp.intel.com) ([10.249.34.252]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2023 01:23:31 -0700 From: Adrian Hunter To: Peter Zijlstra Cc: Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RFC 4/5] perf: Add comm to the sideband ioctl Date: Fri, 14 Apr 2023 11:22:59 +0300 Message-Id: <20230414082300.34798-5-adrian.hunter@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230414082300.34798-1-adrian.hunter@intel.com> References: <20230414082300.34798-1-adrian.hunter@intel.com> MIME-Version: 1.0 Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Support the case of output to an active event, and return an error if output is not possible in that case. Set PERF_RECORD_MISC_STATUS_ONLY to differentiate the ioctl status-only sideband event from a "real" sideband event. Signed-off-by: Adrian Hunter --- kernel/events/core.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index ed4af231853a..cddc02c2e411 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8265,8 +8265,7 @@ static int perf_event_comm_match(struct perf_event *e= vent) return event->attr.comm; } =20 -static void perf_event_comm_output(struct perf_event *event, - void *data) +static int perf_event_comm_output(struct perf_event *event, void *data) { struct perf_comm_event *comm_event =3D data; struct perf_output_handle handle; @@ -8275,7 +8274,7 @@ static void perf_event_comm_output(struct perf_event = *event, int ret; =20 if (!perf_event_comm_match(event)) - return; + return -ENOENT; =20 perf_event_header__init_id(&comm_event->event_id.header, &sample, event); ret =3D perf_output_begin(&handle, &sample, event, @@ -8296,9 +8295,10 @@ static void perf_event_comm_output(struct perf_event= *event, perf_output_end(&handle); out: comm_event->event_id.header.size =3D size; + return ret; } =20 -static void perf_event_comm_event(struct perf_comm_event *comm_event) +static int perf_event_comm_event(struct perf_comm_event *comm_event, struc= t perf_event *event) { char comm[TASK_COMM_LEN]; unsigned int size; @@ -8312,17 +8312,15 @@ static void perf_event_comm_event(struct perf_comm_= event *comm_event) =20 comm_event->event_id.header.size =3D sizeof(comm_event->event_id) + size; =20 - perf_iterate_sb(perf_event_comm_output, - comm_event, - NULL); + return perf_output_sb(perf_event_comm_output, comm_event, NULL, event); } =20 -void perf_event_comm(struct task_struct *task, bool exec) +static int __perf_event_comm(struct task_struct *task, bool exec, struct p= erf_event *event) { struct perf_comm_event comm_event; =20 if (!atomic_read(&nr_comm_events)) - return; + return -ENOENT; =20 comm_event =3D (struct perf_comm_event){ .task =3D task, @@ -8331,7 +8329,8 @@ void perf_event_comm(struct task_struct *task, bool e= xec) .event_id =3D { .header =3D { .type =3D PERF_RECORD_COMM, - .misc =3D exec ? PERF_RECORD_MISC_COMM_EXEC : 0, + .misc =3D (exec ? PERF_RECORD_MISC_COMM_EXEC : 0) | + (event ? PERF_RECORD_MISC_STATUS_ONLY : 0), /* .size */ }, /* .pid */ @@ -8339,7 +8338,12 @@ void perf_event_comm(struct task_struct *task, bool = exec) }, }; =20 - perf_event_comm_event(&comm_event); + return perf_event_comm_event(&comm_event, event); +} + +void perf_event_comm(struct task_struct *task, bool exec) +{ + __perf_event_comm(task, exec, NULL); } =20 /* @@ -12891,7 +12895,10 @@ static int perf_event_emit_namespaces(struct perf_= event *event, struct task_stru =20 static int perf_event_emit_comm(struct perf_event *event, struct task_stru= ct *task) { - return -EINVAL; + if (!event->attr.comm) + return -EINVAL; + + return __perf_event_comm(task, false, event); } =20 static int perf_event_emit_mmap(struct perf_event *event, struct task_stru= ct *task) --=20 2.34.1 From nobody Thu Dec 18 18:43:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46CFCC77B70 for ; Fri, 14 Apr 2023 08:24:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230261AbjDNIYE (ORCPT ); Fri, 14 Apr 2023 04:24:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34104 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230177AbjDNIXv (ORCPT ); Fri, 14 Apr 2023 04:23:51 -0400 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6BBEA83F6; Fri, 14 Apr 2023 01:23:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1681460618; x=1712996618; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KlLl00c1BkbXcaNS+veMVCoA8VHv6YdBHnPGvXsCuZw=; b=GCDCeErIVi60cfi8c5dY0oJLqOLNo1xxN5TNGX0GdZQWxZZNnbR2F/eq JTrJ0P7HUaEQtt+FfZ/VTDCRLMMxs53/YJL6WN4/3/M66gDo9E/ldDQC8 sOTeWzBPONk5TsUWGgSPQLMnbMXpsgo+A9l8W7Z0g8U1Aeh2mOYKvg8YV baSO2n0LknY1XLaMmPgMqMeAmDTh0sCjE27RFlMof/fMYxVdlDYutZYln O3TfRSE97yak4jwRFPy48pO1q0GN/cCSFtDNJFOUSfr3WaJSfZC0BLLyi BzTsKpwwt4+1LCxmktTqqDQvahaQ8uA4URbjLelJES0i6FV++gkaNWoaG Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10679"; a="430708155" X-IronPort-AV: E=Sophos;i="5.99,195,1677571200"; d="scan'208";a="430708155" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2023 01:23:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10679"; a="683267565" X-IronPort-AV: E=Sophos;i="5.99,195,1677571200"; d="scan'208";a="683267565" Received: from ahunter6-mobl1.ger.corp.intel.com (HELO ahunter-VirtualBox.home\044ger.corp.intel.com) ([10.249.34.252]) by orsmga007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Apr 2023 01:23:34 -0700 From: Adrian Hunter To: Peter Zijlstra Cc: Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RFC 5/5] perf: Add mmap to the sideband ioctl Date: Fri, 14 Apr 2023 11:23:00 +0300 Message-Id: <20230414082300.34798-6-adrian.hunter@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230414082300.34798-1-adrian.hunter@intel.com> References: <20230414082300.34798-1-adrian.hunter@intel.com> MIME-Version: 1.0 Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Support the case of output to an active event, and return an error if output is not possible in that case. Set PERF_RECORD_MISC_STATUS_ONLY to differentiate the ioctl status-only sideband event from a "real" sideband event. Set the mmap pid/tid from the appropriate task. Signed-off-by: Adrian Hunter --- kernel/events/core.c | 91 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 18 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index cddc02c2e411..317bdf5f919a 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8584,6 +8584,7 @@ static void perf_event_cgroup(struct cgroup *cgrp) =20 struct perf_mmap_event { struct vm_area_struct *vma; + struct task_struct *task; =20 const char *file_name; int file_size; @@ -8605,19 +8606,25 @@ struct perf_mmap_event { } event_id; }; =20 +static int perf_event_mmap_match_vma(struct perf_event *event, + struct vm_area_struct *vma) +{ + int executable =3D vma->vm_flags & VM_EXEC; + + return (!executable && event->attr.mmap_data) || + (executable && (event->attr.mmap || event->attr.mmap2)); +} + static int perf_event_mmap_match(struct perf_event *event, void *data) { struct perf_mmap_event *mmap_event =3D data; struct vm_area_struct *vma =3D mmap_event->vma; - int executable =3D vma->vm_flags & VM_EXEC; =20 - return (!executable && event->attr.mmap_data) || - (executable && (event->attr.mmap || event->attr.mmap2)); + return perf_event_mmap_match_vma(event, vma); } =20 -static void perf_event_mmap_output(struct perf_event *event, - void *data) +static int perf_event_mmap_output(struct perf_event *event, void *data) { struct perf_mmap_event *mmap_event =3D data; struct perf_output_handle handle; @@ -8628,7 +8635,7 @@ static void perf_event_mmap_output(struct perf_event = *event, int ret; =20 if (!perf_event_mmap_match(event, data)) - return; + return -ENOENT; =20 if (event->attr.mmap2) { mmap_event->event_id.header.type =3D PERF_RECORD_MMAP2; @@ -8646,8 +8653,8 @@ static void perf_event_mmap_output(struct perf_event = *event, if (ret) goto out; =20 - mmap_event->event_id.pid =3D perf_event_pid(event, current); - mmap_event->event_id.tid =3D perf_event_tid(event, current); + mmap_event->event_id.pid =3D perf_event_pid(event, mmap_event->task); + mmap_event->event_id.tid =3D perf_event_tid(event, mmap_event->task); =20 use_build_id =3D event->attr.build_id && mmap_event->build_id_size; =20 @@ -8681,9 +8688,10 @@ static void perf_event_mmap_output(struct perf_event= *event, out: mmap_event->event_id.header.size =3D size; mmap_event->event_id.header.type =3D type; + return ret; } =20 -static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) +static int perf_event_mmap_event(struct perf_mmap_event *mmap_event, struc= t perf_event *event) { struct vm_area_struct *vma =3D mmap_event->vma; struct file *file =3D vma->vm_file; @@ -8694,6 +8702,7 @@ static void perf_event_mmap_event(struct perf_mmap_ev= ent *mmap_event) char tmp[16]; char *buf =3D NULL; char *name; + int ret; =20 if (vma->vm_flags & VM_READ) prot |=3D PROT_READ; @@ -8795,11 +8804,10 @@ static void perf_event_mmap_event(struct perf_mmap_= event *mmap_event) if (atomic_read(&nr_build_id_events)) build_id_parse(vma, mmap_event->build_id, &mmap_event->build_id_size); =20 - perf_iterate_sb(perf_event_mmap_output, - mmap_event, - NULL); + ret =3D perf_output_sb(perf_event_mmap_output, mmap_event, NULL, event); =20 kfree(buf); + return ret; } =20 /* @@ -8899,21 +8907,25 @@ static void perf_addr_filters_adjust(struct vm_area= _struct *vma) rcu_read_unlock(); } =20 -void perf_event_mmap(struct vm_area_struct *vma) +static int __perf_event_mmap(struct vm_area_struct *vma, + struct perf_event *event, + struct task_struct *task) { struct perf_mmap_event mmap_event; =20 if (!atomic_read(&nr_mmap_events)) - return; + return -ENOENT; =20 mmap_event =3D (struct perf_mmap_event){ .vma =3D vma, + .task =3D task ?: current, /* .file_name */ /* .file_size */ .event_id =3D { .header =3D { .type =3D PERF_RECORD_MMAP, - .misc =3D PERF_RECORD_MISC_USER, + .misc =3D PERF_RECORD_MISC_USER | + (event ? PERF_RECORD_MISC_STATUS_ONLY : 0), /* .size */ }, /* .pid */ @@ -8930,8 +8942,14 @@ void perf_event_mmap(struct vm_area_struct *vma) /* .flags (attr_mmap2 only) */ }; =20 - perf_addr_filters_adjust(vma); - perf_event_mmap_event(&mmap_event); + if (!event) + perf_addr_filters_adjust(vma); + return perf_event_mmap_event(&mmap_event, event); +} + +void perf_event_mmap(struct vm_area_struct *vma) +{ + __perf_event_mmap(vma, NULL, NULL); } =20 void perf_event_aux_event(struct perf_event *event, unsigned long head, @@ -12901,9 +12919,46 @@ static int perf_event_emit_comm(struct perf_event = *event, struct task_struct *ta return __perf_event_comm(task, false, event); } =20 +static int perf_event_mm_emit_mmap(struct perf_event *event, + struct task_struct *task, + struct mm_struct *mm) +{ + struct vm_area_struct *vma; + VMA_ITERATOR(vmi, mm, 0); + int err; + + for_each_vma(vmi, vma) { + if (!perf_event_mmap_match_vma(event, vma)) + continue; + err =3D __perf_event_mmap(vma, event, task); + if (err) + return err; + } + + return 0; +} + static int perf_event_emit_mmap(struct perf_event *event, struct task_stru= ct *task) { - return -EINVAL; + struct mm_struct *mm; + int err; + + if (!event->attr.mmap_data && !event->attr.mmap && !event->attr.mmap2) + return -EINVAL; + + mm =3D get_task_mm(task); + if (!mm) + return 0; + + mmap_read_lock(mm); + + err =3D perf_event_mm_emit_mmap(event, task, mm); + + mmap_read_unlock(mm); + + mmput(mm); + + return err; } =20 static int perf_event_emit_sideband(struct perf_event *event, void __user = *arg) --=20 2.34.1