-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Enhance moving PHP code pages into huge pages #12806
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
Conversation
For example:
|
This patch should fix #12807 |
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 patch looks good. Only minor changes requested and few minor questions.
ext/opcache/ZendAccelerator.c
Outdated
if (ret >= 6) { | ||
if (name[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.
In sscanf() reads 6 arguments value of name may be undefined.
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.
Same reason above. The name value in /proc/self/maps
may be empty, I use >=6
to do the judgement.
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 fact that name value in /ptoc/self/maps
is empty doesn't mean that the value of variable name
becomes empty. If scanf()
processed only 6 variables, the value of name
is undefined (most probably unchanged).
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.
Sorry for my wrong explanation. In the codes, scanf()
will processe 7 variables:
ret=sscanf(buffer, "%lx-%lx %4s %lx %9s %lu %s\n", &start, &end, perm, &offset, dev, &inode, name);
If the name in maps is empty, it only return 6 but not 7.
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.
Yes, but the code below checks variable name
even if ret == 6
. I suppose lines without name should be skipped.
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.
OK. Changed the codes and still use ret==7
to do the judgement. Thank you~
ext/opcache/ZendAccelerator.c
Outdated
ret = sscanf(buffer, "%lx-%lx %4s %lx %9s %lu %s\n", &start, &end, perm, &offset, dev, &inode, name); | ||
if (ret >= 6) { | ||
if (name[0] == '[') { | ||
// meet heap segment, should break out. |
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 do you stop on [heap] segment?
We stop on program code segment, but I'm not sure if [heap] may be placed before 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 saw most of the maps, [heap] segment is under program code segment in maps. So I suppose if met heap, the huge page mapping operation should break . Do you think it's unnecessary?
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, it's better to remove this. It's not a problem to scan until the end of the file.
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.
Thank you. I will remove this.
ext/opcache/ZendAccelerator.c
Outdated
if (perm[0] == 'r' && perm[1] == '-' && perm[2] == 'x' && name[0] == '/') { | ||
long unsigned int seg_start = ZEND_MM_ALIGNED_SIZE_EX(start, huge_page_size); | ||
long unsigned int seg_end = (end & ~(huge_page_size-1L)); | ||
long unsigned int real_end; | ||
|
||
ret = fscanf(f, "%lx-", &start); | ||
if (ret == 1 && start == seg_end + huge_page_size) { | ||
real_end = end; | ||
seg_end = start; | ||
} else { | ||
real_end = seg_end; | ||
} | ||
char *is_substring = strstr(name, __progname); | ||
// try to find the php text segment and map it into huge pages | ||
if (is_substring != NULL) { |
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.
Can you please minimize the diff avoiding unnecessary indentation changes.
- if (perm[0] == 'r' && perm[1] == '-' && perm[2] == 'x' && name[0] == '/') {
+ if (perm[0] == 'r' && perm[1] == '-' && perm[2] == 'x' && name[0] == '/'
+ && strstr(name, __progname) != NULL) {
... (the rest seems unchanged)
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.
Done, thank you for your review. :)
02d60f7
to
562fcaf
Compare
ext/opcache/ZendAccelerator.c
Outdated
if (ret == 7) { | ||
if (perm[0] == 'r' && perm[1] == '-' && perm[2] == 'x' && name[0] == '/') { | ||
// try to find the php text segment and map it into huge pages | ||
char *is_substring = strstr(name, __progname); | ||
if (perm[0] == 'r' && perm[1] == '-' && perm[2] == 'x' && name[0] == '/' && is_substring != NULL) { |
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 rewrite this like
if (ret >= 6) {
if (ret > 6
&& perm[0] == 'r' && perm[1] == '-' && perm[2] == 'x' && name[0] == '/'
&& strstr(name, __progname)) {
- lines without "name" are going to be skipped and won't stop the search
- strstr() call is going to be performed only after the cheaper checks
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.
Done. Thank you for your kindness help~
The former implementation of huge pages for PHP code segments may fail to map in certain scenarios. For instance, if the initial 'r-x-' segment is not PHP, it will result in a failure to map into huge pages. Consequently, the optimization for huge pages with PHP code will no longer be effective. This patch improves the implementation by accurately matching all 'r-x-' segments until it locates the PHP code segment. Subsequently, it performs the necessary huge page mapping. Signed-off-by: PeterYang12 <yuhan.yang@intel.com> Reviewed-by: chen-hu-97 <hu1.chen@intel.com>
562fcaf
to
ced9c52
Compare
The former implementation of huge pages for PHP code segments may fail to map in certain scenarios. For instance, if the initial 'r-x-' segment is not PHP, it will result in a failure to map into huge pages. Consequently, the optimization for huge pages with PHP code will no longer be effective.
This patch improves the implementation by accurately matching all 'r-x-' segments until it locates the PHP code segment. Subsequently, it performs the necessary huge page mapping.
Signed-off-by: PeterYang12 yuhan.yang@intel.com
Reviewed-by: chen-hu-97 hu1.chen@intel.com