Em Tue, Mar 29, 2016 at 02:06:09PM +0200, Peter Zijlstra escreveu: > On Wed, Mar 23, 2016 at 11:24:37AM -0700, kan.li...@intel.com wrote: > > The V2 patch is mainly based on Peter's suggestion. But I didn't rename > > perf_event_aux to perf_event_sb. Because it looks there are many aux things > > in the codes, e.g. AUX area in ring buffer. I'm not sure if we need to > > change > > all aux to sb. We may do the rename later in separate patch. > > Right.. no problem doing that in a separate patch. > > > +static void perf_event_sb_mask(unsigned int sb_mask, > > + perf_event_aux_output_cb output, > > + void *data) > > +{ > > + int sb; > > + > > + for (sb = 0; sb < sb_nr; sb++) { > > + if (!(sb_mask & (1 << sb))) > > + continue; > > + perf_event_sb_iterate(sb, output, data); > > + } > > +} > > > @@ -5852,7 +5910,8 @@ static void perf_event_task(struct task_struct *task, > > > > perf_event_aux(perf_event_task_output, > > &task_event, > > - task_ctx); > > + task_ctx, > > + (1 << sb_task) | (1 << sb_mmap) | (1 << sb_comm)); > > } > > So one side-effect of this change is that the above event can be > delivered 3 times if you're 'lucky'. > > Acme; does userspace care?
So, when processing a PERF_RECORD_FORK there is some sanity checks in machine__process_fork_event() (tools/perf/util/machine.c), and one that is affected by copies is: struct thread *thread = machine__find_thread(machine, event->fork.pid, event->fork.tid); <SNIP> /* if a thread currently exists for the thread id remove it */ if (thread != NULL) { machine__remove_thread(machine, thread); thread__put(thread); } thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); <SNIP> So we conceivably may end up with multiple 'struct thread' pointing to the same kernel thread, being held as references somewhere (in a hist_entry, for instance, if a PERF_RECORD_SAMPLE happens mid sentence). It probably will cope, but can't we just emit one single record? PERF_RECORD_EXIT are ok: int machine__process_exit_event(struct machine *machine, union perf_event *event, struct perf_sample *sample __maybe_unused) { struct thread *thread = machine__find_thread(machine, event->fork.pid, event->fork.tid); if (dump_trace) perf_event__fprintf_task(event, stdout); if (thread != NULL) { thread__exited(thread); thread__put(thread); } return 0; } PERF_RECORD_COMM will unecessarily add a new COMM to its list, leading tooling to think that there was a prctl(PR_SET_NAME). This could conceivably be annoyed away by checking if the "new" COMM is the current one, again, can't the kernel emit just one record? - Arnaldo