├── LICENSE ├── README.md ├── RESOURCES.md ├── USER_FEEDBACK.md ├── experimental ├── le9fa_patches │ └── le9fa-5.14.patch ├── le9fb_patches │ └── le9fb-5.14.patch ├── le9fd_patches │ └── le9fd-5.14.patch ├── le9fe_patches │ └── le9fe-4.19.patch ├── le9ga_patches │ └── le9ga-5.15.patch └── le9ha_patches │ └── le9ha-5.15.patch ├── le9ec_patches ├── README.md ├── le9ec-4.14.patch ├── le9ec-4.19.patch ├── le9ec-4.9.patch ├── le9ec-5.10.patch ├── le9ec-5.13-rc2-MGLRU.patch ├── le9ec-5.14-rc6-MGLRU.patch ├── le9ec-5.14.patch ├── le9ec-5.15-MGLRU.patch ├── le9ec-5.15.patch └── le9ec-5.4.patch └── obsolete ├── README.md ├── le9aa1-5.10.patch ├── le9ab_patches ├── le9ab-5.10.patch └── le9ab2-5.10.patch ├── le9ac0-5.10.patch ├── le9ba_patches ├── le9ba0-5.10.patch ├── le9ba1-5.10.patch └── le9ba2-5.10.patch ├── le9bb_patches ├── le9bb0-5.10.patch ├── le9bb1-5.10.patch └── le9bb2-5.10.patch ├── le9ca_patches ├── README.md ├── le9ca0-5.10.patch ├── le9ca1-5.10.patch └── le9ca2-5.10.patch ├── le9cb_patches ├── README.md ├── le9cb0-4.19.patch ├── le9cb0-5.10.patch ├── le9cb0-5.4.patch ├── le9cb1-4.19.patch ├── le9cb1-5.10.patch ├── le9cb1-5.4.patch ├── le9cb2-4.19.patch ├── le9cb2-5.10.patch └── le9cb2-5.4.patch ├── le9da_patches ├── README.md ├── le9da0-5.10.patch ├── le9da1-5.10.patch └── le9da2-5.10.patch ├── le9db_patches ├── README.md ├── le9db-4.14.patch ├── le9db-4.19.patch ├── le9db-5.10.patch ├── le9db-5.13-rc2-mg-LRU-v3.patch ├── le9db-5.14-rc1.patch └── le9db-5.4.patch ├── le9ea_patches ├── README.md ├── le9ea-5.10.patch ├── le9ea-5.13-rc2-mg-LRU.patch └── le9ea-5.14-rc1.patch ├── le9eb_patches ├── README.md ├── le9eb-4.14.patch ├── le9eb-4.19.patch ├── le9eb-5.10.patch ├── le9eb-5.13-rc2-MGLRU.patch ├── le9eb-5.14-rc1.patch ├── le9eb-5.14-rc6-MGLRU.patch └── le9eb-5.4.patch ├── le9pf-5.10.patch ├── le9pf2-5.10.patch └── original_le9_patches ├── README.md ├── le9b.patch ├── le9d.patch ├── le9e.patch ├── le9g.patch ├── le9h.patch ├── le9i.patch └── rebase-5.9 ├── README.md ├── le9g-5.9.patch ├── le9h-5.9.patch └── le9i-5.9.patch /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /RESOURCES.md: -------------------------------------------------------------------------------- 1 | 2 | # Resources 3 | 4 | - RFC: vmscan: add min_filelist_kbytes sysctl for protecting the working set (2010) 5 | - https://lore.kernel.org/lkml/20101028191523.GA14972@google.com/ 6 | - CHROMIUM: vmscan: add min_filelist_kbytes sysctl for protecting the working set (2020) https://chromium.googlesource.com/chromiumos/third_party/kernel-next/+/545e2917dbd863760a51379de8c26631e667c563%5E%21/ 7 | - le9 main thread https://web.archive.org/web/20191018023405/https://gist.github.com/constantoverride/84eba764f487049ed642eb2111a20830 8 | - When DMA is disabled system freeze on high memory usage (since 2007) https://bugs.launchpad.net/ubuntu/+source/linux/+bug/159356 9 | - Let's talk about the elephant in the room - the Linux kernel's inability to gracefully handle low memory pressure 10 | - https://lore.kernel.org/lkml/d9802b6a-949b-b327-c4a6-3dbca485ec20@gmx.com/ 11 | - https://www.phoronix.com/forums/forum/phoronix/general-discussion/1118164-yes-linux-does-bad-in-low-ram-memory-pressure-situations-on-the-desktop 12 | - https://news.ycombinator.com/item?id=20620545 13 | - https://www.reddit.com/r/linux/comments/cmg48b/lets_talk_about_the_elephant_in_the_room_the/ 14 | - Howto prevent kernel from evicting code pages ever? (to avoid disk thrashing when about to run out of RAM) 15 | - https://lore.kernel.org/lkml/CAKYFi-4a=H+vT+vo5s6mpKXAv+0W0pyTj1WtEr6xfjoFVFmtJQ@mail.gmail.com/ 16 | - https://stackoverflow.com/questions/51927528/how-to-prevent-linux-kernel-from-evicting-file-backed-executable-pages-when-abou 17 | - How to keep executable code in memory even under memory pressure ? in Linux 18 | - https://stackoverflow.com/questions/52067753/how-to-keep-executable-code-in-memory-even-under-memory-pressure-in-linux 19 | - OOM killer doesn't work properly, leads to a frozen OS https://unix.stackexchange.com/questions/373312/oom-killer-doesnt-work-properly-leads-to-a-frozen-os/458855#458855 20 | - `le9b.patch` https://launchpadlibrarian.net/386196358/le9b.patch 21 | - `le9d.patch` https://launchpadlibrarian.net/389887258/le9d.patch, https://lkml.org/lkml/diff/2018/9/10/296/1 22 | - `le9e.patch` https://web.archive.org/web/20191018064208/https://github.com/howaboutsynergy/q1q/blob/865a6500231aec266bc9d646dfd230908b8676e5/OSes/archlinux/home/user/build/1packages/4used/kernel/linuxgit/le9e.patch 23 | - `le9g.patch` 24 | - https://bugzilla.kernel.org/show_bug.cgi?id=196729#c49 25 | - https://www.phoronix.com/forums/forum/phoronix/general-discussion/1118164-yes-linux-does-bad-in-low-ram-memory-pressure-situations-on-the-desktop?p=1119440#post1119440 26 | - `le9h.patch` 27 | - https://web.archive.org/web/20191018023217/https://gist.github.com/howaboutsynergy/04fd9be927835b055ac15b8b64658e85 28 | - https://www.phoronix.com/forums/forum/phoronix/general-discussion/1118164-yes-linux-does-bad-in-low-ram-memory-pressure-situations-on-the-desktop?p=1119792#post1119792 29 | - `le9i.patch` https://web.archive.org/web/20191018023434/https://gist.github.com/howaboutsynergy/cbfa3cc5e8093c26c29f5d411c16e6b1 30 | - Bug 111601 - regression: deadlock-freeze due to kernel commit aa56a292ce623734ddd30f52d73f527d1f3529b5 + `memfreeze`, `le9i.patch`, `le9h.patch` https://bugs.freedesktop.org/show_bug.cgi?id=111601 31 | - Merge origin/chromeos-4.19-lowmem https://gitlab.freedesktop.org/seanpaul/dpu-staging/commit/0b992f2dbb044896c3584e10bd5b97cf41e2ec6d 32 | - https://abf.io/mikhailnov/kernel-desktop-4.15/blob/master/Chromium-OS-low-memory-patchset.patch 33 | - Discussing protection of file pages with post-factum and mikhailnov - https://www.linux.org.ru/news/kernel/16052362?cid=16055197 and further. 34 | - How to prevent Linux kernel from evicting file-backed executable pages when about to run out of RAM? (which would otherwise cause disk-thrashing) https://stackoverflow.com/questions/51927528/how-to-prevent-linux-kernel-from-evicting-file-backed-executable-pages-when-abou 35 | - mm/concepts https://www.kernel.org/doc/html/latest/admin-guide/mm/concepts.html 36 | - M. Gorman - Understanding the Linux Virtual Memory Manager https://www.kernel.org/doc/gorman/ 37 | - Unevictable LRU Infrastructure https://www.kernel.org/doc/html/latest/vm/unevictable-lru.html 38 | - Why is kswapd0 running on a computer with no swap? https://askubuntu.com/questions/432809/why-is-kswapd0-running-on-a-computer-with-no-swap/432827 39 | - This patch looks like it could be merged with mainline. Why don't you try sending it to linux-mm? https://www.phoronix.com/forums/forum/phoronix/general-discussion/1118164-yes-linux-does-bad-in-low-ram-memory-pressure-situations-on-the-desktop/page17#post1120024 40 | - Ubuntu freeze when low memory https://askubuntu.com/questions/1017884/ubuntu-freeze-when-low-memory 41 | - How to avoid high latency near OOM situation? https://unix.stackexchange.com/questions/423261/how-to-avoid-high-latency-near-oom-situation 42 | - System hanging when it runs out of memory https://unix.stackexchange.com/questions/28175/system-hanging-when-it-runs-out-of-memory 43 | - Can you set a minimum linux disk buffer size? https://serverfault.com/questions/171164/can-you-set-a-minimum-linux-disk-buffer-size 44 | - Защищаем чистый кэш файлов при нехватке памяти для предотвращения пробуксовки и livelock https://www.linux.org.ru/forum/talks/16255397 45 | - Убунтята, не проходите мимо: le9 patch добавлен в linux-xanmod https://www.linux.org.ru/forum/general/16334308 46 | - "le9" Strives To Make Linux Very Usable On Systems With Small Amounts Of RAM https://www.phoronix.com/scan.php?page=news_item&px=le9-Linux-Low-RAM 47 | - ‘le9’, un parche para mitigar la escasez de RAM en Linux https://www.muylinux.com/2021/07/14/le9-poca-ram-linux/ 48 | - Linux Will Run Even Better On Ancient Hardware, Thanks To The Upcoming Le9 Patch https://fossbytes.com/le9-linux-patch-would-make-linux-better-on-ancient-hardware/ 49 | - Linux for PC from 2007: 37 browser tabs+Discord+Skype with no lag on only 2 GB RAM! https://notes.valdikss.org.ru/linux-for-old-pc-from-2007/en/ 50 | - le9 thread on xanmod forum https://forum.xanmod.org/thread-4102-post-7562.html 51 | - Нехватка памяти, фризы: OOM KILLER, le9-patch и пр. (puppyrus forum) https://forum.puppyrus.org/index.php?topic=23160.msg178228#msg178228 52 | - le9 which is used in ROSA Linux https://abf.io/import/kernel-5.10/blob/rosa2021.1/le9pf.diff 53 | 54 | -------------------------------------------------------------------------------- /USER_FEEDBACK.md: -------------------------------------------------------------------------------- 1 | 2 | # User feedback 3 | 4 | > Memory manager working poorly under heavy memory pressure is one of the problems that gives the linux kernel bad reputation. 5 | > Looking into recent talks over OOM livelocks, I'm pretty much persuaded that OOM-killer coming to save us from thrashing (to death) is nothing but a myth. 6 | > By default overcommit settings, even unprivileged users could easily make thrashing happen, and even hang up the whole system by abusing memory allocation. 7 | 8 | > Protect clean file pages under memory pressure 9 | > https://github.com/hakavlad/le9-patch 10 | 11 | > With this feature enabled, the OOM-killer should kick in very smoothly under critical memory pressure situations (as it originally should). 12 | > Find the video links showing its great resilience, in the project page. 13 | > The behavior can be enabled/disabled and configured by sysctl tunables, meaning that there seems to be no compatibility cost to adopt the patch. 14 | 15 | — *firelzrd*, [forum.xanmod.org](https://forum.xanmod.org/thread-4102-post-7529.html#pid7529) 16 | 17 | --- 18 | 19 | > As far as I've been testing it out, the result is brilliant. 20 | 21 | > - You can explicitly control the minimum amount of file cache to leave untouched on RAM. 22 | > - When you run out of memory, the OOM reaper/killer always works very smoothly without slowing down or freezing the system forever. 23 | > - Settings can be dynamically changed and the effect can be observed, or reverted to stock kernel's behavior by just setting sysctl knobs. 24 | 25 | > With this patch I now set my vm.swappiness = 1 to keep as much working set as possible on memory, and it works just fine. 26 | 27 | — *firelzrd*, [forum.xanmod.org](https://forum.xanmod.org/thread-4102-post-7531.html#pid7531) 28 | 29 | --- 30 | 31 | > In my humble opinion, le9 series isn't about helping server administrators coordinate their resource plans, but meant to address the problem that is making the operating system wrongfully breakable. 32 | 33 | > This infamous thrashing and OOM-livelock problem is like "what Linux virtual memory manager was designed to do something, should be doing it, but isn't doing it" at critical memory pressure situations. 34 | > Yes. It's originally something Linux should be doing. 35 | 36 | > More than CGROUPs or similar kinds of fine-tuned configuration effort, OOM killer, once it's there, when needed, it must just work and kill what should be killed, without special settings. 37 | 38 | > And I believe that le9's modification to the memory manager's behavior just does it perfectly. 39 | 40 | — *firelzrd*, [forum.xanmod.org](https://forum.xanmod.org/thread-4102-post-7603.html#pid7603) 41 | 42 | --- 43 | 44 | > This patchset is surprisingly effective and very useful for low-end PC with slow HDD, single-board ARM boards with slow storage, cheap Android smartphones with limited amount of memory. It almost completely prevents thrashing condition and aids in fast OOM killer invocation. 45 | 46 | > The similar file-locking patch is used in ChromeOS for nearly 10 years but not on stock Linux or Android. It would be very beneficial for lower-performance Android phones, SBCs, old PCs and other devices. 47 | 48 | > With this patch, combined with zram, I'm able to run the following software on an old office PC from 2007 with __only 2GB of RAM__ simultaneously: 49 | 50 | > - Firefox with 37 active tabs (all data in RAM, no tab unloading) 51 | > - Discord 52 | > - Skype 53 | > - LibreOffice with the document opened 54 | > - Two PDF files (14 and 47 megabytes in size) 55 | 56 | > And the PC doesn't crawl like a snail, even with 2+ GB in zram! Without the patch, this PC is barely usable. Please watch the video: 57 | > https://notes.valdikss.org.ru/linux-for-old-pc-from-2007/en/ 58 | 59 | — *VakdikSS*, [lore.kernel.org](https://lore.kernel.org/lkml/2dc51fc8-f14e-17ed-a8c6-0ec70423bf54@valdikss.org.ru/) 60 | 61 | --- 62 | 63 | > I find it especially egregious that so much work has to go into userspace daemons to nudge the kernel OOM killer to do its job; it just seems so wrong to dedicate something as fundamental as memory management to a userspace process. I firmly believe that no condition should ever lead to a frozen system (even if the kernel is still technically running behind the scenes), and blaming the user for overloading it doesn't solve the fundamental issue of the kernel's bad handling of non-optimal conditions. 64 | 65 | — *sb56637*, [www.phoronix.com](https://www.phoronix.com/forums/forum/software/general-linux-open-source/1267300-le9-strives-to-make-linux-very-usable-on-systems-with-small-amounts-of-ram/page2#post1267331) 66 | 67 | --- 68 | 69 | > This doesn't look like a hack to me. It seems to be a fairly simple and effective change that actually eliminates the root cause of these stalls. I hope it makes mainline. 70 | 71 | — *brent*, [www.phoronix.com](https://www.phoronix.com/forums/forum/software/general-linux-open-source/1267300-le9-strives-to-make-linux-very-usable-on-systems-with-small-amounts-of-ram/page4#post1267387) 72 | 73 | --- 74 | 75 | > Either way, killing some processes is obviously preferable to locking up the whole system in endless thrashing (which is equivalent to killing all processes). 76 | 77 | — *intelfx*, [www.phoronix.com](https://www.phoronix.com/forums/forum/software/general-linux-open-source/1267300-le9-strives-to-make-linux-very-usable-on-systems-with-small-amounts-of-ram/page5#post1267436) 78 | 79 | --- 80 | 81 | > I tried the patch by installing the Linux Mint ISO that is on ValdikSS's website on a netbook-class laptop with 2 Gb of RAM (and a painfully slow hard drive) and couldn't believe my eyes. What was previously an unusable system when running a browser (in my case Firefox) is now apparently perfectly fine. I didn't open 37 tabs, but enough of them for casual, every day browsing and it kept going. 82 | 83 | — *tedesign*, [www.phoronix.com](https://www.phoronix.com/forums/forum/software/general-linux-open-source/1267300-le9-strives-to-make-linux-very-usable-on-systems-with-small-amounts-of-ram/page7#post1267789) 84 | 85 | --- 86 | 87 | > I am a near total Linux noob who has been trying to resurrect an old ASUS W3J laptop purchased in 2006 that has a 32 bit intel 945PM chipset that limits the addressable ram. Although there are 2 x 2 GB DDR2 ram modules installed, the system can’t fully use all 4 GB. The RV530 mobility X1600 also allocates some of this ram so that the system has something like 2.8 GB total ram. It has a core2duo T7200 64 bit processor and an IDE 320 GB WD hard drive, so no SSD is possible. I’ve been working on trying out various Linux distributions over the last 3 weeks to replace XP, and they all have had major deficiencies. 32 bit distros don’t allow for the use of modern Firefox, and 64 bit distros use most of the ram very quickly, such that multitasking is not really possible. I happened across ValdikSS’s post and tried out the Mint XFCE 20.2 ISO. 88 | 89 | > Oh my purple penguins! It’s like a whole new computer! I can open multiple tabs in Firefox, run the system monitor, open LibreOffice, and have media playing without the system grinding to a crashing halt! With Firefox, the most tabs I have opened is around 8, but the system is smooooth. It seems to run like it did with XP ages ago. The only issue with the iso from ValdikSS I have is with the suspend not working when I close the lid, but I think it is an XFCE issue, not an issue with the kernel. Still researching that one. 90 | 91 | > In short, XanMod with the le9 patch has transformed a machine from 2006 that was usable but unsafe with XP into a comfortably usable and safe computing system with Mint XFCE 20.2. I can’t thank you enough for this. Seriously, this has saved me from having to buy a new laptop, and has given me so much joy in being able to use something that would otherwise go into a landfill. It’s a win for me and a win for the environment. 92 | 93 | — *KansaKilla*, [www.phoronix.com](https://www.phoronix.com/forums/forum/software/general-linux-open-source/1267300-le9-strives-to-make-linux-very-usable-on-systems-with-small-amounts-of-ram/page8#post1268100) 94 | 95 | -------------------------------------------------------------------------------- /le9ec_patches/README.md: -------------------------------------------------------------------------------- 1 | 2 | # le9ec patch 3 | 4 | The kernel does not provide a way to protect the [working set](https://en.wikipedia.org/wiki/Working_set) under memory pressure. A certain amount of anonymous and clean file pages is required by the userspace for normal operation. First of all, the userspace needs a cache of shared libraries and executable binaries. If the amount of the clean file pages falls below a certain level, then [thrashing](https://en.wikipedia.org/wiki/Thrashing_(computer_science)) and even [livelock](https://en.wikipedia.org/wiki/Deadlock#Livelock) can take place. 5 | 6 | The patch provides sysctl knobs for protecting the working set (anonymous and clean file pages) under memory pressure. 7 | 8 | The `vm.anon_min_kbytes` sysctl knob provides *hard* protection of anonymous pages. The anonymous pages on the current node won't be reclaimed under any conditions when their amount is below `vm.anon_min_kbytes`. This knob may be used to prevent excessive swap thrashing when anonymous memory is low (for example, when memory is going to be overfilled by compressed data of zram module). 9 | 10 | The `vm.clean_low_kbytes` sysctl knob provides *best-effort* protection of clean file pages. The file pages on the current node won't be reclaimed under memory pressure when the amount of clean file pages is below `vm.clean_low_kbytes` *unless* we threaten to OOM. Protection of clean file pages using this knob may be used when swapping is still possible to 11 | - prevent disk I/O thrashing under memory pressure; 12 | - improve performance in disk cache-bound tasks under memory pressure. 13 | 14 | The `vm.clean_min_kbytes` sysctl knob provides *hard* protection of clean file pages. The file pages on the current node won't be reclaimed under memory pressure when the amount of clean file pages is below `vm.clean_min_kbytes`. Hard protection of clean file pages using this knob may be used to 15 | - prevent disk I/O thrashing under memory pressure even with no free swap space; 16 | - improve performance in disk cache-bound tasks under memory pressure; 17 | - avoid high latency and prevent livelock in near-OOM conditions. 18 | 19 | `le9ec` patches provide three sysctl knobs (`vm.anon_min_kbytes`, `vm.clean_low_kbytes`, `vm.clean_min_kbytes`) with zero values and does not protect the working set by default (`CONFIG_ANON_MIN_KBYTES=0`, `CONFIG_CLEAN_LOW_KBYTES=0`, `CONFIG_CLEAN_MIN_KBYTES=0`). You can specify other values during kernel build, or change the knob values on the fly. 20 | 21 | - `le9ec-4.9.patch` may be correctly applied to vanilla Linux 4.9; 22 | - `le9ec-4.14.patch` may be correctly applied to vanilla Linux 4.14; 23 | - `le9ec-4.19.patch` may be correctly applied to vanilla Linux 4.19; 24 | - `le9ec-5.4.patch` may be correctly applied to vanilla Linux 5.4; 25 | - `le9ec-5.10.patch` may be correctly applied to vanilla Linux 5.10—5.13; 26 | - `le9ec-5.13-rc2-MGLRU.patch` may be correctly applied to Linux 5.13 with [mgLRU patchset v3](https://lore.kernel.org/lkml/20210520065355.2736558-1-yuzhao@google.com/) applied; 27 | - `le9ec-5.14-rc6-MGLRU.patch` may be correctly applied to Linux 5.14 with [mgLRU patchset v4](https://lore.kernel.org/lkml/20210818063107.2696454-1-yuzhao@google.com/) applied; 28 | - `le9ec-5.14.patch` may be correctly applied to vanilla Linux 5.14; 29 | - `le9ec-5.15.patch` may be correctly applied to vanilla Linux 5.15—5.19; 30 | - `le9ec-5.15-MGLRU.patch` may be correctly applied to Linux 5.15 with [mgLRU patchset v5](https://lore.kernel.org/lkml/20211111041510.402534-1-yuzhao@google.com/) applied and may be correctly applied to Linux 5.16-rc8 with [mgLRU patchset v6](https://lore.kernel.org/lkml/20220104202227.2903605-1-yuzhao@google.com/) applied. 31 | 32 | Note that enabling multigenerational LRU disables le9 effects. 33 | 34 | -------------------------------------------------------------------------------- /obsolete/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakavlad/le9-patch/835d59774ccc19ed239b34f1d240a76febbe6005/obsolete/README.md -------------------------------------------------------------------------------- /obsolete/le9aa1-5.10.patch: -------------------------------------------------------------------------------- 1 | From e59135be77d51c6f89d66e363ee9b524df4e2a21 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Sat, 26 Dec 2020 23:02:54 +0900 4 | Subject: [PATCH] Protect active file pages under memory pressure 5 | 6 | The patch provides kernel config options and sysctl knobs to control 7 | the aggressiveness of protecting active pages from eviction. 8 | --- 9 | Documentation/admin-guide/sysctl/vm.rst | 33 +++++++++++++++++++++++ 10 | kernel/sysctl.c | 47 +++++++++++++++++++++++++++++++++ 11 | mm/Kconfig | 22 +++++++++++++++ 12 | mm/vmscan.c | 28 ++++++++++++++++++++ 13 | 4 files changed, 130 insertions(+) 14 | 15 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 16 | index f455fa00c..0978fb5ec 100644 17 | --- a/Documentation/admin-guide/sysctl/vm.rst 18 | +++ b/Documentation/admin-guide/sysctl/vm.rst 19 | @@ -24,6 +24,9 @@ files can be found in mm/swap.c. 20 | 21 | Currently, these files are in /proc/sys/vm: 22 | 23 | +- active_file_low_kbytes 24 | +- active_file_low_rigidity 25 | +- active_file_min_kbytes 26 | - admin_reserve_kbytes 27 | - block_dump 28 | - compact_memory 29 | @@ -77,6 +80,36 @@ Currently, these files are in /proc/sys/vm: 30 | - zone_reclaim_mode 31 | 32 | 33 | +active_file_low_kbytes 34 | +====================== 35 | + 36 | +The soft Active(file) protection. 37 | + 38 | +The hardness of protection depends on vm.active_file_low_rigidity. 39 | + 40 | +The default value is 250000. 41 | + 42 | + 43 | +active_file_low_rigidity 44 | +======================== 45 | + 46 | +The rigidity of holding the soft Active(file) protection. 47 | + 48 | +The higher the value, the greater the hardness of the protection. 49 | + 50 | +The values 0 and 1 disable soft Active(file) protection. 51 | + 52 | +The default value is 4. 53 | + 54 | + 55 | +active_file_min_kbytes 56 | +====================== 57 | + 58 | +The hard Active(file) protection. 59 | + 60 | +The default value is 0. 61 | + 62 | + 63 | admin_reserve_kbytes 64 | ==================== 65 | 66 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 67 | index afad08596..128df3ebf 100644 68 | --- a/kernel/sysctl.c 69 | +++ b/kernel/sysctl.c 70 | @@ -111,6 +111,30 @@ 71 | static int sixty = 60; 72 | #endif 73 | 74 | +#if defined(CONFIG_PROTECT_ACTIVE_FILE) 75 | +unsigned long sysctl_active_file_low_kbytes __read_mostly = 76 | +#if CONFIG_PROTECT_ACTIVE_FILE_LOW_KBYTES < 0 77 | +#error "CONFIG_PROTECT_ACTIVE_FILE_LOW_KBYTES should be >= 0" 78 | +#else 79 | + CONFIG_PROTECT_ACTIVE_FILE_LOW_KBYTES 80 | +#endif 81 | +; 82 | +unsigned long sysctl_active_file_low_rigidity __read_mostly = 83 | +#if CONFIG_PROTECT_ACTIVE_FILE_LOW_RIGIDITY < 0 84 | +#error "CONFIG_PROTECT_ACTIVE_FILE_LOW_RIGIDITY should be >= 0" 85 | +#else 86 | + CONFIG_PROTECT_ACTIVE_FILE_LOW_RIGIDITY 87 | +#endif 88 | +; 89 | +unsigned long sysctl_active_file_min_kbytes __read_mostly = 90 | +#if CONFIG_PROTECT_ACTIVE_FILE_MIN_KBYTES < 0 91 | +#error "CONFIG_PROTECT_ACTIVE_FILE_MIN_KBYTES should be >= 0" 92 | +#else 93 | + CONFIG_PROTECT_ACTIVE_FILE_MIN_KBYTES 94 | +#endif 95 | +; 96 | +#endif 97 | + 98 | static int __maybe_unused neg_one = -1; 99 | static int __maybe_unused two = 2; 100 | static int __maybe_unused four = 4; 101 | @@ -3082,6 +3106,29 @@ static struct ctl_table vm_table[] = { 102 | .extra2 = SYSCTL_ONE, 103 | }, 104 | #endif 105 | +#if defined(CONFIG_PROTECT_ACTIVE_FILE) 106 | + { 107 | + .procname = "active_file_low_kbytes", 108 | + .data = &sysctl_active_file_low_kbytes, 109 | + .maxlen = sizeof(sysctl_active_file_low_kbytes), 110 | + .mode = 0644, 111 | + .proc_handler = proc_doulongvec_minmax, 112 | + }, 113 | + { 114 | + .procname = "active_file_low_rigidity", 115 | + .data = &sysctl_active_file_low_rigidity, 116 | + .maxlen = sizeof(sysctl_active_file_low_rigidity), 117 | + .mode = 0644, 118 | + .proc_handler = proc_doulongvec_minmax, 119 | + }, 120 | + { 121 | + .procname = "active_file_min_kbytes", 122 | + .data = &sysctl_active_file_min_kbytes, 123 | + .maxlen = sizeof(sysctl_active_file_min_kbytes), 124 | + .mode = 0644, 125 | + .proc_handler = proc_doulongvec_minmax, 126 | + }, 127 | +#endif 128 | { 129 | .procname = "user_reserve_kbytes", 130 | .data = &sysctl_user_reserve_kbytes, 131 | diff --git a/mm/Kconfig b/mm/Kconfig 132 | index 390165ffb..cc23db256 100644 133 | --- a/mm/Kconfig 134 | +++ b/mm/Kconfig 135 | @@ -63,6 +63,28 @@ config SPARSEMEM_MANUAL 136 | 137 | endchoice 138 | 139 | +config PROTECT_ACTIVE_FILE 140 | + bool "Keep some active file pages under memory pressure" 141 | + depends on SYSCTL 142 | + def_bool y 143 | + help 144 | + Not yet documented. 145 | + 146 | +config PROTECT_ACTIVE_FILE_LOW_KBYTES 147 | + int "Default value for vm.protect_active_file_low_kbytes" 148 | + depends on PROTECT_ACTIVE_FILE 149 | + default "250000" 150 | + 151 | +config PROTECT_ACTIVE_FILE_LOW_RIGIDITY 152 | + int "Default value for vm.protect_active_file_low_rigidity" 153 | + depends on PROTECT_ACTIVE_FILE 154 | + default "4" 155 | + 156 | +config PROTECT_ACTIVE_FILE_MIN_KBYTES 157 | + int "Default value for vm.protect_active_file_min_kbytes" 158 | + depends on PROTECT_ACTIVE_FILE 159 | + default "0" 160 | + 161 | config DISCONTIGMEM 162 | def_bool y 163 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 164 | diff --git a/mm/vmscan.c b/mm/vmscan.c 165 | index 7b4e31eac..6a5eac089 100644 166 | --- a/mm/vmscan.c 167 | +++ b/mm/vmscan.c 168 | @@ -166,6 +166,13 @@ struct scan_control { 169 | #define prefetchw_prev_lru_page(_page, _base, _field) do { } while (0) 170 | #endif 171 | 172 | +#if defined(CONFIG_PROTECT_ACTIVE_FILE) 173 | +#define K(x) ((x) << (PAGE_SHIFT - 10)) 174 | +extern unsigned long sysctl_active_file_min_kbytes; 175 | +extern unsigned long sysctl_active_file_low_kbytes; 176 | +extern unsigned long sysctl_active_file_low_rigidity; 177 | +#endif 178 | + 179 | /* 180 | * From 0 .. 200. Higher means more swappy. 181 | */ 182 | @@ -2418,6 +2425,27 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 183 | BUG(); 184 | } 185 | 186 | +#if defined(CONFIG_PROTECT_ACTIVE_FILE) 187 | + if (lru == LRU_ACTIVE_FILE) { 188 | + 189 | + unsigned long kib_active_file_now = K( 190 | + global_node_page_state(NR_ACTIVE_FILE)); 191 | + 192 | + if (kib_active_file_now <= sysctl_active_file_min_kbytes) { 193 | + nr[lru] = 0; 194 | + continue; 195 | + } 196 | + 197 | + if (kib_active_file_now <= sysctl_active_file_low_kbytes) { 198 | + if (sysctl_active_file_low_rigidity >= 2) { 199 | + nr[lru] = scan / sysctl_active_file_low_rigidity; 200 | + continue; 201 | + } 202 | + } 203 | + 204 | + } 205 | +#endif 206 | + 207 | nr[lru] = scan; 208 | } 209 | } 210 | -- 211 | 2.11.0 212 | 213 | -------------------------------------------------------------------------------- /obsolete/le9ab_patches/le9ab-5.10.patch: -------------------------------------------------------------------------------- 1 | From b5f129bd69d1ac35a432a6adb15cb8ce7b8981e4 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Sat, 2 Jan 2021 03:56:58 +0900 4 | Subject: [PATCH] Reserve minimum amount of active file pages 5 | 6 | Active file pages should not be evicted under memory pressure if their 7 | volume is below selected value. 8 | 9 | Reservation of active file pages may be used to reduce thrashing under 10 | low-memory conditions. 11 | --- 12 | Documentation/admin-guide/sysctl/vm.rst | 27 ++++++++++++++++++++++++++ 13 | kernel/sysctl.c | 29 ++++++++++++++++++++++++++++ 14 | mm/Kconfig | 34 +++++++++++++++++++++++++++++++++ 15 | mm/vmscan.c | 24 +++++++++++++++++++++++ 16 | 4 files changed, 114 insertions(+) 17 | 18 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 19 | index f455fa00c..4322cfdcc 100644 20 | --- a/Documentation/admin-guide/sysctl/vm.rst 21 | +++ b/Documentation/admin-guide/sysctl/vm.rst 22 | @@ -24,6 +24,8 @@ files can be found in mm/swap.c. 23 | 24 | Currently, these files are in /proc/sys/vm: 25 | 26 | +- active_file_reserve_hard_kbytes 27 | +- active_file_reserve_soft_kbytes 28 | - admin_reserve_kbytes 29 | - block_dump 30 | - compact_memory 31 | @@ -77,6 +79,31 @@ Currently, these files are in /proc/sys/vm: 32 | - zone_reclaim_mode 33 | 34 | 35 | +active_file_reserve_hard_kbytes 36 | +=============================== 37 | + 38 | +Available only when CONFIG_ACTIVE_FILE_RESERVE is set. Active file pages should 39 | +not be evicted under memory pressure if their volume is below this (even with 40 | +no free swap space). 41 | + 42 | +The default value is 0. 43 | + 44 | + 45 | +active_file_reserve_soft_kbytes 46 | +=============================== 47 | + 48 | +Available only when CONFIG_ACTIVE_FILE_RESERVE is set. Active file pages should 49 | +not be evicted under memory pressure if their volume is below this (except when 50 | +other pages cannot be evicted, i.e. the reservation does not work if there is 51 | +no free swap space). 52 | + 53 | +If vm.active_file_reserve_soft_kbytes <= vm.active_file_reserve_hard_kbytes 54 | +than vm.active_file_reserve_hard_kbytes threshold will have higher priority and 55 | +hard reservation will be applied. 56 | + 57 | +The default value is 200000. 58 | + 59 | + 60 | admin_reserve_kbytes 61 | ==================== 62 | 63 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 64 | index afad08596..dd5ceabe5 100644 65 | --- a/kernel/sysctl.c 66 | +++ b/kernel/sysctl.c 67 | @@ -111,6 +111,19 @@ 68 | static int sixty = 60; 69 | #endif 70 | 71 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 72 | +#if CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES < 0 73 | +#error "CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES should be >= 0" 74 | +#endif 75 | +#if CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES < 0 76 | +#error "CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES should be >= 0" 77 | +#endif 78 | +unsigned long sysctl_active_file_reserve_hard_kbytes __read_mostly = 79 | + CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES; 80 | +unsigned long sysctl_active_file_reserve_soft_kbytes __read_mostly = 81 | + CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES; 82 | +#endif 83 | + 84 | static int __maybe_unused neg_one = -1; 85 | static int __maybe_unused two = 2; 86 | static int __maybe_unused four = 4; 87 | @@ -3082,6 +3095,22 @@ static struct ctl_table vm_table[] = { 88 | .extra2 = SYSCTL_ONE, 89 | }, 90 | #endif 91 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 92 | + { 93 | + .procname = "active_file_reserve_hard_kbytes", 94 | + .data = &sysctl_active_file_reserve_hard_kbytes, 95 | + .maxlen = sizeof(sysctl_active_file_reserve_hard_kbytes), 96 | + .mode = 0644, 97 | + .proc_handler = proc_doulongvec_minmax, 98 | + }, 99 | + { 100 | + .procname = "active_file_reserve_soft_kbytes", 101 | + .data = &sysctl_active_file_reserve_soft_kbytes, 102 | + .maxlen = sizeof(sysctl_active_file_reserve_soft_kbytes), 103 | + .mode = 0644, 104 | + .proc_handler = proc_doulongvec_minmax, 105 | + }, 106 | +#endif 107 | { 108 | .procname = "user_reserve_kbytes", 109 | .data = &sysctl_user_reserve_kbytes, 110 | diff --git a/mm/Kconfig b/mm/Kconfig 111 | index 390165ffb..103cf09e1 100644 112 | --- a/mm/Kconfig 113 | +++ b/mm/Kconfig 114 | @@ -63,6 +63,40 @@ config SPARSEMEM_MANUAL 115 | 116 | endchoice 117 | 118 | +config ACTIVE_FILE_RESERVE 119 | + bool "Reserve some active file pages under memory pressure" 120 | + depends on SYSCTL 121 | + def_bool y 122 | + help 123 | + Active file pages should not be evicted under memory pressure if their 124 | + volume is below selected value. 125 | + 126 | + Reservation of active file pages may be used to reduce thrashing under 127 | + low-memory conditions. 128 | + 129 | + The amount of reserved active file pages may be set via 130 | + CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES, 131 | + CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES and at runtime via the sysctl 132 | + knobs vm.active_file_reserve_hard_kbytes and 133 | + vm.active_file_reserve_soft_kbytes. 134 | + 135 | +config ACTIVE_FILE_RESERVE_HARD_KBYTES 136 | + int "Default value for vm.active_file_reserve_hard_kbytes" 137 | + depends on ACTIVE_FILE_RESERVE 138 | + default "0" 139 | + help 140 | + Active file pages should not be evicted under memory pressure if their 141 | + volume is below this (even with no free swap space). 142 | + 143 | +config ACTIVE_FILE_RESERVE_SOFT_KBYTES 144 | + int "Default value for vm.active_file_reserve_soft_kbytes" 145 | + depends on ACTIVE_FILE_RESERVE 146 | + default "200000" 147 | + help 148 | + Active file pages should not be evicted under memory pressure if their 149 | + volume is below this (except when other pages cannot be evicted, i.e. the 150 | + reservation does not work if there is no free swap space). 151 | + 152 | config DISCONTIGMEM 153 | def_bool y 154 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 155 | diff --git a/mm/vmscan.c b/mm/vmscan.c 156 | index 7b4e31eac..88ace2d31 100644 157 | --- a/mm/vmscan.c 158 | +++ b/mm/vmscan.c 159 | @@ -186,6 +186,12 @@ static void set_task_reclaim_state(struct task_struct *task, 160 | static LIST_HEAD(shrinker_list); 161 | static DECLARE_RWSEM(shrinker_rwsem); 162 | 163 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 164 | +#define K(x) ((x) << (PAGE_SHIFT - 10)) 165 | +extern unsigned long sysctl_active_file_reserve_hard_kbytes; 166 | +extern unsigned long sysctl_active_file_reserve_soft_kbytes; 167 | +#endif 168 | + 169 | #ifdef CONFIG_MEMCG 170 | /* 171 | * We allow subsystems to populate their shrinker-related 172 | @@ -2418,6 +2424,24 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 173 | BUG(); 174 | } 175 | 176 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 177 | + if (lru == LRU_ACTIVE_FILE) { 178 | + unsigned long kib_active_file_now = K( 179 | + global_node_page_state(NR_ACTIVE_FILE)); 180 | + unsigned long low_scan_granularity = SWAP_CLUSTER_MAX >> sc->priority; 181 | + 182 | + if (kib_active_file_now <= sysctl_active_file_reserve_hard_kbytes) { 183 | + nr[lru] = 0; 184 | + continue; 185 | + } 186 | + if (kib_active_file_now <= sysctl_active_file_reserve_soft_kbytes && 187 | + scan > low_scan_granularity) { 188 | + nr[lru] = low_scan_granularity; 189 | + continue; 190 | + } 191 | + } 192 | +#endif 193 | + 194 | nr[lru] = scan; 195 | } 196 | } 197 | -- 198 | 2.11.0 199 | 200 | -------------------------------------------------------------------------------- /obsolete/le9ab_patches/le9ab2-5.10.patch: -------------------------------------------------------------------------------- 1 | From e60a6446254b4aa69759301760186a0080a0f537 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Sun, 3 Jan 2021 22:08:12 +0900 4 | Subject: [PATCH] Reserve minimum amount of active file pages 5 | 6 | Active file pages should not be evicted under memory pressure if their 7 | volume is below selected value. 8 | 9 | Reservation of active file pages may be used to reduce thrashing under 10 | low-memory conditions. 11 | --- 12 | Documentation/admin-guide/sysctl/vm.rst | 27 ++++++++++++++++++++++++++ 13 | kernel/sysctl.c | 29 ++++++++++++++++++++++++++++ 14 | mm/Kconfig | 34 +++++++++++++++++++++++++++++++++ 15 | mm/vmscan.c | 24 +++++++++++++++++++++++ 16 | 4 files changed, 114 insertions(+) 17 | 18 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 19 | index f455fa00c..677c4610b 100644 20 | --- a/Documentation/admin-guide/sysctl/vm.rst 21 | +++ b/Documentation/admin-guide/sysctl/vm.rst 22 | @@ -24,6 +24,8 @@ files can be found in mm/swap.c. 23 | 24 | Currently, these files are in /proc/sys/vm: 25 | 26 | +- active_file_reserve_hard_kbytes 27 | +- active_file_reserve_soft_kbytes 28 | - admin_reserve_kbytes 29 | - block_dump 30 | - compact_memory 31 | @@ -77,6 +79,31 @@ Currently, these files are in /proc/sys/vm: 32 | - zone_reclaim_mode 33 | 34 | 35 | +active_file_reserve_hard_kbytes 36 | +=============================== 37 | + 38 | +Available only when CONFIG_ACTIVE_FILE_RESERVE is set. Active file pages should 39 | +not be evicted under memory pressure if their volume is below this (even with 40 | +no free swap space). 41 | + 42 | +The default value is 250000. 43 | + 44 | + 45 | +active_file_reserve_soft_kbytes 46 | +=============================== 47 | + 48 | +Available only when CONFIG_ACTIVE_FILE_RESERVE is set. Active file pages should 49 | +not be evicted under memory pressure if their volume is below this (except when 50 | +other pages cannot be evicted, i.e. the reservation does not work if there is 51 | +no free swap space). 52 | + 53 | +If vm.active_file_reserve_soft_kbytes <= vm.active_file_reserve_hard_kbytes 54 | +than vm.active_file_reserve_hard_kbytes threshold will have higher priority and 55 | +hard reservation will be applied. 56 | + 57 | +The default value is 0. 58 | + 59 | + 60 | admin_reserve_kbytes 61 | ==================== 62 | 63 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 64 | index afad08596..dd5ceabe5 100644 65 | --- a/kernel/sysctl.c 66 | +++ b/kernel/sysctl.c 67 | @@ -111,6 +111,19 @@ 68 | static int sixty = 60; 69 | #endif 70 | 71 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 72 | +#if CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES < 0 73 | +#error "CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES should be >= 0" 74 | +#endif 75 | +#if CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES < 0 76 | +#error "CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES should be >= 0" 77 | +#endif 78 | +unsigned long sysctl_active_file_reserve_hard_kbytes __read_mostly = 79 | + CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES; 80 | +unsigned long sysctl_active_file_reserve_soft_kbytes __read_mostly = 81 | + CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES; 82 | +#endif 83 | + 84 | static int __maybe_unused neg_one = -1; 85 | static int __maybe_unused two = 2; 86 | static int __maybe_unused four = 4; 87 | @@ -3082,6 +3095,22 @@ static struct ctl_table vm_table[] = { 88 | .extra2 = SYSCTL_ONE, 89 | }, 90 | #endif 91 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 92 | + { 93 | + .procname = "active_file_reserve_hard_kbytes", 94 | + .data = &sysctl_active_file_reserve_hard_kbytes, 95 | + .maxlen = sizeof(sysctl_active_file_reserve_hard_kbytes), 96 | + .mode = 0644, 97 | + .proc_handler = proc_doulongvec_minmax, 98 | + }, 99 | + { 100 | + .procname = "active_file_reserve_soft_kbytes", 101 | + .data = &sysctl_active_file_reserve_soft_kbytes, 102 | + .maxlen = sizeof(sysctl_active_file_reserve_soft_kbytes), 103 | + .mode = 0644, 104 | + .proc_handler = proc_doulongvec_minmax, 105 | + }, 106 | +#endif 107 | { 108 | .procname = "user_reserve_kbytes", 109 | .data = &sysctl_user_reserve_kbytes, 110 | diff --git a/mm/Kconfig b/mm/Kconfig 111 | index 390165ffb..e4d7416cc 100644 112 | --- a/mm/Kconfig 113 | +++ b/mm/Kconfig 114 | @@ -63,6 +63,40 @@ config SPARSEMEM_MANUAL 115 | 116 | endchoice 117 | 118 | +config ACTIVE_FILE_RESERVE 119 | + bool "Reserve some active file pages under memory pressure" 120 | + depends on SYSCTL 121 | + def_bool y 122 | + help 123 | + Active file pages should not be evicted under memory pressure if their 124 | + volume is below selected value. 125 | + 126 | + Reservation of active file pages may be used to reduce thrashing under 127 | + low-memory conditions. 128 | + 129 | + The amount of reserved active file pages may be set via 130 | + CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES, 131 | + CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES and at runtime via the sysctl 132 | + knobs vm.active_file_reserve_hard_kbytes and 133 | + vm.active_file_reserve_soft_kbytes. 134 | + 135 | +config ACTIVE_FILE_RESERVE_HARD_KBYTES 136 | + int "Default value for vm.active_file_reserve_hard_kbytes" 137 | + depends on ACTIVE_FILE_RESERVE 138 | + default "250000" 139 | + help 140 | + Active file pages should not be evicted under memory pressure if their 141 | + volume is below this (even with no free swap space). 142 | + 143 | +config ACTIVE_FILE_RESERVE_SOFT_KBYTES 144 | + int "Default value for vm.active_file_reserve_soft_kbytes" 145 | + depends on ACTIVE_FILE_RESERVE 146 | + default "0" 147 | + help 148 | + Active file pages should not be evicted under memory pressure if their 149 | + volume is below this (except when other pages cannot be evicted, i.e. the 150 | + reservation does not work if there is no free swap space). 151 | + 152 | config DISCONTIGMEM 153 | def_bool y 154 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 155 | diff --git a/mm/vmscan.c b/mm/vmscan.c 156 | index 7b4e31eac..88ace2d31 100644 157 | --- a/mm/vmscan.c 158 | +++ b/mm/vmscan.c 159 | @@ -186,6 +186,12 @@ static void set_task_reclaim_state(struct task_struct *task, 160 | static LIST_HEAD(shrinker_list); 161 | static DECLARE_RWSEM(shrinker_rwsem); 162 | 163 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 164 | +#define K(x) ((x) << (PAGE_SHIFT - 10)) 165 | +extern unsigned long sysctl_active_file_reserve_hard_kbytes; 166 | +extern unsigned long sysctl_active_file_reserve_soft_kbytes; 167 | +#endif 168 | + 169 | #ifdef CONFIG_MEMCG 170 | /* 171 | * We allow subsystems to populate their shrinker-related 172 | @@ -2418,6 +2424,24 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 173 | BUG(); 174 | } 175 | 176 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 177 | + if (lru == LRU_ACTIVE_FILE) { 178 | + unsigned long kib_active_file_now = K( 179 | + global_node_page_state(NR_ACTIVE_FILE)); 180 | + unsigned long low_scan_granularity = SWAP_CLUSTER_MAX >> sc->priority; 181 | + 182 | + if (kib_active_file_now <= sysctl_active_file_reserve_hard_kbytes) { 183 | + nr[lru] = 0; 184 | + continue; 185 | + } 186 | + if (kib_active_file_now <= sysctl_active_file_reserve_soft_kbytes && 187 | + scan > low_scan_granularity) { 188 | + nr[lru] = low_scan_granularity; 189 | + continue; 190 | + } 191 | + } 192 | +#endif 193 | + 194 | nr[lru] = scan; 195 | } 196 | } 197 | -- 198 | 2.11.0 199 | 200 | -------------------------------------------------------------------------------- /obsolete/le9ac0-5.10.patch: -------------------------------------------------------------------------------- 1 | From 033e2259f00e135f82a98f348823e8221770c418 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 1 Feb 2021 07:10:24 +0900 4 | Subject: [PATCH] Don't evict active file pages in low-memory conditions 5 | 6 | Reservation of active file pages may be used to reduce thrashing under 7 | low-memory conditions. 8 | 9 | The patch provides sysctl knobs to control active file pages eviction 10 | in low-memory conditions. 11 | 12 | The default values is 0 for both (soft and hard reservation) sysctl 13 | knobs by default. 14 | --- 15 | Documentation/admin-guide/sysctl/vm.rst | 43 +++++++++++++++++++++++++++++ 16 | kernel/sysctl.c | 41 +++++++++++++++++++++++++++ 17 | mm/Kconfig | 49 +++++++++++++++++++++++++++++++++ 18 | mm/vmscan.c | 24 ++++++++++++++++ 19 | 4 files changed, 157 insertions(+) 20 | 21 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 22 | index f455fa00c..8caf93ea5 100644 23 | --- a/Documentation/admin-guide/sysctl/vm.rst 24 | +++ b/Documentation/admin-guide/sysctl/vm.rst 25 | @@ -24,6 +24,9 @@ files can be found in mm/swap.c. 26 | 27 | Currently, these files are in /proc/sys/vm: 28 | 29 | +- active_file_reserve_hard_kbytes 30 | +- active_file_reserve_soft_kbytes 31 | +- active_file_reserve_soft_max_scan 32 | - admin_reserve_kbytes 33 | - block_dump 34 | - compact_memory 35 | @@ -77,6 +80,46 @@ Currently, these files are in /proc/sys/vm: 36 | - zone_reclaim_mode 37 | 38 | 39 | +active_file_reserve_hard_kbytes 40 | +=============================== 41 | + 42 | +Available only when CONFIG_ACTIVE_FILE_RESERVE is set. Active file pages should 43 | +not be evicted under memory pressure if their volume is below this (even with 44 | +no free swap space). 45 | + 46 | +The default value is 0. 47 | + 48 | + 49 | +active_file_reserve_soft_kbytes 50 | +=============================== 51 | + 52 | +Available only when CONFIG_ACTIVE_FILE_RESERVE is set. This knob controls soft 53 | +eviction throttling of active file pages eviction under memory pressure. 54 | +Eviction of active file pages will be throttled if their volume is below this 55 | +value. 56 | + 57 | +The severity of the throttling depends on vm.active_file_reserve_soft_max_scan. 58 | + 59 | +If vm.active_file_reserve_soft_kbytes <= vm.active_file_reserve_hard_kbytes 60 | +than vm.active_file_reserve_hard_kbytes threshold will have higher priority and 61 | +hard reservation will be applied. 62 | + 63 | +The default value is 0. 64 | + 65 | + 66 | +active_file_reserve_soft_max_scan 67 | +================================= 68 | + 69 | +Available only when CONFIG_ACTIVE_FILE_RESERVE is set. This knob controls the 70 | +severity of the throttling of active file pages eviction when soft active file 71 | +pages reservation is implied (when the volume of active file pages is below 72 | +vm.active_file_reserve_soft_kbytes). The lower the value, the stronger the 73 | +trottling. Setting the value to zero turns a soft reservation of active file 74 | +pages into a hard reservation. 75 | + 76 | +The default value is 32. 77 | + 78 | + 79 | admin_reserve_kbytes 80 | ==================== 81 | 82 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 83 | index afad08596..44d0bfb6f 100644 84 | --- a/kernel/sysctl.c 85 | +++ b/kernel/sysctl.c 86 | @@ -111,6 +111,24 @@ 87 | static int sixty = 60; 88 | #endif 89 | 90 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 91 | +#if CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES < 0 92 | +#error "CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES should be >= 0" 93 | +#endif 94 | +#if CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES < 0 95 | +#error "CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES should be >= 0" 96 | +#endif 97 | +#if CONFIG_ACTIVE_FILE_RESERVE_SOFT_MAX_SCAN < 0 98 | +#error "CONFIG_ACTIVE_FILE_RESERVE_SOFT_MAX_SCAN should be >= 0" 99 | +#endif 100 | +unsigned long sysctl_active_file_reserve_hard_kbytes __read_mostly = 101 | + CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES; 102 | +unsigned long sysctl_active_file_reserve_soft_kbytes __read_mostly = 103 | + CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES; 104 | +unsigned long sysctl_active_file_reserve_soft_max_scan __read_mostly = 105 | + CONFIG_ACTIVE_FILE_RESERVE_SOFT_MAX_SCAN; 106 | +#endif 107 | + 108 | static int __maybe_unused neg_one = -1; 109 | static int __maybe_unused two = 2; 110 | static int __maybe_unused four = 4; 111 | @@ -3082,6 +3100,29 @@ static struct ctl_table vm_table[] = { 112 | .extra2 = SYSCTL_ONE, 113 | }, 114 | #endif 115 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 116 | + { 117 | + .procname = "active_file_reserve_hard_kbytes", 118 | + .data = &sysctl_active_file_reserve_hard_kbytes, 119 | + .maxlen = sizeof(sysctl_active_file_reserve_hard_kbytes), 120 | + .mode = 0644, 121 | + .proc_handler = proc_doulongvec_minmax, 122 | + }, 123 | + { 124 | + .procname = "active_file_reserve_soft_kbytes", 125 | + .data = &sysctl_active_file_reserve_soft_kbytes, 126 | + .maxlen = sizeof(sysctl_active_file_reserve_soft_kbytes), 127 | + .mode = 0644, 128 | + .proc_handler = proc_doulongvec_minmax, 129 | + }, 130 | + { 131 | + .procname = "active_file_reserve_soft_max_scan", 132 | + .data = &sysctl_active_file_reserve_soft_max_scan, 133 | + .maxlen = sizeof(sysctl_active_file_reserve_soft_max_scan), 134 | + .mode = 0644, 135 | + .proc_handler = proc_doulongvec_minmax, 136 | + }, 137 | +#endif 138 | { 139 | .procname = "user_reserve_kbytes", 140 | .data = &sysctl_user_reserve_kbytes, 141 | diff --git a/mm/Kconfig b/mm/Kconfig 142 | index 390165ffb..b8933f1fe 100644 143 | --- a/mm/Kconfig 144 | +++ b/mm/Kconfig 145 | @@ -63,6 +63,55 @@ config SPARSEMEM_MANUAL 146 | 147 | endchoice 148 | 149 | +config ACTIVE_FILE_RESERVE 150 | + bool "Reserve some active file pages under memory pressure" 151 | + depends on SYSCTL 152 | + default y 153 | + help 154 | + Active file pages should not be evicted under memory pressure if their 155 | + volume is below selected value. 156 | + 157 | + Reservation of active file pages may be used to reduce thrashing under 158 | + low-memory conditions. 159 | + 160 | + The amount of reserved active file pages may be set via 161 | + CONFIG_ACTIVE_FILE_RESERVE_HARD_KBYTES, 162 | + CONFIG_ACTIVE_FILE_RESERVE_SOFT_KBYTES and at runtime via the sysctl 163 | + knobs vm.active_file_reserve_hard_kbytes and 164 | + vm.active_file_reserve_soft_kbytes. 165 | + 166 | +config ACTIVE_FILE_RESERVE_HARD_KBYTES 167 | + int "Default value for vm.active_file_reserve_hard_kbytes" 168 | + depends on ACTIVE_FILE_RESERVE 169 | + default "0" 170 | + help 171 | + Active file pages should not be evicted under memory pressure if their 172 | + volume is below this (even with no free swap space). This is default 173 | + value for vm.active_file_reserve_hard_kbytes. 174 | + 175 | +config ACTIVE_FILE_RESERVE_SOFT_KBYTES 176 | + int "Default value for vm.active_file_reserve_soft_kbytes" 177 | + depends on ACTIVE_FILE_RESERVE 178 | + default "0" 179 | + help 180 | + This is default value for vm.active_file_reserve_soft_kbytes. This knob 181 | + controls soft eviction throttling of active file pages eviction under 182 | + memory pressure. Eviction of active file pages will be throttled if their 183 | + volume is below this value. The severity of the throttling depends on 184 | + vm.active_file_reserve_soft_max_scan. 185 | + 186 | +config ACTIVE_FILE_RESERVE_SOFT_MAX_SCAN 187 | + int "Default value for vm.active_file_reserve_soft_max_scan" 188 | + depends on ACTIVE_FILE_RESERVE 189 | + default "32" 190 | + help 191 | + This knob controls the severity of the throttling of active file pages 192 | + eviction when soft active file pages reservation is implied (when the 193 | + volume of active file pages is below vm.active_file_reserve_soft_kbytes). 194 | + The lower the value, the stronger the trottling. Setting the value to 195 | + zero turns a soft reservation of active file pages into a hard 196 | + reservation. 197 | + 198 | config DISCONTIGMEM 199 | def_bool y 200 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 201 | diff --git a/mm/vmscan.c b/mm/vmscan.c 202 | index 7b4e31eac..539448f36 100644 203 | --- a/mm/vmscan.c 204 | +++ b/mm/vmscan.c 205 | @@ -186,6 +186,13 @@ static void set_task_reclaim_state(struct task_struct *task, 206 | static LIST_HEAD(shrinker_list); 207 | static DECLARE_RWSEM(shrinker_rwsem); 208 | 209 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 210 | +#define K(x) ((x) << (PAGE_SHIFT - 10)) 211 | +extern unsigned long sysctl_active_file_reserve_hard_kbytes; 212 | +extern unsigned long sysctl_active_file_reserve_soft_kbytes; 213 | +extern unsigned long sysctl_active_file_reserve_soft_max_scan; 214 | +#endif 215 | + 216 | #ifdef CONFIG_MEMCG 217 | /* 218 | * We allow subsystems to populate their shrinker-related 219 | @@ -2418,6 +2425,23 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 220 | BUG(); 221 | } 222 | 223 | +#if defined(CONFIG_ACTIVE_FILE_RESERVE) 224 | + if (lru == LRU_ACTIVE_FILE) { 225 | + unsigned long active_file_kbytes = 226 | + K(global_node_page_state(NR_ACTIVE_FILE)); 227 | + unsigned long soft_max_scan = 228 | + sysctl_active_file_reserve_soft_max_scan >> sc->priority; 229 | + 230 | + if (active_file_kbytes <= sysctl_active_file_reserve_hard_kbytes) 231 | + scan = 0; 232 | + else if ( 233 | + active_file_kbytes <= sysctl_active_file_reserve_soft_kbytes && 234 | + scan > soft_max_scan 235 | + ) 236 | + scan = soft_max_scan; 237 | + } 238 | +#endif 239 | + 240 | nr[lru] = scan; 241 | } 242 | } 243 | -- 244 | 2.11.0 245 | 246 | -------------------------------------------------------------------------------- /obsolete/le9ba_patches/le9ba0-5.10.patch: -------------------------------------------------------------------------------- 1 | From 8c3891a00e426e52ca26b4a01d493e56de6e979c Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Sun, 14 Feb 2021 03:54:59 +0900 4 | Subject: [PATCH] Protect file pages under memory pressure 5 | 6 | The patch provides sysctl knobs to control file pages eviction 7 | in low memory conditions. 8 | 9 | vm.file_min_kbytes provides hard memory protection. File pages 10 | should not be evicted under memory pressure if their volume is 11 | below this (even with no free swap space). 12 | The default value is 0. 13 | 14 | vm.file_low_kbytes provides soft memory protection. File pages 15 | should not be evicted under memory pressure if their volume is 16 | below this and free swap space is available. 17 | The default value is 0. 18 | --- 19 | include/linux/mm.h | 5 +++++ 20 | kernel/sysctl.c | 29 +++++++++++++++++++++++++++++ 21 | mm/Kconfig | 14 ++++++++++++++ 22 | mm/vmscan.c | 24 ++++++++++++++++++++++++ 23 | 4 files changed, 72 insertions(+) 24 | 25 | diff --git a/include/linux/mm.h b/include/linux/mm.h 26 | index db6ae4d3f..63f78fc9a 100644 27 | --- a/include/linux/mm.h 28 | +++ b/include/linux/mm.h 29 | @@ -205,6 +205,11 @@ extern int sysctl_max_map_count; 30 | extern unsigned long sysctl_user_reserve_kbytes; 31 | extern unsigned long sysctl_admin_reserve_kbytes; 32 | 33 | +#if defined(CONFIG_PROTECT_FILE) 34 | +extern unsigned long sysctl_file_low_kbytes; 35 | +extern unsigned long sysctl_file_min_kbytes; 36 | +#endif 37 | + 38 | extern int sysctl_overcommit_memory; 39 | extern int sysctl_overcommit_ratio; 40 | extern unsigned long sysctl_overcommit_kbytes; 41 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 42 | index afad08596..4261e5808 100644 43 | --- a/kernel/sysctl.c 44 | +++ b/kernel/sysctl.c 45 | @@ -111,6 +111,19 @@ 46 | static int sixty = 60; 47 | #endif 48 | 49 | +#if defined(CONFIG_PROTECT_FILE) 50 | +#if CONFIG_PROTECT_FILE_LOW_KBYTES < 0 51 | +#error "CONFIG_PROTECT_FILE_LOW_KBYTES should be >= 0" 52 | +#endif 53 | +#if CONFIG_PROTECT_FILE_MIN_KBYTES < 0 54 | +#error "CONFIG_PROTECT_FILE_MIN_KBYTES should be >= 0" 55 | +#endif 56 | +unsigned long sysctl_file_low_kbytes __read_mostly = 57 | + CONFIG_PROTECT_FILE_LOW_KBYTES; 58 | +unsigned long sysctl_file_min_kbytes __read_mostly = 59 | + CONFIG_PROTECT_FILE_MIN_KBYTES; 60 | +#endif 61 | + 62 | static int __maybe_unused neg_one = -1; 63 | static int __maybe_unused two = 2; 64 | static int __maybe_unused four = 4; 65 | @@ -3082,6 +3095,22 @@ static struct ctl_table vm_table[] = { 66 | .extra2 = SYSCTL_ONE, 67 | }, 68 | #endif 69 | +#if defined(CONFIG_PROTECT_FILE) 70 | + { 71 | + .procname = "file_low_kbytes", 72 | + .data = &sysctl_file_low_kbytes, 73 | + .maxlen = sizeof(sysctl_file_low_kbytes), 74 | + .mode = 0644, 75 | + .proc_handler = proc_doulongvec_minmax, 76 | + }, 77 | + { 78 | + .procname = "file_min_kbytes", 79 | + .data = &sysctl_file_min_kbytes, 80 | + .maxlen = sizeof(sysctl_file_min_kbytes), 81 | + .mode = 0644, 82 | + .proc_handler = proc_doulongvec_minmax, 83 | + }, 84 | +#endif 85 | { 86 | .procname = "user_reserve_kbytes", 87 | .data = &sysctl_user_reserve_kbytes, 88 | diff --git a/mm/Kconfig b/mm/Kconfig 89 | index 390165ffb..0e98aa7d3 100644 90 | --- a/mm/Kconfig 91 | +++ b/mm/Kconfig 92 | @@ -63,6 +63,20 @@ config SPARSEMEM_MANUAL 93 | 94 | endchoice 95 | 96 | +config PROTECT_FILE 97 | + def_bool y 98 | + depends on SYSCTL 99 | + 100 | +config PROTECT_FILE_LOW_KBYTES 101 | + int "Default value for vm.file_low_kbytes" 102 | + depends on PROTECT_FILE 103 | + default "0" 104 | + 105 | +config PROTECT_FILE_MIN_KBYTES 106 | + int "Default value for vm.file_min_kbytes" 107 | + depends on PROTECT_FILE 108 | + default "0" 109 | + 110 | config DISCONTIGMEM 111 | def_bool y 112 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 113 | diff --git a/mm/vmscan.c b/mm/vmscan.c 114 | index 7b4e31eac..1fbff14cc 100644 115 | --- a/mm/vmscan.c 116 | +++ b/mm/vmscan.c 117 | @@ -120,6 +120,11 @@ struct scan_control { 118 | /* The file pages on the current node are dangerously low */ 119 | unsigned int file_is_tiny:1; 120 | 121 | +#if defined(CONFIG_PROTECT_FILE) 122 | + unsigned int file_is_low:1; 123 | + unsigned int file_is_min:1; 124 | +#endif 125 | + 126 | /* Allocation order */ 127 | s8 order; 128 | 129 | @@ -2274,6 +2279,13 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 130 | goto out; 131 | } 132 | 133 | +#if defined(CONFIG_PROTECT_FILE) 134 | + if (sc->file_is_low || sc->file_is_min) { 135 | + scan_balance = SCAN_ANON; 136 | + goto out; 137 | + } 138 | +#endif 139 | + 140 | /* 141 | * If the system is almost out of file pages, force-scan anon. 142 | */ 143 | @@ -2418,6 +2430,11 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 144 | BUG(); 145 | } 146 | 147 | +#if defined(CONFIG_PROTECT_FILE) 148 | + if (file && sc->file_is_min) 149 | + scan = 0; 150 | +#endif 151 | + 152 | nr[lru] = scan; 153 | } 154 | } 155 | @@ -2766,6 +2783,13 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) 156 | file + free <= total_high_wmark && 157 | !(sc->may_deactivate & DEACTIVATE_ANON) && 158 | anon >> sc->priority; 159 | + 160 | +#if defined(CONFIG_PROTECT_FILE) 161 | + file <<= (PAGE_SHIFT - 10); 162 | + sc->file_is_low = file <= sysctl_file_low_kbytes; 163 | + sc->file_is_min = file <= sysctl_file_min_kbytes; 164 | +#endif 165 | + 166 | } 167 | 168 | shrink_node_memcgs(pgdat, sc); 169 | -- 170 | 2.11.0 171 | 172 | -------------------------------------------------------------------------------- /obsolete/le9ba_patches/le9ba1-5.10.patch: -------------------------------------------------------------------------------- 1 | From a5fdff804a40cd7709af266dfb36faaf029e2c36 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Sun, 14 Feb 2021 04:50:45 +0900 4 | Subject: [PATCH] Protect file pages under memory pressure 5 | 6 | The patch provides sysctl knobs to control file pages eviction 7 | in low memory conditions. 8 | 9 | vm.file_min_kbytes provides hard memory protection. File pages 10 | should not be evicted under memory pressure if their volume is 11 | below this (even with no free swap space). 12 | The default value is 0. 13 | 14 | vm.file_low_kbytes provides soft memory protection. File pages 15 | should not be evicted under memory pressure if their volume is 16 | below this and free swap space is available. 17 | The default value is 200000. 18 | --- 19 | include/linux/mm.h | 5 +++++ 20 | kernel/sysctl.c | 29 +++++++++++++++++++++++++++++ 21 | mm/Kconfig | 14 ++++++++++++++ 22 | mm/vmscan.c | 24 ++++++++++++++++++++++++ 23 | 4 files changed, 72 insertions(+) 24 | 25 | diff --git a/include/linux/mm.h b/include/linux/mm.h 26 | index db6ae4d3f..63f78fc9a 100644 27 | --- a/include/linux/mm.h 28 | +++ b/include/linux/mm.h 29 | @@ -205,6 +205,11 @@ extern int sysctl_max_map_count; 30 | extern unsigned long sysctl_user_reserve_kbytes; 31 | extern unsigned long sysctl_admin_reserve_kbytes; 32 | 33 | +#if defined(CONFIG_PROTECT_FILE) 34 | +extern unsigned long sysctl_file_low_kbytes; 35 | +extern unsigned long sysctl_file_min_kbytes; 36 | +#endif 37 | + 38 | extern int sysctl_overcommit_memory; 39 | extern int sysctl_overcommit_ratio; 40 | extern unsigned long sysctl_overcommit_kbytes; 41 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 42 | index afad08596..4261e5808 100644 43 | --- a/kernel/sysctl.c 44 | +++ b/kernel/sysctl.c 45 | @@ -111,6 +111,19 @@ 46 | static int sixty = 60; 47 | #endif 48 | 49 | +#if defined(CONFIG_PROTECT_FILE) 50 | +#if CONFIG_PROTECT_FILE_LOW_KBYTES < 0 51 | +#error "CONFIG_PROTECT_FILE_LOW_KBYTES should be >= 0" 52 | +#endif 53 | +#if CONFIG_PROTECT_FILE_MIN_KBYTES < 0 54 | +#error "CONFIG_PROTECT_FILE_MIN_KBYTES should be >= 0" 55 | +#endif 56 | +unsigned long sysctl_file_low_kbytes __read_mostly = 57 | + CONFIG_PROTECT_FILE_LOW_KBYTES; 58 | +unsigned long sysctl_file_min_kbytes __read_mostly = 59 | + CONFIG_PROTECT_FILE_MIN_KBYTES; 60 | +#endif 61 | + 62 | static int __maybe_unused neg_one = -1; 63 | static int __maybe_unused two = 2; 64 | static int __maybe_unused four = 4; 65 | @@ -3082,6 +3095,22 @@ static struct ctl_table vm_table[] = { 66 | .extra2 = SYSCTL_ONE, 67 | }, 68 | #endif 69 | +#if defined(CONFIG_PROTECT_FILE) 70 | + { 71 | + .procname = "file_low_kbytes", 72 | + .data = &sysctl_file_low_kbytes, 73 | + .maxlen = sizeof(sysctl_file_low_kbytes), 74 | + .mode = 0644, 75 | + .proc_handler = proc_doulongvec_minmax, 76 | + }, 77 | + { 78 | + .procname = "file_min_kbytes", 79 | + .data = &sysctl_file_min_kbytes, 80 | + .maxlen = sizeof(sysctl_file_min_kbytes), 81 | + .mode = 0644, 82 | + .proc_handler = proc_doulongvec_minmax, 83 | + }, 84 | +#endif 85 | { 86 | .procname = "user_reserve_kbytes", 87 | .data = &sysctl_user_reserve_kbytes, 88 | diff --git a/mm/Kconfig b/mm/Kconfig 89 | index 390165ffb..36cfdadd8 100644 90 | --- a/mm/Kconfig 91 | +++ b/mm/Kconfig 92 | @@ -63,6 +63,20 @@ config SPARSEMEM_MANUAL 93 | 94 | endchoice 95 | 96 | +config PROTECT_FILE 97 | + def_bool y 98 | + depends on SYSCTL 99 | + 100 | +config PROTECT_FILE_LOW_KBYTES 101 | + int "Default value for vm.file_low_kbytes" 102 | + depends on PROTECT_FILE 103 | + default "200000" 104 | + 105 | +config PROTECT_FILE_MIN_KBYTES 106 | + int "Default value for vm.file_min_kbytes" 107 | + depends on PROTECT_FILE 108 | + default "0" 109 | + 110 | config DISCONTIGMEM 111 | def_bool y 112 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 113 | diff --git a/mm/vmscan.c b/mm/vmscan.c 114 | index 7b4e31eac..1fbff14cc 100644 115 | --- a/mm/vmscan.c 116 | +++ b/mm/vmscan.c 117 | @@ -120,6 +120,11 @@ struct scan_control { 118 | /* The file pages on the current node are dangerously low */ 119 | unsigned int file_is_tiny:1; 120 | 121 | +#if defined(CONFIG_PROTECT_FILE) 122 | + unsigned int file_is_low:1; 123 | + unsigned int file_is_min:1; 124 | +#endif 125 | + 126 | /* Allocation order */ 127 | s8 order; 128 | 129 | @@ -2274,6 +2279,13 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 130 | goto out; 131 | } 132 | 133 | +#if defined(CONFIG_PROTECT_FILE) 134 | + if (sc->file_is_low || sc->file_is_min) { 135 | + scan_balance = SCAN_ANON; 136 | + goto out; 137 | + } 138 | +#endif 139 | + 140 | /* 141 | * If the system is almost out of file pages, force-scan anon. 142 | */ 143 | @@ -2418,6 +2430,11 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 144 | BUG(); 145 | } 146 | 147 | +#if defined(CONFIG_PROTECT_FILE) 148 | + if (file && sc->file_is_min) 149 | + scan = 0; 150 | +#endif 151 | + 152 | nr[lru] = scan; 153 | } 154 | } 155 | @@ -2766,6 +2783,13 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) 156 | file + free <= total_high_wmark && 157 | !(sc->may_deactivate & DEACTIVATE_ANON) && 158 | anon >> sc->priority; 159 | + 160 | +#if defined(CONFIG_PROTECT_FILE) 161 | + file <<= (PAGE_SHIFT - 10); 162 | + sc->file_is_low = file <= sysctl_file_low_kbytes; 163 | + sc->file_is_min = file <= sysctl_file_min_kbytes; 164 | +#endif 165 | + 166 | } 167 | 168 | shrink_node_memcgs(pgdat, sc); 169 | -- 170 | 2.11.0 171 | 172 | -------------------------------------------------------------------------------- /obsolete/le9ba_patches/le9ba2-5.10.patch: -------------------------------------------------------------------------------- 1 | From da75ce205f95d7f2430031973e016ac944f15938 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Sun, 14 Feb 2021 04:56:16 +0900 4 | Subject: [PATCH] Protect file pages under memory pressure 5 | 6 | The patch provides sysctl knobs to control file pages eviction 7 | in low memory conditions. 8 | 9 | vm.file_min_kbytes provides hard memory protection. File pages 10 | should not be evicted under memory pressure if their volume is 11 | below this (even with no free swap space). 12 | The default value is 200000. 13 | 14 | vm.file_low_kbytes provides soft memory protection. File pages 15 | should not be evicted under memory pressure if their volume is 16 | below this and free swap space is available. 17 | The default value is 0. 18 | --- 19 | include/linux/mm.h | 5 +++++ 20 | kernel/sysctl.c | 29 +++++++++++++++++++++++++++++ 21 | mm/Kconfig | 14 ++++++++++++++ 22 | mm/vmscan.c | 24 ++++++++++++++++++++++++ 23 | 4 files changed, 72 insertions(+) 24 | 25 | diff --git a/include/linux/mm.h b/include/linux/mm.h 26 | index db6ae4d3f..63f78fc9a 100644 27 | --- a/include/linux/mm.h 28 | +++ b/include/linux/mm.h 29 | @@ -205,6 +205,11 @@ extern int sysctl_max_map_count; 30 | extern unsigned long sysctl_user_reserve_kbytes; 31 | extern unsigned long sysctl_admin_reserve_kbytes; 32 | 33 | +#if defined(CONFIG_PROTECT_FILE) 34 | +extern unsigned long sysctl_file_low_kbytes; 35 | +extern unsigned long sysctl_file_min_kbytes; 36 | +#endif 37 | + 38 | extern int sysctl_overcommit_memory; 39 | extern int sysctl_overcommit_ratio; 40 | extern unsigned long sysctl_overcommit_kbytes; 41 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 42 | index afad08596..4261e5808 100644 43 | --- a/kernel/sysctl.c 44 | +++ b/kernel/sysctl.c 45 | @@ -111,6 +111,19 @@ 46 | static int sixty = 60; 47 | #endif 48 | 49 | +#if defined(CONFIG_PROTECT_FILE) 50 | +#if CONFIG_PROTECT_FILE_LOW_KBYTES < 0 51 | +#error "CONFIG_PROTECT_FILE_LOW_KBYTES should be >= 0" 52 | +#endif 53 | +#if CONFIG_PROTECT_FILE_MIN_KBYTES < 0 54 | +#error "CONFIG_PROTECT_FILE_MIN_KBYTES should be >= 0" 55 | +#endif 56 | +unsigned long sysctl_file_low_kbytes __read_mostly = 57 | + CONFIG_PROTECT_FILE_LOW_KBYTES; 58 | +unsigned long sysctl_file_min_kbytes __read_mostly = 59 | + CONFIG_PROTECT_FILE_MIN_KBYTES; 60 | +#endif 61 | + 62 | static int __maybe_unused neg_one = -1; 63 | static int __maybe_unused two = 2; 64 | static int __maybe_unused four = 4; 65 | @@ -3082,6 +3095,22 @@ static struct ctl_table vm_table[] = { 66 | .extra2 = SYSCTL_ONE, 67 | }, 68 | #endif 69 | +#if defined(CONFIG_PROTECT_FILE) 70 | + { 71 | + .procname = "file_low_kbytes", 72 | + .data = &sysctl_file_low_kbytes, 73 | + .maxlen = sizeof(sysctl_file_low_kbytes), 74 | + .mode = 0644, 75 | + .proc_handler = proc_doulongvec_minmax, 76 | + }, 77 | + { 78 | + .procname = "file_min_kbytes", 79 | + .data = &sysctl_file_min_kbytes, 80 | + .maxlen = sizeof(sysctl_file_min_kbytes), 81 | + .mode = 0644, 82 | + .proc_handler = proc_doulongvec_minmax, 83 | + }, 84 | +#endif 85 | { 86 | .procname = "user_reserve_kbytes", 87 | .data = &sysctl_user_reserve_kbytes, 88 | diff --git a/mm/Kconfig b/mm/Kconfig 89 | index 390165ffb..aa67d55b4 100644 90 | --- a/mm/Kconfig 91 | +++ b/mm/Kconfig 92 | @@ -63,6 +63,20 @@ config SPARSEMEM_MANUAL 93 | 94 | endchoice 95 | 96 | +config PROTECT_FILE 97 | + def_bool y 98 | + depends on SYSCTL 99 | + 100 | +config PROTECT_FILE_LOW_KBYTES 101 | + int "Default value for vm.file_low_kbytes" 102 | + depends on PROTECT_FILE 103 | + default "0" 104 | + 105 | +config PROTECT_FILE_MIN_KBYTES 106 | + int "Default value for vm.file_min_kbytes" 107 | + depends on PROTECT_FILE 108 | + default "200000" 109 | + 110 | config DISCONTIGMEM 111 | def_bool y 112 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 113 | diff --git a/mm/vmscan.c b/mm/vmscan.c 114 | index 7b4e31eac..1fbff14cc 100644 115 | --- a/mm/vmscan.c 116 | +++ b/mm/vmscan.c 117 | @@ -120,6 +120,11 @@ struct scan_control { 118 | /* The file pages on the current node are dangerously low */ 119 | unsigned int file_is_tiny:1; 120 | 121 | +#if defined(CONFIG_PROTECT_FILE) 122 | + unsigned int file_is_low:1; 123 | + unsigned int file_is_min:1; 124 | +#endif 125 | + 126 | /* Allocation order */ 127 | s8 order; 128 | 129 | @@ -2274,6 +2279,13 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 130 | goto out; 131 | } 132 | 133 | +#if defined(CONFIG_PROTECT_FILE) 134 | + if (sc->file_is_low || sc->file_is_min) { 135 | + scan_balance = SCAN_ANON; 136 | + goto out; 137 | + } 138 | +#endif 139 | + 140 | /* 141 | * If the system is almost out of file pages, force-scan anon. 142 | */ 143 | @@ -2418,6 +2430,11 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 144 | BUG(); 145 | } 146 | 147 | +#if defined(CONFIG_PROTECT_FILE) 148 | + if (file && sc->file_is_min) 149 | + scan = 0; 150 | +#endif 151 | + 152 | nr[lru] = scan; 153 | } 154 | } 155 | @@ -2766,6 +2783,13 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) 156 | file + free <= total_high_wmark && 157 | !(sc->may_deactivate & DEACTIVATE_ANON) && 158 | anon >> sc->priority; 159 | + 160 | +#if defined(CONFIG_PROTECT_FILE) 161 | + file <<= (PAGE_SHIFT - 10); 162 | + sc->file_is_low = file <= sysctl_file_low_kbytes; 163 | + sc->file_is_min = file <= sysctl_file_min_kbytes; 164 | +#endif 165 | + 166 | } 167 | 168 | shrink_node_memcgs(pgdat, sc); 169 | -- 170 | 2.11.0 171 | 172 | -------------------------------------------------------------------------------- /obsolete/le9bb_patches/le9bb0-5.10.patch: -------------------------------------------------------------------------------- 1 | From 75534bc9ba6c8a755502ce6b8bd609f876f785e3 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 22 Feb 2021 08:17:40 +0900 4 | Subject: [PATCH] Protect file pages under memory pressure 5 | 6 | The patch provides sysctl knobs for protecting file pages during low 7 | memory conditions. 8 | 9 | Protection of file pages may be used to prevent thrashing and reducing 10 | I/O under memory pressure. Hard protection of file pages may be used 11 | to avoid high latency and prevent livelock in near-OOM conditions. 12 | 13 | The vm.file_low_kbytes sysctl knob provides *best-effort* protection 14 | of file pages. The file pages on the current node won't be reclaimed 15 | uder memory pressure when their volume is below vm.file_low_kbytes 16 | *unless* we threaten to OOM or have no swap space or vm.swappiness=0. 17 | The default value is 0. 18 | 19 | The vm.file_min_kbytes sysctl knob provides *hard* protection of 20 | file pages. The file pages on the current node won't be reclaimed 21 | under memory pressure when their volume is below vm.file_min_kbytes. 22 | The default value is 0 23 | --- 24 | Documentation/admin-guide/sysctl/vm.rst | 31 ++++++++++++++++++++++++ 25 | include/linux/mm.h | 5 ++++ 26 | kernel/sysctl.c | 29 +++++++++++++++++++++++ 27 | mm/Kconfig | 34 ++++++++++++++++++++++++++ 28 | mm/vmscan.c | 42 +++++++++++++++++++++++++++++++++ 29 | 5 files changed, 141 insertions(+) 30 | 31 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 32 | index f455fa00c..f6b4c94ee 100644 33 | --- a/Documentation/admin-guide/sysctl/vm.rst 34 | +++ b/Documentation/admin-guide/sysctl/vm.rst 35 | @@ -38,6 +38,8 @@ Currently, these files are in /proc/sys/vm: 36 | - dirty_writeback_centisecs 37 | - drop_caches 38 | - extfrag_threshold 39 | +- file_low_kbytes 40 | +- file_min_kbytes 41 | - highmem_is_dirtyable 42 | - hugetlb_shm_group 43 | - laptop_mode 44 | @@ -287,6 +289,35 @@ The kernel will not compact memory in a zone if the 45 | fragmentation index is <= extfrag_threshold. The default value is 500. 46 | 47 | 48 | +file_low_kbytes 49 | +=============== 50 | + 51 | +Available only when CONFIG_PROTECT_FILE is set. This knob provides 52 | +*best-effort* protection of file pages. The file pages on the current 53 | +node won't be reclaimed uder memory pressure when their volume is below 54 | +vm.file_low_kbytes *unless* we threaten to OOM or have no swap space 55 | +or vm.swappiness=0. 56 | + 57 | +Protection of file pages may be used to prevent thrashing and 58 | +reducing I/O under low memory conditions. 59 | + 60 | +The default value is 0. 61 | + 62 | + 63 | +file_min_kbytes 64 | +=============== 65 | + 66 | +Available only when CONFIG_PROTECT_FILE is set. This knob provides 67 | +*hard* protection of file pages. The file pages on the current node 68 | +won't be reclaimed under memory pressure when their volume is below 69 | +vm.file_min_kbytes. 70 | + 71 | +Hard protection of file pages may be used to avoid high latency and 72 | +prevent livelock in near-OOM conditions. 73 | + 74 | +The default value is 0. 75 | + 76 | + 77 | highmem_is_dirtyable 78 | ==================== 79 | 80 | diff --git a/include/linux/mm.h b/include/linux/mm.h 81 | index db6ae4d3f..63f78fc9a 100644 82 | --- a/include/linux/mm.h 83 | +++ b/include/linux/mm.h 84 | @@ -205,6 +205,11 @@ extern int sysctl_max_map_count; 85 | extern unsigned long sysctl_user_reserve_kbytes; 86 | extern unsigned long sysctl_admin_reserve_kbytes; 87 | 88 | +#if defined(CONFIG_PROTECT_FILE) 89 | +extern unsigned long sysctl_file_low_kbytes; 90 | +extern unsigned long sysctl_file_min_kbytes; 91 | +#endif 92 | + 93 | extern int sysctl_overcommit_memory; 94 | extern int sysctl_overcommit_ratio; 95 | extern unsigned long sysctl_overcommit_kbytes; 96 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 97 | index afad08596..4261e5808 100644 98 | --- a/kernel/sysctl.c 99 | +++ b/kernel/sysctl.c 100 | @@ -111,6 +111,19 @@ 101 | static int sixty = 60; 102 | #endif 103 | 104 | +#if defined(CONFIG_PROTECT_FILE) 105 | +#if CONFIG_PROTECT_FILE_LOW_KBYTES < 0 106 | +#error "CONFIG_PROTECT_FILE_LOW_KBYTES should be >= 0" 107 | +#endif 108 | +#if CONFIG_PROTECT_FILE_MIN_KBYTES < 0 109 | +#error "CONFIG_PROTECT_FILE_MIN_KBYTES should be >= 0" 110 | +#endif 111 | +unsigned long sysctl_file_low_kbytes __read_mostly = 112 | + CONFIG_PROTECT_FILE_LOW_KBYTES; 113 | +unsigned long sysctl_file_min_kbytes __read_mostly = 114 | + CONFIG_PROTECT_FILE_MIN_KBYTES; 115 | +#endif 116 | + 117 | static int __maybe_unused neg_one = -1; 118 | static int __maybe_unused two = 2; 119 | static int __maybe_unused four = 4; 120 | @@ -3082,6 +3095,22 @@ static struct ctl_table vm_table[] = { 121 | .extra2 = SYSCTL_ONE, 122 | }, 123 | #endif 124 | +#if defined(CONFIG_PROTECT_FILE) 125 | + { 126 | + .procname = "file_low_kbytes", 127 | + .data = &sysctl_file_low_kbytes, 128 | + .maxlen = sizeof(sysctl_file_low_kbytes), 129 | + .mode = 0644, 130 | + .proc_handler = proc_doulongvec_minmax, 131 | + }, 132 | + { 133 | + .procname = "file_min_kbytes", 134 | + .data = &sysctl_file_min_kbytes, 135 | + .maxlen = sizeof(sysctl_file_min_kbytes), 136 | + .mode = 0644, 137 | + .proc_handler = proc_doulongvec_minmax, 138 | + }, 139 | +#endif 140 | { 141 | .procname = "user_reserve_kbytes", 142 | .data = &sysctl_user_reserve_kbytes, 143 | diff --git a/mm/Kconfig b/mm/Kconfig 144 | index 390165ffb..800362d56 100644 145 | --- a/mm/Kconfig 146 | +++ b/mm/Kconfig 147 | @@ -63,6 +63,40 @@ config SPARSEMEM_MANUAL 148 | 149 | endchoice 150 | 151 | +config PROTECT_FILE 152 | + bool "Add sysctl knobs for protecting file pages under low memory" 153 | + depends on SYSCTL 154 | + default y 155 | + help 156 | + Protection of file pages may be used to prevent thrashing 157 | + and reduce I/O under memory pressure. Hard protection of file pages 158 | + may be used to avoid high latency and prevent livelock in near-OOM 159 | + conditions. 160 | + 161 | + This option provides two sysctl knobs for protecting file pages 162 | + under memory pressure. 163 | + 164 | +config PROTECT_FILE_LOW_KBYTES 165 | + int "Default value for vm.file_low_kbytes" 166 | + depends on PROTECT_FILE 167 | + default "0" 168 | + help 169 | + The vm.file_low_kbytes sysctl knob provides *best-effort* 170 | + protection of file pages. The file pages on the current node 171 | + won't be reclaimed uder memory pressure when their volume is 172 | + below vm.file_low_kbytes *unless* we threaten to OOM or have 173 | + no swap space or vm.swappiness=0. 174 | + 175 | +config PROTECT_FILE_MIN_KBYTES 176 | + int "Default value for vm.file_min_kbytes" 177 | + depends on PROTECT_FILE 178 | + default "0" 179 | + help 180 | + The vm.file_min_kbytes sysctl knob provides *hard* protection 181 | + of file pages. The file pages on the current node won't be 182 | + reclaimed under memory pressure when their volume is below 183 | + vm.file_min_kbytes. 184 | + 185 | config DISCONTIGMEM 186 | def_bool y 187 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 188 | diff --git a/mm/vmscan.c b/mm/vmscan.c 189 | index 7b4e31eac..8183d0ee3 100644 190 | --- a/mm/vmscan.c 191 | +++ b/mm/vmscan.c 192 | @@ -120,6 +120,21 @@ struct scan_control { 193 | /* The file pages on the current node are dangerously low */ 194 | unsigned int file_is_tiny:1; 195 | 196 | +#if defined(CONFIG_PROTECT_FILE) 197 | + /* 198 | + * The file pages on the current node won't be reclaimed when 199 | + * their volume is below vm.file_low_kbytes *unless* we threaten 200 | + * to OOM or have no swap space or vm.swappiness=0. 201 | + */ 202 | + unsigned int file_is_low:1; 203 | + 204 | + /* 205 | + * The file pages on the current node won't be reclaimed when 206 | + * their volume is below vm.file_min_kbytes. 207 | + */ 208 | + unsigned int file_is_min:1; 209 | +#endif 210 | + 211 | /* Allocation order */ 212 | s8 order; 213 | 214 | @@ -2282,6 +2297,18 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 215 | goto out; 216 | } 217 | 218 | +#if defined(CONFIG_PROTECT_FILE) 219 | + /* 220 | + * Force-scan anon if file pages is under vm.file_min_kbytes 221 | + * or vm.file_low_kbytes (unless the swappiness setting 222 | + * disagrees with swapping). 223 | + */ 224 | + if ((sc->file_is_low || sc->file_is_min) && swappiness) { 225 | + scan_balance = SCAN_ANON; 226 | + goto out; 227 | + } 228 | +#endif 229 | + 230 | /* 231 | * If there is enough inactive page cache, we do not reclaim 232 | * anything from the anonymous working right now. 233 | @@ -2418,6 +2445,15 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 234 | BUG(); 235 | } 236 | 237 | +#if defined(CONFIG_PROTECT_FILE) 238 | + /* 239 | + * Don't reclaim file pages when their volume is below 240 | + * vm.file_min_kbytes. 241 | + */ 242 | + if (file && sc->file_is_min) 243 | + scan = 0; 244 | +#endif 245 | + 246 | nr[lru] = scan; 247 | } 248 | } 249 | @@ -2766,6 +2802,12 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) 250 | file + free <= total_high_wmark && 251 | !(sc->may_deactivate & DEACTIVATE_ANON) && 252 | anon >> sc->priority; 253 | + 254 | +#if defined(CONFIG_PROTECT_FILE) 255 | + file <<= (PAGE_SHIFT - 10); 256 | + sc->file_is_low = file <= sysctl_file_low_kbytes; 257 | + sc->file_is_min = file <= sysctl_file_min_kbytes; 258 | +#endif 259 | } 260 | 261 | shrink_node_memcgs(pgdat, sc); 262 | -- 263 | 2.11.0 264 | 265 | -------------------------------------------------------------------------------- /obsolete/le9bb_patches/le9bb1-5.10.patch: -------------------------------------------------------------------------------- 1 | From 74d671a3bc0af9267d523b4a67b716fa1b39b716 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 22 Feb 2021 08:32:59 +0900 4 | Subject: [PATCH] Protect file pages under memory pressure 5 | 6 | The patch provides sysctl knobs for protecting file pages during low 7 | memory conditions. 8 | 9 | Protection of file pages may be used to prevent thrashing and reducing 10 | I/O under memory pressure. Hard protection of file pages may be used 11 | to avoid high latency and prevent livelock in near-OOM conditions. 12 | 13 | The vm.file_low_kbytes sysctl knob provides *best-effort* protection 14 | of file pages. The file pages on the current node won't be reclaimed 15 | uder memory pressure when their volume is below vm.file_low_kbytes 16 | *unless* we threaten to OOM or have no swap space or vm.swappiness=0. 17 | The default value is 200000. 18 | 19 | The vm.file_min_kbytes sysctl knob provides *hard* protection of 20 | file pages. The file pages on the current node won't be reclaimed 21 | under memory pressure when their volume is below vm.file_min_kbytes. 22 | The default value is 0. 23 | --- 24 | Documentation/admin-guide/sysctl/vm.rst | 31 ++++++++++++++++++++++++ 25 | include/linux/mm.h | 5 ++++ 26 | kernel/sysctl.c | 29 +++++++++++++++++++++++ 27 | mm/Kconfig | 34 ++++++++++++++++++++++++++ 28 | mm/vmscan.c | 42 +++++++++++++++++++++++++++++++++ 29 | 5 files changed, 141 insertions(+) 30 | 31 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 32 | index f455fa00c..73fe12a80 100644 33 | --- a/Documentation/admin-guide/sysctl/vm.rst 34 | +++ b/Documentation/admin-guide/sysctl/vm.rst 35 | @@ -38,6 +38,8 @@ Currently, these files are in /proc/sys/vm: 36 | - dirty_writeback_centisecs 37 | - drop_caches 38 | - extfrag_threshold 39 | +- file_low_kbytes 40 | +- file_min_kbytes 41 | - highmem_is_dirtyable 42 | - hugetlb_shm_group 43 | - laptop_mode 44 | @@ -287,6 +289,35 @@ The kernel will not compact memory in a zone if the 45 | fragmentation index is <= extfrag_threshold. The default value is 500. 46 | 47 | 48 | +file_low_kbytes 49 | +=============== 50 | + 51 | +Available only when CONFIG_PROTECT_FILE is set. This knob provides 52 | +*best-effort* protection of file pages. The file pages on the current 53 | +node won't be reclaimed uder memory pressure when their volume is below 54 | +vm.file_low_kbytes *unless* we threaten to OOM or have no swap space 55 | +or vm.swappiness=0. 56 | + 57 | +Protection of file pages may be used to prevent thrashing and 58 | +reducing I/O under low memory conditions. 59 | + 60 | +The default value is 200000. 61 | + 62 | + 63 | +file_min_kbytes 64 | +=============== 65 | + 66 | +Available only when CONFIG_PROTECT_FILE is set. This knob provides 67 | +*hard* protection of file pages. The file pages on the current node 68 | +won't be reclaimed under memory pressure when their volume is below 69 | +vm.file_min_kbytes. 70 | + 71 | +Hard protection of file pages may be used to avoid high latency and 72 | +prevent livelock in near-OOM conditions. 73 | + 74 | +The default value is 0. 75 | + 76 | + 77 | highmem_is_dirtyable 78 | ==================== 79 | 80 | diff --git a/include/linux/mm.h b/include/linux/mm.h 81 | index db6ae4d3f..63f78fc9a 100644 82 | --- a/include/linux/mm.h 83 | +++ b/include/linux/mm.h 84 | @@ -205,6 +205,11 @@ extern int sysctl_max_map_count; 85 | extern unsigned long sysctl_user_reserve_kbytes; 86 | extern unsigned long sysctl_admin_reserve_kbytes; 87 | 88 | +#if defined(CONFIG_PROTECT_FILE) 89 | +extern unsigned long sysctl_file_low_kbytes; 90 | +extern unsigned long sysctl_file_min_kbytes; 91 | +#endif 92 | + 93 | extern int sysctl_overcommit_memory; 94 | extern int sysctl_overcommit_ratio; 95 | extern unsigned long sysctl_overcommit_kbytes; 96 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 97 | index afad08596..4261e5808 100644 98 | --- a/kernel/sysctl.c 99 | +++ b/kernel/sysctl.c 100 | @@ -111,6 +111,19 @@ 101 | static int sixty = 60; 102 | #endif 103 | 104 | +#if defined(CONFIG_PROTECT_FILE) 105 | +#if CONFIG_PROTECT_FILE_LOW_KBYTES < 0 106 | +#error "CONFIG_PROTECT_FILE_LOW_KBYTES should be >= 0" 107 | +#endif 108 | +#if CONFIG_PROTECT_FILE_MIN_KBYTES < 0 109 | +#error "CONFIG_PROTECT_FILE_MIN_KBYTES should be >= 0" 110 | +#endif 111 | +unsigned long sysctl_file_low_kbytes __read_mostly = 112 | + CONFIG_PROTECT_FILE_LOW_KBYTES; 113 | +unsigned long sysctl_file_min_kbytes __read_mostly = 114 | + CONFIG_PROTECT_FILE_MIN_KBYTES; 115 | +#endif 116 | + 117 | static int __maybe_unused neg_one = -1; 118 | static int __maybe_unused two = 2; 119 | static int __maybe_unused four = 4; 120 | @@ -3082,6 +3095,22 @@ static struct ctl_table vm_table[] = { 121 | .extra2 = SYSCTL_ONE, 122 | }, 123 | #endif 124 | +#if defined(CONFIG_PROTECT_FILE) 125 | + { 126 | + .procname = "file_low_kbytes", 127 | + .data = &sysctl_file_low_kbytes, 128 | + .maxlen = sizeof(sysctl_file_low_kbytes), 129 | + .mode = 0644, 130 | + .proc_handler = proc_doulongvec_minmax, 131 | + }, 132 | + { 133 | + .procname = "file_min_kbytes", 134 | + .data = &sysctl_file_min_kbytes, 135 | + .maxlen = sizeof(sysctl_file_min_kbytes), 136 | + .mode = 0644, 137 | + .proc_handler = proc_doulongvec_minmax, 138 | + }, 139 | +#endif 140 | { 141 | .procname = "user_reserve_kbytes", 142 | .data = &sysctl_user_reserve_kbytes, 143 | diff --git a/mm/Kconfig b/mm/Kconfig 144 | index 390165ffb..ae2623350 100644 145 | --- a/mm/Kconfig 146 | +++ b/mm/Kconfig 147 | @@ -63,6 +63,40 @@ config SPARSEMEM_MANUAL 148 | 149 | endchoice 150 | 151 | +config PROTECT_FILE 152 | + bool "Add sysctl knobs for protecting file pages under low memory" 153 | + depends on SYSCTL 154 | + default y 155 | + help 156 | + Protection of file pages may be used to prevent thrashing 157 | + and reduce I/O under memory pressure. Hard protection of file pages 158 | + may be used to avoid high latency and prevent livelock in near-OOM 159 | + conditions. 160 | + 161 | + This option provides two sysctl knobs for protecting file pages 162 | + under memory pressure. 163 | + 164 | +config PROTECT_FILE_LOW_KBYTES 165 | + int "Default value for vm.file_low_kbytes" 166 | + depends on PROTECT_FILE 167 | + default "200000" 168 | + help 169 | + The vm.file_low_kbytes sysctl knob provides *best-effort* 170 | + protection of file pages. The file pages on the current node 171 | + won't be reclaimed uder memory pressure when their volume is 172 | + below vm.file_low_kbytes *unless* we threaten to OOM or have 173 | + no swap space or vm.swappiness=0. 174 | + 175 | +config PROTECT_FILE_MIN_KBYTES 176 | + int "Default value for vm.file_min_kbytes" 177 | + depends on PROTECT_FILE 178 | + default "0" 179 | + help 180 | + The vm.file_min_kbytes sysctl knob provides *hard* protection 181 | + of file pages. The file pages on the current node won't be 182 | + reclaimed under memory pressure when their volume is below 183 | + vm.file_min_kbytes. 184 | + 185 | config DISCONTIGMEM 186 | def_bool y 187 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 188 | diff --git a/mm/vmscan.c b/mm/vmscan.c 189 | index 7b4e31eac..8183d0ee3 100644 190 | --- a/mm/vmscan.c 191 | +++ b/mm/vmscan.c 192 | @@ -120,6 +120,21 @@ struct scan_control { 193 | /* The file pages on the current node are dangerously low */ 194 | unsigned int file_is_tiny:1; 195 | 196 | +#if defined(CONFIG_PROTECT_FILE) 197 | + /* 198 | + * The file pages on the current node won't be reclaimed when 199 | + * their volume is below vm.file_low_kbytes *unless* we threaten 200 | + * to OOM or have no swap space or vm.swappiness=0. 201 | + */ 202 | + unsigned int file_is_low:1; 203 | + 204 | + /* 205 | + * The file pages on the current node won't be reclaimed when 206 | + * their volume is below vm.file_min_kbytes. 207 | + */ 208 | + unsigned int file_is_min:1; 209 | +#endif 210 | + 211 | /* Allocation order */ 212 | s8 order; 213 | 214 | @@ -2282,6 +2297,18 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 215 | goto out; 216 | } 217 | 218 | +#if defined(CONFIG_PROTECT_FILE) 219 | + /* 220 | + * Force-scan anon if file pages is under vm.file_min_kbytes 221 | + * or vm.file_low_kbytes (unless the swappiness setting 222 | + * disagrees with swapping). 223 | + */ 224 | + if ((sc->file_is_low || sc->file_is_min) && swappiness) { 225 | + scan_balance = SCAN_ANON; 226 | + goto out; 227 | + } 228 | +#endif 229 | + 230 | /* 231 | * If there is enough inactive page cache, we do not reclaim 232 | * anything from the anonymous working right now. 233 | @@ -2418,6 +2445,15 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 234 | BUG(); 235 | } 236 | 237 | +#if defined(CONFIG_PROTECT_FILE) 238 | + /* 239 | + * Don't reclaim file pages when their volume is below 240 | + * vm.file_min_kbytes. 241 | + */ 242 | + if (file && sc->file_is_min) 243 | + scan = 0; 244 | +#endif 245 | + 246 | nr[lru] = scan; 247 | } 248 | } 249 | @@ -2766,6 +2802,12 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) 250 | file + free <= total_high_wmark && 251 | !(sc->may_deactivate & DEACTIVATE_ANON) && 252 | anon >> sc->priority; 253 | + 254 | +#if defined(CONFIG_PROTECT_FILE) 255 | + file <<= (PAGE_SHIFT - 10); 256 | + sc->file_is_low = file <= sysctl_file_low_kbytes; 257 | + sc->file_is_min = file <= sysctl_file_min_kbytes; 258 | +#endif 259 | } 260 | 261 | shrink_node_memcgs(pgdat, sc); 262 | -- 263 | 2.11.0 264 | 265 | -------------------------------------------------------------------------------- /obsolete/le9bb_patches/le9bb2-5.10.patch: -------------------------------------------------------------------------------- 1 | From db1f3db7973fc19f62c48338a6f4c7774bd8deb8 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 22 Feb 2021 08:37:21 +0900 4 | Subject: [PATCH] Protect file pages under memory pressure 5 | 6 | The patch provides sysctl knobs for protecting file pages during low 7 | memory conditions. 8 | 9 | Protection of file pages may be used to prevent thrashing and reducing 10 | I/O under memory pressure. Hard protection of file pages may be used 11 | to avoid high latency and prevent livelock in near-OOM conditions. 12 | 13 | The vm.file_low_kbytes sysctl knob provides *best-effort* protection 14 | of file pages. The file pages on the current node won't be reclaimed 15 | uder memory pressure when their volume is below vm.file_low_kbytes 16 | *unless* we threaten to OOM or have no swap space or vm.swappiness=0. 17 | The default value is 0. 18 | 19 | The vm.file_min_kbytes sysctl knob provides *hard* protection of 20 | file pages. The file pages on the current node won't be reclaimed 21 | under memory pressure when their volume is below vm.file_min_kbytes. 22 | The default value is 200000. 23 | --- 24 | Documentation/admin-guide/sysctl/vm.rst | 31 ++++++++++++++++++++++++ 25 | include/linux/mm.h | 5 ++++ 26 | kernel/sysctl.c | 29 +++++++++++++++++++++++ 27 | mm/Kconfig | 34 ++++++++++++++++++++++++++ 28 | mm/vmscan.c | 42 +++++++++++++++++++++++++++++++++ 29 | 5 files changed, 141 insertions(+) 30 | 31 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 32 | index f455fa00c..c839e1658 100644 33 | --- a/Documentation/admin-guide/sysctl/vm.rst 34 | +++ b/Documentation/admin-guide/sysctl/vm.rst 35 | @@ -38,6 +38,8 @@ Currently, these files are in /proc/sys/vm: 36 | - dirty_writeback_centisecs 37 | - drop_caches 38 | - extfrag_threshold 39 | +- file_low_kbytes 40 | +- file_min_kbytes 41 | - highmem_is_dirtyable 42 | - hugetlb_shm_group 43 | - laptop_mode 44 | @@ -287,6 +289,35 @@ The kernel will not compact memory in a zone if the 45 | fragmentation index is <= extfrag_threshold. The default value is 500. 46 | 47 | 48 | +file_low_kbytes 49 | +=============== 50 | + 51 | +Available only when CONFIG_PROTECT_FILE is set. This knob provides 52 | +*best-effort* protection of file pages. The file pages on the current 53 | +node won't be reclaimed uder memory pressure when their volume is below 54 | +vm.file_low_kbytes *unless* we threaten to OOM or have no swap space 55 | +or vm.swappiness=0. 56 | + 57 | +Protection of file pages may be used to prevent thrashing and 58 | +reducing I/O under low memory conditions. 59 | + 60 | +The default value is 0. 61 | + 62 | + 63 | +file_min_kbytes 64 | +=============== 65 | + 66 | +Available only when CONFIG_PROTECT_FILE is set. This knob provides 67 | +*hard* protection of file pages. The file pages on the current node 68 | +won't be reclaimed under memory pressure when their volume is below 69 | +vm.file_min_kbytes. 70 | + 71 | +Hard protection of file pages may be used to avoid high latency and 72 | +prevent livelock in near-OOM conditions. 73 | + 74 | +The default value is 200000. 75 | + 76 | + 77 | highmem_is_dirtyable 78 | ==================== 79 | 80 | diff --git a/include/linux/mm.h b/include/linux/mm.h 81 | index db6ae4d3f..63f78fc9a 100644 82 | --- a/include/linux/mm.h 83 | +++ b/include/linux/mm.h 84 | @@ -205,6 +205,11 @@ extern int sysctl_max_map_count; 85 | extern unsigned long sysctl_user_reserve_kbytes; 86 | extern unsigned long sysctl_admin_reserve_kbytes; 87 | 88 | +#if defined(CONFIG_PROTECT_FILE) 89 | +extern unsigned long sysctl_file_low_kbytes; 90 | +extern unsigned long sysctl_file_min_kbytes; 91 | +#endif 92 | + 93 | extern int sysctl_overcommit_memory; 94 | extern int sysctl_overcommit_ratio; 95 | extern unsigned long sysctl_overcommit_kbytes; 96 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 97 | index afad08596..4261e5808 100644 98 | --- a/kernel/sysctl.c 99 | +++ b/kernel/sysctl.c 100 | @@ -111,6 +111,19 @@ 101 | static int sixty = 60; 102 | #endif 103 | 104 | +#if defined(CONFIG_PROTECT_FILE) 105 | +#if CONFIG_PROTECT_FILE_LOW_KBYTES < 0 106 | +#error "CONFIG_PROTECT_FILE_LOW_KBYTES should be >= 0" 107 | +#endif 108 | +#if CONFIG_PROTECT_FILE_MIN_KBYTES < 0 109 | +#error "CONFIG_PROTECT_FILE_MIN_KBYTES should be >= 0" 110 | +#endif 111 | +unsigned long sysctl_file_low_kbytes __read_mostly = 112 | + CONFIG_PROTECT_FILE_LOW_KBYTES; 113 | +unsigned long sysctl_file_min_kbytes __read_mostly = 114 | + CONFIG_PROTECT_FILE_MIN_KBYTES; 115 | +#endif 116 | + 117 | static int __maybe_unused neg_one = -1; 118 | static int __maybe_unused two = 2; 119 | static int __maybe_unused four = 4; 120 | @@ -3082,6 +3095,22 @@ static struct ctl_table vm_table[] = { 121 | .extra2 = SYSCTL_ONE, 122 | }, 123 | #endif 124 | +#if defined(CONFIG_PROTECT_FILE) 125 | + { 126 | + .procname = "file_low_kbytes", 127 | + .data = &sysctl_file_low_kbytes, 128 | + .maxlen = sizeof(sysctl_file_low_kbytes), 129 | + .mode = 0644, 130 | + .proc_handler = proc_doulongvec_minmax, 131 | + }, 132 | + { 133 | + .procname = "file_min_kbytes", 134 | + .data = &sysctl_file_min_kbytes, 135 | + .maxlen = sizeof(sysctl_file_min_kbytes), 136 | + .mode = 0644, 137 | + .proc_handler = proc_doulongvec_minmax, 138 | + }, 139 | +#endif 140 | { 141 | .procname = "user_reserve_kbytes", 142 | .data = &sysctl_user_reserve_kbytes, 143 | diff --git a/mm/Kconfig b/mm/Kconfig 144 | index 390165ffb..935014966 100644 145 | --- a/mm/Kconfig 146 | +++ b/mm/Kconfig 147 | @@ -63,6 +63,40 @@ config SPARSEMEM_MANUAL 148 | 149 | endchoice 150 | 151 | +config PROTECT_FILE 152 | + bool "Add sysctl knobs for protecting file pages under low memory" 153 | + depends on SYSCTL 154 | + default y 155 | + help 156 | + Protection of file pages may be used to prevent thrashing 157 | + and reduce I/O under memory pressure. Hard protection of file pages 158 | + may be used to avoid high latency and prevent livelock in near-OOM 159 | + conditions. 160 | + 161 | + This option provides two sysctl knobs for protecting file pages 162 | + under memory pressure. 163 | + 164 | +config PROTECT_FILE_LOW_KBYTES 165 | + int "Default value for vm.file_low_kbytes" 166 | + depends on PROTECT_FILE 167 | + default "0" 168 | + help 169 | + The vm.file_low_kbytes sysctl knob provides *best-effort* 170 | + protection of file pages. The file pages on the current node 171 | + won't be reclaimed uder memory pressure when their volume is 172 | + below vm.file_low_kbytes *unless* we threaten to OOM or have 173 | + no swap space or vm.swappiness=0. 174 | + 175 | +config PROTECT_FILE_MIN_KBYTES 176 | + int "Default value for vm.file_min_kbytes" 177 | + depends on PROTECT_FILE 178 | + default "200000" 179 | + help 180 | + The vm.file_min_kbytes sysctl knob provides *hard* protection 181 | + of file pages. The file pages on the current node won't be 182 | + reclaimed under memory pressure when their volume is below 183 | + vm.file_min_kbytes. 184 | + 185 | config DISCONTIGMEM 186 | def_bool y 187 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 188 | diff --git a/mm/vmscan.c b/mm/vmscan.c 189 | index 7b4e31eac..8183d0ee3 100644 190 | --- a/mm/vmscan.c 191 | +++ b/mm/vmscan.c 192 | @@ -120,6 +120,21 @@ struct scan_control { 193 | /* The file pages on the current node are dangerously low */ 194 | unsigned int file_is_tiny:1; 195 | 196 | +#if defined(CONFIG_PROTECT_FILE) 197 | + /* 198 | + * The file pages on the current node won't be reclaimed when 199 | + * their volume is below vm.file_low_kbytes *unless* we threaten 200 | + * to OOM or have no swap space or vm.swappiness=0. 201 | + */ 202 | + unsigned int file_is_low:1; 203 | + 204 | + /* 205 | + * The file pages on the current node won't be reclaimed when 206 | + * their volume is below vm.file_min_kbytes. 207 | + */ 208 | + unsigned int file_is_min:1; 209 | +#endif 210 | + 211 | /* Allocation order */ 212 | s8 order; 213 | 214 | @@ -2282,6 +2297,18 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 215 | goto out; 216 | } 217 | 218 | +#if defined(CONFIG_PROTECT_FILE) 219 | + /* 220 | + * Force-scan anon if file pages is under vm.file_min_kbytes 221 | + * or vm.file_low_kbytes (unless the swappiness setting 222 | + * disagrees with swapping). 223 | + */ 224 | + if ((sc->file_is_low || sc->file_is_min) && swappiness) { 225 | + scan_balance = SCAN_ANON; 226 | + goto out; 227 | + } 228 | +#endif 229 | + 230 | /* 231 | * If there is enough inactive page cache, we do not reclaim 232 | * anything from the anonymous working right now. 233 | @@ -2418,6 +2445,15 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 234 | BUG(); 235 | } 236 | 237 | +#if defined(CONFIG_PROTECT_FILE) 238 | + /* 239 | + * Don't reclaim file pages when their volume is below 240 | + * vm.file_min_kbytes. 241 | + */ 242 | + if (file && sc->file_is_min) 243 | + scan = 0; 244 | +#endif 245 | + 246 | nr[lru] = scan; 247 | } 248 | } 249 | @@ -2766,6 +2802,12 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) 250 | file + free <= total_high_wmark && 251 | !(sc->may_deactivate & DEACTIVATE_ANON) && 252 | anon >> sc->priority; 253 | + 254 | +#if defined(CONFIG_PROTECT_FILE) 255 | + file <<= (PAGE_SHIFT - 10); 256 | + sc->file_is_low = file <= sysctl_file_low_kbytes; 257 | + sc->file_is_min = file <= sysctl_file_min_kbytes; 258 | +#endif 259 | } 260 | 261 | shrink_node_memcgs(pgdat, sc); 262 | -- 263 | 2.11.0 264 | 265 | -------------------------------------------------------------------------------- /obsolete/le9ca_patches/README.md: -------------------------------------------------------------------------------- 1 | 2 | # le9cb patches 3 | 4 | `le9ca*-5.10` patches may be correctly applied to Linux 5.10—5.12-rc4. 5 | 6 | The `vm.clean_file_low_kbytes` sysctl knob provides *best-effort* protection of clean file pages. The clean file pages on the current node won't be reclaimed uder memory pressure when their volume is below `vm.clean_file_low_kbytes` *unless* we threaten to OOM or have no swap space or vm.swappiness=0. 7 | 8 | The `vm.clean_file_min_kbytes` sysctl knob provides *hard* protection of clean file pages. The clean file pages on the current node won't be reclaimed under memory pressure when their volume is below `vm.clean_file_min_kbytes`. 9 | 10 | `le9ca0` just provides two sysctl knobs with 0 values and does not protect clean file pages by default. 11 | 12 | `le9ca1` provides only soft protection (`vm.clean_file_low_kbytes=150000`, `vm.clean_file_min_kbytes=0`). This patch may be safly used by default. 13 | 14 | `le9ca2` provides hard protection of clean file pages (`vm.clean_file_low_kbytes=250000`, `vm.clean_file_min_kbytes=200000`). 15 | -------------------------------------------------------------------------------- /obsolete/le9cb_patches/README.md: -------------------------------------------------------------------------------- 1 | 2 | # le9cb patches 3 | 4 | `le9cb*-5.10` patches may be correctly applied to Linux 5.10—5.12-rc4. 5 | 6 | `le9cb*-5.4` patches may be correctly applied to Linux 5.4. 7 | 8 | `le9cb*-4.19` patches may be correctly applied to Linux 4.19. 9 | 10 | The `vm.clean_file_low_kbytes` sysctl knob provides *best-effort* protection of clean file pages. The clean file pages on the current node won't be reclaimed uder memory pressure when their volume is below `vm.clean_file_low_kbytes` *unless* we threaten to OOM or have no swap space or vm.swappiness=0. 11 | 12 | The `vm.clean_file_min_kbytes` sysctl knob provides *hard* protection of clean file pages. The clean file pages on the current node won't be reclaimed under memory pressure when their volume is below `vm.clean_file_min_kbytes`. 13 | 14 | The `le9cb0`, `le9cb1`, `le9cb2` patches differ only in the default values. 15 | 16 | `le9cb0` just provides two sysctl knobs with 0 values and does not protect clean file pages by default. 17 | 18 | `le9cb1` provides only soft protection (`vm.clean_file_low_kbytes=150000`, `vm.clean_file_min_kbytes=0`). This patch may be safly used by default. 19 | 20 | `le9cb2` provides hard protection of clean file pages (`vm.clean_file_low_kbytes=250000`, `vm.clean_file_min_kbytes=200000`). 21 | -------------------------------------------------------------------------------- /obsolete/le9cb_patches/le9cb0-4.19.patch: -------------------------------------------------------------------------------- 1 | From b7580af8054dadddac3c21dd9fc8815c86959603 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 29 Mar 2021 02:38:23 +0900 4 | Subject: [PATCH] mm: Protect clean file pages under memory pressure 5 | 6 | The patch provides sysctl knobs for protecting clean file pages 7 | during low-memory conditions. 8 | 9 | Protection of clean file pages may be used to prevent thrashing and 10 | reducing I/O under memory pressure. Hard protection of clean file 11 | pages may be used to avoid high latency and prevent livelock in 12 | near-OOM conditions. 13 | 14 | The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 15 | protection of clean file pages. The clean file pages on the current 16 | node won't be reclaimed uder memory pressure when their volume is 17 | below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 18 | no swap space or vm.swappiness=0. 19 | The default value is 0. 20 | 21 | The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 22 | of clean file pages. The clean file pages on the current node won't 23 | be reclaimed under memory pressure when their volume is below 24 | vm.file_min_kbytes. 25 | The default value is 0. 26 | 27 | Signed-off-by: Alexey Avramov 28 | --- 29 | Documentation/sysctl/vm.txt | 31 +++++++++++++++++++++++++++++++ 30 | include/linux/mm.h | 5 +++++ 31 | kernel/sysctl.c | 29 +++++++++++++++++++++++++++++ 32 | mm/Kconfig | 34 ++++++++++++++++++++++++++++++++++ 33 | mm/vmscan.c | 35 +++++++++++++++++++++++++++++++++++ 34 | 5 files changed, 134 insertions(+) 35 | 36 | diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt 37 | index 7d73882e2..119ae96c4 100644 38 | --- a/Documentation/sysctl/vm.txt 39 | +++ b/Documentation/sysctl/vm.txt 40 | @@ -20,6 +20,8 @@ Currently, these files are in /proc/sys/vm: 41 | 42 | - admin_reserve_kbytes 43 | - block_dump 44 | +- clean_file_low_kbytes 45 | +- clean_file_min_kbytes 46 | - compact_memory 47 | - compact_unevictable_allowed 48 | - dirty_background_bytes 49 | @@ -104,6 +106,35 @@ information on block I/O debugging is in Documentation/laptops/laptop-mode.txt. 50 | 51 | ============================================================== 52 | 53 | +clean_file_low_kbytes 54 | + 55 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 56 | +*best-effort* protection of clean file pages. The clean file pages on the 57 | +current node won't be reclaimed uder memory pressure when their volume is 58 | +below vm.clean_file_low_kbytes *unless* we threaten to OOM or have no swap 59 | +space or vm.swappiness=0. 60 | + 61 | +Protection of clean file pages may be used to prevent thrashing and 62 | +reducing I/O under low-memory conditions. 63 | + 64 | +The default value is 0. 65 | + 66 | +============================================================== 67 | + 68 | +clean_file_min_kbytes 69 | + 70 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 71 | +*hard* protection of clean file pages. The clean file pages on the current 72 | +node won't be reclaimed under memory pressure when their volume is below 73 | +vm.clean_file_min_kbytes. 74 | + 75 | +Hard protection of clean file pages may be used to avoid high latency and 76 | +prevent livelock in near-OOM conditions. 77 | + 78 | +The default value is 0. 79 | + 80 | +============================================================== 81 | + 82 | compact_memory 83 | 84 | Available only when CONFIG_COMPACTION is set. When 1 is written to the file, 85 | diff --git a/include/linux/mm.h b/include/linux/mm.h 86 | index 0416a7204..be4b0b649 100644 87 | --- a/include/linux/mm.h 88 | +++ b/include/linux/mm.h 89 | @@ -129,6 +129,11 @@ extern int sysctl_max_map_count; 90 | extern unsigned long sysctl_user_reserve_kbytes; 91 | extern unsigned long sysctl_admin_reserve_kbytes; 92 | 93 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 94 | +extern unsigned long sysctl_clean_file_low_kbytes; 95 | +extern unsigned long sysctl_clean_file_min_kbytes; 96 | +#endif 97 | + 98 | extern int sysctl_overcommit_memory; 99 | extern int sysctl_overcommit_ratio; 100 | extern unsigned long sysctl_overcommit_kbytes; 101 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 102 | index cc02050fd..d13836c42 100644 103 | --- a/kernel/sysctl.c 104 | +++ b/kernel/sysctl.c 105 | @@ -119,6 +119,19 @@ extern int sysctl_nr_trim_pages; 106 | static int sixty = 60; 107 | #endif 108 | 109 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 110 | +#if CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES < 0 111 | +#error "CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES should be >= 0" 112 | +#endif 113 | +#if CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES < 0 114 | +#error "CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES should be >= 0" 115 | +#endif 116 | +unsigned long sysctl_clean_file_low_kbytes __read_mostly = 117 | + CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES; 118 | +unsigned long sysctl_clean_file_min_kbytes __read_mostly = 119 | + CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES; 120 | +#endif 121 | + 122 | static int __maybe_unused neg_one = -1; 123 | 124 | static int zero; 125 | @@ -1628,6 +1641,22 @@ static struct ctl_table vm_table[] = { 126 | .extra2 = &one, 127 | }, 128 | #endif 129 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 130 | + { 131 | + .procname = "clean_file_low_kbytes", 132 | + .data = &sysctl_clean_file_low_kbytes, 133 | + .maxlen = sizeof(sysctl_clean_file_low_kbytes), 134 | + .mode = 0644, 135 | + .proc_handler = proc_doulongvec_minmax, 136 | + }, 137 | + { 138 | + .procname = "clean_file_min_kbytes", 139 | + .data = &sysctl_clean_file_min_kbytes, 140 | + .maxlen = sizeof(sysctl_clean_file_min_kbytes), 141 | + .mode = 0644, 142 | + .proc_handler = proc_doulongvec_minmax, 143 | + }, 144 | +#endif 145 | { 146 | .procname = "user_reserve_kbytes", 147 | .data = &sysctl_user_reserve_kbytes, 148 | diff --git a/mm/Kconfig b/mm/Kconfig 149 | index de64ea658..825f35e21 100644 150 | --- a/mm/Kconfig 151 | +++ b/mm/Kconfig 152 | @@ -64,6 +64,40 @@ config SPARSEMEM_MANUAL 153 | 154 | endchoice 155 | 156 | +config PROTECT_CLEAN_FILE 157 | + bool "Add sysctl knobs for protecting clean file pages under low memory" 158 | + depends on SYSCTL 159 | + default y 160 | + help 161 | + Protection of clean file pages may be used to prevent thrashing 162 | + and reduce I/O under memory pressure. Hard protection of clean file 163 | + pages may be used to avoid high latency and prevent livelock in 164 | + near-OOM conditions. 165 | + 166 | + This option provides two sysctl knobs for protecting clean file pages 167 | + under memory pressure. 168 | + 169 | +config PROTECT_CLEAN_FILE_LOW_KBYTES 170 | + int "Default value for vm.clean_file_low_kbytes" 171 | + depends on PROTECT_CLEAN_FILE 172 | + default "0" 173 | + help 174 | + The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 175 | + protection of clean file pages. The clean file pages on the current 176 | + node won't be reclaimed uder memory pressure when their volume is 177 | + below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 178 | + no swap space or vm.swappiness=0. 179 | + 180 | +config PROTECT_CLEAN_FILE_MIN_KBYTES 181 | + int "Default value for vm.clean_file_min_kbytes" 182 | + depends on PROTECT_CLEAN_FILE 183 | + default "0" 184 | + help 185 | + The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 186 | + of clean file pages. The clean file pages on the current node won't be 187 | + reclaimed under memory pressure when their volume is below 188 | + vm.clean_file_min_kbytes. 189 | + 190 | config DISCONTIGMEM 191 | def_bool y 192 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 193 | diff --git a/mm/vmscan.c b/mm/vmscan.c 194 | index c5ef7240c..070aedd53 100644 195 | --- a/mm/vmscan.c 196 | +++ b/mm/vmscan.c 197 | @@ -2294,6 +2294,20 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 198 | unsigned long anon, file; 199 | unsigned long ap, fp; 200 | enum lru_list lru; 201 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 202 | + unsigned long node_file, node_dirty, node_clean; 203 | + bool clean_file_below_low, clean_file_below_min; 204 | + 205 | + node_dirty = node_page_state(pgdat, NR_FILE_DIRTY); 206 | + node_file = node_page_state(pgdat, NR_ACTIVE_FILE) + 207 | + node_page_state(pgdat, NR_INACTIVE_FILE); 208 | + 209 | + if (node_file > node_dirty) 210 | + node_clean = (node_file - node_dirty) << (PAGE_SHIFT - 10); 211 | + 212 | + clean_file_below_low = node_clean <= sysctl_clean_file_low_kbytes; 213 | + clean_file_below_min = node_clean <= sysctl_clean_file_min_kbytes; 214 | +#endif 215 | 216 | /* If we have no swap space, do not bother scanning anon pages. */ 217 | if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) { 218 | @@ -2365,6 +2379,18 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 219 | } 220 | } 221 | 222 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 223 | + /* 224 | + * Force-scan anon if clean file pages is under vm.clean_file_min_kbytes 225 | + * or vm.clean_file_low_kbytes (unless the swappiness setting 226 | + * disagrees with swapping). 227 | + */ 228 | + if ((clean_file_below_low || clean_file_below_min) && swappiness) { 229 | + scan_balance = SCAN_ANON; 230 | + goto out; 231 | + } 232 | +#endif 233 | + 234 | /* 235 | * If there is enough inactive page cache, i.e. if the size of the 236 | * inactive list is greater than that of the active list *and* the 237 | @@ -2473,6 +2499,15 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 238 | BUG(); 239 | } 240 | 241 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 242 | + /* 243 | + * Don't reclaim clean file pages when their volume is below 244 | + * vm.clean_file_min_kbytes. 245 | + */ 246 | + if (file && clean_file_below_min) 247 | + scan = 0; 248 | +#endif 249 | + 250 | *lru_pages += size; 251 | nr[lru] = scan; 252 | } 253 | -- 254 | 2.11.0 255 | 256 | -------------------------------------------------------------------------------- /obsolete/le9cb_patches/le9cb0-5.4.patch: -------------------------------------------------------------------------------- 1 | From 9f06b121cfc590ae45e909e99e1206453e6da3ce Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 29 Mar 2021 01:00:36 +0900 4 | Subject: [PATCH] mm: Protect clean file pages under memory pressure 5 | 6 | The patch provides sysctl knobs for protecting clean file pages 7 | during low-memory conditions. 8 | 9 | Protection of clean file pages may be used to prevent thrashing and 10 | reducing I/O under memory pressure. Hard protection of clean file 11 | pages may be used to avoid high latency and prevent livelock in 12 | near-OOM conditions. 13 | 14 | The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 15 | protection of clean file pages. The clean file pages on the current 16 | node won't be reclaimed uder memory pressure when their volume is 17 | below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 18 | no swap space or vm.swappiness=0. 19 | The default value is 0. 20 | 21 | The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 22 | of clean file pages. The clean file pages on the current node won't 23 | be reclaimed under memory pressure when their volume is below 24 | vm.file_min_kbytes. 25 | The default value is 0. 26 | 27 | Signed-off-by: Alexey Avramov 28 | --- 29 | Documentation/admin-guide/sysctl/vm.rst | 31 +++++++++++++++++++++++++++++ 30 | include/linux/mm.h | 5 +++++ 31 | kernel/sysctl.c | 29 +++++++++++++++++++++++++++ 32 | mm/Kconfig | 34 ++++++++++++++++++++++++++++++++ 33 | mm/vmscan.c | 35 +++++++++++++++++++++++++++++++++ 34 | 5 files changed, 134 insertions(+) 35 | 36 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 37 | index 64aeee100..d15dda712 100644 38 | --- a/Documentation/admin-guide/sysctl/vm.rst 39 | +++ b/Documentation/admin-guide/sysctl/vm.rst 40 | @@ -26,6 +26,8 @@ Currently, these files are in /proc/sys/vm: 41 | 42 | - admin_reserve_kbytes 43 | - block_dump 44 | +- clean_file_low_kbytes 45 | +- clean_file_min_kbytes 46 | - compact_memory 47 | - compact_unevictable_allowed 48 | - dirty_background_bytes 49 | @@ -111,6 +113,35 @@ block_dump enables block I/O debugging when set to a nonzero value. More 50 | information on block I/O debugging is in Documentation/admin-guide/laptops/laptop-mode.rst. 51 | 52 | 53 | +clean_file_low_kbytes 54 | +===================== 55 | + 56 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 57 | +*best-effort* protection of clean file pages. The clean file pages on the 58 | +current node won't be reclaimed uder memory pressure when their volume is 59 | +below vm.clean_file_low_kbytes *unless* we threaten to OOM or have no swap 60 | +space or vm.swappiness=0. 61 | + 62 | +Protection of clean file pages may be used to prevent thrashing and 63 | +reducing I/O under low-memory conditions. 64 | + 65 | +The default value is 0. 66 | + 67 | + 68 | +clean_file_min_kbytes 69 | +===================== 70 | + 71 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 72 | +*hard* protection of clean file pages. The clean file pages on the current 73 | +node won't be reclaimed under memory pressure when their volume is below 74 | +vm.clean_file_min_kbytes. 75 | + 76 | +Hard protection of clean file pages may be used to avoid high latency and 77 | +prevent livelock in near-OOM conditions. 78 | + 79 | +The default value is 0. 80 | + 81 | + 82 | compact_memory 83 | ============== 84 | 85 | diff --git a/include/linux/mm.h b/include/linux/mm.h 86 | index a2adf95b3..16780ad31 100644 87 | --- a/include/linux/mm.h 88 | +++ b/include/linux/mm.h 89 | @@ -201,6 +201,11 @@ extern int sysctl_max_map_count; 90 | extern unsigned long sysctl_user_reserve_kbytes; 91 | extern unsigned long sysctl_admin_reserve_kbytes; 92 | 93 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 94 | +extern unsigned long sysctl_clean_file_low_kbytes; 95 | +extern unsigned long sysctl_clean_file_min_kbytes; 96 | +#endif 97 | + 98 | extern int sysctl_overcommit_memory; 99 | extern int sysctl_overcommit_ratio; 100 | extern unsigned long sysctl_overcommit_kbytes; 101 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 102 | index b6f2f35d0..ce3bf4bf9 100644 103 | --- a/kernel/sysctl.c 104 | +++ b/kernel/sysctl.c 105 | @@ -124,6 +124,19 @@ extern int sysctl_nr_trim_pages; 106 | static int sixty = 60; 107 | #endif 108 | 109 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 110 | +#if CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES < 0 111 | +#error "CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES should be >= 0" 112 | +#endif 113 | +#if CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES < 0 114 | +#error "CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES should be >= 0" 115 | +#endif 116 | +unsigned long sysctl_clean_file_low_kbytes __read_mostly = 117 | + CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES; 118 | +unsigned long sysctl_clean_file_min_kbytes __read_mostly = 119 | + CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES; 120 | +#endif 121 | + 122 | static int __maybe_unused neg_one = -1; 123 | static int __maybe_unused two = 2; 124 | static int __maybe_unused four = 4; 125 | @@ -1694,6 +1707,22 @@ static struct ctl_table vm_table[] = { 126 | .extra2 = SYSCTL_ONE, 127 | }, 128 | #endif 129 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 130 | + { 131 | + .procname = "clean_file_low_kbytes", 132 | + .data = &sysctl_clean_file_low_kbytes, 133 | + .maxlen = sizeof(sysctl_clean_file_low_kbytes), 134 | + .mode = 0644, 135 | + .proc_handler = proc_doulongvec_minmax, 136 | + }, 137 | + { 138 | + .procname = "clean_file_min_kbytes", 139 | + .data = &sysctl_clean_file_min_kbytes, 140 | + .maxlen = sizeof(sysctl_clean_file_min_kbytes), 141 | + .mode = 0644, 142 | + .proc_handler = proc_doulongvec_minmax, 143 | + }, 144 | +#endif 145 | { 146 | .procname = "user_reserve_kbytes", 147 | .data = &sysctl_user_reserve_kbytes, 148 | diff --git a/mm/Kconfig b/mm/Kconfig 149 | index a5dae9a7e..d3f279228 100644 150 | --- a/mm/Kconfig 151 | +++ b/mm/Kconfig 152 | @@ -63,6 +63,40 @@ config SPARSEMEM_MANUAL 153 | 154 | endchoice 155 | 156 | +config PROTECT_CLEAN_FILE 157 | + bool "Add sysctl knobs for protecting clean file pages under low memory" 158 | + depends on SYSCTL 159 | + default y 160 | + help 161 | + Protection of clean file pages may be used to prevent thrashing 162 | + and reduce I/O under memory pressure. Hard protection of clean file 163 | + pages may be used to avoid high latency and prevent livelock in 164 | + near-OOM conditions. 165 | + 166 | + This option provides two sysctl knobs for protecting clean file pages 167 | + under memory pressure. 168 | + 169 | +config PROTECT_CLEAN_FILE_LOW_KBYTES 170 | + int "Default value for vm.clean_file_low_kbytes" 171 | + depends on PROTECT_CLEAN_FILE 172 | + default "0" 173 | + help 174 | + The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 175 | + protection of clean file pages. The clean file pages on the current 176 | + node won't be reclaimed uder memory pressure when their volume is 177 | + below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 178 | + no swap space or vm.swappiness=0. 179 | + 180 | +config PROTECT_CLEAN_FILE_MIN_KBYTES 181 | + int "Default value for vm.clean_file_min_kbytes" 182 | + depends on PROTECT_CLEAN_FILE 183 | + default "0" 184 | + help 185 | + The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 186 | + of clean file pages. The clean file pages on the current node won't be 187 | + reclaimed under memory pressure when their volume is below 188 | + vm.clean_file_min_kbytes. 189 | + 190 | config DISCONTIGMEM 191 | def_bool y 192 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 193 | diff --git a/mm/vmscan.c b/mm/vmscan.c 194 | index ee4eecc7e..225306f36 100644 195 | --- a/mm/vmscan.c 196 | +++ b/mm/vmscan.c 197 | @@ -2315,6 +2315,20 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 198 | unsigned long anon, file; 199 | unsigned long ap, fp; 200 | enum lru_list lru; 201 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 202 | + unsigned long node_file, node_dirty, node_clean; 203 | + bool clean_file_below_low, clean_file_below_min; 204 | + 205 | + node_dirty = node_page_state(pgdat, NR_FILE_DIRTY); 206 | + node_file = node_page_state(pgdat, NR_ACTIVE_FILE) + 207 | + node_page_state(pgdat, NR_INACTIVE_FILE); 208 | + 209 | + if (node_file > node_dirty) 210 | + node_clean = (node_file - node_dirty) << (PAGE_SHIFT - 10); 211 | + 212 | + clean_file_below_low = node_clean <= sysctl_clean_file_low_kbytes; 213 | + clean_file_below_min = node_clean <= sysctl_clean_file_min_kbytes; 214 | +#endif 215 | 216 | /* If we have no swap space, do not bother scanning anon pages. */ 217 | if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) { 218 | @@ -2386,6 +2400,18 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 219 | } 220 | } 221 | 222 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 223 | + /* 224 | + * Force-scan anon if clean file pages is under vm.clean_file_min_kbytes 225 | + * or vm.clean_file_low_kbytes (unless the swappiness setting 226 | + * disagrees with swapping). 227 | + */ 228 | + if ((clean_file_below_low || clean_file_below_min) && swappiness) { 229 | + scan_balance = SCAN_ANON; 230 | + goto out; 231 | + } 232 | +#endif 233 | + 234 | /* 235 | * If there is enough inactive page cache, i.e. if the size of the 236 | * inactive list is greater than that of the active list *and* the 237 | @@ -2549,6 +2575,15 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 238 | BUG(); 239 | } 240 | 241 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 242 | + /* 243 | + * Don't reclaim clean file pages when their volume is below 244 | + * vm.clean_file_min_kbytes. 245 | + */ 246 | + if (file && clean_file_below_min) 247 | + scan = 0; 248 | +#endif 249 | + 250 | *lru_pages += lruvec_size; 251 | nr[lru] = scan; 252 | } 253 | -- 254 | 2.11.0 255 | 256 | -------------------------------------------------------------------------------- /obsolete/le9cb_patches/le9cb1-4.19.patch: -------------------------------------------------------------------------------- 1 | From 68f6f17c66d8c7280dbd62a7f06befc566b2e1c0 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 29 Mar 2021 02:48:02 +0900 4 | Subject: [PATCH] mm: Protect clean file pages under memory pressure 5 | 6 | The patch provides sysctl knobs for protecting clean file pages 7 | during low-memory conditions. 8 | 9 | Protection of clean file pages may be used to prevent thrashing and 10 | reducing I/O under memory pressure. Hard protection of clean file 11 | pages may be used to avoid high latency and prevent livelock in 12 | near-OOM conditions. 13 | 14 | The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 15 | protection of clean file pages. The clean file pages on the current 16 | node won't be reclaimed uder memory pressure when their volume is 17 | below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 18 | no swap space or vm.swappiness=0. 19 | The default value is 150000. 20 | 21 | The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 22 | of clean file pages. The clean file pages on the current node won't 23 | be reclaimed under memory pressure when their volume is below 24 | vm.file_min_kbytes. 25 | The default value is 0. 26 | 27 | Signed-off-by: Alexey Avramov 28 | --- 29 | Documentation/sysctl/vm.txt | 31 +++++++++++++++++++++++++++++++ 30 | include/linux/mm.h | 5 +++++ 31 | kernel/sysctl.c | 29 +++++++++++++++++++++++++++++ 32 | mm/Kconfig | 34 ++++++++++++++++++++++++++++++++++ 33 | mm/vmscan.c | 35 +++++++++++++++++++++++++++++++++++ 34 | 5 files changed, 134 insertions(+) 35 | 36 | diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt 37 | index 7d73882e2..9557acb40 100644 38 | --- a/Documentation/sysctl/vm.txt 39 | +++ b/Documentation/sysctl/vm.txt 40 | @@ -20,6 +20,8 @@ Currently, these files are in /proc/sys/vm: 41 | 42 | - admin_reserve_kbytes 43 | - block_dump 44 | +- clean_file_low_kbytes 45 | +- clean_file_min_kbytes 46 | - compact_memory 47 | - compact_unevictable_allowed 48 | - dirty_background_bytes 49 | @@ -104,6 +106,35 @@ information on block I/O debugging is in Documentation/laptops/laptop-mode.txt. 50 | 51 | ============================================================== 52 | 53 | +clean_file_low_kbytes 54 | + 55 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 56 | +*best-effort* protection of clean file pages. The clean file pages on the 57 | +current node won't be reclaimed uder memory pressure when their volume is 58 | +below vm.clean_file_low_kbytes *unless* we threaten to OOM or have no swap 59 | +space or vm.swappiness=0. 60 | + 61 | +Protection of clean file pages may be used to prevent thrashing and 62 | +reducing I/O under low-memory conditions. 63 | + 64 | +The default value is 150000. 65 | + 66 | +============================================================== 67 | + 68 | +clean_file_min_kbytes 69 | + 70 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 71 | +*hard* protection of clean file pages. The clean file pages on the current 72 | +node won't be reclaimed under memory pressure when their volume is below 73 | +vm.clean_file_min_kbytes. 74 | + 75 | +Hard protection of clean file pages may be used to avoid high latency and 76 | +prevent livelock in near-OOM conditions. 77 | + 78 | +The default value is 0. 79 | + 80 | +============================================================== 81 | + 82 | compact_memory 83 | 84 | Available only when CONFIG_COMPACTION is set. When 1 is written to the file, 85 | diff --git a/include/linux/mm.h b/include/linux/mm.h 86 | index 0416a7204..be4b0b649 100644 87 | --- a/include/linux/mm.h 88 | +++ b/include/linux/mm.h 89 | @@ -129,6 +129,11 @@ extern int sysctl_max_map_count; 90 | extern unsigned long sysctl_user_reserve_kbytes; 91 | extern unsigned long sysctl_admin_reserve_kbytes; 92 | 93 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 94 | +extern unsigned long sysctl_clean_file_low_kbytes; 95 | +extern unsigned long sysctl_clean_file_min_kbytes; 96 | +#endif 97 | + 98 | extern int sysctl_overcommit_memory; 99 | extern int sysctl_overcommit_ratio; 100 | extern unsigned long sysctl_overcommit_kbytes; 101 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 102 | index cc02050fd..d13836c42 100644 103 | --- a/kernel/sysctl.c 104 | +++ b/kernel/sysctl.c 105 | @@ -119,6 +119,19 @@ extern int sysctl_nr_trim_pages; 106 | static int sixty = 60; 107 | #endif 108 | 109 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 110 | +#if CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES < 0 111 | +#error "CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES should be >= 0" 112 | +#endif 113 | +#if CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES < 0 114 | +#error "CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES should be >= 0" 115 | +#endif 116 | +unsigned long sysctl_clean_file_low_kbytes __read_mostly = 117 | + CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES; 118 | +unsigned long sysctl_clean_file_min_kbytes __read_mostly = 119 | + CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES; 120 | +#endif 121 | + 122 | static int __maybe_unused neg_one = -1; 123 | 124 | static int zero; 125 | @@ -1628,6 +1641,22 @@ static struct ctl_table vm_table[] = { 126 | .extra2 = &one, 127 | }, 128 | #endif 129 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 130 | + { 131 | + .procname = "clean_file_low_kbytes", 132 | + .data = &sysctl_clean_file_low_kbytes, 133 | + .maxlen = sizeof(sysctl_clean_file_low_kbytes), 134 | + .mode = 0644, 135 | + .proc_handler = proc_doulongvec_minmax, 136 | + }, 137 | + { 138 | + .procname = "clean_file_min_kbytes", 139 | + .data = &sysctl_clean_file_min_kbytes, 140 | + .maxlen = sizeof(sysctl_clean_file_min_kbytes), 141 | + .mode = 0644, 142 | + .proc_handler = proc_doulongvec_minmax, 143 | + }, 144 | +#endif 145 | { 146 | .procname = "user_reserve_kbytes", 147 | .data = &sysctl_user_reserve_kbytes, 148 | diff --git a/mm/Kconfig b/mm/Kconfig 149 | index de64ea658..a1e1682e8 100644 150 | --- a/mm/Kconfig 151 | +++ b/mm/Kconfig 152 | @@ -64,6 +64,40 @@ config SPARSEMEM_MANUAL 153 | 154 | endchoice 155 | 156 | +config PROTECT_CLEAN_FILE 157 | + bool "Add sysctl knobs for protecting clean file pages under low memory" 158 | + depends on SYSCTL 159 | + default y 160 | + help 161 | + Protection of clean file pages may be used to prevent thrashing 162 | + and reduce I/O under memory pressure. Hard protection of clean file 163 | + pages may be used to avoid high latency and prevent livelock in 164 | + near-OOM conditions. 165 | + 166 | + This option provides two sysctl knobs for protecting clean file pages 167 | + under memory pressure. 168 | + 169 | +config PROTECT_CLEAN_FILE_LOW_KBYTES 170 | + int "Default value for vm.clean_file_low_kbytes" 171 | + depends on PROTECT_CLEAN_FILE 172 | + default "150000" 173 | + help 174 | + The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 175 | + protection of clean file pages. The clean file pages on the current 176 | + node won't be reclaimed uder memory pressure when their volume is 177 | + below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 178 | + no swap space or vm.swappiness=0. 179 | + 180 | +config PROTECT_CLEAN_FILE_MIN_KBYTES 181 | + int "Default value for vm.clean_file_min_kbytes" 182 | + depends on PROTECT_CLEAN_FILE 183 | + default "0" 184 | + help 185 | + The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 186 | + of clean file pages. The clean file pages on the current node won't be 187 | + reclaimed under memory pressure when their volume is below 188 | + vm.clean_file_min_kbytes. 189 | + 190 | config DISCONTIGMEM 191 | def_bool y 192 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 193 | diff --git a/mm/vmscan.c b/mm/vmscan.c 194 | index c5ef7240c..070aedd53 100644 195 | --- a/mm/vmscan.c 196 | +++ b/mm/vmscan.c 197 | @@ -2294,6 +2294,20 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 198 | unsigned long anon, file; 199 | unsigned long ap, fp; 200 | enum lru_list lru; 201 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 202 | + unsigned long node_file, node_dirty, node_clean; 203 | + bool clean_file_below_low, clean_file_below_min; 204 | + 205 | + node_dirty = node_page_state(pgdat, NR_FILE_DIRTY); 206 | + node_file = node_page_state(pgdat, NR_ACTIVE_FILE) + 207 | + node_page_state(pgdat, NR_INACTIVE_FILE); 208 | + 209 | + if (node_file > node_dirty) 210 | + node_clean = (node_file - node_dirty) << (PAGE_SHIFT - 10); 211 | + 212 | + clean_file_below_low = node_clean <= sysctl_clean_file_low_kbytes; 213 | + clean_file_below_min = node_clean <= sysctl_clean_file_min_kbytes; 214 | +#endif 215 | 216 | /* If we have no swap space, do not bother scanning anon pages. */ 217 | if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) { 218 | @@ -2365,6 +2379,18 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 219 | } 220 | } 221 | 222 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 223 | + /* 224 | + * Force-scan anon if clean file pages is under vm.clean_file_min_kbytes 225 | + * or vm.clean_file_low_kbytes (unless the swappiness setting 226 | + * disagrees with swapping). 227 | + */ 228 | + if ((clean_file_below_low || clean_file_below_min) && swappiness) { 229 | + scan_balance = SCAN_ANON; 230 | + goto out; 231 | + } 232 | +#endif 233 | + 234 | /* 235 | * If there is enough inactive page cache, i.e. if the size of the 236 | * inactive list is greater than that of the active list *and* the 237 | @@ -2473,6 +2499,15 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 238 | BUG(); 239 | } 240 | 241 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 242 | + /* 243 | + * Don't reclaim clean file pages when their volume is below 244 | + * vm.clean_file_min_kbytes. 245 | + */ 246 | + if (file && clean_file_below_min) 247 | + scan = 0; 248 | +#endif 249 | + 250 | *lru_pages += size; 251 | nr[lru] = scan; 252 | } 253 | -- 254 | 2.11.0 255 | 256 | -------------------------------------------------------------------------------- /obsolete/le9cb_patches/le9cb1-5.4.patch: -------------------------------------------------------------------------------- 1 | From 8b0e027e89f5940020d7bba4e9c3dc4fbb5edbf2 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 29 Mar 2021 01:12:17 +0900 4 | Subject: [PATCH] mm: Protect clean file pages under memory pressure 5 | 6 | The patch provides sysctl knobs for protecting clean file pages 7 | during low-memory conditions. 8 | 9 | Protection of clean file pages may be used to prevent thrashing and 10 | reducing I/O under memory pressure. Hard protection of clean file 11 | pages may be used to avoid high latency and prevent livelock in 12 | near-OOM conditions. 13 | 14 | The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 15 | protection of clean file pages. The clean file pages on the current 16 | node won't be reclaimed uder memory pressure when their volume is 17 | below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 18 | no swap space or vm.swappiness=0. 19 | The default value is 150000. 20 | 21 | The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 22 | of clean file pages. The clean file pages on the current node won't 23 | be reclaimed under memory pressure when their volume is below 24 | vm.file_min_kbytes. 25 | The default value is 0. 26 | 27 | Signed-off-by: Alexey Avramov 28 | --- 29 | Documentation/admin-guide/sysctl/vm.rst | 31 +++++++++++++++++++++++++++++ 30 | include/linux/mm.h | 5 +++++ 31 | kernel/sysctl.c | 29 +++++++++++++++++++++++++++ 32 | mm/Kconfig | 34 ++++++++++++++++++++++++++++++++ 33 | mm/vmscan.c | 35 +++++++++++++++++++++++++++++++++ 34 | 5 files changed, 134 insertions(+) 35 | 36 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 37 | index 64aeee100..286ac958f 100644 38 | --- a/Documentation/admin-guide/sysctl/vm.rst 39 | +++ b/Documentation/admin-guide/sysctl/vm.rst 40 | @@ -26,6 +26,8 @@ Currently, these files are in /proc/sys/vm: 41 | 42 | - admin_reserve_kbytes 43 | - block_dump 44 | +- clean_file_low_kbytes 45 | +- clean_file_min_kbytes 46 | - compact_memory 47 | - compact_unevictable_allowed 48 | - dirty_background_bytes 49 | @@ -111,6 +113,35 @@ block_dump enables block I/O debugging when set to a nonzero value. More 50 | information on block I/O debugging is in Documentation/admin-guide/laptops/laptop-mode.rst. 51 | 52 | 53 | +clean_file_low_kbytes 54 | +===================== 55 | + 56 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 57 | +*best-effort* protection of clean file pages. The clean file pages on the 58 | +current node won't be reclaimed uder memory pressure when their volume is 59 | +below vm.clean_file_low_kbytes *unless* we threaten to OOM or have no swap 60 | +space or vm.swappiness=0. 61 | + 62 | +Protection of clean file pages may be used to prevent thrashing and 63 | +reducing I/O under low-memory conditions. 64 | + 65 | +The default value is 150000. 66 | + 67 | + 68 | +clean_file_min_kbytes 69 | +===================== 70 | + 71 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 72 | +*hard* protection of clean file pages. The clean file pages on the current 73 | +node won't be reclaimed under memory pressure when their volume is below 74 | +vm.clean_file_min_kbytes. 75 | + 76 | +Hard protection of clean file pages may be used to avoid high latency and 77 | +prevent livelock in near-OOM conditions. 78 | + 79 | +The default value is 0. 80 | + 81 | + 82 | compact_memory 83 | ============== 84 | 85 | diff --git a/include/linux/mm.h b/include/linux/mm.h 86 | index a2adf95b3..16780ad31 100644 87 | --- a/include/linux/mm.h 88 | +++ b/include/linux/mm.h 89 | @@ -201,6 +201,11 @@ extern int sysctl_max_map_count; 90 | extern unsigned long sysctl_user_reserve_kbytes; 91 | extern unsigned long sysctl_admin_reserve_kbytes; 92 | 93 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 94 | +extern unsigned long sysctl_clean_file_low_kbytes; 95 | +extern unsigned long sysctl_clean_file_min_kbytes; 96 | +#endif 97 | + 98 | extern int sysctl_overcommit_memory; 99 | extern int sysctl_overcommit_ratio; 100 | extern unsigned long sysctl_overcommit_kbytes; 101 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 102 | index b6f2f35d0..ce3bf4bf9 100644 103 | --- a/kernel/sysctl.c 104 | +++ b/kernel/sysctl.c 105 | @@ -124,6 +124,19 @@ extern int sysctl_nr_trim_pages; 106 | static int sixty = 60; 107 | #endif 108 | 109 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 110 | +#if CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES < 0 111 | +#error "CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES should be >= 0" 112 | +#endif 113 | +#if CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES < 0 114 | +#error "CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES should be >= 0" 115 | +#endif 116 | +unsigned long sysctl_clean_file_low_kbytes __read_mostly = 117 | + CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES; 118 | +unsigned long sysctl_clean_file_min_kbytes __read_mostly = 119 | + CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES; 120 | +#endif 121 | + 122 | static int __maybe_unused neg_one = -1; 123 | static int __maybe_unused two = 2; 124 | static int __maybe_unused four = 4; 125 | @@ -1694,6 +1707,22 @@ static struct ctl_table vm_table[] = { 126 | .extra2 = SYSCTL_ONE, 127 | }, 128 | #endif 129 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 130 | + { 131 | + .procname = "clean_file_low_kbytes", 132 | + .data = &sysctl_clean_file_low_kbytes, 133 | + .maxlen = sizeof(sysctl_clean_file_low_kbytes), 134 | + .mode = 0644, 135 | + .proc_handler = proc_doulongvec_minmax, 136 | + }, 137 | + { 138 | + .procname = "clean_file_min_kbytes", 139 | + .data = &sysctl_clean_file_min_kbytes, 140 | + .maxlen = sizeof(sysctl_clean_file_min_kbytes), 141 | + .mode = 0644, 142 | + .proc_handler = proc_doulongvec_minmax, 143 | + }, 144 | +#endif 145 | { 146 | .procname = "user_reserve_kbytes", 147 | .data = &sysctl_user_reserve_kbytes, 148 | diff --git a/mm/Kconfig b/mm/Kconfig 149 | index a5dae9a7e..11afaabb4 100644 150 | --- a/mm/Kconfig 151 | +++ b/mm/Kconfig 152 | @@ -63,6 +63,40 @@ config SPARSEMEM_MANUAL 153 | 154 | endchoice 155 | 156 | +config PROTECT_CLEAN_FILE 157 | + bool "Add sysctl knobs for protecting clean file pages under low memory" 158 | + depends on SYSCTL 159 | + default y 160 | + help 161 | + Protection of clean file pages may be used to prevent thrashing 162 | + and reduce I/O under memory pressure. Hard protection of clean file 163 | + pages may be used to avoid high latency and prevent livelock in 164 | + near-OOM conditions. 165 | + 166 | + This option provides two sysctl knobs for protecting clean file pages 167 | + under memory pressure. 168 | + 169 | +config PROTECT_CLEAN_FILE_LOW_KBYTES 170 | + int "Default value for vm.clean_file_low_kbytes" 171 | + depends on PROTECT_CLEAN_FILE 172 | + default "150000" 173 | + help 174 | + The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 175 | + protection of clean file pages. The clean file pages on the current 176 | + node won't be reclaimed uder memory pressure when their volume is 177 | + below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 178 | + no swap space or vm.swappiness=0. 179 | + 180 | +config PROTECT_CLEAN_FILE_MIN_KBYTES 181 | + int "Default value for vm.clean_file_min_kbytes" 182 | + depends on PROTECT_CLEAN_FILE 183 | + default "0" 184 | + help 185 | + The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 186 | + of clean file pages. The clean file pages on the current node won't be 187 | + reclaimed under memory pressure when their volume is below 188 | + vm.clean_file_min_kbytes. 189 | + 190 | config DISCONTIGMEM 191 | def_bool y 192 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 193 | diff --git a/mm/vmscan.c b/mm/vmscan.c 194 | index ee4eecc7e..225306f36 100644 195 | --- a/mm/vmscan.c 196 | +++ b/mm/vmscan.c 197 | @@ -2315,6 +2315,20 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 198 | unsigned long anon, file; 199 | unsigned long ap, fp; 200 | enum lru_list lru; 201 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 202 | + unsigned long node_file, node_dirty, node_clean; 203 | + bool clean_file_below_low, clean_file_below_min; 204 | + 205 | + node_dirty = node_page_state(pgdat, NR_FILE_DIRTY); 206 | + node_file = node_page_state(pgdat, NR_ACTIVE_FILE) + 207 | + node_page_state(pgdat, NR_INACTIVE_FILE); 208 | + 209 | + if (node_file > node_dirty) 210 | + node_clean = (node_file - node_dirty) << (PAGE_SHIFT - 10); 211 | + 212 | + clean_file_below_low = node_clean <= sysctl_clean_file_low_kbytes; 213 | + clean_file_below_min = node_clean <= sysctl_clean_file_min_kbytes; 214 | +#endif 215 | 216 | /* If we have no swap space, do not bother scanning anon pages. */ 217 | if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) { 218 | @@ -2386,6 +2400,18 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 219 | } 220 | } 221 | 222 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 223 | + /* 224 | + * Force-scan anon if clean file pages is under vm.clean_file_min_kbytes 225 | + * or vm.clean_file_low_kbytes (unless the swappiness setting 226 | + * disagrees with swapping). 227 | + */ 228 | + if ((clean_file_below_low || clean_file_below_min) && swappiness) { 229 | + scan_balance = SCAN_ANON; 230 | + goto out; 231 | + } 232 | +#endif 233 | + 234 | /* 235 | * If there is enough inactive page cache, i.e. if the size of the 236 | * inactive list is greater than that of the active list *and* the 237 | @@ -2549,6 +2575,15 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 238 | BUG(); 239 | } 240 | 241 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 242 | + /* 243 | + * Don't reclaim clean file pages when their volume is below 244 | + * vm.clean_file_min_kbytes. 245 | + */ 246 | + if (file && clean_file_below_min) 247 | + scan = 0; 248 | +#endif 249 | + 250 | *lru_pages += lruvec_size; 251 | nr[lru] = scan; 252 | } 253 | -- 254 | 2.11.0 255 | 256 | -------------------------------------------------------------------------------- /obsolete/le9cb_patches/le9cb2-4.19.patch: -------------------------------------------------------------------------------- 1 | From c47f612c8ba8633e5390de8959eee4c86e5c8080 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 29 Mar 2021 02:52:56 +0900 4 | Subject: [PATCH] mm: Protect clean file pages under memory pressure 5 | 6 | The patch provides sysctl knobs for protecting clean file pages 7 | during low-memory conditions. 8 | 9 | Protection of clean file pages may be used to prevent thrashing and 10 | reducing I/O under memory pressure. Hard protection of clean file 11 | pages may be used to avoid high latency and prevent livelock in 12 | near-OOM conditions. 13 | 14 | The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 15 | protection of clean file pages. The clean file pages on the current 16 | node won't be reclaimed uder memory pressure when their volume is 17 | below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 18 | no swap space or vm.swappiness=0. 19 | The default value is 250000. 20 | 21 | The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 22 | of clean file pages. The clean file pages on the current node won't 23 | be reclaimed under memory pressure when their volume is below 24 | vm.file_min_kbytes. 25 | The default value is 200000. 26 | 27 | Signed-off-by: Alexey Avramov 28 | --- 29 | Documentation/sysctl/vm.txt | 31 +++++++++++++++++++++++++++++++ 30 | include/linux/mm.h | 5 +++++ 31 | kernel/sysctl.c | 29 +++++++++++++++++++++++++++++ 32 | mm/Kconfig | 34 ++++++++++++++++++++++++++++++++++ 33 | mm/vmscan.c | 35 +++++++++++++++++++++++++++++++++++ 34 | 5 files changed, 134 insertions(+) 35 | 36 | diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt 37 | index 7d73882e2..7e8b6b3f0 100644 38 | --- a/Documentation/sysctl/vm.txt 39 | +++ b/Documentation/sysctl/vm.txt 40 | @@ -20,6 +20,8 @@ Currently, these files are in /proc/sys/vm: 41 | 42 | - admin_reserve_kbytes 43 | - block_dump 44 | +- clean_file_low_kbytes 45 | +- clean_file_min_kbytes 46 | - compact_memory 47 | - compact_unevictable_allowed 48 | - dirty_background_bytes 49 | @@ -104,6 +106,35 @@ information on block I/O debugging is in Documentation/laptops/laptop-mode.txt. 50 | 51 | ============================================================== 52 | 53 | +clean_file_low_kbytes 54 | + 55 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 56 | +*best-effort* protection of clean file pages. The clean file pages on the 57 | +current node won't be reclaimed uder memory pressure when their volume is 58 | +below vm.clean_file_low_kbytes *unless* we threaten to OOM or have no swap 59 | +space or vm.swappiness=0. 60 | + 61 | +Protection of clean file pages may be used to prevent thrashing and 62 | +reducing I/O under low-memory conditions. 63 | + 64 | +The default value is 250000. 65 | + 66 | +============================================================== 67 | + 68 | +clean_file_min_kbytes 69 | + 70 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 71 | +*hard* protection of clean file pages. The clean file pages on the current 72 | +node won't be reclaimed under memory pressure when their volume is below 73 | +vm.clean_file_min_kbytes. 74 | + 75 | +Hard protection of clean file pages may be used to avoid high latency and 76 | +prevent livelock in near-OOM conditions. 77 | + 78 | +The default value is 200000. 79 | + 80 | +============================================================== 81 | + 82 | compact_memory 83 | 84 | Available only when CONFIG_COMPACTION is set. When 1 is written to the file, 85 | diff --git a/include/linux/mm.h b/include/linux/mm.h 86 | index 0416a7204..be4b0b649 100644 87 | --- a/include/linux/mm.h 88 | +++ b/include/linux/mm.h 89 | @@ -129,6 +129,11 @@ extern int sysctl_max_map_count; 90 | extern unsigned long sysctl_user_reserve_kbytes; 91 | extern unsigned long sysctl_admin_reserve_kbytes; 92 | 93 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 94 | +extern unsigned long sysctl_clean_file_low_kbytes; 95 | +extern unsigned long sysctl_clean_file_min_kbytes; 96 | +#endif 97 | + 98 | extern int sysctl_overcommit_memory; 99 | extern int sysctl_overcommit_ratio; 100 | extern unsigned long sysctl_overcommit_kbytes; 101 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 102 | index cc02050fd..d13836c42 100644 103 | --- a/kernel/sysctl.c 104 | +++ b/kernel/sysctl.c 105 | @@ -119,6 +119,19 @@ extern int sysctl_nr_trim_pages; 106 | static int sixty = 60; 107 | #endif 108 | 109 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 110 | +#if CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES < 0 111 | +#error "CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES should be >= 0" 112 | +#endif 113 | +#if CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES < 0 114 | +#error "CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES should be >= 0" 115 | +#endif 116 | +unsigned long sysctl_clean_file_low_kbytes __read_mostly = 117 | + CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES; 118 | +unsigned long sysctl_clean_file_min_kbytes __read_mostly = 119 | + CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES; 120 | +#endif 121 | + 122 | static int __maybe_unused neg_one = -1; 123 | 124 | static int zero; 125 | @@ -1628,6 +1641,22 @@ static struct ctl_table vm_table[] = { 126 | .extra2 = &one, 127 | }, 128 | #endif 129 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 130 | + { 131 | + .procname = "clean_file_low_kbytes", 132 | + .data = &sysctl_clean_file_low_kbytes, 133 | + .maxlen = sizeof(sysctl_clean_file_low_kbytes), 134 | + .mode = 0644, 135 | + .proc_handler = proc_doulongvec_minmax, 136 | + }, 137 | + { 138 | + .procname = "clean_file_min_kbytes", 139 | + .data = &sysctl_clean_file_min_kbytes, 140 | + .maxlen = sizeof(sysctl_clean_file_min_kbytes), 141 | + .mode = 0644, 142 | + .proc_handler = proc_doulongvec_minmax, 143 | + }, 144 | +#endif 145 | { 146 | .procname = "user_reserve_kbytes", 147 | .data = &sysctl_user_reserve_kbytes, 148 | diff --git a/mm/Kconfig b/mm/Kconfig 149 | index de64ea658..a198fe2b0 100644 150 | --- a/mm/Kconfig 151 | +++ b/mm/Kconfig 152 | @@ -64,6 +64,40 @@ config SPARSEMEM_MANUAL 153 | 154 | endchoice 155 | 156 | +config PROTECT_CLEAN_FILE 157 | + bool "Add sysctl knobs for protecting clean file pages under low memory" 158 | + depends on SYSCTL 159 | + default y 160 | + help 161 | + Protection of clean file pages may be used to prevent thrashing 162 | + and reduce I/O under memory pressure. Hard protection of clean file 163 | + pages may be used to avoid high latency and prevent livelock in 164 | + near-OOM conditions. 165 | + 166 | + This option provides two sysctl knobs for protecting clean file pages 167 | + under memory pressure. 168 | + 169 | +config PROTECT_CLEAN_FILE_LOW_KBYTES 170 | + int "Default value for vm.clean_file_low_kbytes" 171 | + depends on PROTECT_CLEAN_FILE 172 | + default "250000" 173 | + help 174 | + The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 175 | + protection of clean file pages. The clean file pages on the current 176 | + node won't be reclaimed uder memory pressure when their volume is 177 | + below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 178 | + no swap space or vm.swappiness=0. 179 | + 180 | +config PROTECT_CLEAN_FILE_MIN_KBYTES 181 | + int "Default value for vm.clean_file_min_kbytes" 182 | + depends on PROTECT_CLEAN_FILE 183 | + default "200000" 184 | + help 185 | + The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 186 | + of clean file pages. The clean file pages on the current node won't be 187 | + reclaimed under memory pressure when their volume is below 188 | + vm.clean_file_min_kbytes. 189 | + 190 | config DISCONTIGMEM 191 | def_bool y 192 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 193 | diff --git a/mm/vmscan.c b/mm/vmscan.c 194 | index c5ef7240c..070aedd53 100644 195 | --- a/mm/vmscan.c 196 | +++ b/mm/vmscan.c 197 | @@ -2294,6 +2294,20 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 198 | unsigned long anon, file; 199 | unsigned long ap, fp; 200 | enum lru_list lru; 201 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 202 | + unsigned long node_file, node_dirty, node_clean; 203 | + bool clean_file_below_low, clean_file_below_min; 204 | + 205 | + node_dirty = node_page_state(pgdat, NR_FILE_DIRTY); 206 | + node_file = node_page_state(pgdat, NR_ACTIVE_FILE) + 207 | + node_page_state(pgdat, NR_INACTIVE_FILE); 208 | + 209 | + if (node_file > node_dirty) 210 | + node_clean = (node_file - node_dirty) << (PAGE_SHIFT - 10); 211 | + 212 | + clean_file_below_low = node_clean <= sysctl_clean_file_low_kbytes; 213 | + clean_file_below_min = node_clean <= sysctl_clean_file_min_kbytes; 214 | +#endif 215 | 216 | /* If we have no swap space, do not bother scanning anon pages. */ 217 | if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) { 218 | @@ -2365,6 +2379,18 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 219 | } 220 | } 221 | 222 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 223 | + /* 224 | + * Force-scan anon if clean file pages is under vm.clean_file_min_kbytes 225 | + * or vm.clean_file_low_kbytes (unless the swappiness setting 226 | + * disagrees with swapping). 227 | + */ 228 | + if ((clean_file_below_low || clean_file_below_min) && swappiness) { 229 | + scan_balance = SCAN_ANON; 230 | + goto out; 231 | + } 232 | +#endif 233 | + 234 | /* 235 | * If there is enough inactive page cache, i.e. if the size of the 236 | * inactive list is greater than that of the active list *and* the 237 | @@ -2473,6 +2499,15 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 238 | BUG(); 239 | } 240 | 241 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 242 | + /* 243 | + * Don't reclaim clean file pages when their volume is below 244 | + * vm.clean_file_min_kbytes. 245 | + */ 246 | + if (file && clean_file_below_min) 247 | + scan = 0; 248 | +#endif 249 | + 250 | *lru_pages += size; 251 | nr[lru] = scan; 252 | } 253 | -- 254 | 2.11.0 255 | 256 | -------------------------------------------------------------------------------- /obsolete/le9cb_patches/le9cb2-5.4.patch: -------------------------------------------------------------------------------- 1 | From 3865cdf9e06e511540b84809fd8a367a6c25ea91 Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 29 Mar 2021 01:17:05 +0900 4 | Subject: [PATCH] mm: Protect clean file pages under memory pressure 5 | 6 | The patch provides sysctl knobs for protecting clean file pages 7 | during low-memory conditions. 8 | 9 | Protection of clean file pages may be used to prevent thrashing and 10 | reducing I/O under memory pressure. Hard protection of clean file 11 | pages may be used to avoid high latency and prevent livelock in 12 | near-OOM conditions. 13 | 14 | The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 15 | protection of clean file pages. The clean file pages on the current 16 | node won't be reclaimed uder memory pressure when their volume is 17 | below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 18 | no swap space or vm.swappiness=0. 19 | The default value is 250000. 20 | 21 | The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 22 | of clean file pages. The clean file pages on the current node won't 23 | be reclaimed under memory pressure when their volume is below 24 | vm.file_min_kbytes. 25 | The default value is 200000. 26 | 27 | Signed-off-by: Alexey Avramov 28 | --- 29 | Documentation/admin-guide/sysctl/vm.rst | 31 +++++++++++++++++++++++++++++ 30 | include/linux/mm.h | 5 +++++ 31 | kernel/sysctl.c | 29 +++++++++++++++++++++++++++ 32 | mm/Kconfig | 34 ++++++++++++++++++++++++++++++++ 33 | mm/vmscan.c | 35 +++++++++++++++++++++++++++++++++ 34 | 5 files changed, 134 insertions(+) 35 | 36 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 37 | index 64aeee100..506c6e0fb 100644 38 | --- a/Documentation/admin-guide/sysctl/vm.rst 39 | +++ b/Documentation/admin-guide/sysctl/vm.rst 40 | @@ -26,6 +26,8 @@ Currently, these files are in /proc/sys/vm: 41 | 42 | - admin_reserve_kbytes 43 | - block_dump 44 | +- clean_file_low_kbytes 45 | +- clean_file_min_kbytes 46 | - compact_memory 47 | - compact_unevictable_allowed 48 | - dirty_background_bytes 49 | @@ -111,6 +113,35 @@ block_dump enables block I/O debugging when set to a nonzero value. More 50 | information on block I/O debugging is in Documentation/admin-guide/laptops/laptop-mode.rst. 51 | 52 | 53 | +clean_file_low_kbytes 54 | +===================== 55 | + 56 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 57 | +*best-effort* protection of clean file pages. The clean file pages on the 58 | +current node won't be reclaimed uder memory pressure when their volume is 59 | +below vm.clean_file_low_kbytes *unless* we threaten to OOM or have no swap 60 | +space or vm.swappiness=0. 61 | + 62 | +Protection of clean file pages may be used to prevent thrashing and 63 | +reducing I/O under low-memory conditions. 64 | + 65 | +The default value is 250000. 66 | + 67 | + 68 | +clean_file_min_kbytes 69 | +===================== 70 | + 71 | +Available only when CONFIG_PROTECT_CLEAN_FILE is set. This knob provides 72 | +*hard* protection of clean file pages. The clean file pages on the current 73 | +node won't be reclaimed under memory pressure when their volume is below 74 | +vm.clean_file_min_kbytes. 75 | + 76 | +Hard protection of clean file pages may be used to avoid high latency and 77 | +prevent livelock in near-OOM conditions. 78 | + 79 | +The default value is 200000. 80 | + 81 | + 82 | compact_memory 83 | ============== 84 | 85 | diff --git a/include/linux/mm.h b/include/linux/mm.h 86 | index a2adf95b3..16780ad31 100644 87 | --- a/include/linux/mm.h 88 | +++ b/include/linux/mm.h 89 | @@ -201,6 +201,11 @@ extern int sysctl_max_map_count; 90 | extern unsigned long sysctl_user_reserve_kbytes; 91 | extern unsigned long sysctl_admin_reserve_kbytes; 92 | 93 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 94 | +extern unsigned long sysctl_clean_file_low_kbytes; 95 | +extern unsigned long sysctl_clean_file_min_kbytes; 96 | +#endif 97 | + 98 | extern int sysctl_overcommit_memory; 99 | extern int sysctl_overcommit_ratio; 100 | extern unsigned long sysctl_overcommit_kbytes; 101 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 102 | index b6f2f35d0..ce3bf4bf9 100644 103 | --- a/kernel/sysctl.c 104 | +++ b/kernel/sysctl.c 105 | @@ -124,6 +124,19 @@ extern int sysctl_nr_trim_pages; 106 | static int sixty = 60; 107 | #endif 108 | 109 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 110 | +#if CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES < 0 111 | +#error "CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES should be >= 0" 112 | +#endif 113 | +#if CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES < 0 114 | +#error "CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES should be >= 0" 115 | +#endif 116 | +unsigned long sysctl_clean_file_low_kbytes __read_mostly = 117 | + CONFIG_PROTECT_CLEAN_FILE_LOW_KBYTES; 118 | +unsigned long sysctl_clean_file_min_kbytes __read_mostly = 119 | + CONFIG_PROTECT_CLEAN_FILE_MIN_KBYTES; 120 | +#endif 121 | + 122 | static int __maybe_unused neg_one = -1; 123 | static int __maybe_unused two = 2; 124 | static int __maybe_unused four = 4; 125 | @@ -1694,6 +1707,22 @@ static struct ctl_table vm_table[] = { 126 | .extra2 = SYSCTL_ONE, 127 | }, 128 | #endif 129 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 130 | + { 131 | + .procname = "clean_file_low_kbytes", 132 | + .data = &sysctl_clean_file_low_kbytes, 133 | + .maxlen = sizeof(sysctl_clean_file_low_kbytes), 134 | + .mode = 0644, 135 | + .proc_handler = proc_doulongvec_minmax, 136 | + }, 137 | + { 138 | + .procname = "clean_file_min_kbytes", 139 | + .data = &sysctl_clean_file_min_kbytes, 140 | + .maxlen = sizeof(sysctl_clean_file_min_kbytes), 141 | + .mode = 0644, 142 | + .proc_handler = proc_doulongvec_minmax, 143 | + }, 144 | +#endif 145 | { 146 | .procname = "user_reserve_kbytes", 147 | .data = &sysctl_user_reserve_kbytes, 148 | diff --git a/mm/Kconfig b/mm/Kconfig 149 | index a5dae9a7e..49677b2d4 100644 150 | --- a/mm/Kconfig 151 | +++ b/mm/Kconfig 152 | @@ -63,6 +63,40 @@ config SPARSEMEM_MANUAL 153 | 154 | endchoice 155 | 156 | +config PROTECT_CLEAN_FILE 157 | + bool "Add sysctl knobs for protecting clean file pages under low memory" 158 | + depends on SYSCTL 159 | + default y 160 | + help 161 | + Protection of clean file pages may be used to prevent thrashing 162 | + and reduce I/O under memory pressure. Hard protection of clean file 163 | + pages may be used to avoid high latency and prevent livelock in 164 | + near-OOM conditions. 165 | + 166 | + This option provides two sysctl knobs for protecting clean file pages 167 | + under memory pressure. 168 | + 169 | +config PROTECT_CLEAN_FILE_LOW_KBYTES 170 | + int "Default value for vm.clean_file_low_kbytes" 171 | + depends on PROTECT_CLEAN_FILE 172 | + default "250000" 173 | + help 174 | + The vm.clean_file_low_kbytes sysctl knob provides *best-effort* 175 | + protection of clean file pages. The clean file pages on the current 176 | + node won't be reclaimed uder memory pressure when their volume is 177 | + below vm.clean_file_low_kbytes *unless* we threaten to OOM or have 178 | + no swap space or vm.swappiness=0. 179 | + 180 | +config PROTECT_CLEAN_FILE_MIN_KBYTES 181 | + int "Default value for vm.clean_file_min_kbytes" 182 | + depends on PROTECT_CLEAN_FILE 183 | + default "200000" 184 | + help 185 | + The vm.clean_file_min_kbytes sysctl knob provides *hard* protection 186 | + of clean file pages. The clean file pages on the current node won't be 187 | + reclaimed under memory pressure when their volume is below 188 | + vm.clean_file_min_kbytes. 189 | + 190 | config DISCONTIGMEM 191 | def_bool y 192 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 193 | diff --git a/mm/vmscan.c b/mm/vmscan.c 194 | index ee4eecc7e..225306f36 100644 195 | --- a/mm/vmscan.c 196 | +++ b/mm/vmscan.c 197 | @@ -2315,6 +2315,20 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 198 | unsigned long anon, file; 199 | unsigned long ap, fp; 200 | enum lru_list lru; 201 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 202 | + unsigned long node_file, node_dirty, node_clean; 203 | + bool clean_file_below_low, clean_file_below_min; 204 | + 205 | + node_dirty = node_page_state(pgdat, NR_FILE_DIRTY); 206 | + node_file = node_page_state(pgdat, NR_ACTIVE_FILE) + 207 | + node_page_state(pgdat, NR_INACTIVE_FILE); 208 | + 209 | + if (node_file > node_dirty) 210 | + node_clean = (node_file - node_dirty) << (PAGE_SHIFT - 10); 211 | + 212 | + clean_file_below_low = node_clean <= sysctl_clean_file_low_kbytes; 213 | + clean_file_below_min = node_clean <= sysctl_clean_file_min_kbytes; 214 | +#endif 215 | 216 | /* If we have no swap space, do not bother scanning anon pages. */ 217 | if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) { 218 | @@ -2386,6 +2400,18 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 219 | } 220 | } 221 | 222 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 223 | + /* 224 | + * Force-scan anon if clean file pages is under vm.clean_file_min_kbytes 225 | + * or vm.clean_file_low_kbytes (unless the swappiness setting 226 | + * disagrees with swapping). 227 | + */ 228 | + if ((clean_file_below_low || clean_file_below_min) && swappiness) { 229 | + scan_balance = SCAN_ANON; 230 | + goto out; 231 | + } 232 | +#endif 233 | + 234 | /* 235 | * If there is enough inactive page cache, i.e. if the size of the 236 | * inactive list is greater than that of the active list *and* the 237 | @@ -2549,6 +2575,15 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 238 | BUG(); 239 | } 240 | 241 | +#if defined(CONFIG_PROTECT_CLEAN_FILE) 242 | + /* 243 | + * Don't reclaim clean file pages when their volume is below 244 | + * vm.clean_file_min_kbytes. 245 | + */ 246 | + if (file && clean_file_below_min) 247 | + scan = 0; 248 | +#endif 249 | + 250 | *lru_pages += lruvec_size; 251 | nr[lru] = scan; 252 | } 253 | -- 254 | 2.11.0 255 | 256 | -------------------------------------------------------------------------------- /obsolete/le9da_patches/README.md: -------------------------------------------------------------------------------- 1 | 2 | # le9da patches 3 | 4 | `le9da*-5.10` patches may be correctly applied to Linux 5.10—5.12-rc6. 5 | 6 | The `vm.clean_low_kbytes` sysctl knob provides *best-effort* protection of clean file pages. The clean file pages on the current node won't be reclaimed under memory pressure when their amount is below `vm.clean_low_kbytes` *unless* we threaten to OOM or have no free swap space or vm.swappiness=0. 7 | 8 | The `vm.clean_min_kbytes` sysctl knob provides *hard* protection of clean file pages. The clean file pages on the current node won't be reclaimed under memory pressure when their amount is below `vm.clean_min_kbytes`. 9 | 10 | The `le9da0`, `le9da1`, `le9da2` patches differ only in the default values. 11 | 12 | `le9da0` just provides two sysctl knobs with 0 values and does not protect clean file pages by default. 13 | 14 | `le9da1` provides only soft protection by default (`vm.clean_low_kbytes=150000`, `vm.clean_min_kbytes=0`). This patch may be safly used by default. 15 | 16 | `le9da2` provides hard protection of clean file pages by default (`vm.clean_low_kbytes=250000`, `vm.clean_min_kbytes=200000`). 17 | 18 | -------------------------------------------------------------------------------- /obsolete/le9db_patches/README.md: -------------------------------------------------------------------------------- 1 | 2 | # le9db patch 3 | 4 | The patches provide sysctl knobs for protecting the specified amount of clean file pages (CFP) under memory pressure. 5 | 6 | The kernel does not have a mechanism for selectively protecting clean file pages. A certain amount of the CFP is required by the userspace for normal operation. First of all, you need a cache of shared libraries and executable files. If the volume of the CFP cache falls below a certain level, thrashing and even livelock occurs. 7 | 8 | Protection of CFP may be used to prevent thrashing and reducing I/O under memory pressure. Hard protection of CFP may be used to avoid high latency and prevent livelock in near-OOM conditions. The patch provides sysctl knobs for protecting the specified amount of clean file cache under memory pressure. 9 | 10 | The `vm.clean_low_kbytes` sysctl knob provides *best-effort* protection of CFP. The CFP on the current node won't be reclaimed under memory pressure when their amount is below `vm.clean_low_kbytes` *unless* we threaten to OOM or have no free swap space or vm.swappiness=0. Setting it to a high value may result in a early eviction of anonymous pages into the swap space by attempting to hold the protected amount of clean file pages in memory. The default value is defined by `CONFIG_CLEAN_LOW_KBYTES`. 11 | 12 | The `vm.clean_min_kbytes` sysctl knob provides *hard* protection of CFP. The CFP on the current node won't be reclaimed under memory pressure when their amount is below `vm.clean_min_kbytes`. Setting it to a high value may result in a early out-of-memory condition due to the inability to reclaim the protected amount of CFP when other types of pages cannot be reclaimed. The default value is defined by `CONFIG_CLEAN_MIN_KBYTES`. 13 | 14 | - `le9db-4.14.patch` may be correctly applied to vanilla Linux 4.14; 15 | - `le9db-4.19.patch` may be correctly applied to vanilla Linux 4.19; 16 | - `le9db-5.4.patch` may be correctly applied to vanilla Linux 5.4; 17 | - `le9db-5.10.patch` may be correctly applied to vanilla Linux 5.10—5.13; 18 | - `le9db-5.14-rc1.patch` may be correctly applied to vanilla Linux 5.14-rc1. 19 | 20 | `le9db` patches provide two sysctl knobs with 0 values and does not protect clean file pages by default (`CONFIG_CLEAN_LOW_KBYTES=0`, `CONFIG_CLEAN_MIN_KBYTES=0`). 21 | 22 | -------------------------------------------------------------------------------- /obsolete/le9ea_patches/README.md: -------------------------------------------------------------------------------- 1 | 2 | # le9ea patch 3 | 4 | The kernel does not provide a way to protect the working set under memory pressure. A certain amount of anonymous and clean file pages is required by the userspace for normal operation. First of all, the userspace needs a cache of shared libraries and executable binaries. If the amount of the clean file pages falls below a certain level, then thrashing and even livelock can take place. The patch provides sysctl knobs for protecting the working set (anonymous and clean file pages) under memory pressure. Protection of clean file pages may be used to prevent thrashing and reducing I/O under memory pressure. Hard protection of clean file pages may be used to avoid high latency and prevent livelock in near-OOM conditions. 5 | 6 | The `vm.anon_min_kbytes` sysctl knob provides *hard* protection of anonymous pages. The anonymous pages on the current node won't be reclaimed under any conditions when their amount is below `vm.anon_min_kbytes`. The default value is defined by `CONFIG_ANON_MIN_KBYTES` (suggested 0 in Kconfig). 7 | 8 | The `vm.clean_low_kbytes` sysctl knob provides *best-effort* protection of clean file pages. The clean file pages on the current node won't be reclaimed under memory pressure when their amount is below `vm.clean_low_kbytes` *unless* we threaten to OOM or have no free swap space or vm.swappiness=0. Setting it to a high value may result in a early eviction of anonymous pages into the swap space by attempting to hold the protected amount of clean file pages in memory. The default value is defined by `CONFIG_CLEAN_LOW_KBYTES` (suggested 0 in Kconfig). 9 | 10 | The `vm.clean_min_kbytes` sysctl knob provides *hard* protection of clean file pages. The clean file pages on the current node won't be reclaimed under memory pressure when their amount is below `vm.clean_min_kbytes`. Setting it to a high value may result in a early out-of-memory condition due to the inability to reclaim the protected amount of clean file pages when other types of pages cannot be reclaimed. The default value is defined by `CONFIG_CLEAN_MIN_KBYTES` (suggested 0 in Kconfig). 11 | -------------------------------------------------------------------------------- /obsolete/le9eb_patches/README.md: -------------------------------------------------------------------------------- 1 | 2 | # le9eb patch 3 | 4 | The kernel does not provide a way to protect the [working set](https://en.wikipedia.org/wiki/Working_set) under memory pressure. A certain amount of anonymous and clean file pages is required by the userspace for normal operation. First of all, the userspace needs a cache of shared libraries and executable binaries. If the amount of the clean file pages falls below a certain level, then [thrashing](https://en.wikipedia.org/wiki/Thrashing_(computer_science)) and even [livelock](https://en.wikipedia.org/wiki/Deadlock#Livelock) can take place. 5 | 6 | The patch provides sysctl knobs for protecting the working set (anonymous and clean file pages) under memory pressure. 7 | 8 | The `vm.anon_min_kbytes` sysctl knob provides *hard* protection of anonymous pages. The anonymous pages on the current node won't be reclaimed under any conditions when their amount is below `vm.anon_min_kbytes`. This knob may be used to prevent excessive swap thrashing when anonymous memory is low (for example, when memory is going to be overfilled by compressed data of zram module). 9 | 10 | The `vm.clean_low_kbytes` sysctl knob provides *best-effort* protection of clean file pages. The clean file pages on the current node won't be reclaimed under memory pressure when their amount is below `vm.clean_low_kbytes` *unless* we threaten to OOM or have no free swap space or vm.swappiness=0. Protection of clean file pages using this knob may be used when swapping is still possible to 11 | - prevent disk I/O thrashing under memory pressure; 12 | - improve performance in disk cache-bound tasks under memory pressure. 13 | 14 | The `vm.clean_min_kbytes` sysctl knob provides *hard* protection of clean file pages. The clean file pages on the current node won't be reclaimed under memory pressure when their amount is below `vm.clean_min_kbytes`. Hard protection of clean file pages using this knob may be used to 15 | - prevent disk I/O thrashing under memory pressure even with no swap space; 16 | - improve performance in disk cache-bound tasks under memory pressure; 17 | - avoid high latency and prevent livelock in near-OOM conditions. 18 | 19 | `le9eb` patches provide three sysctl knobs with 0 values and does not protect the working set by default (`CONFIG_ANON_MIN_KBYTES=0`, `CONFIG_CLEAN_LOW_KBYTES=0`, `CONFIG_CLEAN_MIN_KBYTES=0`). 20 | 21 | - `le9eb-4.14.patch` may be correctly applied to vanilla Linux 4.14; 22 | - `le9eb-4.19.patch` may be correctly applied to vanilla Linux 4.19; 23 | - `le9eb-5.4.patch` may be correctly applied to vanilla Linux 5.4; 24 | - `le9eb-5.10.patch` may be correctly applied to vanilla Linux 5.10—5.13; 25 | - `le9eb-5.13-rc2-MGLRU.patch` may be correctly applied to Linux 5.13 with [mgLRU patchset v3](https://lore.kernel.org/lkml/20210520065355.2736558-1-yuzhao@google.com/) applied (note that enabling mgLRU disables le9 effects); 26 | - `le9eb-5.14-rc1.patch` may be correctly applied (at least) to vanilla Linux 5.14-rc1; 27 | - `le9eb-5.14-rc6-MGLRU.patch` may be correctly applied to Linux 5.14 with [mgLRU patchset v4](https://lore.kernel.org/lkml/20210818063107.2696454-1-yuzhao@google.com/) applied (note that enabling mgLRU disables le9 effects). 28 | 29 | -------------------------------------------------------------------------------- /obsolete/le9pf-5.10.patch: -------------------------------------------------------------------------------- 1 | From 70ff8bcc2f39e05e93ffedfe168811f4d9fbc88c Mon Sep 17 00:00:00 2001 2 | From: Alexey Avramov 3 | Date: Mon, 21 Dec 2020 20:36:32 +0900 4 | Subject: [PATCH] Set minimum unevictable Active(file)/Inactive(file) values 5 | 6 | Set minimum Active(file) and Inactive(file) values to never be evicted under 7 | low-memory conditions to prevent thrashing and improve system responsiveness. 8 | 9 | Homepage: https://github.com/hakavlad/le9-patch 10 | --- 11 | Documentation/admin-guide/sysctl/vm.rst | 23 +++++++++++++++++ 12 | kernel/sysctl.c | 37 ++++++++++++++++++++++++++ 13 | mm/Kconfig | 46 +++++++++++++++++++++++++++++++++ 14 | mm/vmscan.c | 33 +++++++++++++++++++++++ 15 | 4 files changed, 139 insertions(+) 16 | 17 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 18 | index f455fa00c..265cabf6a 100644 19 | --- a/Documentation/admin-guide/sysctl/vm.rst 20 | +++ b/Documentation/admin-guide/sysctl/vm.rst 21 | @@ -69,6 +69,8 @@ Currently, these files are in /proc/sys/vm: 22 | - stat_refresh 23 | - numa_stat 24 | - swappiness 25 | +- unevictable_activefile_kbytes 26 | +- unevictable_inactivefile_kbytes 27 | - unprivileged_userfaultfd 28 | - user_reserve_kbytes 29 | - vfs_cache_pressure 30 | @@ -881,6 +883,27 @@ privileged users (with SYS_CAP_PTRACE capability). 31 | The default value is 1. 32 | 33 | 34 | +unevictable_activefile_kbytes 35 | +============================= 36 | + 37 | +Keep some active file pages still mapped under memory pressure to avoid 38 | +potential disk thrashing that may occur due to evicting running executables 39 | +code. 40 | + 41 | +Setting it to 0 effectively disables this feature. 42 | + 43 | +The default value is 256 MiB. 44 | + 45 | + 46 | +unevictable_inactivefile_kbytes 47 | +=============================== 48 | + 49 | +This knob is for inactive file pages. See unevictable_activefile_kbytes 50 | +for more details. 51 | + 52 | +The feature is disabled by default. 53 | + 54 | + 55 | user_reserve_kbytes 56 | =================== 57 | 58 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 59 | index afad08596..f46f2dbed 100644 60 | --- a/kernel/sysctl.c 61 | +++ b/kernel/sysctl.c 62 | @@ -111,6 +111,25 @@ 63 | static int sixty = 60; 64 | #endif 65 | 66 | +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) 67 | +unsigned long sysctl_unevictable_activefile_kbytes __read_mostly = 68 | +#if CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES < 0 69 | +#error "CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES should be >= 0" 70 | +#else 71 | + CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES 72 | +#endif 73 | +; 74 | +#endif 75 | +#if defined(CONFIG_UNEVICTABLE_INACTIVEFILE) 76 | +unsigned long sysctl_unevictable_inactivefile_kbytes __read_mostly = 77 | +#if CONFIG_UNEVICTABLE_INACTIVEFILE_KBYTES < 0 78 | +#error "CONFIG_UNEVICTABLE_INACTIVEFILE_KBYTES should be >= 0" 79 | +#else 80 | + CONFIG_UNEVICTABLE_INACTIVEFILE_KBYTES 81 | +#endif 82 | +; 83 | +#endif 84 | + 85 | static int __maybe_unused neg_one = -1; 86 | static int __maybe_unused two = 2; 87 | static int __maybe_unused four = 4; 88 | @@ -3082,6 +3101,24 @@ static struct ctl_table vm_table[] = { 89 | .extra2 = SYSCTL_ONE, 90 | }, 91 | #endif 92 | +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) 93 | + { 94 | + .procname = "unevictable_activefile_kbytes", 95 | + .data = &sysctl_unevictable_activefile_kbytes, 96 | + .maxlen = sizeof(sysctl_unevictable_activefile_kbytes), 97 | + .mode = 0644, 98 | + .proc_handler = proc_doulongvec_minmax, 99 | + }, 100 | +#endif 101 | +#if defined(CONFIG_UNEVICTABLE_INACTIVEFILE) 102 | + { 103 | + .procname = "unevictable_inactivefile_kbytes", 104 | + .data = &sysctl_unevictable_inactivefile_kbytes, 105 | + .maxlen = sizeof(sysctl_unevictable_inactivefile_kbytes), 106 | + .mode = 0644, 107 | + .proc_handler = proc_doulongvec_minmax, 108 | + }, 109 | +#endif 110 | { 111 | .procname = "user_reserve_kbytes", 112 | .data = &sysctl_user_reserve_kbytes, 113 | diff --git a/mm/Kconfig b/mm/Kconfig 114 | index 390165ffb..0b1047994 100644 115 | --- a/mm/Kconfig 116 | +++ b/mm/Kconfig 117 | @@ -63,6 +63,52 @@ config SPARSEMEM_MANUAL 118 | 119 | endchoice 120 | 121 | +config UNEVICTABLE_ACTIVEFILE 122 | + bool "Keep some active file pages under memory pressure" 123 | + depends on SYSCTL 124 | + def_bool y 125 | + help 126 | + Keep some active file pages still mapped under memory pressure to avoid 127 | + potential disk thrashing that may occur due to evicting running executables 128 | + code. 129 | + 130 | + The UNEVICTABLE_ACTIVEFILE_KBYTES value sets the amount of pages to keep 131 | + by default (in KiB). The vm.unevictable_activefile_kbytes sysctl knob is used 132 | + to change the amount in the runtime (setting it to 0 effectively disables 133 | + this feature). 134 | + 135 | + Recommended value: 262144 for typical desktop workload. 136 | + 137 | + See also: Documentation/admin-guide/sysctl/vm.rst 138 | + 139 | +config UNEVICTABLE_ACTIVEFILE_KBYTES 140 | + int "Default value for vm.unevictable_activefile_kbytes" 141 | + depends on UNEVICTABLE_ACTIVEFILE 142 | + default "262144" 143 | + 144 | +config UNEVICTABLE_INACTIVEFILE 145 | + bool "Keep some inactive file pages under memory pressure" 146 | + depends on SYSCTL 147 | + def_bool y 148 | + help 149 | + Keep some inactive file pages still mapped under memory pressure to avoid 150 | + potential disk thrashing that may occur due to evicting running executables 151 | + code. 152 | + 153 | + The UNEVICTABLE_INACTIVEFILE_KBYTES value sets the amount of pages to keep 154 | + by default (in KiB). The vm.unevictable_inactivefile_kbytes sysctl knob is used 155 | + to change the amount in the runtime (setting it to 0 effectively disables 156 | + this feature). 157 | + 158 | + Recommended value: 0 for typical desktop workload. 159 | + 160 | + See also: Documentation/admin-guide/sysctl/vm.rst 161 | + 162 | +config UNEVICTABLE_INACTIVEFILE_KBYTES 163 | + int "Default value for vm.unevictable_inactivefile_kbytes" 164 | + depends on UNEVICTABLE_INACTIVEFILE 165 | + default "0" 166 | + 167 | config DISCONTIGMEM 168 | def_bool y 169 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 170 | diff --git a/mm/vmscan.c b/mm/vmscan.c 171 | index 7b4e31eac..7bb5ae75e 100644 172 | --- a/mm/vmscan.c 173 | +++ b/mm/vmscan.c 174 | @@ -166,6 +166,14 @@ struct scan_control { 175 | #define prefetchw_prev_lru_page(_page, _base, _field) do { } while (0) 176 | #endif 177 | 178 | +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) 179 | +extern unsigned long sysctl_unevictable_activefile_kbytes; 180 | +#endif 181 | + 182 | +#if defined(CONFIG_UNEVICTABLE_INACTIVEFILE) 183 | +extern unsigned long sysctl_unevictable_inactivefile_kbytes; 184 | +#endif 185 | + 186 | /* 187 | * From 0 .. 200. Higher means more swappy. 188 | */ 189 | @@ -2225,6 +2233,11 @@ enum scan_balance { 190 | SCAN_FILE, 191 | }; 192 | 193 | +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) || \ 194 | + defined(CONFIG_UNEVICTABLE_INACTIVEFILE) 195 | +#define K(x) ((x) << (PAGE_SHIFT - 10)) 196 | +#endif 197 | + 198 | /* 199 | * Determine how aggressively the anon and file LRU lists should be 200 | * scanned. The relative value of each set of LRU lists is determined 201 | @@ -2418,6 +2432,28 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 202 | BUG(); 203 | } 204 | 205 | +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) 206 | + if (lru == LRU_ACTIVE_FILE) { 207 | + unsigned long kib_active_file_now = K(global_node_page_state(NR_ACTIVE_FILE)); 208 | + 209 | + if (kib_active_file_now <= sysctl_unevictable_activefile_kbytes) { 210 | + nr[lru] = 0; 211 | + continue; 212 | + } 213 | + } 214 | +#endif 215 | + 216 | +#if defined(CONFIG_UNEVICTABLE_INACTIVEFILE) 217 | + if (lru == LRU_INACTIVE_FILE) { 218 | + unsigned long kib_inactive_file_now = K(global_node_page_state(NR_INACTIVE_FILE)); 219 | + 220 | + if (kib_inactive_file_now <= sysctl_unevictable_inactivefile_kbytes) { 221 | + nr[lru] = 0; 222 | + continue; 223 | + } 224 | + } 225 | +#endif 226 | + 227 | nr[lru] = scan; 228 | } 229 | } 230 | -- 231 | 2.11.0 232 | 233 | -------------------------------------------------------------------------------- /obsolete/le9pf2-5.10.patch: -------------------------------------------------------------------------------- 1 | From 990ddacf8d6a475aaba52d930306ff023ea52d87 Mon Sep 17 00:00:00 2001 2 | From: Oleksandr Natalenko 3 | Date: Mon, 28 Dec 2020 12:48:07 +0100 4 | Subject: [PATCH] mm-5.11: protect file mappings under memory pressure 5 | 6 | Signed-off-by: Oleksandr Natalenko 7 | --- 8 | Documentation/admin-guide/sysctl/vm.rst | 27 +++++++++++++++++++ 9 | kernel/sysctl.c | 35 +++++++++++++++++++++++++ 10 | mm/Kconfig | 35 +++++++++++++++++++++++++ 11 | mm/vmscan.c | 22 ++++++++++++++++ 12 | 4 files changed, 119 insertions(+) 13 | 14 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 15 | index e35a3f2fb006..cfff03882dec 100644 16 | --- a/Documentation/admin-guide/sysctl/vm.rst 17 | +++ b/Documentation/admin-guide/sysctl/vm.rst 18 | @@ -69,6 +69,8 @@ Currently, these files are in /proc/sys/vm: 19 | - stat_refresh 20 | - numa_stat 21 | - swappiness 22 | +- unevictable_activefile_kbytes_low 23 | +- unevictable_activefile_kbytes_min 24 | - unprivileged_userfaultfd 25 | - user_reserve_kbytes 26 | - vfs_cache_pressure 27 | @@ -886,6 +888,31 @@ calls without any restrictions. 28 | The default value is 0. 29 | 30 | 31 | +unevictable_activefile_kbytes_low 32 | +================================= 33 | + 34 | +Keep some active file pages still mapped under memory pressure to avoid 35 | +potential disk thrashing that may occur due to evicting running executables 36 | +code. This implements soft eviction throttling, and some file pages can still 37 | +be discarded. 38 | + 39 | +Setting it to 0 effectively disables this feature. 40 | + 41 | +The default value is 512 MiB. 42 | + 43 | + 44 | +unevictable_activefile_kbytes_min 45 | +================================= 46 | + 47 | +Keep all active file pages still mapped under memory pressure to avoid 48 | +potential disk thrashing that may occur due to evicting running executables 49 | +code. This is the hard limit. 50 | + 51 | +Setting it to 0 effectively disables this feature. 52 | + 53 | +The default value is 256 MiB. 54 | + 55 | + 56 | user_reserve_kbytes 57 | =================== 58 | 59 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 60 | index c9fbdd848138..8d4f58a481f0 100644 61 | --- a/kernel/sysctl.c 62 | +++ b/kernel/sysctl.c 63 | @@ -111,6 +111,22 @@ 64 | static int sixty = 60; 65 | #endif 66 | 67 | +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) 68 | +#if CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES_LOW < 0 69 | +#error "CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES_LOW should be >= 0" 70 | +#endif 71 | +#if CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES_MIN < 0 72 | +#error "CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES_MIN should be >= 0" 73 | +#endif 74 | +#if CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES_LOW < CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES_MIN 75 | +#error "CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES_LOW should be >= CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES_MIN" 76 | +#endif 77 | +unsigned long sysctl_unevictable_activefile_kbytes_low __read_mostly = 78 | + CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES_LOW; 79 | +unsigned long sysctl_unevictable_activefile_kbytes_min __read_mostly = 80 | + CONFIG_UNEVICTABLE_ACTIVEFILE_KBYTES_MIN; 81 | +#endif 82 | + 83 | static int __maybe_unused neg_one = -1; 84 | static int __maybe_unused two = 2; 85 | static int __maybe_unused four = 4; 86 | @@ -3092,6 +3108,25 @@ static struct ctl_table vm_table[] = { 87 | .extra1 = SYSCTL_ZERO, 88 | .extra2 = SYSCTL_ONE, 89 | }, 90 | +#endif 91 | +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) 92 | + { 93 | + .procname = "unevictable_activefile_kbytes_low", 94 | + .data = &sysctl_unevictable_activefile_kbytes_low, 95 | + .maxlen = sizeof(sysctl_unevictable_activefile_kbytes_low), 96 | + .mode = 0644, 97 | + .proc_handler = proc_doulongvec_minmax, 98 | + .extra1 = &sysctl_unevictable_activefile_kbytes_min, 99 | + }, 100 | + { 101 | + .procname = "unevictable_activefile_kbytes_min", 102 | + .data = &sysctl_unevictable_activefile_kbytes_min, 103 | + .maxlen = sizeof(sysctl_unevictable_activefile_kbytes_min), 104 | + .mode = 0644, 105 | + .proc_handler = proc_doulongvec_minmax, 106 | + .extra1 = &zero_ul, 107 | + .extra2 = &sysctl_unevictable_activefile_kbytes_low, 108 | + }, 109 | #endif 110 | { 111 | .procname = "user_reserve_kbytes", 112 | diff --git a/mm/Kconfig b/mm/Kconfig 113 | index f730605b8dcf..5f4846c7de45 100644 114 | --- a/mm/Kconfig 115 | +++ b/mm/Kconfig 116 | @@ -63,6 +63,41 @@ config SPARSEMEM_MANUAL 117 | 118 | endchoice 119 | 120 | +config UNEVICTABLE_ACTIVEFILE 121 | + bool "Keep some active file pages under memory pressure" 122 | + depends on SYSCTL 123 | + def_bool y 124 | + help 125 | + Keep some active file pages still mapped under memory pressure to avoid 126 | + potential disk thrashing that may occur due to evicting running executables 127 | + code. 128 | + 129 | + The UNEVICTABLE_ACTIVEFILE_KBYTES_LOW value defines a threshold to activate 130 | + file pages eviction throttling. The vm.unevictable_activefile_kbytes_low 131 | + sysctl knob is used to change the amount in the runtime (setting it to 0 132 | + effectively disables this feature). 133 | + 134 | + Recommended value: 524288 for typical desktop workload. 135 | + 136 | + The UNEVICTABLE_ACTIVEFILE_KBYTES_MIN value sets the amount of pages to keep 137 | + as a hard limit. The vm.unevictable_activefile_kbytes_min sysctl knob is used 138 | + to change the amount in the runtime (setting it to 0 effectively disables 139 | + this feature). 140 | + 141 | + Recommended value: 262144 for typical desktop workload. 142 | + 143 | + See also: Documentation/admin-guide/sysctl/vm.rst 144 | + 145 | +config UNEVICTABLE_ACTIVEFILE_KBYTES_LOW 146 | + int "Default value for vm.unevictable_activefile_kbytes_low" 147 | + depends on UNEVICTABLE_ACTIVEFILE 148 | + default "524288" 149 | + 150 | +config UNEVICTABLE_ACTIVEFILE_KBYTES_MIN 151 | + int "Default value for vm.unevictable_activefile_kbytes_min" 152 | + depends on UNEVICTABLE_ACTIVEFILE 153 | + default "262144" 154 | + 155 | config DISCONTIGMEM 156 | def_bool y 157 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 158 | diff --git a/mm/vmscan.c b/mm/vmscan.c 159 | index 257cba79a96d..e4f4349fb3b3 100644 160 | --- a/mm/vmscan.c 161 | +++ b/mm/vmscan.c 162 | @@ -164,6 +164,11 @@ struct scan_control { 163 | #define prefetchw_prev_lru_page(_page, _base, _field) do { } while (0) 164 | #endif 165 | 166 | +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) 167 | +extern unsigned long sysctl_unevictable_activefile_kbytes_low; 168 | +extern unsigned long sysctl_unevictable_activefile_kbytes_min; 169 | +#endif 170 | + 171 | /* 172 | * From 0 .. 200. Higher means more swappy. 173 | */ 174 | @@ -2232,6 +2237,10 @@ enum scan_balance { 175 | SCAN_FILE, 176 | }; 177 | 178 | +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) 179 | +#define K(x) ((x) << (PAGE_SHIFT - 10)) 180 | +#endif 181 | + 182 | /* 183 | * Determine how aggressively the anon and file LRU lists should be 184 | * scanned. The relative value of each set of LRU lists is determined 185 | @@ -2425,6 +2434,19 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 186 | BUG(); 187 | } 188 | 189 | +#if defined(CONFIG_UNEVICTABLE_ACTIVEFILE) 190 | + if (lru == LRU_ACTIVE_FILE) { 191 | + unsigned long activefile_kbytes_now = K(global_node_page_state(NR_ACTIVE_FILE)); 192 | + unsigned long low_scan_granularity = SWAP_CLUSTER_MAX >> sc->priority; 193 | + 194 | + if (activefile_kbytes_now < sysctl_unevictable_activefile_kbytes_low && 195 | + activefile_kbytes_now > sysctl_unevictable_activefile_kbytes_min && 196 | + scan > low_scan_granularity) 197 | + scan = low_scan_granularity; 198 | + else if (activefile_kbytes_now <= sysctl_unevictable_activefile_kbytes_min) 199 | + scan = 0; 200 | + } 201 | +#endif 202 | nr[lru] = scan; 203 | } 204 | } 205 | -- 206 | GitLab 207 | 208 | -------------------------------------------------------------------------------- /obsolete/original_le9_patches/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakavlad/le9-patch/835d59774ccc19ed239b34f1d240a76febbe6005/obsolete/original_le9_patches/README.md -------------------------------------------------------------------------------- /obsolete/original_le9_patches/le9b.patch: -------------------------------------------------------------------------------- 1 | preliminary patch to avoid disk thrashing (constant reading) under memory pressure before OOM-killer triggers 2 | more info: https://gist.github.com/constantoverride/84eba764f487049ed642eb2111a20830 3 | 4 | diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h 5 | index 32699b2..7636498 100644 6 | --- a/include/linux/mmzone.h 7 | +++ b/include/linux/mmzone.h 8 | @@ -208,7 +208,7 @@ enum lru_list { 9 | 10 | #define for_each_lru(lru) for (lru = 0; lru < NR_LRU_LISTS; lru++) 11 | 12 | -#define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_ACTIVE_FILE; lru++) 13 | +#define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_INACTIVE_FILE; lru++) 14 | 15 | static inline int is_file_lru(enum lru_list lru) 16 | { 17 | diff --git a/mm/vmscan.c b/mm/vmscan.c 18 | index 03822f8..1f3ffb5 100644 19 | --- a/mm/vmscan.c 20 | +++ b/mm/vmscan.c 21 | @@ -2234,7 +2234,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 22 | 23 | anon = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON, MAX_NR_ZONES) + 24 | lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, MAX_NR_ZONES); 25 | - file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) + 26 | + file = //lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) + 27 | lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, MAX_NR_ZONES); 28 | 29 | spin_lock_irq(&pgdat->lru_lock); 30 | @@ -2345,7 +2345,7 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc 31 | sc->priority == DEF_PRIORITY); 32 | 33 | blk_start_plug(&plug); 34 | - while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || 35 | + while (nr[LRU_INACTIVE_ANON] || //nr[LRU_ACTIVE_FILE] || 36 | nr[LRU_INACTIVE_FILE]) { 37 | unsigned long nr_anon, nr_file, percentage; 38 | unsigned long nr_scanned; 39 | @@ -2372,7 +2372,8 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc 40 | * stop reclaiming one LRU and reduce the amount scanning 41 | * proportional to the original scan target. 42 | */ 43 | - nr_file = nr[LRU_INACTIVE_FILE] + nr[LRU_ACTIVE_FILE]; 44 | + nr_file = nr[LRU_INACTIVE_FILE] //+ nr[LRU_ACTIVE_FILE] 45 | + ; 46 | nr_anon = nr[LRU_INACTIVE_ANON] + nr[LRU_ACTIVE_ANON]; 47 | 48 | /* 49 | @@ -2391,7 +2392,8 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc 50 | percentage = nr_anon * 100 / scan_target; 51 | } else { 52 | unsigned long scan_target = targets[LRU_INACTIVE_FILE] + 53 | - targets[LRU_ACTIVE_FILE] + 1; 54 | + //targets[LRU_ACTIVE_FILE] + 55 | + 1; 56 | lru = LRU_FILE; 57 | percentage = nr_file * 100 / scan_target; 58 | } 59 | -------------------------------------------------------------------------------- /obsolete/original_le9_patches/le9d.patch: -------------------------------------------------------------------------------- 1 | revision 3 2 | preliminary patch to avoid disk thrashing (constant reading) under memory pressure before OOM-killer triggers 3 | more info: https://gist.github.com/constantoverride/84eba764f487049ed642eb2111a20830 4 | 5 | diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h 6 | index 32699b2..7636498 100644 7 | --- a/include/linux/mmzone.h 8 | +++ b/include/linux/mmzone.h 9 | @@ -208,7 +208,7 @@ enum lru_list { 10 | 11 | #define for_each_lru(lru) for (lru = 0; lru < NR_LRU_LISTS; lru++) 12 | 13 | -#define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_ACTIVE_FILE; lru++) 14 | +#define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_INACTIVE_FILE; lru++) 15 | 16 | static inline int is_file_lru(enum lru_list lru) 17 | { 18 | diff --git a/mm/vmscan.c b/mm/vmscan.c 19 | index 03822f8..1f3ffb5 100644 20 | --- a/mm/vmscan.c 21 | +++ b/mm/vmscan.c 22 | @@ -2086,9 +2086,9 @@ static unsigned long shrink_list(enum lr 23 | struct scan_control *sc) 24 | { 25 | if (is_active_lru(lru)) { 26 | - if (inactive_list_is_low(lruvec, is_file_lru(lru), 27 | - memcg, sc, true)) 28 | - shrink_active_list(nr_to_scan, lruvec, sc, lru); 29 | + //if (inactive_list_is_low(lruvec, is_file_lru(lru), 30 | + // memcg, sc, true)) 31 | + // shrink_active_list(nr_to_scan, lruvec, sc, lru); 32 | return 0; 33 | } 34 | 35 | @@ -2234,7 +2234,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 36 | 37 | anon = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON, MAX_NR_ZONES) + 38 | lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, MAX_NR_ZONES); 39 | - file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) + 40 | + file = //lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) + 41 | lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, MAX_NR_ZONES); 42 | 43 | spin_lock_irq(&pgdat->lru_lock); 44 | @@ -2345,7 +2345,7 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc 45 | sc->priority == DEF_PRIORITY); 46 | 47 | blk_start_plug(&plug); 48 | - while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || 49 | + while (nr[LRU_INACTIVE_ANON] || //nr[LRU_ACTIVE_FILE] || 50 | nr[LRU_INACTIVE_FILE]) { 51 | unsigned long nr_anon, nr_file, percentage; 52 | unsigned long nr_scanned; 53 | @@ -2372,7 +2372,8 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc 54 | * stop reclaiming one LRU and reduce the amount scanning 55 | * proportional to the original scan target. 56 | */ 57 | - nr_file = nr[LRU_INACTIVE_FILE] + nr[LRU_ACTIVE_FILE]; 58 | + nr_file = nr[LRU_INACTIVE_FILE] //+ nr[LRU_ACTIVE_FILE] 59 | + ; 60 | nr_anon = nr[LRU_INACTIVE_ANON] + nr[LRU_ACTIVE_ANON]; 61 | 62 | /* 63 | @@ -2391,7 +2392,8 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc 64 | percentage = nr_anon * 100 / scan_target; 65 | } else { 66 | unsigned long scan_target = targets[LRU_INACTIVE_FILE] + 67 | - targets[LRU_ACTIVE_FILE] + 1; 68 | + //targets[LRU_ACTIVE_FILE] + 69 | + 1; 70 | lru = LRU_FILE; 71 | percentage = nr_file * 100 / scan_target; 72 | } 73 | @@ -2409,10 +2411,12 @@ static void shrink_node_memcg(struct pgl 74 | nr[lru] = targets[lru] * (100 - percentage) / 100; 75 | nr[lru] -= min(nr[lru], nr_scanned); 76 | 77 | + if (LRU_FILE != lru) { //avoid this block for LRU_ACTIVE_FILE 78 | lru += LRU_ACTIVE; 79 | nr_scanned = targets[lru] - nr[lru]; 80 | nr[lru] = targets[lru] * (100 - percentage) / 100; 81 | nr[lru] -= min(nr[lru], nr_scanned); 82 | + } 83 | 84 | scan_adjusted = true; 85 | } 86 | -------------------------------------------------------------------------------- /obsolete/original_le9_patches/le9e.patch: -------------------------------------------------------------------------------- 1 | updated for kernel 5.1.0-rc5(almost rc6) commit 9e5de623a0cb9374bdcc73c0c098818f0d7ab7e9 2 | 3 | this le9e.patch is just le9d.patch with an added .config option 4 | Warning: Active(file) value got to 7306716 during the compile/install of the kernel! that is, without using drop_caches at all! I dno why I remember it never going over 4G maybe it was with a prev. patch?! 5 | With this option unset(# CONFIG_LE9D_PATCH is not set), it got to 5770568 kB ! 6 | 7 | from: https://github.com/CconEstaNntoSverOriRdeED/qubes-linux-kernel/blob/bbecb78ff38770367b0f1d18a1c860db401322c7/patches.addon/le9d.patch#L1 8 | Warning: you need to run `echo 1 | sudo tee /proc/sys/vm/drop_caches` periodically, or else you can run out of memory when you wouldn't have otherwise without this patch. But hey at least it doesn't freakin' freeze/crash your system! 9 | So you can expect Xorg and xfwm4 to get killed due to some filesystem caching(eg. during `sha256sum -c`) or during firefox compilation with output in /tmp (tmpfs) filled with 12-13G out of 16G total computer RAM. 10 | 11 | I'm personally running on xfce startup: xfce4-terminal -x freepagecachepages_automatically 1000000 12 | 13 | TODO: use this vmstat number(which is very different than /proc/meminfo one! eg. Active(file): 123524 kB): 14 | $ grep nr_active_file /proc/vmstat 15 | nr_active_file 29803 16 | ok Active(file) is actually 4 times more than nr_active_file (due to a << (PAGE_SHIFT - 10) which is <<2 see: fs/proc/meminfo.c func. show_val_kb ) 17 | 18 | WARNING: do NOT use this patch with swap enabled! because people who did experienced more disk thrashing and higher swap usage and quicker OOM-kills, as reported here: https://gist.github.com/CconEstaNntoSverOriRdeED/84eba764f487049ed642eb2111a20830#gistcomment-2779445 19 | I always have swap disabled! # CONFIG_SWAP is not set 20 | also perhaps sysctl settings matter? here were mine: https://github.com/CExftNSroxORgpxED/a3/tree/cd4a22fb54095fdf665c743c4c3476b433768209/system/Z575/OSes/3archlinux/on_baremetal/filesystem_now/archlinux/etc/sysctl.d 21 | 22 | revision 3 23 | preliminary patch to avoid disk thrashing (constant reading) under memory pressure before OOM-killer triggers 24 | more info: https://gist.github.com/CconEstaNntoSverOriRdeED/84eba764f487049ed642eb2111a20830 25 | 26 | diff --git a/mm/Kconfig b/mm/Kconfig 27 | index 25c71eb8a7db..abbda4e61514 100644 28 | --- a/mm/Kconfig 29 | +++ b/mm/Kconfig 30 | @@ -1,6 +1,25 @@ 31 | 32 | menu "Memory Management options" 33 | 34 | +config LE9D_PATCH 35 | + bool "Keep Active(file) pages in RAM even during low memory situations!" if EXPERT 36 | + default n 37 | + depends on !SWAP && IKCONFIG_PROC && EXPERT 38 | + help 39 | + Keep Active(file) pages in RAM so as to avoid system freeze due to the 40 | + disk thrashing(disk reading only) that occurrs because running 41 | + executables's code is being evicted during low-mem conditions which is 42 | + why it also prevent oom-killer from triggering until 10s of minutes later. 43 | + This allows scripts to check whether this patch was applied by looking 44 | + through /proc/config.gz 45 | + Can't see/use this option when you have CONFIG_SWAP enabled 46 | + or IKCONFIG_PROC not set. 47 | + Using this le9d.patch requires you to periodically do something like 48 | + 'echo 1 | sudo tee /proc/sys/vm/drop_caches' 49 | + otherwise you risk running out of memory and oom-killer triggering for 50 | + programs like Xorg or chromium. 51 | + 52 | + 53 | config SELECT_MEMORY_MODEL 54 | def_bool y 55 | depends on ARCH_SELECT_MEMORY_MODEL 56 | diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h 57 | index 842f9189537b..8a594b83148d 100644 58 | --- a/include/linux/mmzone.h 59 | +++ b/include/linux/mmzone.h 60 | @@ -210,7 +210,11 @@ enum lru_list { 61 | 62 | #define for_each_lru(lru) for (lru = 0; lru < NR_LRU_LISTS; lru++) 63 | 64 | -#define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_ACTIVE_FILE; lru++) 65 | +#ifdef CONFIG_LE9D_PATCH 66 | + #define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_INACTIVE_FILE; lru++) 67 | +#else //original 68 | + #define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_ACTIVE_FILE; lru++) 69 | +#endif 70 | 71 | static inline int is_file_lru(enum lru_list lru) 72 | { 73 | diff --git a/mm/vmscan.c b/mm/vmscan.c 74 | index e979705bbf32..2eaaec24cba3 100644 75 | --- a/mm/vmscan.c 76 | +++ b/mm/vmscan.c 77 | @@ -2225,8 +2225,10 @@ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, 78 | struct lruvec *lruvec, struct scan_control *sc) 79 | { 80 | if (is_active_lru(lru)) { 81 | +#ifndef CONFIG_LE9D_PATCH 82 | if (inactive_list_is_low(lruvec, is_file_lru(lru), sc, true)) 83 | shrink_active_list(nr_to_scan, lruvec, sc, lru); 84 | +#endif 85 | return 0; 86 | } 87 | 88 | @@ -2402,7 +2404,10 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 89 | 90 | anon = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON, MAX_NR_ZONES) + 91 | lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, MAX_NR_ZONES); 92 | - file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) + 93 | + file = 94 | +#ifndef CONFIG_LE9D_PATCH 95 | + lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) + 96 | +#endif 97 | lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, MAX_NR_ZONES); 98 | 99 | spin_lock_irq(&pgdat->lru_lock); 100 | @@ -2515,7 +2520,10 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc 101 | sc->priority == DEF_PRIORITY); 102 | 103 | blk_start_plug(&plug); 104 | - while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] || 105 | + while (nr[LRU_INACTIVE_ANON] || 106 | +#ifndef CONFIG_LE9D_PATCH 107 | + nr[LRU_ACTIVE_FILE] || 108 | +#endif 109 | nr[LRU_INACTIVE_FILE]) { 110 | unsigned long nr_anon, nr_file, percentage; 111 | unsigned long nr_scanned; 112 | @@ -2542,7 +2550,11 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc 113 | * stop reclaiming one LRU and reduce the amount scanning 114 | * proportional to the original scan target. 115 | */ 116 | - nr_file = nr[LRU_INACTIVE_FILE] + nr[LRU_ACTIVE_FILE]; 117 | + nr_file = nr[LRU_INACTIVE_FILE] 118 | +#ifndef CONFIG_LE9D_PATCH 119 | + + nr[LRU_ACTIVE_FILE] 120 | +#endif 121 | + ; 122 | nr_anon = nr[LRU_INACTIVE_ANON] + nr[LRU_ACTIVE_ANON]; 123 | 124 | /* 125 | @@ -2561,7 +2573,10 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc 126 | percentage = nr_anon * 100 / scan_target; 127 | } else { 128 | unsigned long scan_target = targets[LRU_INACTIVE_FILE] + 129 | - targets[LRU_ACTIVE_FILE] + 1; 130 | +#ifndef CONFIG_LE9D_PATCH 131 | + targets[LRU_ACTIVE_FILE] + 132 | +#endif 133 | + 1; 134 | lru = LRU_FILE; 135 | percentage = nr_file * 100 / scan_target; 136 | } 137 | @@ -2579,10 +2594,16 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc 138 | nr[lru] = targets[lru] * (100 - percentage) / 100; 139 | nr[lru] -= min(nr[lru], nr_scanned); 140 | 141 | +#ifdef CONFIG_LE9D_PATCH 142 | + if (LRU_FILE != lru) { //avoid this block for LRU_ACTIVE_FILE 143 | +#endif 144 | lru += LRU_ACTIVE; 145 | nr_scanned = targets[lru] - nr[lru]; 146 | nr[lru] = targets[lru] * (100 - percentage) / 100; 147 | nr[lru] -= min(nr[lru], nr_scanned); 148 | +#ifdef CONFIG_LE9D_PATCH 149 | + } 150 | +#endif 151 | 152 | scan_adjusted = true; 153 | } 154 | -------------------------------------------------------------------------------- /obsolete/original_le9_patches/le9g.patch: -------------------------------------------------------------------------------- 1 | crystal ball https://lkml.org/lkml/2019/8/12/163 2 | TODO: Use a sysctl knob called crystal ball to set minimum Active(file) to never be evicted. 3 | 4 | Patch inspired by Michal Hocko 's "Have a look at get_scan_count" from https://lkml.org/lkml/2019/8/12/163 and the idea in this patch was suggested to me a while ago by Mikko Rantalainen here: https://stackoverflow.com/questions/52067753/how-to-keep-executable-code-in-memory-even-under-memory-pressure-in-linux#comment95017646_52067753 5 | 6 | Basically, we don't evict Active(file) pages if they are under 256MiB (the default crystal ball value - not yet implemented) even when under memory pressure. 7 | This should get rid of most/all disk thrashing. To be tested on 5.3.0-rc4-gd45331b00ddb yep it works! 8 | 9 | No swap and no freeze: 10 | $ memfreeze 11 | workingset_nodes 1529 12 | workingset_refault 59958 13 | workingset_activate 37435 14 | workingset_restore 9885 15 | workingset_nodereclaim 11 16 | Will alloc: 13971696 kB for each of the 2 concurrent threads. 17 | MemTotal before: 15715256 kB 18 | stress: info: [20184] dispatching hogs: 0 cpu, 0 io, 2 vm, 0 hdd 19 | stress: FAIL: [20184] (415) <-- worker 20186 got signal 9 20 | stress: WARN: [20184] (417) now reaping child worker processes 21 | stress: FAIL: [20184] (421) kill error: No such process 22 | stress: FAIL: [20184] (451) failed run completed in 120s 23 | 24 | real 2m0.152s 25 | user 1m52.255s 26 | sys 0m12.581s 27 | exit code: 1 28 | MemTotal afterwards: 15715256 kB 29 | workingset_nodes 1987 30 | workingset_refault 71803 31 | workingset_activate 48562 32 | workingset_restore 11015 33 | workingset_nodereclaim 11 34 | 35 | `memfreeze` script is: 36 | timeout=120s threads=2 alloc="$(awk '/MemAvailable/{printf "%d\n", $2 + 4000;}' < /proc/meminfo)"; echo "Will alloc: $alloc kB for each of the $threads concurrent threads."; echo "MemTotal before: $(awk '/MemTotal/{printf "%d kB\n", $2;}' < /proc/meminfo)";time stress --vm-bytes "${alloc}k" --vm-keep -m $threads --timeout $timeout ; echo "exit code: $?" ; awk '/MemTotal/{printf "MemTotal afterwards: %d kB\n", $2;}' < /proc/meminfo 37 | 38 | 39 | Now I've to somehow disable oom-killer or something! or else memfreeze2 will cause OOM-killer to kill Xorg but this is completely unrelated to this patch/change, `memfreeze2` is: 40 | time stress -m 3000 --vm-bytes 10M --timeout 50 41 | 42 | 43 | diff --git a/mm/vmscan.c b/mm/vmscan.c 44 | index dbdc46a84f63..7a0b7e32ff45 100644 45 | --- a/mm/vmscan.c 46 | +++ b/mm/vmscan.c 47 | @@ -2445,6 +2445,13 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 48 | BUG(); 49 | } 50 | 51 | + if (NR_ACTIVE_FILE == lru) { 52 | + long long kib_active_file_now=global_node_page_state(NR_ACTIVE_FILE) * MAX_NR_ZONES; 53 | + if (kib_active_file_now <= 256*1024) { 54 | + nr[lru] = 0; //don't reclaim any Active(file) (see /proc/meminfo) if they are under 256MiB 55 | + continue; 56 | + } 57 | + } 58 | *lru_pages += size; 59 | nr[lru] = scan; 60 | } 61 | -------------------------------------------------------------------------------- /obsolete/original_le9_patches/le9h.patch: -------------------------------------------------------------------------------- 1 | le9h.patch 2 | 3 | revision 4: removed CONFIG_PROC_FS / CONFIG_IKCONFIG_PROC because IKCONFIG_PROC was initially used by le9e.patch as a personal preference, but for everyone else it's not needed! 4 | 5 | revision 3: replaced CONFIG_IKCONFIG_PROC dependency with CONFIG_PROC_FS 6 | ^ thanks to mikhailnov for pointing it out here https://gist.github.com/constantoverride/84eba764f487049ed642eb2111a20830#gistcomment-3015618 7 | 8 | revision 2: fixed 1 compilation warning. 9 | 10 | warning: there's a regression that is fixed by reverting commit aa56a292ce623734ddd30f52d73f527d1f3529b5 which is required to use this patch successfully(even tho this regression happens without this patch too!) see https://bugzilla.kernel.org/show_bug.cgi?id=203317#c4 11 | 12 | this is licensed under all/any of: 13 | Apache License, Version 2.0 14 | MIT license 15 | 0BSD 16 | CC0 17 | UNLICENSE 18 | 19 | Interesting, a phoronix user here https://www.phoronix.com/forums/forum/phoronix/general-discussion/1118164-yes-linux-does-bad-in-low-ram-memory-pressure-situations-on-the-desktop/page17#post1120291 linked to two older patches(that I was completely unaware of) which are supposedly doing this same thing (9yrs ago for the first, Oct 23, 2018 or earlier for the second): 20 | https://lore.kernel.org/patchwork/patch/222042/ 21 | https://gitlab.freedesktop.org/seanpaul/dpu-staging/commit/0b992f2dbb044896c3584e10bd5b97cf41e2ec6d 22 | 23 | they seem way more complicated though, at first glance. 24 | but hey, they were at least aware of the issue and how to fix it! 25 | 26 | see also: https://gitlab.freedesktop.org/hadess/low-memory-monitor/ 27 | earlyoom 28 | etc. 29 | 30 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 31 | index 64aeee1009ca..d0f3f7080f03 100644 32 | --- a/Documentation/admin-guide/sysctl/vm.rst 33 | +++ b/Documentation/admin-guide/sysctl/vm.rst 34 | @@ -68,6 +68,7 @@ Currently, these files are in /proc/sys/vm: 35 | - numa_stat 36 | - swappiness 37 | - unprivileged_userfaultfd 38 | +- unevictable_activefile_kbytes 39 | - user_reserve_kbytes 40 | - vfs_cache_pressure 41 | - watermark_boost_factor 42 | @@ -848,6 +849,69 @@ privileged users (with SYS_CAP_PTRACE capability). 43 | The default value is 1. 44 | 45 | 46 | +unevictable_activefile_kbytes 47 | +============================= 48 | + 49 | +How many kilobytes of `Active(file)` to never evict during high-pressure 50 | +low-memory situations. ie. never evict active file pages if under this value. 51 | +This will help prevent disk thrashing caused by Active(file) being close to zero 52 | +in such situations, especially when no swap is used. 53 | + 54 | +As 'nivedita' (phoronix user) put it: 55 | +"Executables and shared libraries are paged into memory, and can be paged out 56 | +even with no swap. [...] The kernel is dumping those pages and [...] immediately 57 | +reading them back in when execution continues." 58 | +^ and that's what's causing the disk thrashing during memory pressure. 59 | + 60 | +unevictable_activefile_kbytes=X will prevent X kbytes of those most used pages 61 | +from being evicted. 62 | + 63 | +The default value is 65536. That's 64 MiB. 64 | + 65 | +Set it to 0 to keep the default behaviour, as if this option was never 66 | +implemented, so you can see the disk thrashing as usual. 67 | + 68 | +To get an idea what value to use here for your workload(eg. xfce4 with idle 69 | +terminals) to not disk thrash at all, run this:: 70 | + 71 | + $ echo 1 | sudo tee /proc/sys/vm/drop_caches; grep -F 'Active(file)' /proc/meminfo 72 | + 1 73 | + Active(file): 203444 kB 74 | + 75 | +so, using vm.unevictable_activefile_kbytes=203444 would be a good idea here. 76 | +(you can even add a `sleep` before the grep to get a slightly increased value, 77 | +which might be useful if something is compiling in the background and you want 78 | +to account for that too) 79 | + 80 | +But you can probably go with the default value of just 65536 (aka 64 MiB) 81 | +as this will eliminate most disk thrashing anyway, unless you're not using 82 | +an SSD, in which case it might still be noticeable (I'm guessing?). 83 | + 84 | +Note that `echo 1 | sudo tee /proc/sys/vm/drop_caches` can still cause 85 | +Active(file) to go a under the vm.unevictable_activefile_kbytes value. 86 | +It's not an issue and this is how you know how much the value for 87 | +vm.unevictable_activefile_kbytes should be, at the time/workload when you ran it. 88 | + 89 | +The value of `Active(file)` can be gotten in two ways:: 90 | + 91 | + $ grep -F 'Active(file)' /proc/meminfo 92 | + Active(file): 2712004 kB 93 | + 94 | +and:: 95 | + 96 | + $ grep nr_active_file /proc/vmstat 97 | + nr_active_file 678001 98 | + 99 | +and multiply that with MAX_NR_ZONES (which is 4), ie. `nr_active_file * MAX_NR_ZONES` 100 | +so 678001*4=2712004 kB 101 | + 102 | +MAX_NR_ZONES is 4 as per: 103 | +`include/generated/bounds.h:10:#define MAX_NR_ZONES 4 /* __MAX_NR_ZONES */` 104 | +and is unlikely the change in the future. 105 | + 106 | +The hub of disk thrashing tests/explanations is here: 107 | +https://gist.github.com/constantoverride/84eba764f487049ed642eb2111a20830 108 | + 109 | user_reserve_kbytes 110 | =================== 111 | 112 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 113 | index 078950d9605b..c2726324a176 100644 114 | --- a/kernel/sysctl.c 115 | +++ b/kernel/sysctl.c 116 | @@ -110,6 +110,15 @@ extern int core_uses_pid; 117 | extern char core_pattern[]; 118 | extern unsigned int core_pipe_limit; 119 | #endif 120 | +#if defined(CONFIG_RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING) 121 | +unsigned long sysctl_unevictable_activefile_kbytes __read_mostly = 122 | +#if CONFIG_RESERVE_ACTIVEFILE_KBYTES < 0 123 | +#error "CONFIG_RESERVE_ACTIVEFILE_KBYTES should be >= 0" 124 | +#else 125 | + CONFIG_RESERVE_ACTIVEFILE_KBYTES 126 | +#endif 127 | +; 128 | +#endif 129 | extern int pid_max; 130 | extern int pid_max_min, pid_max_max; 131 | extern int percpu_pagelist_fraction; 132 | @@ -1691,6 +1701,15 @@ static struct ctl_table vm_table[] = { 133 | .extra1 = SYSCTL_ZERO, 134 | .extra2 = SYSCTL_ONE, 135 | }, 136 | +#endif 137 | +#if defined(CONFIG_RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING) 138 | + { 139 | + .procname = "unevictable_activefile_kbytes", 140 | + .data = &sysctl_unevictable_activefile_kbytes, 141 | + .maxlen = sizeof(sysctl_unevictable_activefile_kbytes), 142 | + .mode = 0644, 143 | + .proc_handler = proc_doulongvec_minmax, 144 | + }, 145 | #endif 146 | { 147 | .procname = "user_reserve_kbytes", 148 | diff --git a/mm/Kconfig b/mm/Kconfig 149 | index 56cec636a1fc..d21b737ca32e 100644 150 | --- a/mm/Kconfig 151 | +++ b/mm/Kconfig 152 | @@ -63,6 +63,39 @@ config SPARSEMEM_MANUAL 153 | 154 | endchoice 155 | 156 | +config RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING 157 | + bool "Reserve some `Active(file)` to prevent disk thrashing" 158 | + depends on SYSCTL 159 | + def_bool y 160 | + help 161 | + Keep `Active(file)`(/proc/meminfo) pages in RAM so as to avoid system freeze 162 | + due to the disk thrashing(disk reading only) that occurrs because the running 163 | + executables's code is being evicted during low-mem conditions which is 164 | + why it also prevents oom-killer from triggering until 10s of minutes later 165 | + on some systems. 166 | + 167 | + Please see the value of CONFIG_RESERVE_ACTIVEFILE_KBYTES to set how many 168 | + KiloBytes of Active(file) to keep by default in the sysctl setting 169 | + vm.unevictable_activefile_kbytes 170 | + see Documentation/admin-guide/sysctl/vm.rst for more info 171 | + 172 | +config RESERVE_ACTIVEFILE_KBYTES 173 | + int "Set default value for vm.unevictable_activefile_kbytes" 174 | + depends on RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING 175 | + default "65536" 176 | + help 177 | + This is the default value(in KiB) that vm.unevictable_activefile_kbytes gets. 178 | + A value of at least 65536 or at most 262144 is recommended for users 179 | + of xfce4 to avoid disk thrashing on low-memory/memory-pressure conditions, 180 | + ie. mouse freeze with constant disk activity (but you can still sysrq+f to 181 | + trigger oom-killer though, even without this mitigation) 182 | + 183 | + You can still sysctl set vm.unevictable_activefile_kbytes to a value of 0 184 | + to disable this whole feature at runtime. 185 | + 186 | + see Documentation/admin-guide/sysctl/vm.rst for more info 187 | + see also CONFIG_RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING 188 | + 189 | config DISCONTIGMEM 190 | def_bool y 191 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 192 | diff --git a/mm/vmscan.c b/mm/vmscan.c 193 | index dbdc46a84f63..0dcd4e2dc02d 100644 194 | --- a/mm/vmscan.c 195 | +++ b/mm/vmscan.c 196 | @@ -2445,6 +2445,16 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, 197 | BUG(); 198 | } 199 | 200 | +#if defined(CONFIG_RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING) 201 | + extern unsigned int sysctl_unevictable_activefile_kbytes; //FIXME: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] //this just needs to be moved earlier in this same function (too lazy to, atm) 202 | + if (LRU_ACTIVE_FILE == lru) { //doneFIXME: warning: comparison between ‘enum node_stat_item’ and ‘enum lru_list’ [-Wenum-compare] //fixed: replaced NR_ACTIVE_FILE with LRU_ACTIVE_FILE (they are both == 3 ) 203 | + long long kib_active_file_now=global_node_page_state(NR_ACTIVE_FILE) * MAX_NR_ZONES; 204 | + if (kib_active_file_now <= sysctl_unevictable_activefile_kbytes) { 205 | + nr[lru] = 0; //ie. don't reclaim any Active(file) (see /proc/meminfo) if they are under sysctl_unevictable_activefile_kbytes see Documentation/admin-guide/sysctl/vm.rst and CONFIG_RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING and CONFIG_RESERVE_ACTIVEFILE_KBYTES 206 | + continue; 207 | + } 208 | + } 209 | +#endif 210 | *lru_pages += size; 211 | nr[lru] = scan; 212 | } 213 | -------------------------------------------------------------------------------- /obsolete/original_le9_patches/rebase-5.9/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakavlad/le9-patch/835d59774ccc19ed239b34f1d240a76febbe6005/obsolete/original_le9_patches/rebase-5.9/README.md -------------------------------------------------------------------------------- /obsolete/original_le9_patches/rebase-5.9/le9g-5.9.patch: -------------------------------------------------------------------------------- 1 | From 88c9ec97011632f42edafa3881f34f8573e8ed5a Mon Sep 17 00:00:00 2001 2 | From: Artem Polishchuk 3 | Date: Mon, 14 Dec 2020 14:19:06 +0200 4 | Subject: [PATCH] le9g-5.9 5 | 6 | This patch is an attempt to rebase the original `le9g.patch` for Linux 5.9 7 | and also may be correctly applied to Linux 5.10 (with some offset). 8 | 9 | --- 10 | mm/vmscan.c | 8 ++++++++ 11 | 1 file changed, 8 insertions(+) 12 | 13 | diff --git a/mm/vmscan.c b/mm/vmscan.c 14 | index 466fc3144..f991b4d58 100644 15 | --- a/mm/vmscan.c 16 | +++ b/mm/vmscan.c 17 | @@ -2415,6 +2415,14 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, 18 | BUG(); 19 | } 20 | 21 | + if (NR_ACTIVE_FILE == lru) { 22 | + long long kib_active_file_now=global_node_page_state(NR_ACTIVE_FILE) * MAX_NR_ZONES; 23 | + if (kib_active_file_now <= 256*1024) { 24 | + nr[lru] = 0; //don't reclaim any Active(file) (see /proc/meminfo) if they are under 256MiB 25 | + continue; 26 | + } 27 | + } 28 | + 29 | nr[lru] = scan; 30 | } 31 | } 32 | -- 33 | 2.29.2 34 | 35 | -------------------------------------------------------------------------------- /obsolete/original_le9_patches/rebase-5.9/le9h-5.9.patch: -------------------------------------------------------------------------------- 1 | This patch is an attempt to rebase the original `le9h.patch` for Linux 5.9 2 | and also may be correctly applied to Linux 5.10 (with some offset). 3 | 4 | diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst 5 | index 4b9d2e8..0722589 100644 6 | --- a/Documentation/admin-guide/sysctl/vm.rst 7 | +++ b/Documentation/admin-guide/sysctl/vm.rst 8 | @@ -67,6 +67,7 @@ Currently, these files are in /proc/sys/vm: 9 | - stat_refresh 10 | - numa_stat 11 | - swappiness 12 | +- unevictable_activefile_kbytes 13 | - unprivileged_userfaultfd 14 | - user_reserve_kbytes 15 | - vfs_cache_pressure 16 | @@ -879,6 +880,70 @@ privileged users (with SYS_CAP_PTRACE capability). 17 | The default value is 1. 18 | 19 | 20 | +unevictable_activefile_kbytes 21 | +============================= 22 | + 23 | +How many kilobytes of `Active(file)` to never evict during high-pressure 24 | +low-memory situations. ie. never evict active file pages if under this value. 25 | +This will help prevent disk thrashing caused by Active(file) being close to zero 26 | +in such situations, especially when no swap is used. 27 | + 28 | +As 'nivedita' (phoronix user) put it: 29 | +"Executables and shared libraries are paged into memory, and can be paged out 30 | +even with no swap. [...] The kernel is dumping those pages and [...] immediately 31 | +reading them back in when execution continues." 32 | +^ and that's what's causing the disk thrashing during memory pressure. 33 | + 34 | +unevictable_activefile_kbytes=X will prevent X kbytes of those most used pages 35 | +from being evicted. 36 | + 37 | +The default value is 65536. That's 64 MiB. 38 | + 39 | +Set it to 0 to keep the default behaviour, as if this option was never 40 | +implemented, so you can see the disk thrashing as usual. 41 | + 42 | +To get an idea what value to use here for your workload(eg. xfce4 with idle 43 | +terminals) to not disk thrash at all, run this:: 44 | + 45 | + $ echo 1 | sudo tee /proc/sys/vm/drop_caches; grep -F 'Active(file)' /proc/meminfo 46 | + 1 47 | + Active(file): 203444 kB 48 | + 49 | +so, using vm.unevictable_activefile_kbytes=203444 would be a good idea here. 50 | +(you can even add a `sleep` before the grep to get a slightly increased value, 51 | +which might be useful if something is compiling in the background and you want 52 | +to account for that too) 53 | + 54 | +But you can probably go with the default value of just 65536 (aka 64 MiB) 55 | +as this will eliminate most disk thrashing anyway, unless you're not using 56 | +an SSD, in which case it might still be noticeable (I'm guessing?). 57 | + 58 | +Note that `echo 1 | sudo tee /proc/sys/vm/drop_caches` can still cause 59 | +Active(file) to go a under the vm.unevictable_activefile_kbytes value. 60 | +It's not an issue and this is how you know how much the value for 61 | +vm.unevictable_activefile_kbytes should be, at the time/workload when you ran it. 62 | + 63 | +The value of `Active(file)` can be gotten in two ways:: 64 | + 65 | + $ grep -F 'Active(file)' /proc/meminfo 66 | + Active(file): 2712004 kB 67 | + 68 | +and:: 69 | + 70 | + $ grep nr_active_file /proc/vmstat 71 | + nr_active_file 678001 72 | + 73 | +and multiply that with MAX_NR_ZONES (which is 4), ie. `nr_active_file * MAX_NR_ZONES` 74 | +so 678001*4=2712004 kB 75 | + 76 | +MAX_NR_ZONES is 4 as per: 77 | +`include/generated/bounds.h:10:#define MAX_NR_ZONES 4 /* __MAX_NR_ZONES */` 78 | +and is unlikely the change in the future. 79 | + 80 | +The hub of disk thrashing tests/explanations is here: 81 | +https://web.archive.org/web/20191018023405/https://gist.github.com/constantoverride/84eba764f487049ed642eb2111a20830 82 | + 83 | + 84 | user_reserve_kbytes 85 | =================== 86 | 87 | diff --git a/kernel/sysctl.c b/kernel/sysctl.c 88 | index afad085..65334cb 100644 89 | --- a/kernel/sysctl.c 90 | +++ b/kernel/sysctl.c 91 | @@ -111,6 +111,16 @@ 92 | static int sixty = 60; 93 | #endif 94 | 95 | +#if defined(CONFIG_RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING) 96 | +unsigned long sysctl_unevictable_activefile_kbytes __read_mostly = 97 | +#if CONFIG_RESERVE_ACTIVEFILE_KBYTES < 0 98 | +#error "CONFIG_RESERVE_ACTIVEFILE_KBYTES should be >= 0" 99 | +#else 100 | + CONFIG_RESERVE_ACTIVEFILE_KBYTES 101 | +#endif 102 | +; 103 | +#endif 104 | + 105 | static int __maybe_unused neg_one = -1; 106 | static int __maybe_unused two = 2; 107 | static int __maybe_unused four = 4; 108 | @@ -3082,6 +3092,15 @@ static struct ctl_table vm_table[] = { 109 | .extra2 = SYSCTL_ONE, 110 | }, 111 | #endif 112 | +#if defined(CONFIG_RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING) 113 | + { 114 | + .procname = "unevictable_activefile_kbytes", 115 | + .data = &sysctl_unevictable_activefile_kbytes, 116 | + .maxlen = sizeof(sysctl_unevictable_activefile_kbytes), 117 | + .mode = 0644, 118 | + .proc_handler = proc_doulongvec_minmax, 119 | + }, 120 | +#endif 121 | { 122 | .procname = "user_reserve_kbytes", 123 | .data = &sysctl_user_reserve_kbytes, 124 | diff --git a/mm/Kconfig b/mm/Kconfig 125 | index 6c97488..f63f35c 100644 126 | --- a/mm/Kconfig 127 | +++ b/mm/Kconfig 128 | @@ -63,6 +63,39 @@ config SPARSEMEM_MANUAL 129 | 130 | endchoice 131 | 132 | +config RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING 133 | + bool "Reserve some `Active(file)` to prevent disk thrashing" 134 | + depends on SYSCTL 135 | + def_bool y 136 | + help 137 | + Keep `Active(file)`(/proc/meminfo) pages in RAM so as to avoid system freeze 138 | + due to the disk thrashing(disk reading only) that occurrs because the running 139 | + executables's code is being evicted during low-mem conditions which is 140 | + why it also prevents oom-killer from triggering until 10s of minutes later 141 | + on some systems. 142 | + 143 | + Please see the value of CONFIG_RESERVE_ACTIVEFILE_KBYTES to set how many 144 | + KiloBytes of Active(file) to keep by default in the sysctl setting 145 | + vm.unevictable_activefile_kbytes 146 | + see Documentation/admin-guide/sysctl/vm.rst for more info 147 | + 148 | +config RESERVE_ACTIVEFILE_KBYTES 149 | + int "Set default value for vm.unevictable_activefile_kbytes" 150 | + depends on RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING 151 | + default "65536" 152 | + help 153 | + This is the default value(in KiB) that vm.unevictable_activefile_kbytes gets. 154 | + A value of at least 65536 or at most 262144 is recommended for users 155 | + of xfce4 to avoid disk thrashing on low-memory/memory-pressure conditions, 156 | + ie. mouse freeze with constant disk activity (but you can still sysrq+f to 157 | + trigger oom-killer though, even without this mitigation) 158 | + 159 | + You can still sysctl set vm.unevictable_activefile_kbytes to a value of 0 160 | + to disable this whole feature at runtime. 161 | + 162 | + see Documentation/admin-guide/sysctl/vm.rst for more info 163 | + see also CONFIG_RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING 164 | + 165 | config DISCONTIGMEM 166 | def_bool y 167 | depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL 168 | diff --git a/mm/vmscan.c b/mm/vmscan.c 169 | index 8b11736..60371c4 100644 170 | --- a/mm/vmscan.c 171 | +++ b/mm/vmscan.c 172 | @@ -2416,6 +2416,17 @@ out: 173 | BUG(); 174 | } 175 | 176 | +#if defined(CONFIG_RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING) 177 | + extern unsigned int sysctl_unevictable_activefile_kbytes; //FIXME: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] //this just needs to be moved earlier in this same function (too lazy to, atm) 178 | + if (LRU_ACTIVE_FILE == lru) { //doneFIXME: warning: comparison between ‘enum node_stat_item’ and ‘enum lru_list’ [-Wenum-compare] //fixed: replaced NR_ACTIVE_FILE with LRU_ACTIVE_FILE (they are both == 3 ) 179 | + long long kib_active_file_now=global_node_page_state(NR_ACTIVE_FILE) * MAX_NR_ZONES; 180 | + if (kib_active_file_now <= sysctl_unevictable_activefile_kbytes) { 181 | + nr[lru] = 0; //ie. don't reclaim any Active(file) (see /proc/meminfo) if they are under sysctl_unevictable_activefile_kbytes see Documentation/admin-guide/sysctl/vm.rst and CONFIG_RESERVE_ACTIVEFILE_TO_PREVENT_DISK_THRASHING and CONFIG_RESERVE_ACTIVEFILE_KBYTES 182 | + continue; 183 | + } 184 | + } 185 | +#endif 186 | + 187 | nr[lru] = scan; 188 | } 189 | } 190 | --------------------------------------------------------------------------------