Commit 775cb093 authored by Vincent Donnefort's avatar Vincent Donnefort Committed by Steven Rostedt (Google)
Browse files

tracing: Add events/ root files to trace remotes

Just like for the kernel events directory, add 'enable', 'header_page'
and 'header_event' at the root of the trace remote events/ directory.

Link: https://patch.msgid.link/20260309162516.2623589-11-vdonnefort@google.com


Reviewed-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: default avatarVincent Donnefort <vdonnefort@google.com>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent 07252915
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -640,7 +640,8 @@ int ring_buffer_print_page_header(struct trace_buffer *buffer, struct trace_seq
	trace_seq_printf(s, "\tfield: char data;\t"
			 "offset:%u;\tsize:%u;\tsigned:%u;\n",
			 (unsigned int)offsetof(typeof(field), data),
			 (unsigned int)buffer->subbuf_size,
			 (unsigned int)(buffer ? buffer->subbuf_size :
						 PAGE_SIZE - BUF_PAGE_HDR_SIZE),
			 (unsigned int)is_signed_type(char));

	return !trace_seq_has_overflowed(s);
+137 −1
Original line number Diff line number Diff line
@@ -1125,10 +1125,145 @@ static int remote_event_callback(const char *name, umode_t *mode, void **data,
	return 0;
}

static ssize_t remote_events_dir_enable_write(struct file *filp, const char __user *ubuf,
					      size_t count, loff_t *ppos)
{
	struct trace_remote *remote = file_inode(filp)->i_private;
	int i, ret;
	u8 enable;

	ret = kstrtou8_from_user(ubuf, count, 10, &enable);
	if (ret)
		return ret;

	guard(mutex)(&remote->lock);

	for (i = 0; i < remote->nr_events; i++) {
		struct remote_event *evt = &remote->events[i];

		trace_remote_enable_event(remote, evt, enable);
	}

	return count;
}

static ssize_t remote_events_dir_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
					     loff_t *ppos)
{
	struct trace_remote *remote = file_inode(filp)->i_private;
	const char enabled_char[] = {'0', '1', 'X'};
	char enabled_str[] = " \n";
	int i, enabled = -1;

	guard(mutex)(&remote->lock);

	for (i = 0; i < remote->nr_events; i++) {
		struct remote_event *evt = &remote->events[i];

		if (enabled == -1) {
			enabled = evt->enabled;
		} else if (enabled != evt->enabled) {
			enabled = 2;
			break;
		}
	}

	enabled_str[0] = enabled_char[enabled == -1 ? 0 : enabled];

	return simple_read_from_buffer(ubuf, cnt, ppos, enabled_str, 2);
}

static const struct file_operations remote_events_dir_enable_fops = {
	.write = remote_events_dir_enable_write,
	.read = remote_events_dir_enable_read,
};

static ssize_t
remote_events_dir_header_page_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
{
	struct trace_seq *s;
	int ret;

	s = kmalloc(sizeof(*s), GFP_KERNEL);
	if (!s)
		return -ENOMEM;

	trace_seq_init(s);

	ring_buffer_print_page_header(NULL, s);
	ret = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, trace_seq_used(s));
	kfree(s);

	return ret;
}

static const struct file_operations remote_events_dir_header_page_fops = {
	.read = remote_events_dir_header_page_read,
};

static ssize_t
remote_events_dir_header_event_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
{
	struct trace_seq *s;
	int ret;

	s = kmalloc(sizeof(*s), GFP_KERNEL);
	if (!s)
		return -ENOMEM;

	trace_seq_init(s);

	ring_buffer_print_entry_header(s);
	ret = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, trace_seq_used(s));
	kfree(s);

	return ret;
}

static const struct file_operations remote_events_dir_header_event_fops = {
	.read = remote_events_dir_header_event_read,
};

static int remote_events_dir_callback(const char *name, umode_t *mode, void **data,
				      const struct file_operations **fops)
{
	if (!strcmp(name, "enable")) {
		*mode = TRACEFS_MODE_WRITE;
		*fops = &remote_events_dir_enable_fops;
		return 1;
	}

	if (!strcmp(name, "header_page")) {
		*mode = TRACEFS_MODE_READ;
		*fops = &remote_events_dir_header_page_fops;
		return 1;
	}

	if (!strcmp(name, "header_event")) {
		*mode = TRACEFS_MODE_READ;
		*fops = &remote_events_dir_header_event_fops;
		return 1;
	}

	return 0;
}

static int trace_remote_init_eventfs(const char *remote_name, struct trace_remote *remote,
				     struct remote_event *evt)
{
	struct eventfs_inode *eventfs = remote->eventfs;
	static struct eventfs_entry dir_entries[] = {
		{
			.name		= "enable",
			.callback	= remote_events_dir_callback,
		}, {
			.name		= "header_page",
			.callback	= remote_events_dir_callback,
		}, {
			.name		= "header_event",
			.callback	= remote_events_dir_callback,
		}
	};
	static struct eventfs_entry entries[] = {
		{
			.name		= "enable",
@@ -1144,7 +1279,8 @@ static int trace_remote_init_eventfs(const char *remote_name, struct trace_remot
	bool eventfs_create = false;

	if (!eventfs) {
		eventfs = eventfs_create_events_dir("events", remote->dentry, NULL, 0, NULL);
		eventfs = eventfs_create_events_dir("events", remote->dentry, dir_entries,
						    ARRAY_SIZE(dir_entries), remote);
		if (IS_ERR(eventfs))
			return PTR_ERR(eventfs);