Skip to content
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

Consider disabling JIT by default #1924

Closed
3 tasks done
PowerKiKi opened this issue Feb 7, 2023 · 20 comments
Closed
3 tasks done

Consider disabling JIT by default #1924

PowerKiKi opened this issue Feb 7, 2023 · 20 comments

Comments

@PowerKiKi
Copy link

Frequently asked questions

  • I have read Frequently Asked Questions
  • I have looked at the list of the existing issues (including closed issues) and searched if my issue has been already reported
  • I have tried to resolve the issue myself and will describe what I did in clear and consise manner

Describe the bug

For a little more than 1 year a few people reported segfaults in PHP when JIT is enabled. Until now the only clear solution to avoid those is to either entirely disable JIT, or at least configure it with the flag 1205 (or equivalent function).

The JIT author himself said that the current JIT version is buggy, hard to debug, and "often almost useless for real-life apps". He also happens to be working on a new JIT version, so it seems unlikely he would have time to investigate complex bugs in the coming months.

So the current situation is that the default configuration of PHP is subject to segfault that are unlikely to be fixed quickly. The workaround around that is to simply configure PHP to not use JIT. There doesn't seem to be any downside "for real-life apps".

To Reproduce

Unfortunately there is no clear reproduction steps

Your understanding of what is happening

Some hard-to-reproduce race conditions might corrupt the JIT engine, leading to sporadic segfaults.

What steps did you take to resolve issue yourself before reporting it here

Manually configure JIT to be disable.

Expected behavior

I expect default PHP configuration to never segfaults. So it should be changed to either disable or function. And if advanced users who know what they are doing actually need it, they can always re-enable it.

Distribution (please complete the following information):

  • OS: Ubuntu 22.04.1
  • Architecture: amd64
  • Repository: Ubuntu PPA

Package(s) (please complete the following information):

php8.1-fpm:
  Installed: 8.1.14-2+ubuntu22.04.1+deb.sury.org+1
  Candidate: 8.1.14-2+ubuntu22.04.1+deb.sury.org+1
  Version table:
 *** 8.1.14-2+ubuntu22.04.1+deb.sury.org+1 500
        500 http://ppa.launchpad.net/ondrej/php/ubuntu jammy/main amd64 Packages
        100 /var/lib/dpkg/status
     8.1.2-1ubuntu2.10 500
        500 http://ch.archive.ubuntu.com/ubuntu jammy-security/universe amd64 Packages
        500 http://ch.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages
     8.1.2-1ubuntu2 500
        500 http://ch.archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
@oerdnj
Copy link
Owner

oerdnj commented Feb 7, 2023

That's probably not a bad idea.

@PowerKiKi
Copy link
Author

Meanwhile, it has been pointed out that the default config of opcache.jit_buffer_size => 0 also means that JIT is disabled. I would still argue that disabling JIT explicitly with disable would send a stronger signal as to whether JIT is mature enough or not, and that disabling it was a clear, conscious decision, and not an happenstance.

But I'll let you be the judge of that...

@oerdnj
Copy link
Owner

oerdnj commented Feb 7, 2023

The opcache.ini now has opcache.jit=off

@oerdnj oerdnj closed this as completed Feb 7, 2023
@GreenReaper
Copy link

GreenReaper commented Feb 7, 2023

The latest update today seems to have caused segmentation faults and a PHP-FPM gateway failure. It is possible that our configuration is odd, though. Setting opcache to disabled temporarily worked, so maybe it's an unrelated issue there...

Our config is held in /etc/php/8.1/fpm/conf.d/00-[sitename].ini which has

[opcache]
;added to debug segmentation fault
opcache.enable=0
opcache.enable_cli=1
opcache.memory_consumption=14
; was 64 with piwik
opcache.interned_strings_buffer=3
; was 12, you actually get 3/4 of the reservation
opcache.max_accelerated_files=463
;was 3500, using 2nd prime to get ~0.4 load factor (~185 entries), 4KB size
opcache.max_wasted_percentage=50
opcache.validate_timestamps=0
opcache.save_comments=0
opcache.file_cache=/var/lib/php/opcache
opcache.huge_code_pages=1
opcache.jit_buffer_size=1280K

[apc]
apc.enabled = 1
apc.enable_cli = 1
apc.serializer = igbinary
apc.rfc1867 = 1
apc.shm_size = 40M
apc.ttl = 7200
apc.entries_hint = 8209

Perhaps setting a buffer size and then disabling JIT is not a supported combination.

@oerdnj
Copy link
Owner

oerdnj commented Feb 7, 2023

