Commit 46d29f23 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'trace-ringbuffer-v6.15-2' of...

Merge tag 'trace-ringbuffer-v6.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull ring-buffer updates from Steven Rostedt:

 - Restructure the persistent memory to have a "scratch" area

   Instead of hard coding the KASLR offset in the persistent memory by
   the ring buffer, push that work up to the callers of the persistent
   memory as they are the ones that need this information. The offsets
   and such is not important to the ring buffer logic and it should not
   be part of that.

   A scratch pad is now created when the caller allocates a ring buffer
   from persistent memory by stating how much memory it needs to save.

 - Allow where modules are loaded to be saved in the new scratch pad

   Save the addresses of modules when they are loaded into the
   persistent memory scratch pad.

 - A new module_for_each_mod() helper function was created

   With the acknowledgement of the module maintainers a new module
   helper function was created to iterate over all the currently loaded
   modules. This has a callback to be called for each module. This is
   needed for when tracing is started in the persistent buffer and the
   currently loaded modules need to be saved in the scratch area.

 - Expose the last boot information where the kernel and modules were
   loaded

   The last_boot_info file is updated to print out the addresses of
   where the kernel "_text" location was loaded from a previous boot, as
   well as where the modules are loaded. If the buffer is recording the
   current boot, it only prints "# Current" so that it does not expose
   the KASLR offset of the currently running kernel.

 - Allow the persistent ring buffer to be released (freed)

   To have this in production environments, where the kernel command
   line can not be changed easily, the ring buffer needs to be freed
   when it is not going to be used. The memory for the buffer will
   always be allocated at boot up, but if the system isn't going to
   enable tracing, the memory needs to be freed. Allow it to be freed
   and added back to the kernel memory pool.

 - Allow stack traces to print the function names in the persistent
   buffer

   Now that the modules are saved in the persistent ring buffer, if the
   same modules are loaded, the printing of the function names will
   examine the saved modules. If the module is found in the scratch area
   and is also loaded, then it will do the offset shift and use kallsyms
   to display the function name. If the address is not found, it simply
   displays the address from the previous boot in hex.

* tag 'trace-ringbuffer-v6.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  tracing: Use _text and the kernel offset in last_boot_info
  tracing: Show last module text symbols in the stacktrace
  ring-buffer: Remove the unused variable bmeta
  tracing: Skip update_last_data() if cleared and remove active check for save_mod()
  tracing: Initialize scratch_size to zero to prevent UB
  tracing: Fix a compilation error without CONFIG_MODULES
  tracing: Freeable reserved ring buffer
  mm/memblock: Add reserved memory release function
  tracing: Update modules to persistent instances when loaded
  tracing: Show module names and addresses of last boot
  tracing: Have persistent trace instances save module addresses
  module: Add module_for_each_mod() function
  tracing: Have persistent trace instances save KASLR offset
  ring-buffer: Add ring_buffer_meta_scratch()
  ring-buffer: Add buffer meta data for persistent ring buffer
  ring-buffer: Use kaslr address instead of text delta
  ring-buffer: Fix bytes_dropped calculation issue
parents 60970685 028a58ec
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4110,6 +4110,7 @@ void vma_pgtable_walk_begin(struct vm_area_struct *vma);
void vma_pgtable_walk_end(struct vm_area_struct *vma);

int reserve_mem_find_by_name(const char *name, phys_addr_t *start, phys_addr_t *size);
int reserve_mem_release_by_name(const char *name);

#ifdef CONFIG_64BIT
int do_mseal(unsigned long start, size_t len_in, unsigned long flags);
+6 −0
Original line number Diff line number Diff line
@@ -771,6 +771,8 @@ static inline bool is_livepatch_module(struct module *mod)

void set_module_sig_enforced(void);

void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data);

#else /* !CONFIG_MODULES... */

static inline struct module *__module_address(unsigned long addr)
@@ -878,6 +880,10 @@ static inline bool module_is_coming(struct module *mod)
{
	return false;
}

static inline void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data)
{
}
#endif /* CONFIG_MODULES */

#ifdef CONFIG_SYSFS
+4 −4
Original line number Diff line number Diff line
@@ -92,10 +92,10 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k
struct trace_buffer *__ring_buffer_alloc_range(unsigned long size, unsigned flags,
					       int order, unsigned long start,
					       unsigned long range_size,
					       unsigned long scratch_size,
					       struct lock_class_key *key);

bool ring_buffer_last_boot_delta(struct trace_buffer *buffer, long *text,
				 long *data);
void *ring_buffer_meta_scratch(struct trace_buffer *buffer, unsigned int *size);

/*
 * Because the ring buffer is generic, if other users of the ring buffer get
@@ -113,11 +113,11 @@ bool ring_buffer_last_boot_delta(struct trace_buffer *buffer, long *text,
 * traced by ftrace, it can produce lockdep warnings. We need to keep each
 * ring buffer's lock class separate.
 */
#define ring_buffer_alloc_range(size, flags, order, start, range_size)	\
#define ring_buffer_alloc_range(size, flags, order, start, range_size, s_size)	\
({									\
	static struct lock_class_key __key;				\
	__ring_buffer_alloc_range((size), (flags), (order), (start),	\
				  (range_size), &__key);		\
				  (range_size), (s_size), &__key);	\
})

typedef bool (*ring_buffer_cond_fn)(void *data);
+13 −0
Original line number Diff line number Diff line
@@ -3744,6 +3744,19 @@ bool is_module_text_address(unsigned long addr)
	return __module_text_address(addr) != NULL;
}

void module_for_each_mod(int(*func)(struct module *mod, void *data), void *data)
{
	struct module *mod;

	guard(rcu)();
	list_for_each_entry_rcu(mod, &modules, list) {
		if (mod->state == MODULE_STATE_UNFORMED)
			continue;
		if (func(mod, data))
			break;
	}
}

/**
 * __module_text_address() - get the module whose code contains an address.
 * @addr: the address.
+144 −103
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@

#include <asm/local64.h>
#include <asm/local.h>
#include <asm/setup.h>

#include "trace.h"

@@ -48,9 +49,12 @@ static void update_pages_handler(struct work_struct *work);

struct ring_buffer_meta {
	int		magic;
	int		struct_size;
	unsigned long	text_addr;
	unsigned long	data_addr;
	int		struct_sizes;
	unsigned long	total_size;
	unsigned long	buffers_offset;
};

struct ring_buffer_cpu_meta {
	unsigned long	first_buffer;
	unsigned long	head_buffer;
	unsigned long	commit_buffer;
@@ -517,7 +521,7 @@ struct ring_buffer_per_cpu {
	struct mutex			mapping_lock;
	unsigned long			*subbuf_ids;	/* ID to subbuf VA */
	struct trace_buffer_meta	*meta_page;
	struct ring_buffer_meta		*ring_meta;
	struct ring_buffer_cpu_meta	*ring_meta;

	/* ring buffer pages to update, > 0 to add, < 0 to remove */
	long				nr_pages_to_update;
@@ -550,8 +554,7 @@ struct trace_buffer {
	unsigned long			range_addr_start;
	unsigned long			range_addr_end;

	long				last_text_delta;
	long				last_data_delta;
	struct ring_buffer_meta		*meta;

	unsigned int			subbuf_size;
	unsigned int			subbuf_order;
@@ -1271,7 +1274,7 @@ static void rb_head_page_activate(struct ring_buffer_per_cpu *cpu_buffer)
	rb_set_list_to_head(head->list.prev);

	if (cpu_buffer->ring_meta) {
		struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
		struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
		meta->head_buffer = (unsigned long)head->page;
	}
}
@@ -1569,7 +1572,7 @@ static void rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer)
static unsigned long
rb_range_align_subbuf(unsigned long addr, int subbuf_size, int nr_subbufs)
{
	addr += sizeof(struct ring_buffer_meta) +
	addr += sizeof(struct ring_buffer_cpu_meta) +
		sizeof(int) * nr_subbufs;
	return ALIGN(addr, subbuf_size);
}
@@ -1580,19 +1583,22 @@ rb_range_align_subbuf(unsigned long addr, int subbuf_size, int nr_subbufs)
static void *rb_range_meta(struct trace_buffer *buffer, int nr_pages, int cpu)
{
	int subbuf_size = buffer->subbuf_size + BUF_PAGE_HDR_SIZE;
	unsigned long ptr = buffer->range_addr_start;
	struct ring_buffer_meta *meta;
	struct ring_buffer_cpu_meta *meta;
	struct ring_buffer_meta *bmeta;
	unsigned long ptr;
	int nr_subbufs;

	if (!ptr)
	bmeta = buffer->meta;
	if (!bmeta)
		return NULL;

	ptr = (unsigned long)bmeta + bmeta->buffers_offset;
	meta = (struct ring_buffer_cpu_meta *)ptr;

	/* When nr_pages passed in is zero, the first meta has already been initialized */
	if (!nr_pages) {
		meta = (struct ring_buffer_meta *)ptr;
		nr_subbufs = meta->nr_subbufs;
	} else {
		meta = NULL;
		/* Include the reader page */
		nr_subbufs = nr_pages + 1;
	}
@@ -1624,7 +1630,7 @@ static void *rb_range_meta(struct trace_buffer *buffer, int nr_pages, int cpu)
}

