The following commit has been merged in the master branch:
commit dd161f74f8198c62f9bcf893f72c64bbb0d68b25
Merge: 5c2a430e85994f4873ea5ec42091baa1153bc731 
dc208c69c033d3caba0509da1ae065d2b5ff165f
Author: Linus Torvalds <[email protected]>
Date:   Thu Mar 27 15:44:34 2025 -0700

    Merge tag 'trace-sorttable-v6.15' of 
git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
    
    Pull tracing / sorttable updates from Steven Rostedt:
    
     - Implement arm64 build time sorting of the mcount location table
    
       When gcc is used to build arm64, the mcount_loc section is all zeros
       in the vmlinux elf file. The addresses are stored in the Elf_Rela
       location.
    
       To sort at build time, an array is allocated and the addresses are
       added to it via the content of the mcount_loc section as well as he
       Elf_Rela data. After sorting, the information is put back into the
       Elf_Rela which now has the section sorted.
    
     - Make sorting of mcount location table for arm64 work with clang as
       well
    
       When clang is used, the mcount_loc section contains the addresses,
       unlike the gcc build. An array is still created and the sorting works
       for both methods.
    
     - Remove weak functions from the mcount_loc section
    
       Have the sorttable code pass in the data of functions defined via
       'nm -S' which shows the functions as well as their sizes. Using this
       information the sorttable code can determine if a function in the
       mcount_loc section was weak and overridden. If the function is not
       found, it is set to be zero. On boot, when the mcount_loc section is
       read and the ftrace table is created, if the address in the
       mcount_loc is not in the kernel core text then it is removed and not
       added to the ftrace_filter_functions (the functions that can be
       attached by ftrace callbacks).
    
     - Update and fix the reporting of how much data is used for ftrace
       functions
    
       On boot, a report of how many pages were used by the ftrace table as
       well as how they were grouped (the table holds a list of sections
       that are groups of pages that were able to be allocated). The
       removing of the weak functions required the accounting to be updated.
    
    * tag 'trace-sorttable-v6.15' of 
git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
      scripts/sorttable: Allow matches to functions before function entry
      scripts/sorttable: Use normal sort if theres no relocs in the mcount 
section
      ftrace: Check against is_kernel_text() instead of kaslr_offset()
      ftrace: Test mcount_loc addr before calling ftrace_call_addr()
      ftrace: Have ftrace pages output reflect freed pages
      ftrace: Update the mcount_loc check of skipped entries
      scripts/sorttable: Zero out weak functions in mcount_loc table
      scripts/sorttable: Always use an array for the mcount_loc sorting
      scripts/sorttable: Have mcount rela sort use direct values
      arm64: scripts/sorttable: Implement sorting mcount_loc at boot for arm64

diff --combined arch/arm64/Kconfig
index f2d724c1dfd29,4521ecefc0312..62dc903ecc7fe
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@@ -162,7 -162,6 +162,7 @@@ config ARM6
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_TIME_VSYSCALL
        select GENERIC_GETTIMEOFDAY
 +      select GENERIC_VDSO_DATA_STORE
        select GENERIC_VDSO_TIME_NS
        select HARDIRQS_SW_RESEND
        select HAS_IOPORT
@@@ -218,6 -217,7 +218,7 @@@
                if DYNAMIC_FTRACE_WITH_ARGS
        select HAVE_SAMPLE_FTRACE_DIRECT
        select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
+       select HAVE_BUILDTIME_MCOUNT_SORT
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
        select HAVE_GUP_FAST
        select HAVE_FTRACE_GRAPH_FUNC
@@@ -251,7 -251,6 +252,7 @@@
        select HAVE_KRETPROBES
        select HAVE_GENERIC_VDSO
        select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
 +      select HOTPLUG_SMT if HOTPLUG_CPU
        select IRQ_DOMAIN
        select IRQ_FORCED_THREADING
        select KASAN_VMALLOC if KASAN
@@@ -325,7 -324,7 +326,7 @@@ config ARCH_MMAP_RND_BITS_MI
        default 18
  
  # max bits determined by the following formula:
 -#  VA_BITS - PAGE_SHIFT - 3
 +#  VA_BITS - PTDESC_TABLE_SHIFT
  config ARCH_MMAP_RND_BITS_MAX
        default 19 if ARM64_VA_BITS=36
        default 24 if ARM64_VA_BITS=39
@@@ -1304,15 -1303,6 +1305,15 @@@ config NVIDIA_CARMEL_CNP_ERRATU
  
          If unsure, say Y.
  
 +config ROCKCHIP_ERRATUM_3568002
 +      bool "Rockchip 3568002: GIC600 can not access physical addresses higher 
than 4GB"
 +      default y
 +      help
 +        The Rockchip RK3566 and RK3568 GIC600 SoC integrations have AXI
 +        addressing limited to the first 32bit of physical address space.
 +
 +        If unsure, say Y.
 +
  config ROCKCHIP_ERRATUM_3588001
        bool "Rockchip 3588001: GIC600 can not support shareability attributes"
        default y
