Hi Menglong, Sorry, one more thing. > @@ -260,14 +263,12 @@ static int fprobe_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops, > if (WARN_ON_ONCE(!fregs)) > return 0; > > - first = node = find_first_fprobe_node(func); > - if (unlikely(!first)) > - return 0; > - > + rcu_read_lock(); Actually, we don't need these rcu_read_lock() in this function, because the caller function_graph_enter_regs() uses ftrace_test_recursion_trylock() which disables preemption. Thus we don't need to do this again here. > + head = rhltable_lookup(&fprobe_ip_table, &func, fprobe_rht_params); > reserved_words = 0; > - hlist_for_each_entry_from_rcu(node, hlist) { > + rhl_for_each_entry_rcu(node, pos, head, hlist) { > if (node->addr != func) > - break; > + continue; > fp = READ_ONCE(node->fp); > if (!fp || !fp->exit_handler) > continue; > @@ -278,17 +279,19 @@ static int fprobe_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops, > reserved_words += > FPROBE_HEADER_SIZE_IN_LONG + SIZE_IN_LONG(fp->entry_data_size); > } > - node = first; > + rcu_read_unlock(); > if (reserved_words) { > fgraph_data = fgraph_reserve_data(gops->idx, reserved_words * sizeof(long)); > if (unlikely(!fgraph_data)) { > - hlist_for_each_entry_from_rcu(node, hlist) { > + rcu_read_lock(); Ditto. > + rhl_for_each_entry_rcu(node, pos, head, hlist) { > if (node->addr != func) > - break; > + continue; > fp = READ_ONCE(node->fp); > if (fp && !fprobe_disabled(fp)) > fp->nmissed++; > } > + rcu_read_unlock(); > return 0; > } > } Thank you, -- Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx>