Again, looks good to me, but I have a minor nit. Feel free to ignore. On 03/12, Andrii Nakryiko wrote: > > static void __uprobe_trace_func(struct trace_uprobe *tu, > unsigned long func, struct pt_regs *regs, > - struct uprobe_cpu_buffer *ucb, > + struct uprobe_cpu_buffer **ucbp, > struct trace_event_file *trace_file) > { > struct uprobe_trace_entry_head *entry; > struct trace_event_buffer fbuffer; > + struct uprobe_cpu_buffer *ucb; > void *data; > int size, esize; > struct trace_event_call *call = trace_probe_event_call(&tu->tp); > > + ucb = *ucbp; > + if (!ucb) { > + ucb = prepare_uprobe_buffer(tu, regs); > + *ucbp = ucb; > + } perhaps it would be more clean to pass ucbp to prepare_uprobe_buffer() and change it to do if (*ucbp) return *ucbp; at the start. Then __uprobe_trace_func() and __uprobe_perf_func() can simply do ucb = prepare_uprobe_buffer(tu, regs, ucbp); > - uprobe_buffer_put(ucb); > + if (ucb) > + uprobe_buffer_put(ucb); Similarly, I think the "ucb != NULL" check should be shifted into uprobe_buffer_put(). Oleg.