Patch "ftrace: Fix possible warning on checking all pages used in ftrace_process_locs()" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    ftrace: Fix possible warning on checking all pages used in ftrace_process_locs()

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     ftrace-fix-possible-warning-on-checking-all-pages-us.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 7e5dec206b49d9eb7381362f5a619aaf20226786
Author: Zheng Yejian <zhengyejian1@xxxxxxxxxx>
Date:   Wed Jul 12 14:04:52 2023 +0800

    ftrace: Fix possible warning on checking all pages used in ftrace_process_locs()
    
    [ Upstream commit 26efd79c4624294e553aeaa3439c646729bad084 ]
    
    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 20e5227e9f55 ("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 706c81f87f84 ("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/20230712060452.3175675-1-zhengyejian1@xxxxxxxxxx
    
    Cc: stable@xxxxxxxxxxxxxxx
    Fixes: 706c81f87f84 ("ftrace: Remove extra helper functions")
    Suggested-by: Steven Rostedt <rostedt@xxxxxxxxxxx>
    Signed-off-by: Zheng Yejian <zhengyejian1@xxxxxxxxxx>
    Signed-off-by: Steven Rostedt (Google) <rostedt@xxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index aa2530cbcb8fd..412505d948651 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3037,6 +3037,22 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count)
 	return cnt;
 }
 
+static void ftrace_free_pages(struct ftrace_page *pages)
+{
+	struct ftrace_page *pg = pages;
+
+	while (pg) {
+		if (pg->records) {
+			free_pages((unsigned long)pg->records, pg->order);
+			ftrace_number_of_pages -= 1 << pg->order;
+		}
+		pages = pg->next;
+		kfree(pg);
+		pg = pages;
+		ftrace_number_of_groups--;
+	}
+}
+
 static struct ftrace_page *
 ftrace_allocate_pages(unsigned long num_to_init)
 {
@@ -3075,17 +3091,7 @@ ftrace_allocate_pages(unsigned long num_to_init)
 	return start_pg;
 
  free_pages:
-	pg = start_pg;
-	while (pg) {
-		if (pg->records) {
-			free_pages((unsigned long)pg->records, pg->order);
-			ftrace_number_of_pages -= 1 << pg->order;
-		}
-		start_pg = pg->next;
-		kfree(pg);
-		pg = start_pg;
-		ftrace_number_of_groups--;
-	}
+	ftrace_free_pages(start_pg);
 	pr_info("ftrace: FAILED to allocate memory for functions\n");
 	return NULL;
 }
@@ -5627,9 +5633,11 @@ static int ftrace_process_locs(struct module *mod,
 			       unsigned long *start,
 			       unsigned long *end)
 {
+	struct ftrace_page *pg_unuse = NULL;
 	struct ftrace_page *start_pg;
 	struct ftrace_page *pg;
 	struct dyn_ftrace *rec;
+	unsigned long skipped = 0;
 	unsigned long count;
 	unsigned long *p;
 	unsigned long addr;
@@ -5683,8 +5691,10 @@ static int ftrace_process_locs(struct module *mod,
 		 * object files to satisfy alignments.
 		 * Skip any NULL pointers.
 		 */
-		if (!addr)
+		if (!addr) {
+			skipped++;
 			continue;
+		}
 
 		end_offset = (pg->index+1) * sizeof(pg->records[0]);
 		if (end_offset > PAGE_SIZE << pg->order) {
@@ -5698,8 +5708,10 @@ static int ftrace_process_locs(struct module *mod,
 		rec->ip = addr;
 	}
 
-	/* We should have used all pages */
-	WARN_ON(pg->next);
+	if (pg->next) {
+		pg_unuse = pg->next;
+		pg->next = NULL;
+	}
 
 	/* Assign the last page to ftrace_pages */
 	ftrace_pages = pg;
@@ -5721,6 +5733,11 @@ static int ftrace_process_locs(struct module *mod,
  out:
 	mutex_unlock(&ftrace_lock);
 
+	/* We should have used all pages unless we skipped some */
+	if (pg_unuse) {
+		WARN_ON(!skipped);
+		ftrace_free_pages(pg_unuse);
+	}
 	return ret;
 }
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux