On Thu, Dec 06, 2018 at 09:24:55AM +0100, Jiri Olsa wrote: > On Thu, Dec 06, 2018 at 09:10:28AM +0100, Peter Zijlstra wrote: > > On Wed, Dec 05, 2018 at 05:05:02PM +0100, Jiri Olsa wrote: > > > +static void trace_block_syscall(struct pt_regs *regs, bool enter) > > > +{ > > > + current->perf_blocked = true; > > > + > > > + do { > > > + schedule_timeout(100 * HZ); > > > + current->perf_blocked_cnt = 0; > > > + > > > + if (enter) { > > > + /* perf syscalls:* enter */ > > > + perf_trace_syscall_enter(regs); > > > + > > > + /* perf raw_syscalls:* enter */ > > > + perf_trace_sys_enter(&event_sys_enter, regs, > > > regs->orig_ax); > > > + } else { > > > + /* perf syscalls:* enter */ > > > + perf_trace_syscall_exit(regs); > > > + > > > + /* perf raw_syscalls:* enter */ > > > + perf_trace_sys_exit(&event_sys_exit, regs, regs->ax); > > > + } > > > + } while (current->perf_blocked_cnt); > > > + > > > + current->perf_blocked = false; > > > +} > > > > I don't understand this.. why are we using schedule_timeout() and all > > that? > > the idea is to block the process and try to deliver the event later > > the ring buffer space is freed by user space process moving the tail > pointer, so I can't see doing this other way than polling
Right, figured that out. I really really hate this stuff. poll-waiting fundamentally stinks, but also perf is designed to not/minimally interfere with the observed tasks, as is ftrace. And bolting, as it really doesn't fit in the fundamental design, this fugly thing on top for this special case.. urgh.