Skip to content

Commit dada03d

Browse files
Daniel Bristot de Oliveirarostedt
authored andcommitted
rtla: Remove procps-ng dependency
Daniel Wagner reported to me that readproc.h got deprecated. Also, while the procps-ng library was available on Fedora, it was not available on RHEL, which is a piece of evidence that it was not that used. rtla uses procps-ng only to find the PID of the tracers' workload. I used the procps-ng library to avoid reinventing the wheel. But in this case, reinventing the wheel took me less time than the time we already took trying to work around problems. Implement a function that reads /proc/ entries, checking if: - the entry is a directory - the directory name is composed only of digits (PID) - the directory contains the comm file - the comm file contains a comm that matches the tracers' workload prefix. - then return true; otherwise, return false. And use it instead of procps-ng. Link: https://lkml.kernel.org/r/e8276e122ee9eb2c5a0ba8e673fb6488b924b825.1652423574.git.bristot@kernel.org Cc: John Kacur <jkacur@redhat.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tao Zhou <tao.zhou@linux.dev> Fixes: b169637 ("rtla: Helper functions for rtla") Reported-by: Daniel Wagner <dwagner@suse.de> Reviewed-by: Daniel Wagner <dwagner@suse.de> Signed-off-by: Daniel Bristot de Oliveira <bristot@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 941a53c commit dada03d

4 files changed

Lines changed: 88 additions & 24 deletions

File tree

tools/tracing/rtla/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ TRACEFS_HEADERS := $$($(PKG_CONFIG) --cflags libtracefs)
3232

3333
CFLAGS := -O -g -DVERSION=\"$(VERSION)\" $(FOPTS) $(MOPTS) $(WOPTS) $(TRACEFS_HEADERS)
3434
LDFLAGS := -ggdb
35-
LIBS := $$($(PKG_CONFIG) --libs libtracefs) -lprocps
35+
LIBS := $$($(PKG_CONFIG) --libs libtracefs)
3636

