@@ -1595,12 +1595,15 @@ static struct dyn_ftrace *lookup_rec(unsigned long start, unsigned long end)
15951595unsigned long ftrace_location_range (unsigned long start , unsigned long end )
15961596{
15971597 struct dyn_ftrace * rec ;
1598+ unsigned long ip = 0 ;
15981599
1600+ rcu_read_lock ();
15991601 rec = lookup_rec (start , end );
16001602 if (rec )
1601- return rec -> ip ;
1603+ ip = rec -> ip ;
1604+ rcu_read_unlock ();
16021605
1603- return 0 ;
1606+ return ip ;
16041607}
16051608
16061609/**
@@ -1614,25 +1617,22 @@ unsigned long ftrace_location_range(unsigned long start, unsigned long end)
16141617 */
16151618unsigned long ftrace_location (unsigned long ip )
16161619{
1617- struct dyn_ftrace * rec ;
1620+ unsigned long loc ;
16181621 unsigned long offset ;
16191622 unsigned long size ;
16201623
1621- rec = lookup_rec (ip , ip );
1622- if (!rec ) {
1624+ loc = ftrace_location_range (ip , ip );
1625+ if (!loc ) {
16231626 if (!kallsyms_lookup_size_offset (ip , & size , & offset ))
16241627 goto out ;
16251628
16261629 /* map sym+0 to __fentry__ */
16271630 if (!offset )
1628- rec = lookup_rec (ip , ip + size - 1 );
1631+ loc = ftrace_location_range (ip , ip + size - 1 );
16291632 }
16301633
1631- if (rec )
1632- return rec -> ip ;
1633-
16341634out :
1635- return 0 ;
1635+ return loc ;
16361636}
16371637
16381638/**
@@ -2538,7 +2538,6 @@ ftrace_find_unique_ops(struct dyn_ftrace *rec)
25382538/* Protected by rcu_tasks for reading, and direct_mutex for writing */
25392539static struct ftrace_hash __rcu * direct_functions = EMPTY_HASH ;
25402540static DEFINE_MUTEX (direct_mutex );
2541- int ftrace_direct_func_count ;
25422541
25432542/*
25442543 * Search the direct_functions hash to see if the given instruction pointer
@@ -4201,12 +4200,12 @@ static int
42014200add_rec_by_index (struct ftrace_hash * hash , struct ftrace_glob * func_g ,
42024201 int clear_filter )
42034202{
4204- long index = simple_strtoul ( func_g -> search , NULL , 0 ) ;
4203+ long index ;
42054204 struct ftrace_page * pg ;
42064205 struct dyn_ftrace * rec ;
42074206
42084207 /* The index starts at 1 */
4209- if (-- index < 0 )
4208+ if (kstrtoul ( func_g -> search , 0 , & index ) || -- index < 0 )
42104209 return 0 ;
42114210
42124211 do_for_each_ftrace_rec (pg , rec ) {
@@ -5317,14 +5316,6 @@ ftrace_set_addr(struct ftrace_ops *ops, unsigned long *ips, unsigned int cnt,
53175316
53185317#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
53195318
5320- struct ftrace_direct_func {
5321- struct list_head next ;
5322- unsigned long addr ;
5323- int count ;
5324- };
5325-
5326- static LIST_HEAD (ftrace_direct_funcs );
5327-
53285319static int register_ftrace_function_nolock (struct ftrace_ops * ops );
53295320
53305321/*
@@ -5365,6 +5356,13 @@ static void remove_direct_functions_hash(struct ftrace_hash *hash, unsigned long
53655356 }
53665357}
53675358
5359+ static void register_ftrace_direct_cb (struct rcu_head * rhp )
5360+ {
5361+ struct ftrace_hash * fhp = container_of (rhp , struct ftrace_hash , rcu );
5362+
5363+ free_ftrace_hash (fhp );
5364+ }
5365+
53685366/**
53695367 * register_ftrace_direct - Call a custom trampoline directly
53705368 * for multiple functions registered in @ops
@@ -5463,10 +5461,8 @@ int register_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
54635461 out_unlock :
54645462 mutex_unlock (& direct_mutex );
54655463
5466- if (free_hash && free_hash != EMPTY_HASH ) {
5467- synchronize_rcu_tasks ();
5468- free_ftrace_hash (free_hash );
5469- }
5464+ if (free_hash && free_hash != EMPTY_HASH )
5465+ call_rcu_tasks (& free_hash -> rcu , register_ftrace_direct_cb );
54705466
54715467 if (new_hash )
54725468 free_ftrace_hash (new_hash );
@@ -5816,9 +5812,8 @@ __setup("ftrace_graph_notrace=", set_graph_notrace_function);
58165812
58175813static int __init set_graph_max_depth_function (char * str )
58185814{
5819- if (!str )
5815+ if (!str || kstrtouint ( str , 0 , & fgraph_max_depth ) )
58205816 return 0 ;
5821- fgraph_max_depth = simple_strtoul (str , NULL , 0 );
58225817 return 1 ;
58235818}
58245819__setup ("ftrace_graph_max_depth=" , set_graph_max_depth_function );
@@ -6595,6 +6590,8 @@ static int ftrace_process_locs(struct module *mod,
65956590 /* We should have used all pages unless we skipped some */
65966591 if (pg_unuse ) {
65976592 WARN_ON (!skipped );
6593+ /* Need to synchronize with ftrace_location_range() */
6594+ synchronize_rcu ();
65986595 ftrace_free_pages (pg_unuse );
65996596 }
66006597 return ret ;
@@ -6808,6 +6805,9 @@ void ftrace_release_mod(struct module *mod)
68086805 out_unlock :
68096806 mutex_unlock (& ftrace_lock );
68106807
6808+ /* Need to synchronize with ftrace_location_range() */
6809+ if (tmp_page )
6810+ synchronize_rcu ();
68116811 for (pg = tmp_page ; pg ; pg = tmp_page ) {
68126812
68136813 /* Needs to be called outside of ftrace_lock */
@@ -7141,6 +7141,7 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr)
71417141 unsigned long start = (unsigned long )(start_ptr );
71427142 unsigned long end = (unsigned long )(end_ptr );
71437143 struct ftrace_page * * last_pg = & ftrace_pages_start ;
7144+ struct ftrace_page * tmp_page = NULL ;
71447145 struct ftrace_page * pg ;
71457146 struct dyn_ftrace * rec ;
71467147 struct dyn_ftrace key ;
@@ -7182,12 +7183,8 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr)
71827183 ftrace_update_tot_cnt -- ;
71837184 if (!pg -> index ) {
71847185 * last_pg = pg -> next ;
7185- if (pg -> records ) {
7186- free_pages ((unsigned long )pg -> records , pg -> order );
7187- ftrace_number_of_pages -= 1 << pg -> order ;
7188- }
7189- ftrace_number_of_groups -- ;
7190- kfree (pg );
7186+ pg -> next = tmp_page ;
7187+ tmp_page = pg ;
71917188 pg = container_of (last_pg , struct ftrace_page , next );
71927189 if (!(* last_pg ))
71937190 ftrace_pages = pg ;
@@ -7204,6 +7201,11 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr)
72047201 clear_func_from_hashes (func );
72057202 kfree (func );
72067203 }
7204+ /* Need to synchronize with ftrace_location_range() */
7205+ if (tmp_page ) {
7206+ synchronize_rcu ();
7207+ ftrace_free_pages (tmp_page );
7208+ }
72077209}
72087210
72097211void __init ftrace_free_init_mem (void )
0 commit comments