You can try enabling the jit again with opcache.jit=tracing to restore the previous behaviour or opcache.jit=function to use the safe configuration (for some definition of "safe").

@oerdnj
Copy link
Owner

oerdnj commented Feb 7, 2023

I didn't want to disable the opcache completely in case that people know it works for them and they want to re-enable it.

@GreenReaper
Copy link

GreenReaper commented Feb 7, 2023

opcache.enabled = 1 without opcache.jit_buffer_size=1280K works.

opcache.jit=tracing or =function with or without opcache.jit_buffer_size=1280K does not seem to work, even after I moved the config file to 99-[sitename].conf so it's applied after 10-opcache.conf. Which is odd since in theory it should be disabled without buffer. I can't debug much on the live site at our busiest time so I'll have to defer further experimentation for now, at least.

As you say JIT often does not provide a benefit, but it did seem to have a small benefit for our use-case, so we were using it.

@oerdnj
Copy link
Owner

oerdnj commented Feb 7, 2023

This is definitely weird and should be reported upstream. If there are more reports, I think the sane thing to do would be to disable the OPcache JIT at the compile time.

@GreenReaper
Copy link

GreenReaper commented Feb 7, 2023

I did a bit more debugging since PHP 8.1 CLI scripts continued to segfault in some cases, which turned out to be zend_accel_inheritance_cache_find at ./ext/opcache/ZendAccellerator.c:2261 (possibly if (entry->parent != parent) { if the code was not changed from 8.1.15).

It looks like clearing out the old files in the opcache.file_cache=/var/lib/php/opcache directory was required, and after this I could re-enable JIT as before. This might be php/php-src#8143. (Edit: Now fixed.)

I had been upgrading from version 8.1.15-1 to 8.1.15-3 (20230203.33 to 20230207.35) when the issue was triggered.

@AgentOak
Copy link

The opcache.ini now has opcache.jit=off

This was pretty annoying to find, as I tried everything to enable the JIT but of course no change to the php.ini would have any effect... I don't really see the purpose of this roadblock since JIT is already off by default.

@joanhey
Copy link

joanhey commented Apr 6, 2023

I think like @AgentOak , if anybody have problems with JIT, then don't enable it.
By default it's disabled. But now we can't enable it from php.ini.

The worst think, is that is a silent change. Only if you check if it's enabled, you will investigate why it isn't.

What is the percentage of apps having problems? 1-10% ? 50% ?
But now it's disabled for all apps, silently.

@joanhey
Copy link

joanhey commented Apr 6, 2023

Defaults:

opcache.jit => tracing => tracing
opcache.jit_buffer_size => 0 => 0

Some people only see opcache.jit, but only it's enabled when we set the memory in opcache.jit_buffer_size.

@PowerKiKi commented php/php-src#7817 (comment)
and immediately was answered php/php-src#7817 (comment)

So JIT is always disabled by default.

@oerdnj Please review this change.
Thank you.

@joanhey
Copy link

joanhey commented Apr 6, 2023

If any dev want to check if is enabled. Please use:
echo opcache_get_status()["jit"]["enabled"] ? "JIT enabled" : "JIT disabled";
Or check the phpinfo();

I found this problem creating a test for Ngx-php:
https://github.com/rryqszq4/ngx-php/blob/master/t/025-opcache.t#L28-L41

And also need to change it for the Techempower benchmark: TechEmpower/FrameworkBenchmarks#8130

@piotrekkr
Copy link

I think there is now accepted RFC to change ini in php 8.4 so it will be clear if it is enabled or not

@tim-hitchins-ekkosense
Copy link

https://www.php.net/manual/en/opcache.configuration.php claims that the default is tracing, not off still

@joanhey
Copy link

joanhey commented Mar 26, 2024

@tim-hitchins-ekkosense
the default value for opcache.jit_buffer_size => 0, so jit is always disabled by default.

https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit-buffer-size

image

@tim-hitchins-ekkosense
Copy link

@joanhey yes, I know that - I'm pointing out that the documentation is wrong for the specific setting of opcache.jit.

image

image

@joanhey
Copy link

joanhey commented Mar 26, 2024

https://wiki.php.net/rfc/jit_config_defaults

It's accepted, but for PHP 8.4.
And later, we'll need to change 2 ini settings for work the jit.

@GreenReaper
Copy link

Indeed, this kills the JIT. But, as the RFC notes, not in 8.4.

Perhaps "Set by default" would be better terminology, but I imagine the argument would be that it's indeed enabled, just has no space to do anything.

As always your best advice is to set the config you want explicitly rather than rely on upstream or package defaults.

@tim-hitchins-ekkosense
Copy link

Sorry, understood, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants