]> Git Repo - linux.git/commitdiff
Merge tag 'trace-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux...
authorLinus Torvalds <[email protected]>
Fri, 3 Nov 2023 17:41:18 +0000 (07:41 -1000)
committerLinus Torvalds <[email protected]>
Fri, 3 Nov 2023 17:41:18 +0000 (07:41 -1000)
Pull tracing updates from Steven Rostedt:

 - Remove eventfs_file descriptor

   This is the biggest change, and the second part of making eventfs
   create its files dynamically.

   In 6.6 the first part was added, and that maintained a one to one
   mapping between eventfs meta descriptors and the directories and file
   inodes and dentries that were dynamically created. The directories
   were represented by a eventfs_inode and the files were represented by
   a eventfs_file.

   In v6.7 the eventfs_file is removed. As all events have the same
   directory make up (sched_switch has an "enable", "id", "format", etc
   files), the handing of what files are underneath each leaf eventfs
   directory is moved back to the tracing subsystem via a callback.

   When an event is added to the eventfs, it registers an array of
   evenfs_entry's. These hold the names of the files and the callbacks
   to call when the file is referenced. The callback gets the name so
   that the same callback may be used by multiple files. The callback
   then supplies the filesystem_operations structure needed to create
   this file.

   This has brought the memory footprint of creating multiple eventfs
   instances down by 2 megs each!

 - User events now has persistent events that are not associated to a
   single processes. These are privileged events that hang around even
   if no process is attached to them

 - Clean up of seq_buf

   There's talk about using seq_buf more to replace strscpy() and
   friends. But this also requires some minor modifications of seq_buf
   to be able to do this

 - Expand instance ring buffers individually

   Currently if boot up creates an instance, and a trace event is
   enabled on that instance, the ring buffer for that instance and the
   top level ring buffer are expanded (1.4 MB per CPU). This wastes
   memory as this happens when nothing is using the top level instance

 - Other minor clean ups and fixes

* tag 'trace-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: (34 commits)
  seq_buf: Export seq_buf_puts()
  seq_buf: Export seq_buf_putc()
  eventfs: Use simple_recursive_removal() to clean up dentries
  eventfs: Remove special processing of dput() of events directory
  eventfs: Delete eventfs_inode when the last dentry is freed
  eventfs: Hold eventfs_mutex when calling callback functions
  eventfs: Save ownership and mode
  eventfs: Test for ei->is_freed when accessing ei->dentry
  eventfs: Have a free_ei() that just frees the eventfs_inode
  eventfs: Remove "is_freed" union with rcu head
  eventfs: Fix kerneldoc of eventfs_remove_rec()
  tracing: Have the user copy of synthetic event address use correct context
  eventfs: Remove extra dget() in eventfs_create_events_dir()
  tracing: Have trace_event_file have ref counters
  seq_buf: Introduce DECLARE_SEQ_BUF and seq_buf_str()
  eventfs: Fix typo in eventfs_inode union comment
  eventfs: Fix WARN_ON() in create_file_dentry()
  powerpc: Remove initialisation of readpos
  tracing/histograms: Simplify last_cmd_set()
  seq_buf: fix a misleading comment
  ...

1  2 
arch/powerpc/kernel/setup-common.c
fs/tracefs/inode.c
include/linux/trace_events.h
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_char.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
tools/testing/selftests/user_events/abi_test.c

index 20f72cd1d8138d7de79ed8fc034454ebf4ef5453,34975532e44c9f8a60176d6a300c8fdd5c378a43..ca92cf0ffde123230a2727010ffd1ae60912d6aa
@@@ -601,7 -601,6 +601,6 @@@ struct seq_buf ppc_hw_desc __initdata 
        .buffer = ppc_hw_desc_buf,
        .size = sizeof(ppc_hw_desc_buf),
        .len = 0,
-       .readpos = 0,
  };
  
  static __init void probe_machine(void)