diff --combined kernel/trace/ftrace.c
index fc88e0688daf0,bec7b5dbdb3b4..97c1be9f727ad
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@@ -540,7 -540,6 +540,7 @@@ static int function_stat_show(struct se
        static struct trace_seq s;
        unsigned long long avg;
        unsigned long long stddev;
 +      unsigned long long stddev_denom;
  #endif
        guard(mutex)(&ftrace_profile_lock);
  
@@@ -560,19 -559,23 +560,19 @@@
  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        seq_puts(m, "    ");
  
 -      /* Sample standard deviation (s^2) */
 -      if (rec->counter <= 1)
 -              stddev = 0;
 -      else {
 -              /*
 -               * Apply Welford's method:
 -               * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2)
 -               */
 +      /*
 +       * Variance formula:
 +       * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2)
 +       * Maybe Welford's method is better here?
 +       * Divide only by 1000 for ns^2 -> us^2 conversion.
 +       * trace_print_graph_duration will divide by 1000 again.
 +       */
 +      stddev = 0;
 +      stddev_denom = rec->counter * (rec->counter - 1) * 1000;
 +      if (stddev_denom) {
                stddev = rec->counter * rec->time_squared -
                         rec->time * rec->time;
 -
 -              /*
 -               * Divide only 1000 for ns^2 -> us^2 conversion.
 -               * trace_print_graph_duration will divide 1000 again.
 -               */
 -              stddev = div64_ul(stddev,
 -                                rec->counter * (rec->counter - 1) * 1000);
 +              stddev = div64_ul(stddev, stddev_denom);
        }
  
        trace_seq_init(&s);
@@@ -3217,22 -3220,15 +3217,22 @@@ static struct ftrace_hash *copy_hash(st
   *  The filter_hash updates uses just the append_hash() function
   *  and the notrace_hash does not.
   */
 -static int append_hash(struct ftrace_hash **hash, struct ftrace_hash 
*new_hash)
 +static int append_hash(struct ftrace_hash **hash, struct ftrace_hash 
*new_hash,
 +                     int size_bits)
  {
        struct ftrace_func_entry *entry;
        int size;
        int i;
  
 -      /* An empty hash does everything */
 -      if (ftrace_hash_empty(*hash))
 -              return 0;
 +      if (*hash) {
 +              /* An empty hash does everything */
 +              if (ftrace_hash_empty(*hash))
 +                      return 0;
 +      } else {
 +              *hash = alloc_ftrace_hash(size_bits);
 +              if (!*hash)
 +                      return -ENOMEM;
 +      }
  
        /* If new_hash has everything make hash have everything */
        if (ftrace_hash_empty(new_hash)) {
@@@ -3296,18 -3292,16 +3296,18 @@@ static int intersect_hash(struct ftrace
  /* Return a new hash that has a union of all @ops->filter_hash entries */
  static struct ftrace_hash *append_hashes(struct ftrace_ops *ops)
  {
 -      struct ftrace_hash *new_hash;
 +      struct ftrace_hash *new_hash = NULL;
        struct ftrace_ops *subops;
 +      int size_bits;
        int ret;
  
 -      new_hash = alloc_ftrace_hash(ops->func_hash->filter_hash->size_bits);
 -      if (!new_hash)
 -              return NULL;
 +      if (ops->func_hash->filter_hash)
 +              size_bits = ops->func_hash->filter_hash->size_bits;
 +      else
 +              size_bits = FTRACE_HASH_DEFAULT_BITS;
  
        list_for_each_entry(subops, &ops->subop_list, list) {
 -              ret = append_hash(&new_hash, subops->func_hash->filter_hash);
 +              ret = append_hash(&new_hash, subops->func_hash->filter_hash, 
size_bits);
                if (ret < 0) {
                        free_ftrace_hash(new_hash);
                        return NULL;
@@@ -3316,8 -3310,7 +3316,8 @@@
                if (ftrace_hash_empty(new_hash))
                        break;
        }
 -      return new_hash;
 +      /* Can't return NULL as that means this failed */
 +      return new_hash ? : EMPTY_HASH;
  }
  
  /* Make @ops trace evenything except what all its subops do not trace */
@@@ -3512,8 -3505,7 +3512,8 @@@ int ftrace_startup_subops(struct ftrace
                filter_hash = alloc_and_copy_ftrace_hash(size_bits, 
ops->func_hash->filter_hash);
                if (!filter_hash)
                        return -ENOMEM;
 -              ret = append_hash(&filter_hash, subops->func_hash->filter_hash);
 +              ret = append_hash(&filter_hash, subops->func_hash->filter_hash,
 +                                size_bits);
                if (ret < 0) {
                        free_ftrace_hash(filter_hash);
                        return ret;
@@@ -5715,9 -5707,6 +5715,9 @@@ __ftrace_match_addr(struct ftrace_hash 
                        return -ENOENT;
                free_hash_entry(hash, entry);
                return 0;
 +      } else if (__ftrace_lookup_ip(hash, ip) != NULL) {
 +              /* Already exists */
 +              return 0;
        }
  
        entry = add_hash_entry(hash, ip);
@@@ -7016,6 -7005,7 +7016,7 @@@ static int ftrace_process_locs(struct m
        unsigned long *p;
        unsigned long addr;
        unsigned long flags = 0; /* Shut up gcc */
+       unsigned long pages;
        int ret = -ENOMEM;
  
        count = end - start;
@@@ -7023,6 -7013,8 +7024,8 @@@
        if (!count)
                return 0;
  
+       pages = DIV_ROUND_UP(count, ENTRIES_PER_PAGE);
+ 
        /*
         * Sorting mcount in vmlinux at build time depend on
         * CONFIG_BUILDTIME_MCOUNT_SORT, while mcount loc in
@@@ -7067,7 -7059,9 +7070,9 @@@
        pg = start_pg;
        while (p < end) {
                unsigned long end_offset;
-               addr = ftrace_call_adjust(*p++);
+ 
+               addr = *p++;
+ 
                /*
                 * Some architecture linkers will pad between
                 * the different mcount_loc sections of different
@@@ -7079,6 -7073,19 +7084,19 @@@
                        continue;
                }
  
+               /*
+                * If this is core kernel, make sure the address is in core
+                * or inittext, as weak functions get zeroed and KASLR can
+                * move them to something other than zero. It just will not
+                * move it to an area where kernel text is.
+                */
+               if (!mod && !(is_kernel_text(addr) || 
is_kernel_inittext(addr))) {
+                       skipped++;
+                       continue;
+               }
+ 
+               addr = ftrace_call_adjust(addr);
+ 
                end_offset = (pg->index+1) * sizeof(pg->records[0]);
                if (end_offset > PAGE_SIZE << pg->order) {
                        /* We should have allocated enough */
@@@ -7118,11 -7125,41 +7136,41 @@@
  
        /* We should have used all pages unless we skipped some */
        if (pg_unuse) {
-               WARN_ON(!skipped);
+               unsigned long pg_remaining, remaining = 0;
+               unsigned long skip;
+ 
+               /* Count the number of entries unused and compare it to 
skipped. */
+               pg_remaining = (ENTRIES_PER_PAGE << pg->order) - pg->index;
+ 
+               if (!WARN(skipped < pg_remaining, "Extra allocated pages for 
ftrace")) {
+ 
+                       skip = skipped - pg_remaining;
+ 
+                       for (pg = pg_unuse; pg; pg = pg->next)
+                               remaining += 1 << pg->order;
+ 
+                       pages -= remaining;
+ 
+                       skip = DIV_ROUND_UP(skip, ENTRIES_PER_PAGE);
+ 
+                       /*
+                        * Check to see if the number of pages remaining would
+                        * just fit the number of entries skipped.
+                        */
+                       WARN(skip != remaining, "Extra allocated pages for 
ftrace: %lu with %lu skipped",
+                            remaining, skipped);
+               }
                /* Need to synchronize with ftrace_location_range() */
                synchronize_rcu();
                ftrace_free_pages(pg_unuse);
        }
+ 
+       if (!mod) {
+               count -= skipped;
+               pr_info("ftrace: allocating %ld entries in %ld pages\n",
+                       count, pages);
+       }
+ 
        return ret;
  }
  
@@@ -7768,9 -7805,6 +7816,6 @@@ void __init ftrace_init(void
                goto failed;
        }
  
-       pr_info("ftrace: allocating %ld entries in %ld pages\n",
-               count, DIV_ROUND_UP(count, ENTRIES_PER_PAGE));
- 
        ret = ftrace_process_locs(NULL,
                                  __start_mcount_loc,
                                  __stop_mcount_loc);
diff --combined scripts/link-vmlinux.sh
index 67e66333bd2a3,59b07fe6fd004..94c78244a2b08
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@@ -144,6 -144,10 +144,6 @@@ kallsyms(
                kallsymopt="${kallsymopt} --all-symbols"
        fi
  
 -      if is_enabled CONFIG_KALLSYMS_ABSOLUTE_PERCPU; then
 -              kallsymopt="${kallsymopt} --absolute-percpu"
 -      fi
 -
        info KSYMS "${2}.S"
        scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S"
  
@@@ -173,12 -177,14 +173,14 @@@ mksysmap(
  
  sorttable()
  {
-       ${objtree}/scripts/sorttable ${1}
+       ${NM} -S ${1} > .tmp_vmlinux.nm-sort
+       ${objtree}/scripts/sorttable -s .tmp_vmlinux.nm-sort ${1}
  }
  
  cleanup()
  {
        rm -f .btf.*
+       rm -f .tmp_vmlinux.nm-sort
        rm -f System.map
        rm -f vmlinux
        rm -f vmlinux.map

-- 
LinuxNextTracking

Reply via email to