-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Fixed JIT startup failure not being respected by new threads in ZTS #16853
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
With I wonder, though, what happens when there are multiple processes involved (e.g. FCGI without FPM). Could that cause the same issue? Do we need to promote the global to SHM? |
I'm not familiar enough with FCGI to know for sure if this would be a problem. Possibly the same issue could arise in a forked process, but I think this global will be sufficient to fix 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.
The following looks suspicious to me: "when a second thread is started, INI is loaded again, setting JIT_G(enabled) = 1 and JIT_G(on) = 1, but this time accel_post_startup() does not override these settings".
Why INI is loaded again?
In ZTS build (without threaded extension) INI directives are inherited from parent process using zend_copy_ini_directives()
.
Line 875 in ff5b42b
In the case of threading extensions, because the threads are created post-startup, That being said, I'd expect problems without threading extensions too. Even if all threads' INI were set up before |
there doesn't seem to be a thread post-startup hook that runs after zend_startup_cb() that could be used for this this fix is similar to accel_startup_ok() as seen here: https://github.com/php/php-src/blob/fc1db70f106525e81f9a24539340b7cf2e82e844/ext/opcache/ZendAccelerator.c#L2631-L2634
I've pushed an alternative fix using RINIT to set the values, which should cover the case where threads were started before accel_post_startup(). It's not the cleanest fix (since really it should only run when threads are started and not on request start), but judging by this code it looks like it's the way to go: php-src/ext/opcache/ZendAccelerator.c Lines 2631 to 2634 in fc1db70
|
Right. Threads in ZTS build seems ignoring jit startup failure. |
While there might be a more general problem, the issue at hand is just that we try to protect the ext/opcache/jit/zend_jit.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c
index ffcb8daaf5..a4d74872b0 100644
--- a/ext/opcache/jit/zend_jit.c
+++ b/ext/opcache/jit/zend_jit.c
@@ -3424,7 +3424,7 @@ void zend_jit_unprotect(void)
#else
new = PAGE_READWRITE;
#endif
- if (!VirtualProtect(dasm_buf, dasm_size, new, &old)) {
+ if (dasm_buf && !VirtualProtect(dasm_buf, dasm_size, new, &old)) {
DWORD err = GetLastError();
char *msg = php_win32_error_to_msg(err);
fprintf(stderr, "VirtualProtect() failed [%u] %s\n", err, msg);
@@ -3451,7 +3451,7 @@ void zend_jit_protect(void)
if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) {
DWORD old;
- if (!VirtualProtect(dasm_buf, dasm_size, PAGE_EXECUTE_READ, &old)) {
+ if (dasm_buf && !VirtualProtect(dasm_buf, dasm_size, PAGE_EXECUTE_READ, &old)) {
DWORD err = GetLastError();
char *msg = php_win32_error_to_msg(err);
fprintf(stderr, "VirtualProtect() failed [%u] %s\n", err, msg); That lets the ext/parallel test suite pass (regardless of the value of |
Yeah, I did consider that solution too @cmb69 but I don't know what other bugs might be lurking on account of this missing initialization. Thought it was best to cover all bases.
@dstogov Yep, I think so. I guess few extensions do this in a significant way so it hasn't been noticed before. |
I don't see an obvious general fix for this problem. Since the problem really affects the TS globals and not the INI values themselves. The TS global struct would have to be copied from the main thread, but that might include pointers to thread-local objects that shouldn't be copied. For this PR, it's possible using |
OK let fix the problem in this way. |
Thank you! Applied to PHP-8.2 and merged up. |
The merge into PHP-8.4 went bad, so I reverted for now. Will have a look shortly; AFK for now. |
I think the return value for zend_jit_startup() is gone in 8.4, that's probably why it conflicts. |
Indeed, thanks! So an extraneous |
There doesn't seem to be a thread post-startup hook that runs after zend_startup_cb() that could be used for this this fix is similar to accel_startup_ok() as seen here: https://github.com/php/php-src/blob/fc1db70f106525e81f9a24539340b7cf2e82e844/ext/opcache/ZendAccelerator.c#L2631-L2634 Closes phpGH-16853.
Fixes #16851
@cmb69 would you be able to verify if this fixes the issue you had with ext-parallel?