@@@ -948,8 -947,6 +947,8 @@@ void __init setup_arch(char **cmdline_p
  
        /* Parse memory topology */
        mem_topology_setup();
 +      /* Set max_mapnr before paging_init() */
 +      set_max_mapnr(max_pfn);
  
        /*
         * Release secondary cpus out of their spinloops at 0x60 now that
diff --combined fs/tracefs/inode.c
index 429603d865a9bd590f3d773c1394f812818ab472,34ffb2f8114e04dbe702e284fed0cc5b79646f09..5b54948514fe21de97b1fe0c35b3fa2a1d91de46
@@@ -152,7 -152,7 +152,7 @@@ struct inode *tracefs_get_inode(struct 
        struct inode *inode = new_inode(sb);
        if (inode) {
                inode->i_ino = get_next_ino();
 -              inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
 +              simple_inode_init_ts(inode);
        }
        return inode;
  }
@@@ -385,7 -385,7 +385,7 @@@ static void tracefs_dentry_iput(struct 
  
        ti = get_tracefs(inode);
        if (ti && ti->flags & TRACEFS_EVENT_INODE)
-               eventfs_set_ef_status_free(ti, dentry);
+               eventfs_set_ei_status_free(ti, dentry);
        iput(inode);
  }
  
index 5eb88a66eb682cca1aa492788954e9fdb9046d2c,696f8dc4aa53c14a70c9da93f8851b60ae1712bc..d68ff9b1247f984e127cb62c07d5aa9508b6db5b
@@@ -492,6 -492,7 +492,7 @@@ enum 
        EVENT_FILE_FL_TRIGGER_COND_BIT,
        EVENT_FILE_FL_PID_FILTER_BIT,
        EVENT_FILE_FL_WAS_ENABLED_BIT,
+       EVENT_FILE_FL_FREED_BIT,
  };
  
  extern struct trace_event_file *trace_get_event_file(const char *instance,
@@@ -630,6 -631,7 +631,7 @@@ extern int __kprobe_event_add_fields(st
   *  TRIGGER_COND  - When set, one or more triggers has an associated filter
   *  PID_FILTER    - When set, the event is filtered based on pid
   *  WAS_ENABLED   - Set when enabled to know to clear trace on module removal
+  *  FREED         - File descriptor is freed, all fields should be considered invalid
   */
  enum {
        EVENT_FILE_FL_ENABLED           = (1 << EVENT_FILE_FL_ENABLED_BIT),
        EVENT_FILE_FL_TRIGGER_COND      = (1 << EVENT_FILE_FL_TRIGGER_COND_BIT),
        EVENT_FILE_FL_PID_FILTER        = (1 << EVENT_FILE_FL_PID_FILTER_BIT),
        EVENT_FILE_FL_WAS_ENABLED       = (1 << EVENT_FILE_FL_WAS_ENABLED_BIT),
+       EVENT_FILE_FL_FREED             = (1 << EVENT_FILE_FL_FREED_BIT),
  };
  
  struct trace_event_file {
        struct list_head                list;
        struct trace_event_call         *event_call;
        struct event_filter __rcu       *filter;
-       struct eventfs_file             *ef;
+       struct eventfs_inode            *ei;
        struct trace_array              *tr;
        struct trace_subsystem_dir      *system;
        struct list_head                triggers;
         * caching and such. Which is mostly OK ;-)
         */
        unsigned long           flags;
+       atomic_t                ref;    /* ref count for opened files */
        atomic_t                sm_ref; /* soft-mode reference counter */
        atomic_t                tm_ref; /* trigger-mode reference counter */
  };
@@@ -761,8 -765,7 +765,8 @@@ struct bpf_raw_event_map *bpf_get_raw_t
  void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp);
  int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
                            u32 *fd_type, const char **buf,
 -                          u64 *probe_offset, u64 *probe_addr);
 +                          u64 *probe_offset, u64 *probe_addr,
 +                          unsigned long *missed);
  int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog);
  int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog);
  #else
@@@ -802,7 -805,7 +806,7 @@@ static inline void bpf_put_raw_tracepoi
  static inline int bpf_get_perf_event_info(const struct perf_event *event,
                                          u32 *prog_id, u32 *fd_type,
                                          const char **buf, u64 *probe_offset,
 -                                        u64 *probe_addr)
 +                                        u64 *probe_addr, unsigned long *missed)
  {
        return -EOPNOTSUPP;
  }
@@@ -878,7 -881,6 +882,7 @@@ extern void perf_kprobe_destroy(struct 
  extern int bpf_get_kprobe_info(const struct perf_event *event,
                               u32 *fd_type, const char **symbol,
                               u64 *probe_offset, u64 *probe_addr,
 +                             unsigned long *missed,
                               bool perf_type_tracepoint);
  #endif
  #ifdef CONFIG_UPROBE_EVENTS
index 21db6b720754f6251a8ceb13f6eb84559bbe276a,c639c6c8ca03fec022eb419375a7eda474b29f96..e21c9c27ece4761640d5d8e4cb7c7f5cb9fb4266
@@@ -28,19 -28,15 +28,21 @@@ s390*
  mips*)
    ARG1=%r4
  ;;
 +loongarch*)
 +  ARG1=%r4
 +;;
 +riscv*)
 +  ARG1=%a0
 +;;
  *)
    echo "Please implement other architecture here"
    exit_untested
  esac
  
  : "Test get argument (1)"
- if grep -q eventfs_add_dir available_filter_functions; then
+ if grep -q eventfs_create_dir available_filter_functions; then
+   DIR_NAME="eventfs_create_dir"
+ elif grep -q eventfs_add_dir available_filter_functions; then
    DIR_NAME="eventfs_add_dir"
  else
    DIR_NAME="tracefs_create_dir"
index 4e086f871ceef9491968b50d1a21e30c7fba0030,a5ab4d5c74ac70e5977cb5f810ef705b66bc4a00..93217d4595563f4111e12c1cf1faf584cb314f8e
@@@ -31,16 -31,15 +31,18 @@@ mips*
  loongarch*)
    ARG1=%r4
  ;;
 +riscv*)
 +  ARG1=%a0
 +;;
  *)
    echo "Please implement other architecture here"
    exit_untested
  esac
  
  : "Test get argument (1)"
