Commit 615d3006 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull tracing and eventfs fixes from Steven Rostedt:

 - Fix histogram tracing_map insertion.

   The tracing_map_insert copies the value into the elt variable and
   then assigns the elt to the entry value. But it is possible that the
   entry value becomes visible on other CPUs before the elt is fully
   initialized. This is fixed by adding a wmb() between the
   initialization of the elt variable and assigning it.

 - Have eventfs directory have unique inode numbers.

   Having them be all the same proved to be a failure as the 'find'
   application will think that the directories are causing loops, as it
   checks for directory loops via their inodes. Have the evenfs dir
   entries get their inodes assigned when they are referenced and then
   save them in the eventfs_inode structure.

* tag 'trace-v6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  eventfs: Save directory inodes in the eventfs_inode structure
  tracing: Ensure visibility when inserting an element into tracing_map
parents 7ed2632e 834bf76a
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -34,7 +34,15 @@ static DEFINE_MUTEX(eventfs_mutex);

/* Choose something "unique" ;-) */
#define EVENTFS_FILE_INODE_INO		0x12c4e37
#define EVENTFS_DIR_INODE_INO		0x134b2f5

/* Just try to make something consistent and unique */
static int eventfs_dir_ino(struct eventfs_inode *ei)
{
	if (!ei->ino)
		ei->ino = get_next_ino();

	return ei->ino;
}

/*
 * The eventfs_inode (ei) itself is protected by SRCU. It is released from
@@ -396,7 +404,7 @@ static struct dentry *create_dir(struct eventfs_inode *ei, struct dentry *parent
	inode->i_fop = &eventfs_file_operations;

	/* All directories will have the same inode number */
	inode->i_ino = EVENTFS_DIR_INODE_INO;
	inode->i_ino = eventfs_dir_ino(ei);

	ti = get_tracefs(inode);
	ti->flags |= TRACEFS_EVENT_INODE;
@@ -802,7 +810,7 @@ static int eventfs_iterate(struct file *file, struct dir_context *ctx)

		name = ei_child->name;

		ino = EVENTFS_DIR_INODE_INO;
		ino = eventfs_dir_ino(ei_child);

		if (!dir_emit(ctx, name, strlen(name), ino, DT_DIR))
			goto out_dec;
+4 −3
Original line number Diff line number Diff line
@@ -55,6 +55,10 @@ struct eventfs_inode {
	struct eventfs_attr		*entry_attrs;
	struct eventfs_attr		attr;
	void				*data;
	unsigned int			is_freed:1;
	unsigned int			is_events:1;
	unsigned int			nr_entries:30;
	unsigned int			ino;
	/*
	 * Union - used for deletion
	 * @llist:	for calling dput() if needed after RCU
@@ -64,9 +68,6 @@ struct eventfs_inode {
		struct llist_node	llist;
		struct rcu_head		rcu;
	};
	unsigned int			is_freed:1;
	unsigned int			is_events:1;
	unsigned int			nr_entries:30;
};

static inline struct tracefs_inode *get_tracefs(const struct inode *inode)
+6 −1
Original line number Diff line number Diff line
@@ -574,7 +574,12 @@ __tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only)
				}

				memcpy(elt->key, key, map->key_size);
				entry->val = elt;
				/*
				 * Ensure the initialization is visible and
				 * publish the elt.
				 */
				smp_wmb();
				WRITE_ONCE(entry->val, elt);
				atomic64_inc(&map->hits);

				return entry->val;