Skip to content

Commit 26efd79

Browse files
Zheng Yejianrostedt
authored andcommitted
ftrace: Fix possible warning on checking all pages used in ftrace_process_locs()
As comments in ftrace_process_locs(), there may be NULL pointers in mcount_loc section: > Some architecture linkers will pad between > the different mcount_loc sections of different > object files to satisfy alignments. > Skip any NULL pointers. After commit 20e5227 ("ftrace: allow NULL pointers in mcount_loc"), NULL pointers will be accounted when allocating ftrace pages but skipped before adding into ftrace pages, this may result in some pages not being used. Then after commit 706c81f ("ftrace: Remove extra helper functions"), warning may occur at: WARN_ON(pg->next); To fix it, only warn for case that no pointers skipped but pages not used up, then free those unused pages after releasing ftrace_lock. Link: https://lore.kernel.org/linux-trace-kernel/[email protected] Cc: [email protected] Fixes: 706c81f ("ftrace: Remove extra helper functions") Suggested-by: Steven Rostedt <[email protected]> Signed-off-by: Zheng Yejian <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 7e42907 commit 26efd79

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

kernel/trace/ftrace.c

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3305,6 +3305,22 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count)
33053305
return cnt;
33063306
}
33073307

3308+
static void ftrace_free_pages(struct ftrace_page *pages)
3309+
{
3310+
struct ftrace_page *pg = pages;
3311+
3312+
while (pg) {
3313+
if (pg->records) {
3314+
free_pages((unsigned long)pg->records, pg->order);
3315+
ftrace_number_of_pages -= 1 << pg->order;
3316+
}
3317+
pages = pg->next;
3318+
kfree(pg);
3319+
pg = pages;
3320+
ftrace_number_of_groups--;
3321+
}
3322+
}
3323+
33083324
static struct ftrace_page *
33093325
ftrace_allocate_pages(unsigned long num_to_init)
33103326
{
@@ -3343,17 +3359,7 @@ ftrace_allocate_pages(unsigned long num_to_init)
33433359
return start_pg;
33443360

33453361
free_pages:
3346-
pg = start_pg;
3347-
while (pg) {
3348-
if (pg->records) {
3349-
free_pages((unsigned long)pg->records, pg->order);
3350-
ftrace_number_of_pages -= 1 << pg->order;
3351-
}
3352-
start_pg = pg->next;
3353-
kfree(pg);
3354-
pg = start_pg;
3355-
ftrace_number_of_groups--;
3356-
}
3362+
ftrace_free_pages(start_pg);
33573363
pr_info("ftrace: FAILED to allocate memory for functions\n");
33583364
return NULL;
33593365
}
@@ -6471,9 +6477,11 @@ static int ftrace_process_locs(struct module *mod,
64716477
unsigned long *start,
64726478
unsigned long *end)
64736479
{
6480+
struct ftrace_page *pg_unuse = NULL;
64746481
struct ftrace_page *start_pg;
64756482
struct ftrace_page *pg;
64766483
struct dyn_ftrace *rec;
6484+
unsigned long skipped = 0;
64776485
unsigned long count;
64786486
unsigned long *p;
64796487
unsigned long addr;
@@ -6536,8 +6544,10 @@ static int ftrace_process_locs(struct module *mod,
65366544
* object files to satisfy alignments.
65376545
* Skip any NULL pointers.
65386546
*/
6539-
if (!addr)
6547+
if (!addr) {
6548+
skipped++;
65406549
continue;
6550+
}
65416551

65426552
end_offset = (pg->index+1) * sizeof(pg->records[0]);
65436553
if (end_offset > PAGE_SIZE << pg->order) {
@@ -6551,8 +6561,10 @@ static int ftrace_process_locs(struct module *mod,
65516561
rec->ip = addr;
65526562
}
65536563

6554-
/* We should have used all pages */
6555-
WARN_ON(pg->next);
6564+
if (pg->next) {
6565+
pg_unuse = pg->next;
6566+
pg->next = NULL;
6567+
}
65566568

65576569
/* Assign the last page to ftrace_pages */
65586570
ftrace_pages = pg;
@@ -6574,6 +6586,11 @@ static int ftrace_process_locs(struct module *mod,
65746586
out:
65756587
mutex_unlock(&ftrace_lock);
65766588

6589+
/* We should have used all pages unless we skipped some */
6590+
if (pg_unuse) {
6591+
WARN_ON(!skipped);
6592+
ftrace_free_pages(pg_unuse);
6593+
}
65776594
return ret;
65786595
}
65796596

0 commit comments

Comments
 (0)