New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
utils: Fix an issue not finding tracefs on some kernels #1762
Conversation
e835911
to
edb43bd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR. But as you mentioned, statfs
is deprecated so I'm not sure if it's good to use the interface here.
I thought we could just check whether /sys/kernel/tracing/tracing_on
or /sys/kernel/debug/tracing/tracing_on
exists or not.
@namhyung Do you think we can use statfs
check here?
utils/tracefs.c
Outdated
pr_dbg2("Use %s as TRACING_DIR\n", TRACING_DIR); | ||
/* check debugfs path is mounted */ | ||
statfs(DEBUGFS_DIR_PATH, &fs); | ||
if (fs.f_type == DEBUGFS_MAGIC) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check actually fails because /sys/kernel/debug
is debugfs, but /sys/kernel/debug/tracing
is mounted as tracefs on top of the debugfs.
There might be a chance that old kernel uses /sys/kernel/debug/tracing
as debugfs so you might be better to check both DEBUGFS_MAGIC
and TRACEFS_MAGIC
.
And please reword the commit message to make it begin with a verb instead of past tense. i.e. Please read other commit message to get more references by running |
Hi @honggyukim of course, statfs was marked as deprecated as I mentioned, so I wasn't sure if it was right to use it, but I used it for the following reasons.
Thank you for always reviewing my code and comments and pointing out anything I've missed. I'm learning a lot thanks! I will re-apply and commit push the feedback you suggested. 😃 |
edb43bd
to
d2728d2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than just checking the path, I wanted to do an additional check to make sure this physical path is indeed the path we are looking for.
I think existence check is enough for /sys/kernel/{debug/}tracing/tracing_on
with access
call. Doing so, you can remove statfs
and be free from using deprecated call.
utils/tracefs.c
Outdated
xasprintf(&TRACING_DIR, "%s", TRACEFS_DIR_PATH); | ||
goto found; | ||
} | ||
else if (!statfs("/sys/kernel/debug", &fs) && fs.f_type == DEBUGFS_MAGIC) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not testing /sys/kernel/debug/tracing
here? i.e. OLD_TRACEFS_DIR_PATH
.
Please don't remove the original logic and use it as a fallback when the quick check for the known path fails. I'm not sure why Also it's not true that having debugfs at |
Do you want to keep the parsing logic from
Then I'm fine using
The new tracefs location seems to be fixed at As you mentioned I'm not sure about the tracefs location at
I also think so. |
Hi @namhyung and @honggyukim. I agree with honggyukim, it's better to use So I thought it would be better to remove the existing logic using I still don't understand why you don't remove the existing logic, can you explain why? |
OK, I agree to use |
d2728d2
to
afef79f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commit message is too long, please break long lines not to exceed 72 characters.
utils/tracefs.c
Outdated
else if (!strcmp(ent->mnt_fsname, "debugfs")) { | ||
xasprintf(&TRACING_DIR, "%s/tracing", ent->mnt_dir); | ||
found = true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this 'else if' part should be removed because there's no guarantee for tracefs even if it found debugfs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll accept the feedback and upload the changed code.
utils/tracefs.c
Outdated
} | ||
|
||
endmntent(fp); | ||
} while (0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you use do ... while (0)
block?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First, I wanted to go down without executing the while() { ... }
and endmntent()
below when the result of the setmntent()
function is NULL.
Second, I didn't want to keep the if ~ else
statements too long. If the if ~ else
statement is too long or deep it becomes hard to read. so I wanted to use do ~ while(0)
which is used by the Linux kernel to avoid this.
I thought this was best, but if there is a better alternative, I'm open to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can split the check for TRACEFS_DIR_PATH into a separate commit and focus on the mntent change here. Then it can be like this.
fp = setmntent("/proc/mounts", "r");
if (fp == NULL)
return false;
while ((ent = getmntent(fp)) != NULL) {
if (strcmp(ent->mnt_fsname, "tracefs"))
continue;
xasprintf(&TRACING_DIR, "%s", ent->mnt_dir);
found = true;
break;
}
endmntent(fp);
return found;
size_t len; | ||
|
||
if (TRACING_DIR) | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You removed this caching logic..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll revert the caching logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm.. I'm not sure why the original code returns false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't figure out why the original code was returning false either.
The original code works fine, but I think it's semantically correct for the caching logic to return true.
bc8c281
to
0743e95
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with the change roughly but want to have the commits in the reverse order. The first commit removed the original logic and added a new code to quickly check the well-known path. That's +1 and -1 in terms of the functionality. And the second commit added /proc parsing back, changing -1 to 0.
I'd like to have a commit that fixes /proc parsing first so that we don't lose any functionality in the meantime (like +1 to +1, no change). Then add the the quick check in the second commit (+1 to +2). Even though the net result is the same (+1), this way we can gaurantee it only adds and never loses. :)
utils/tracefs.c
Outdated
bool found = false; | ||
|
||
if (TRACING_DIR) | ||
return true; | ||
|
||
if (!statfs(TRACEFS_DIR_PATH, &fs) && fs.f_type == TRACEFS_MAGIC) { | ||
xasprintf(&TRACING_DIR, "%s", TRACEFS_DIR_PATH); | ||
pr_dbg2("TRACING_DIR : %s\n", TRACING_DIR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can keep this or not introduce in the first place.
98835ae
to
c3c5df3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update. I have some comments.
In addition, the link in the below commit message is broken.
However, we can get faster performance by checking the
default tracefs path given in https://github.com/torvalds/linux/commit/cc31004
before checking the previously added logic.
I think it wouldn't make faster performance because this path is not in hot spot. It's just to simplify the logic.
I've merged a few commits into master so please rebase and update this PR onto the current master. |
This logic change is to address issue namhyung#1753, which was causing issue on some kernels. The previous logic used '/proc/self/mountinfo', but in some cases the number of fields was different, causing a parse error. This has been fixed by using getmntent() and setmntent() to parse '/proc/mounts' structurally. Signed-off-by: Gichoel Choi <gichoel3101@gmail.com>
c3c5df3
to
d39158a
Compare
@honggyukim, I replaced the broken commit link and re-uploaded the commit with the feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update. I have two last comments. One is the inlined comment below.
The other is that I would like to ask you to use URL from the official kernel repo instead of github one.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2455f0e
In addition, the link can be clicked in github, but not from the commit message itself because it's shown as just torvalds/linux@2455f0e
, which is not a complete URL.
Instead of it, please add the line below and just above Signed-off-by
line as follows.
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2455f0e
Signed-off-by: Gichoel Choi <gichoel3101@gmail.com>
Actually 7 digit is not enough for kernel commits due to possible collision, kernel community recommends 12. And there's a short form of the URL like: https://git.kernel.org/torvalds/c/2455f0e124d3 |
d39158a
to
c9b7691
Compare
utils/tracefs.c
Outdated
if ((!statfs(TRACEFS_DIR_PATH, &fs) && fs.f_type == TRACEFS_MAGIC) || | ||
(!statfs(OLD_TRACEFS_DIR_PATH, &fs) && fs.f_type == TRACEFS_MAGIC)) { | ||
xasprintf(&TRACING_DIR, "%s", TRACEFS_DIR_PATH); | ||
return true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm.. Does it really handle when only /sys/kernel/debug/tracing
is available? This logic sets TRACING_DIR
to /sys/kernel/tracing
in both cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've incorporated feedback on what I missed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not that important but the expression "incorporated feedback" sounds awkward. You can just say that "I've updated it based on your feedback".
c9b7691
to
44f1a26
Compare
utils/tracefs.c
Outdated
if (!statfs(TRACEFS_DIR_PATH, &fs) && fs.f_type == TRACEFS_MAGIC) { | ||
xasprintf(&TRACING_DIR, "%s", TRACEFS_DIR_PATH); | ||
found = true; | ||
} | ||
else if (!statfs(OLD_TRACEFS_DIR_PATH, &fs) && fs.f_type == TRACEFS_MAGIC) { | ||
xasprintf(&TRACING_DIR, "%s", OLD_TRACEFS_DIR_PATH); | ||
found = true; | ||
} | ||
|
||
fp = fopen(PROC_MOUNTINFO, "r"); | ||
if (found) | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather write this part as follows.
if (!statfs(TRACEFS_DIR_PATH, &fs) && fs.f_type == TRACEFS_MAGIC) {
xasprintf(&TRACING_DIR, "%s", TRACEFS_DIR_PATH);
return true;
}
if (!statfs(OLD_TRACEFS_DIR_PATH, &fs) && fs.f_type == TRACEFS_MAGIC) {
xasprintf(&TRACING_DIR, "%s", OLD_TRACEFS_DIR_PATH);
return true;
}
This is to reduce one more branch from if (found)
.
The logic we added previously was to use '/proc/mounts' to find the tracefs path. However, the logic can be simplified even further by using the canonical ftrace path, as per commit from torvalds/linux@2455f0e. Link: https://git.kernel.org/torvalds/c/2455f0e124d3 Signed-off-by: Gichoel Choi <gichoel3101@gmail.com>
44f1a26
to
a689290
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks very much for your patience.
Thank you @namhyung and @honggyukim for the great feedback each time. I learned a lot from this PR and issue :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
The currnet find_tracing_dir logic parses /proc/self/mounts to find tracefs, but some cases show the number of fields in /proc/self/mounts differs and it makes a parsing failure. Gichoel fixes this issue with two steps as follows. 1. Try known paths at /sys/kernel/tracing and /sys/kernel/debug/tracing 2. Use setmntent/getmntent to identify tracefs from /proc/mounts. Signed-off-by: Honggyu Kim <honggyu.kp@gmail.com>
When parsing /proc/self/mountinfo on some kernels, the number of fields is different and tracefs cannot be obtained.
changed method to check if paths of "/sys/kernel/tracing (tracefs)" and "/sys/kernel/debug/tracing (debugfs)" exist
Fixed: #1753