From mboxrd@z Thu Jan 1 00:00:00 1970 From: Song Liu Subject: Re: [PATCH bpf-next 1/3] perf/core: introduce perf_event_mmap_bpf_prog Date: Wed, 19 Sep 2018 23:30:17 +0000 Message-ID: <4DBB524C-09B1-46BD-A56E-1E372E87F2E8@fb.com> References: <20180919223935.999270-1-ast@kernel.org> <20180919223935.999270-2-ast@kernel.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Cc: "David S . Miller" , "daniel@iogearbox.net" , "peterz@infradead.org" , "acme@kernel.org" , "netdev@vger.kernel.org" , Kernel Team To: Alexei Starovoitov Return-path: Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:58810 "EHLO mx0b-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725993AbeITFLT (ORCPT ); Thu, 20 Sep 2018 01:11:19 -0400 In-Reply-To: <20180919223935.999270-2-ast@kernel.org> Content-Language: en-US Content-ID: Sender: netdev-owner@vger.kernel.org List-ID: > On Sep 19, 2018, at 3:39 PM, Alexei Starovoitov wrote: >=20 > introduce perf_event_mmap_bpf_prog() helper to emit RECORD_MMAP events > into perf ring buffer. > It's used by bpf load/unload logic to notify user space of addresses > and names of JITed bpf programs. >=20 > Note that event->mmap.pid =3D=3D -1 is an existing indicator of kernel ev= ent. > In addition use event->mmap.tid =3D=3D BPF_FS_MAGIC to indicate bpf relat= ed > RECORD_MMAP event. >=20 > Alternatively it's possible to introduce new 'enum perf_event_type' comma= nd > specificially for bpf prog load/unload, but existing RECORD_MMAP > is very close, so the choice made by this patch is to extend it. >=20 > Signed-off-by: Alexei Starovoitov Acked-by: Song Liu I guess we should also use this for kernel modules load/unload?=20 > --- > include/linux/perf_event.h | 1 + > kernel/events/core.c | 44 +++++++++++++++++++++++++++++++++----- > 2 files changed, 40 insertions(+), 5 deletions(-) >=20 > diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h > index 53c500f0ca79..0e79af83138f 100644 > --- a/include/linux/perf_event.h > +++ b/include/linux/perf_event.h > @@ -1113,6 +1113,7 @@ static inline void perf_event_task_sched_out(struct= task_struct *prev, > } >=20 > extern void perf_event_mmap(struct vm_area_struct *vma); > +void perf_event_mmap_bpf_prog(u64 start, u64 len, char *name, int size); > extern struct perf_guest_info_callbacks *perf_guest_cbs; > extern int perf_register_guest_info_callbacks(struct perf_guest_info_call= backs *callbacks); > extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_ca= llbacks *callbacks); > diff --git a/kernel/events/core.c b/kernel/events/core.c > index 2a62b96600ad..c48244ddf993 100644 > --- a/kernel/events/core.c > +++ b/kernel/events/core.c > @@ -7152,7 +7152,7 @@ static int perf_event_mmap_match(struct perf_event = *event, > { > 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; > + int executable =3D !vma || vma->vm_flags & VM_EXEC; >=20 > return (!executable && event->attr.mmap_data) || > (executable && (event->attr.mmap || event->attr.mmap2)); > @@ -7165,12 +7165,13 @@ static void perf_event_mmap_output(struct perf_ev= ent *event, > struct perf_output_handle handle; > struct perf_sample_data sample; > int size =3D mmap_event->event_id.header.size; > + bool bpf_event =3D !mmap_event->vma; > int ret; >=20 > if (!perf_event_mmap_match(event, data)) > return; >=20 > - if (event->attr.mmap2) { > + if (event->attr.mmap2 && !bpf_event) { > mmap_event->event_id.header.type =3D PERF_RECORD_MMAP2; > mmap_event->event_id.header.size +=3D sizeof(mmap_event->maj); > mmap_event->event_id.header.size +=3D sizeof(mmap_event->min); > @@ -7186,12 +7187,14 @@ static void perf_event_mmap_output(struct perf_ev= ent *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); > + if (!bpf_event) { > + mmap_event->event_id.pid =3D perf_event_pid(event, current); > + mmap_event->event_id.tid =3D perf_event_tid(event, current); > + } >=20 > perf_output_put(&handle, mmap_event->event_id); >=20 > - if (event->attr.mmap2) { > + if (event->attr.mmap2 && !bpf_event) { > perf_output_put(&handle, mmap_event->maj); > perf_output_put(&handle, mmap_event->min); > perf_output_put(&handle, mmap_event->ino); > @@ -7448,6 +7451,37 @@ void perf_event_mmap(struct vm_area_struct *vma) > perf_event_mmap_event(&mmap_event); > } >=20 > +void perf_event_mmap_bpf_prog(u64 start, u64 len, char *name, int size) > +{ > + struct perf_mmap_event mmap_event; > + > + if (!atomic_read(&nr_mmap_events)) > + return; > + > + if (!IS_ALIGNED(size, sizeof(u64))) { > + WARN_ONCE(1, "size is not aligned\n"); > + return; > + } > + > + mmap_event =3D (struct perf_mmap_event){ > + .file_name =3D name, > + .file_size =3D size, > + .event_id =3D { > + .header =3D { > + .type =3D PERF_RECORD_MMAP, > + .misc =3D PERF_RECORD_MISC_KERNEL, > + .size =3D sizeof(mmap_event.event_id) + size, > + }, > + .pid =3D -1, /* indicates kernel */ > + .tid =3D BPF_FS_MAGIC, /* bpf mmap event */ > + .start =3D start, > + .len =3D len, > + .pgoff =3D start, > + }, > + }; > + perf_iterate_sb(perf_event_mmap_output, &mmap_event, NULL); > +} > + > void perf_event_aux_event(struct perf_event *event, unsigned long head, > unsigned long size, u64 flags) > { > --=20 > 2.17.1 >=20