/* Return the start of subbufs given the meta pointer */
static void *rb_subbufs_from_meta(struct ring_buffer_meta *meta)
static void *rb_subbufs_from_meta(struct ring_buffer_cpu_meta *meta)
{
	int subbuf_size = meta->subbuf_size;
	unsigned long ptr;
@@ -1640,7 +1646,7 @@ static void *rb_subbufs_from_meta(struct ring_buffer_meta *meta)
 */
static void *rb_range_buffer(struct ring_buffer_per_cpu *cpu_buffer, int idx)
{
	struct ring_buffer_meta *meta;
	struct ring_buffer_cpu_meta *meta;
	unsigned long ptr;
	int subbuf_size;

@@ -1665,13 +1671,76 @@ static void *rb_range_buffer(struct ring_buffer_per_cpu *cpu_buffer, int idx)
	return (void *)ptr;
}

/*
 * See if the existing memory contains a valid meta section.
 * if so, use that, otherwise initialize it.
 */
static bool rb_meta_init(struct trace_buffer *buffer, int scratch_size)
{
	unsigned long ptr = buffer->range_addr_start;
	struct ring_buffer_meta *bmeta;
	unsigned long total_size;
	int struct_sizes;

	bmeta = (struct ring_buffer_meta *)ptr;
	buffer->meta = bmeta;

	total_size = buffer->range_addr_end - buffer->range_addr_start;

	struct_sizes = sizeof(struct ring_buffer_cpu_meta);
	struct_sizes |= sizeof(*bmeta) << 16;

	/* The first buffer will start word size after the meta page */
	ptr += sizeof(*bmeta);
	ptr = ALIGN(ptr, sizeof(long));
	ptr += scratch_size;

	if (bmeta->magic != RING_BUFFER_META_MAGIC) {
		pr_info("Ring buffer boot meta mismatch of magic\n");
		goto init;
	}

	if (bmeta->struct_sizes != struct_sizes) {
		pr_info("Ring buffer boot meta mismatch of struct size\n");
		goto init;
	}

	if (bmeta->total_size != total_size) {
		pr_info("Ring buffer boot meta mismatch of total size\n");
		goto init;
	}

	if (bmeta->buffers_offset > bmeta->total_size) {
		pr_info("Ring buffer boot meta mismatch of offset outside of total size\n");
		goto init;
	}

	if (bmeta->buffers_offset != (void *)ptr - (void *)bmeta) {
		pr_info("Ring buffer boot meta mismatch of first buffer offset\n");
		goto init;
	}

	return true;

 init:
	bmeta->magic = RING_BUFFER_META_MAGIC;
	bmeta->struct_sizes = struct_sizes;
	bmeta->total_size = total_size;
	bmeta->buffers_offset = (void *)ptr - (void *)bmeta;

	/* Zero out the scatch pad */
	memset((void *)bmeta + sizeof(*bmeta), 0, bmeta->buffers_offset - sizeof(*bmeta));

	return false;
}

/*
 * See if the existing memory contains valid ring buffer data.
 * As the previous kernel must be the same as this kernel, all
 * the calculations (size of buffers and number of buffers)
 * must be the same.
 */
static bool rb_meta_valid(struct ring_buffer_meta *meta, int cpu,
static bool rb_cpu_meta_valid(struct ring_buffer_cpu_meta *meta, int cpu,
			      struct trace_buffer *buffer, int nr_pages,
			      unsigned long *subbuf_mask)
{
@@ -1684,20 +1753,6 @@ static bool rb_meta_valid(struct ring_buffer_meta *meta, int cpu,
	if (!subbuf_mask)
		return false;

	/* Check the meta magic and meta struct size */
	if (meta->magic != RING_BUFFER_META_MAGIC ||
	    meta->struct_size != sizeof(*meta)) {
		pr_info("Ring buffer boot meta[%d] mismatch of magic or struct size\n", cpu);
		return false;
	}

	/* The subbuffer's size and number of subbuffers must match */
	if (meta->subbuf_size != subbuf_size ||
	    meta->nr_subbufs != nr_pages + 1) {
		pr_info("Ring buffer boot meta [%d] mismatch of subbuf_size/nr_pages\n", cpu);
		return false;
	}

	buffers_start = meta->first_buffer;
	buffers_end = meta->first_buffer + (subbuf_size * meta->nr_subbufs);

@@ -1743,7 +1798,7 @@ static bool rb_meta_valid(struct ring_buffer_meta *meta, int cpu,
	return true;
}

static int rb_meta_subbuf_idx(struct ring_buffer_meta *meta, void *subbuf);
static int rb_meta_subbuf_idx(struct ring_buffer_cpu_meta *meta, void *subbuf);

static int rb_read_data_buffer(struct buffer_data_page *dpage, int tail, int cpu,
			       unsigned long long *timestamp, u64 *delta_ptr)
@@ -1810,7 +1865,7 @@ static int rb_validate_buffer(struct buffer_data_page *dpage, int cpu)
/* If the meta data has been validated, now validate the events */
static void rb_meta_validate_events(struct ring_buffer_per_cpu *cpu_buffer)
{
	struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
	struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
	struct buffer_page *head_page;
	unsigned long entry_bytes = 0;
	unsigned long entries = 0;
@@ -1891,24 +1946,13 @@ static void rb_meta_validate_events(struct ring_buffer_per_cpu *cpu_buffer)
	}
}

/* Used to calculate data delta */
static char rb_data_ptr[] = "";

#define THIS_TEXT_PTR		((unsigned long)rb_meta_init_text_addr)
#define THIS_DATA_PTR		((unsigned long)rb_data_ptr)

static void rb_meta_init_text_addr(struct ring_buffer_meta *meta)
{
	meta->text_addr = THIS_TEXT_PTR;
	meta->data_addr = THIS_DATA_PTR;
}

static void rb_range_meta_init(struct trace_buffer *buffer, int nr_pages)
static void rb_range_meta_init(struct trace_buffer *buffer, int nr_pages, int scratch_size)
{
	struct ring_buffer_meta *meta;
	struct ring_buffer_cpu_meta *meta;
	unsigned long *subbuf_mask;
	unsigned long delta;
	void *subbuf;
	bool valid = false;
	int cpu;
	int i;

@@ -1916,20 +1960,21 @@ static void rb_range_meta_init(struct trace_buffer *buffer, int nr_pages)
	subbuf_mask = bitmap_alloc(nr_pages + 1, GFP_KERNEL);
	/* If subbuf_mask fails to allocate, then rb_meta_valid() will return false */

	if (rb_meta_init(buffer, scratch_size))
		valid = true;

	for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
		void *next_meta;

		meta = rb_range_meta(buffer, nr_pages, cpu);

		if (rb_meta_valid(meta, cpu, buffer, nr_pages, subbuf_mask)) {
		if (valid && rb_cpu_meta_valid(meta, cpu, buffer, nr_pages, subbuf_mask)) {
			/* Make the mappings match the current address */
			subbuf = rb_subbufs_from_meta(meta);
			delta = (unsigned long)subbuf - meta->first_buffer;
			meta->first_buffer += delta;
			meta->head_buffer += delta;
			meta->commit_buffer += delta;
			buffer->last_text_delta = THIS_TEXT_PTR - meta->text_addr;
			buffer->last_data_delta = THIS_DATA_PTR - meta->data_addr;
			continue;
		}

@@ -1940,16 +1985,12 @@ static void rb_range_meta_init(struct trace_buffer *buffer, int nr_pages)

		memset(meta, 0, next_meta - (void *)meta);

		meta->magic = RING_BUFFER_META_MAGIC;
		meta->struct_size = sizeof(*meta);

		meta->nr_subbufs = nr_pages + 1;
		meta->subbuf_size = PAGE_SIZE;

		subbuf = rb_subbufs_from_meta(meta);

		meta->first_buffer = (unsigned long)subbuf;
		rb_meta_init_text_addr(meta);

		/*
		 * The buffers[] array holds the order of the sub-buffers
@@ -1971,7 +2012,7 @@ static void rb_range_meta_init(struct trace_buffer *buffer, int nr_pages)
static void *rbm_start(struct seq_file *m, loff_t *pos)
{
	struct ring_buffer_per_cpu *cpu_buffer = m->private;
	struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
	struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
	unsigned long val;

	if (!meta)
@@ -1996,7 +2037,7 @@ static void *rbm_next(struct seq_file *m, void *v, loff_t *pos)
static int rbm_show(struct seq_file *m, void *v)
{
	struct ring_buffer_per_cpu *cpu_buffer = m->private;
	struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
	struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
	unsigned long val = (unsigned long)v;

	if (val == 1) {
@@ -2045,7 +2086,7 @@ int ring_buffer_meta_seq_init(struct file *file, struct trace_buffer *buffer, in
static void rb_meta_buffer_update(struct ring_buffer_per_cpu *cpu_buffer,
				  struct buffer_page *bpage)
{
	struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
	struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;

	if (meta->head_buffer == (unsigned long)bpage->page)
		cpu_buffer->head_page = bpage;
@@ -2060,7 +2101,7 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
		long nr_pages, struct list_head *pages)
{
	struct trace_buffer *buffer = cpu_buffer->buffer;
	struct ring_buffer_meta *meta = NULL;
	struct ring_buffer_cpu_meta *meta = NULL;
	struct buffer_page *bpage, *tmp;
	bool user_thread = current->mm != NULL;
	gfp_t mflags;
@@ -2184,7 +2225,7 @@ static struct ring_buffer_per_cpu *
rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
{
	struct ring_buffer_per_cpu *cpu_buffer;
	struct ring_buffer_meta *meta;
	struct ring_buffer_cpu_meta *meta;
	struct buffer_page *bpage;
	struct page *page;
	int ret;
@@ -2313,6 +2354,7 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
					 int order, unsigned long start,
					 unsigned long end,
					 unsigned long scratch_size,
					 struct lock_class_key *key)
{
	struct trace_buffer *buffer;
@@ -2355,10 +2397,23 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,

	/* If start/end are specified, then that overrides size */
	if (start && end) {
		unsigned long buffers_start;
		unsigned long ptr;
		int n;

		size = end - start;
		/* Make sure that start is word aligned */
		start = ALIGN(start, sizeof(long));

		/* scratch_size needs to be aligned too */
		scratch_size = ALIGN(scratch_size, sizeof(long));

		/* Subtract the buffer meta data and word aligned */
		buffers_start = start + sizeof(struct ring_buffer_cpu_meta);
		buffers_start = ALIGN(buffers_start, sizeof(long));
		buffers_start += scratch_size;

		/* Calculate the size for the per CPU data */
		size = end - buffers_start;
		size = size / nr_cpu_ids;

		/*
@@ -2368,7 +2423,7 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
		 * needed, plus account for the integer array index that
		 * will be appended to the meta data.
		 */
		nr_pages = (size - sizeof(struct ring_buffer_meta)) /
		nr_pages = (size - sizeof(struct ring_buffer_cpu_meta)) /
			(subbuf_size + sizeof(int));
		/* Need at least two pages plus the reader page */
		if (nr_pages < 3)
@@ -2376,8 +2431,8 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,

 again:
		/* Make sure that the size fits aligned */
		for (n = 0, ptr = start; n < nr_cpu_ids; n++) {
			ptr += sizeof(struct ring_buffer_meta) +
		for (n = 0, ptr = buffers_start; n < nr_cpu_ids; n++) {
			ptr += sizeof(struct ring_buffer_cpu_meta) +
				sizeof(int) * nr_pages;
			ptr = ALIGN(ptr, subbuf_size);
			ptr += subbuf_size * nr_pages;
@@ -2394,7 +2449,7 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
		buffer->range_addr_start = start;
		buffer->range_addr_end = end;

		rb_range_meta_init(buffer, nr_pages);
		rb_range_meta_init(buffer, nr_pages, scratch_size);
	} else {

		/* need at least two pages */
@@ -2447,7 +2502,7 @@ struct trace_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags,
					struct lock_class_key *key)
{
	/* Default buffer page size - one system page */
	return alloc_buffer(size, flags, 0, 0, 0,key);
	return alloc_buffer(size, flags, 0, 0, 0, 0, key);

}
EXPORT_SYMBOL_GPL(__ring_buffer_alloc);
@@ -2459,6 +2514,7 @@ EXPORT_SYMBOL_GPL(__ring_buffer_alloc);
 * @order: sub-buffer order
 * @start: start of allocated range
 * @range_size: size of allocated range
 * @scratch_size: size of scratch area (for preallocated memory buffers)
 * @key: ring buffer reader_lock_key.
 *
 * Currently the only flag that is available is the RB_FL_OVERWRITE
@@ -2469,32 +2525,29 @@ EXPORT_SYMBOL_GPL(__ring_buffer_alloc);
struct trace_buffer *__ring_buffer_alloc_range(unsigned long size, unsigned flags,
					       int order, unsigned long start,
					       unsigned long range_size,
					       unsigned long scratch_size,
					       struct lock_class_key *key)
{
	return alloc_buffer(size, flags, order, start, start + range_size, key);
	return alloc_buffer(size, flags, order, start, start + range_size,
			    scratch_size, key);
}

/**
 * ring_buffer_last_boot_delta - return the delta offset from last boot
 * @buffer: The buffer to return the delta from
 * @text: Return text delta
 * @data: Return data delta
 *
 * Returns: The true if the delta is non zero
 */
bool ring_buffer_last_boot_delta(struct trace_buffer *buffer, long *text,
				 long *data)
void *ring_buffer_meta_scratch(struct trace_buffer *buffer, unsigned int *size)
{
	if (!buffer)
		return false;
	struct ring_buffer_meta *meta;
	void *ptr;

	if (!buffer->last_text_delta)
		return false;
	if (!buffer || !buffer->meta)
		return NULL;

	*text = buffer->last_text_delta;
	*data = buffer->last_data_delta;
	meta = buffer->meta;

	return true;
	ptr = (void *)ALIGN((unsigned long)meta + sizeof(*meta), sizeof(long));

	if (size)
		*size = (void *)meta + meta->buffers_offset - ptr;

	return ptr;
}

/**
@@ -3105,7 +3158,7 @@ static void rb_inc_iter(struct ring_buffer_iter *iter)
}

/* Return the index into the sub-buffers for a given sub-buffer */
static int rb_meta_subbuf_idx(struct ring_buffer_meta *meta, void *subbuf)
static int rb_meta_subbuf_idx(struct ring_buffer_cpu_meta *meta, void *subbuf)
{
	void *subbuf_array;

@@ -3117,7 +3170,7 @@ static int rb_meta_subbuf_idx(struct ring_buffer_meta *meta, void *subbuf)
static void rb_update_meta_head(struct ring_buffer_per_cpu *cpu_buffer,
				struct buffer_page *next_page)
{
	struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
	struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
	unsigned long old_head = (unsigned long)next_page->page;
	unsigned long new_head;

@@ -3134,7 +3187,7 @@ static void rb_update_meta_head(struct ring_buffer_per_cpu *cpu_buffer,
static void rb_update_meta_reader(struct ring_buffer_per_cpu *cpu_buffer,
				  struct buffer_page *reader)
{
	struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
	struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
	void *old_reader = cpu_buffer->reader_page->page;
	void *new_reader = reader->page;
	int id;
@@ -3763,7 +3816,7 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
			  rb_page_write(cpu_buffer->commit_page));
		rb_inc_page(&cpu_buffer->commit_page);
		if (cpu_buffer->ring_meta) {
			struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
			struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
			meta->commit_buffer = (unsigned long)cpu_buffer->commit_page->page;
		}
		/* add barrier to keep gcc from optimizing too much */
@@ -6016,7 +6069,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
	if (cpu_buffer->mapped) {
		rb_update_meta_page(cpu_buffer);
		if (cpu_buffer->ring_meta) {
			struct ring_buffer_meta *meta = cpu_buffer->ring_meta;
			struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
			meta->commit_buffer = meta->head_buffer;
		}
	}
@@ -6050,7 +6103,6 @@ static void reset_disabled_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
void ring_buffer_reset_cpu(struct trace_buffer *buffer, int cpu)
{
	struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
	struct ring_buffer_meta *meta;

	if (!cpumask_test_cpu(cpu, buffer->cpumask))
		return;
@@ -6069,11 +6121,6 @@ void ring_buffer_reset_cpu(struct trace_buffer *buffer, int cpu)
	atomic_dec(&cpu_buffer->record_disabled);
	atomic_dec(&cpu_buffer->resize_disabled);

	/* Make sure persistent meta now uses this buffer's addresses */
	meta = rb_range_meta(buffer, 0, cpu_buffer->cpu);
	if (meta)
		rb_meta_init_text_addr(meta);

	mutex_unlock(&buffer->mutex);
}
EXPORT_SYMBOL_GPL(ring_buffer_reset_cpu);
@@ -6088,7 +6135,6 @@ EXPORT_SYMBOL_GPL(ring_buffer_reset_cpu);
void ring_buffer_reset_online_cpus(struct trace_buffer *buffer)
{
	struct ring_buffer_per_cpu *cpu_buffer;
	struct ring_buffer_meta *meta;
	int cpu;

	/* prevent another thread from changing buffer sizes */
@@ -6116,11 +6162,6 @@ void ring_buffer_reset_online_cpus(struct trace_buffer *buffer)

		reset_disabled_cpu_buffer(cpu_buffer);

		/* Make sure persistent meta now uses this buffer's addresses */
		meta = rb_range_meta(buffer, 0, cpu_buffer->cpu);
		if (meta)
			rb_meta_init_text_addr(meta);

		atomic_dec(&cpu_buffer->record_disabled);
		atomic_sub(RESET_BIT, &cpu_buffer->resize_disabled);
	}
@@ -7411,9 +7452,9 @@ static __init int rb_write_something(struct rb_test_data *data, bool nested)
		/* Ignore dropped events before test starts. */
		if (started) {
			if (nested)
				data->bytes_dropped += len;
			else
				data->bytes_dropped_nested += len;
			else
				data->bytes_dropped += len;
		}
		return len;
	}
Loading