How do I modify "/sys/kernel/mm/transparent_hugepage/enabled"

I use mongodb 3.0 and I find a warning:

MongoDB shell version: 3.0.0
connecting to: test
Server has startup warnings: 
2015-03-13T16:28:29.405+0800 I CONTROL  [initandlisten] 
2015-03-13T16:28:29.406+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2015-03-13T16:28:29.406+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2015-03-13T16:28:29.406+0800 I CONTROL  [initandlisten] 
2015-03-13T16:28:29.407+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-03-13T16:28:29.407+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2015-03-13T16:28:29.407+0800 I CONTROL  [initandlisten]

~# cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never

~# cat /sys/kernel/mm/transparent_hugepage/defrag
[always] madvise never

I try to use echo, but it's not permanent, after reboot it will be reset.

echo never > /sys/kernel/mm/transparent_hugepage/defrag

How do I modify /sys/kernel/mm/transparent_hugepage/enabled permanently?


You can

  1. install the sysfsutils package:

    sudo apt install sysfsutils
    
  2. and append a line with that setting to /etc/sysfs.conf:

    kernel/mm/transparent_hugepage/enabled = never
    

This is the cleanest solution, because it keeps all the sysfs configuration in one place instead of relying on custom start-up scripts. The other answers, with the scripts and conditional expressions, are suitable if you don't know through which path the kernel will expose that setting, i. e. if you don't even have a rough idea of the kernel version running on the affected machine.


The MongoDB docs have a few suggestions. http://docs.mongodb.org/manual/reference/transparent-huge-pages/

The "preferred" way is to edit /etc/default/grub and append transparent_hugepage=never to GRUB_CMDLINE_LINUX_DEFAULT then run update-grub to rebuild the GRUB configuration.

The following two-liner will do just that. Make sure to verify the output!

sed -r 's/GRUB_CMDLINE_LINUX_DEFAULT="[a-zA-Z0-9_= ]*/& transparent_hugepage=never/' /etc/default/grub | sudo tee /etc/default/grub
sudo update-grub

Note that update-grub is a wrapper for grub-mkconfig. grub-mkconfig will clobber entries in /etc/default/grub with those from /etc/default/grub.d/*. If by chance you are running on AWS, you will need to instead edit /etc/default/grub.d/50-cloudimg-settings.cfg.

The "alternate" method is to edit /etc/rc.local and add the following before exit 0:

if test -f /sys/kernel/mm/transparent_hugepage/khugepaged/defrag; then
  echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
  echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
  echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi

Personally, I ended up doing both the "preferred" and "alternate" methods since they aren't mutually exclusive and it eliminates the warning about defrag.

* Worked for me on Ubuntu 14.04, MongoDB 3.0.2, and AWS.


Here's a solution that has been tested to work on Ubuntu 16.04 on AWS EC2. Ubuntu 16.04 uses the systemd init system, and this config file expresses that these settings should be changed before MongoDB boots up.

Create a file named /etc/systemd/system/mongodb-hugepage-fix.service and add the following content:

[Unit]
Description="Disable Transparent Hugepage before MongoDB boots"
#WARN: check service name on your system
# If you are using MongoDB Cloud, service name is "mongodb-mms-automation-agent.service"
Before=mongodb.service      

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
ExecStart=/bin/bash -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'

[Install]
#WARN: check service name on your system
# If you are using MongoDB Cloud, service name is "mongodb-mms-automation-agent.service"
RequiredBy=mongodb.service

To load the file into systemd:

systemctl daemon-reload

To activate the file as a boot-time dependency of MongoDB

systemctl enable mongodb-hugepage-fix

If you want to activate the changes immediately (before the next boot)

systemctl start mongodb-hugepage-fix
systemctl restart mongod

This solution is not suitable for Ubuntu 14.04, which uses the Upstart init solution instead of systemd.


Append the following lines below into of /etc/rc.local.

if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
  echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi

if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
   echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi

This will run when you reboot the server.