3737
SRC := $(wildcard src/*.c)
3838
HDR := $(wildcard src/*.h)

tools/tracing/rtla/README.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ RTLA depends on the following libraries and tools:
1111

1212
- libtracefs
1313
- libtraceevent
14-
- procps
1514

1615
It also depends on python3-docutils to compile man pages.
1716

tools/tracing/rtla/src/utils.c

Lines changed: 85 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Copyright (C) 2021 Red Hat Inc, Daniel Bristot de Oliveira <bristot@kernel.org>
44
*/
55

6-
#include <proc/readproc.h>
6+
#include <dirent.h>
77
#include <stdarg.h>
88
#include <stdlib.h>
99
#include <string.h>
@@ -262,43 +262,107 @@ int __set_sched_attr(int pid, struct sched_attr *attr)
262262

263263
return 0;
264264
}
265+
266+
/*
267+
* procfs_is_workload_pid - check if a procfs entry contains a comm_prefix* comm
268+
*
269+
* Check if the procfs entry is a directory of a process, and then check if the
270+
* process has a comm with the prefix set in char *comm_prefix. As the
271+
* current users of this function only check for kernel threads, there is no
272+
* need to check for the threads for the process.
273+
*
274+
* Return: True if the proc_entry contains a comm file with comm_prefix*.
275+
* Otherwise returns false.
276+
*/
277+
static int procfs_is_workload_pid(const char *comm_prefix, struct dirent *proc_entry)
278+
{
279+
char buffer[MAX_PATH];
280+
int comm_fd, retval;
281+
char *t_name;
282+
283+
if (proc_entry->d_type != DT_DIR)
284+
return 0;
285+
286+
if (*proc_entry->d_name == '.')
287+
return 0;
288+
289+
/* check if the string is a pid */
290+
for (t_name = proc_entry->d_name; t_name; t_name++) {
291+
if (!isdigit(*t_name))
292+
break;
293+
}
294+
295+
if (*t_name != '\0')
296+
return 0;
297+
298+
snprintf(buffer, MAX_PATH, "/proc/%s/comm", proc_entry->d_name);
299+
comm_fd = open(buffer, O_RDONLY);
300+
if (comm_fd < 0)
301+
return 0;
302+
303+
memset(buffer, 0, MAX_PATH);
304+
retval = read(comm_fd, buffer, MAX_PATH);
305+
306+
close(comm_fd);
307+
308+
if (retval <= 0)
309+
return 0;
310+
311+
retval = strncmp(comm_prefix, buffer, strlen(comm_prefix));
312+
if (retval)
313+
return 0;
314+
315+
/* comm already have \n */
316+
debug_msg("Found workload pid:%s comm:%s", proc_entry->d_name, buffer);
317+
318+
return 1;
319+
}
320+
265321
/*
266-
* set_comm_sched_attr - set sched params to threads starting with char *comm
322+
* set_comm_sched_attr - set sched params to threads starting with char *comm_prefix
267323
*
268-
* This function uses procps to list the currently running threads and then
269-
* set the sched_attr *attr to the threads that start with char *comm. It is
324+
* This function uses procfs to list the currently running threads and then set the
325+
* sched_attr *attr to the threads that start with char *comm_prefix. It is
270326
* mainly used to set the priority to the kernel threads created by the
271327
* tracers.
272328
*/
273-
int set_comm_sched_attr(const char *comm, struct sched_attr *attr)
329+
int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr)
274330
{
275-
int flags = PROC_FILLCOM | PROC_FILLSTAT;
276-
PROCTAB *ptp;
277-
proc_t task;
331+
struct dirent *proc_entry;
332+
DIR *procfs;
278333
int retval;
279334

280-
ptp = openproc(flags);
281-
if (!ptp) {
282-
err_msg("error openproc()\n");
283-
return -ENOENT;
335+
if (strlen(comm_prefix) >= MAX_PATH) {
336+
err_msg("Command prefix is too long: %d < strlen(%s)\n",
337+
MAX_PATH, comm_prefix);
338+
return 1;
284339
}
285340

286-
memset(&task, 0, sizeof(task));
341+
procfs = opendir("/proc");
342+
if (!procfs) {
343+
err_msg("Could not open procfs\n");
344+
return 1;
345+
}
287346

288-
while (readproc(ptp, &task)) {
289-
retval = strncmp(comm, task.cmd, strlen(comm));
290-
if (retval)
347+
while ((proc_entry = readdir(procfs))) {
348+
349+
retval = procfs_is_workload_pid(comm_prefix, proc_entry);
350+
if (!retval)
291351
continue;
292-
retval = __set_sched_attr(task.tid, attr);
293-
if (retval)
352+
353+
/* procfs_is_workload_pid confirmed it is a pid */
354+
retval = __set_sched_attr(atoi(proc_entry->d_name), attr);
355+
if (retval) {
356+
err_msg("Error setting sched attributes for pid:%s\n", proc_entry->d_name);
294357
goto out_err;
295-
}
358+
}
296359

297-
closeproc(ptp);
360+
debug_msg("Set sched attributes for pid:%s\n", proc_entry->d_name);
361+
}
298362
return 0;
299363

300364
out_err:
301-
closeproc(ptp);
365+
closedir(procfs);
302366
return 1;
303367
}
304368

tools/tracing/rtla/src/utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* '18446744073709551615\0'
77
*/
88
#define BUFF_U64_STR_SIZE 24
9+
#define MAX_PATH 1024
910

1011
#define container_of(ptr, type, member)({ \
1112
const typeof(((type *)0)->member) *__mptr = (ptr); \
@@ -53,5 +54,5 @@ struct sched_attr {
5354
};
5455

5556
int parse_prio(char *arg, struct sched_attr *sched_param);
56-
int set_comm_sched_attr(const char *comm, struct sched_attr *attr);
57+
int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr);
5758
int set_cpu_dma_latency(int32_t latency);

0 commit comments

Comments
 (0)