aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Google) <rostedt@goodmis.org>2023-01-06 13:39:26 -0500
committerSteven Rostedt (Google) <rostedt@goodmis.org>2023-01-09 13:12:37 -0500
commit57b2342dca41f6467b59ea293414f1694896c4a7 (patch)
tree4916f01c57ccbf84cc6f1372b24c6a833a261a51
parent2391750cceb385ba7d8e68d6337469eccfa5cecc (diff)
downloadtrace-cmd-57b2342dca41f6467b59ea293414f1694896c4a7.tar.gz
trace-cmd: Have trace_stream_read() use poll()
Replace the select() that is used in trace_stream_read() with poll() as that is the more robust function, as select() is limited to fds that are less than 1024, and today's kernels can have fds bigger than that. As a side-effect, since poll() uses milliseconds for its timeout, the granularity of the timeout is no longer microseconds, even though that is what is passed in on the command line. We may need to changes this. If 1us is passed in, it will be rounded up to 1ms. But zero and negative numbers shall remain the same. Link: https://lore.kernel.org/linux-trace-devel/20230106183930.12565-7-rostedt@goodmis.org Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-rw-r--r--tracecmd/include/trace-local.h2
-rw-r--r--tracecmd/trace-record.c13
-rw-r--r--tracecmd/trace-stream.c34
3 files changed, 21 insertions, 28 deletions
diff --git a/tracecmd/include/trace-local.h b/tracecmd/include/trace-local.h
index 023afb3b..ae208fb6 100644
--- a/tracecmd/include/trace-local.h
+++ b/tracecmd/include/trace-local.h
@@ -137,7 +137,7 @@ struct tracecmd_input *
trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
struct hook_list *hooks,
tracecmd_handle_init_func handle_init, int global);
-int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv);
+int trace_stream_read(struct pid_record_data *pids, int nr_pids, long sleep_us);
void trace_show_data(struct tracecmd_input *handle, struct tep_record *record);
diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
index 83ae8e60..03f990e3 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -73,7 +73,7 @@ static int rt_prio;
static int keep;
static int latency;
-static int sleep_time = 1000;
+static long sleep_time = 1000;
static int recorder_threads;
static struct pid_record_data *pids;
static int buffers;
@@ -798,8 +798,7 @@ static void stop_threads(enum trace_type type)
/* Flush out the pipes */
if (type & TRACE_TYPE_STREAM) {
do {
- struct timeval tv = { 0, 0 };
- ret = trace_stream_read(pids, recorder_threads, &tv);
+ ret = trace_stream_read(pids, recorder_threads, 0);
} while (ret > 0);
}
}
@@ -1307,7 +1306,6 @@ static void update_task_filter(void)
static pid_t trace_waitpid(enum trace_type type, pid_t pid, int *status, int options)
{
- struct timeval tv = { 1, 0 };
int ret;
if (type & TRACE_TYPE_STREAM)
@@ -1319,7 +1317,7 @@ static pid_t trace_waitpid(enum trace_type type, pid_t pid, int *status, int opt
return ret;
if (type & TRACE_TYPE_STREAM)
- trace_stream_read(pids, recorder_threads, &tv);
+ trace_stream_read(pids, recorder_threads, sleep_time);
} while (1);
}
@@ -1640,14 +1638,13 @@ static inline void ptrace_attach(struct buffer_instance *instance, int pid) { }
static void trace_or_sleep(enum trace_type type, bool pwait)
{
- struct timeval tv = { 1 , 0 };
int i;
if (pwait)
ptrace_wait(type);
else if (type & TRACE_TYPE_STREAM) {
/* Returns zero if it did not read anything (and did a sleep) */
- if (trace_stream_read(pids, recorder_threads, &tv) > 0)
+ if (trace_stream_read(pids, recorder_threads, sleep_time) > 0)
return;
/* Force a flush if nothing was read (including on errors) */
for (i = 0; i < recorder_threads; i++) {
@@ -7021,7 +7018,7 @@ static void record_trace(int argc, char **argv,
trace_or_sleep(type, pwait);
/* Streams need to be flushed one more time */
if (type & TRACE_TYPE_STREAM)
- trace_stream_read(pids, recorder_threads, NULL);
+ trace_stream_read(pids, recorder_threads, -1);
}
tell_guests_to_stop(ctx);
diff --git a/tracecmd/trace-stream.c b/tracecmd/trace-stream.c
index d83513f8..ec6a10f7 100644
--- a/tracecmd/trace-stream.c
+++ b/tracecmd/trace-stream.c
@@ -4,6 +4,7 @@
*
*/
#include <stdio.h>
+#include <poll.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@@ -83,17 +84,19 @@ trace_stream_init(struct buffer_instance *instance, int cpu, int fd, int cpus,
return NULL;
}
-int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval *tv)
+int trace_stream_read(struct pid_record_data *pids, int nr_pids, long sleep_us)
{
- struct tep_record *record;
- struct pid_record_data *pid;
struct pid_record_data *last_pid;
- fd_set rfds;
- int top_rfd = 0;
- int nr_fd;
+ struct pid_record_data *pid;
+ struct tep_record *record;
+ struct pollfd pollfd[nr_pids];
+ long sleep_ms = sleep_us > 0 ? (sleep_us + 999) / 1000 : sleep_us;
int ret;
int i;
+ if (!nr_pids)
+ return 0;
+
last_pid = NULL;
again:
@@ -118,25 +121,18 @@ int trace_stream_read(struct pid_record_data *pids, int nr_pids, struct timeval
return 1;
}
- nr_fd = 0;
- FD_ZERO(&rfds);
-
for (i = 0; i < nr_pids; i++) {
/* Do not process closed pipes */
- if (pids[i].closed)
+ if (pids[i].closed) {
+ memset(pollfd + i, 0, sizeof(*pollfd));
continue;
- nr_fd++;
- if (pids[i].brass[0] > top_rfd)
- top_rfd = pids[i].brass[0];
+ }
- FD_SET(pids[i].brass[0], &rfds);
+ pollfd[i].fd = pids[i].brass[0];
+ pollfd[i].events = POLLIN;
}
- if (!nr_fd)
- return 0;
-
- ret = select(top_rfd + 1, &rfds, NULL, NULL, tv);
-
+ ret = poll(pollfd, nr_pids, sleep_ms);
if (ret > 0)
goto again;