- if grep -q eventfs_add_dir available_filter_functions; then
+ if grep -q eventfs_create_dir available_filter_functions; then
+   DIR_NAME="eventfs_create_dir"
+ elif grep -q eventfs_add_dir available_filter_functions; then
    DIR_NAME="eventfs_add_dir"
  else
    DIR_NAME="tracefs_create_dir"
index f5575ef2007cef53b7eaffbff481ba0572c9835f,3d539e556dcdf82a5cdbd43873a12ef0bd2f5de3..cef1ff1af2236846d58d2d884221d98297206639
  const char *data_file = "/sys/kernel/tracing/user_events_data";
  const char *enable_file = "/sys/kernel/tracing/events/user_events/__abi_event/enable";
  
+ static bool event_exists(void)
+ {
+       int fd = open(enable_file, O_RDWR);
+       if (fd < 0)
+               return false;
+       close(fd);
+       return true;
+ }
  static int change_event(bool enable)
  {
        int fd = open(enable_file, O_RDWR);
        return ret;
  }
  
- static int reg_enable(void *enable, int size, int bit)
+ static int event_delete(void)
+ {
+       int fd = open(data_file, O_RDWR);
+       int ret;
+       if (fd < 0)
+               return -1;
+       ret = ioctl(fd, DIAG_IOCSDEL, "__abi_event");
+       close(fd);
+       return ret;
+ }
 -static int reg_enable_flags(long *enable, int size, int bit, int flags)
++static int reg_enable_flags(void *enable, int size, int bit, int flags)
  {
        struct user_reg reg = {0};
        int fd = open(data_file, O_RDWR);
@@@ -58,6 -85,7 +85,7 @@@
  
        reg.size = sizeof(reg);
        reg.name_args = (__u64)"__abi_event";
+       reg.flags = flags;
        reg.enable_bit = bit;
        reg.enable_addr = (__u64)enable;
        reg.enable_size = size;
        return ret;
  }
  
 -static int reg_enable(long *enable, int size, int bit)
++static int reg_enable(void *enable, int size, int bit)
+ {
+       return reg_enable_flags(enable, size, bit, 0);
+ }
 -static int reg_disable(long *enable, int bit)
 +static int reg_disable(void *enable, int bit)
  {
        struct user_unreg reg = {0};
        int fd = open(data_file, O_RDWR);
  }
  
  FIXTURE(user) {
 -      long check;
 +      int check;
 +      long check_long;
        bool umount;
  };
  
@@@ -100,7 -132,6 +133,7 @@@ FIXTURE_SETUP(user) 
  
        change_event(false);
        self->check = 0;
 +      self->check_long = 0;
  }
  
  FIXTURE_TEARDOWN(user) {
@@@ -128,6 -159,26 +161,26 @@@ TEST_F(user, enablement) 
        ASSERT_EQ(0, change_event(false));
  }
  
+ TEST_F(user, flags) {
+       /* USER_EVENT_REG_PERSIST is allowed */
+       ASSERT_EQ(0, reg_enable_flags(&self->check, sizeof(int), 0,
+                                     USER_EVENT_REG_PERSIST));
+       ASSERT_EQ(0, reg_disable(&self->check, 0));
+       /* Ensure it exists after close and disable */
+       ASSERT_TRUE(event_exists());
+       /* Ensure we can delete it */
+       ASSERT_EQ(0, event_delete());
+       /* USER_EVENT_REG_MAX or above is not allowed */
+       ASSERT_EQ(-1, reg_enable_flags(&self->check, sizeof(int), 0,
+                                      USER_EVENT_REG_MAX));
+       /* Ensure it does not exist after invalid flags */
+       ASSERT_FALSE(event_exists());
+ }
  TEST_F(user, bit_sizes) {
        /* Allow 0-31 bits for 32-bit */
        ASSERT_EQ(0, reg_enable(&self->check, sizeof(int), 0));
  
  #if BITS_PER_LONG == 8
        /* Allow 0-64 bits for 64-bit */
 -      ASSERT_EQ(0, reg_enable(&self->check, sizeof(long), 63));
 -      ASSERT_NE(0, reg_enable(&self->check, sizeof(long), 64));
 -      ASSERT_EQ(0, reg_disable(&self->check, 63));
 +      ASSERT_EQ(0, reg_enable(&self->check_long, sizeof(long), 63));
 +      ASSERT_NE(0, reg_enable(&self->check_long, sizeof(long), 64));
 +      ASSERT_EQ(0, reg_disable(&self->check_long, 63));
  #endif
  
        /* Disallowed sizes (everything beside 4 and 8) */
@@@ -202,7 -253,7 +255,7 @@@ static int clone_check(void *check
        for (i = 0; i < 10; ++i) {
                usleep(100000);
  
 -              if (*(long *)check)
 +              if (*(int *)check)
                        return 0;
        }
  
This page took 0.108469 seconds and 4 git commands to generate.