Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable Transparent Hugepage #4174

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bin/varnishd/mgt/mgt.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ extern const struct jail_tech jail_tech_unix;
extern const struct jail_tech jail_tech_solaris;
extern const struct jail_tech jail_tech_linux;

#define MATCH_JAIL_ARG(arg, option) (!strncmp(arg, option, sizeof(option) - 1))

/* mgt_main.c */
extern struct vsb *vident;
extern struct VSC_mgt *VSC_C_mgt;
Expand Down
71 changes: 64 additions & 7 deletions bin/varnishd/mgt/mgt_jail_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,61 @@
#include "mgt/mgt.h"
#include "common/heritage.h"

static int
vjl_set_thp(const char *arg)
{
int val;

if (!strcmp(arg, "ignore"))
return (0);
if (!strcmp(arg, "enable"))
val = 0;
else if (!strcmp(arg, "disable"))
val = 1;
else {
ARGV_ERR(
"linux jail: unknown value '%s' for argument transparent_hugepage.\n",
arg);
}
if (prctl(PR_SET_THP_DISABLE, val, 0, 0, 0) != 0) {
MGT_Complain(C_ERR,
"Could not %s Transparent Hugepage: %s (%d)",
arg, VAS_errtxt(errno), errno);
}
return (0);
}

static int
vjl_init(char **args)
{
char **unix_args;
int ret = 0;
size_t i;

if (args == NULL) {
/* Autoconfig */
if (vjl_set_thp("disable") != 0)
return (1);
return (jail_tech_unix.init(NULL));
}

return jail_tech_unix.init(args);
for (i = 0; args[i] != NULL; i++);
unix_args = calloc(i + 1, sizeof *unix_args);
AN(unix_args);

for (i = 0; *args != NULL && ret == 0; args++) {
if (MATCH_JAIL_ARG(*args, "transparent_hugepage=")) {
ret = vjl_set_thp((*args) + (sizeof("transparent_hugepage=") - 1));
} else {
unix_args[i] = *args;
i++;
}
}

if (ret == 0)
ret = jail_tech_unix.init(unix_args);
free(unix_args);
return (ret);
}

static void
Expand Down Expand Up @@ -94,17 +144,24 @@ vjl_make_workdir(const char *dname, const char *what, struct vsb *vsb)

vjl_master(JAIL_MASTER_FILE);
if (statfs(dname, &info) != 0) {
if (vsb)
VSB_printf(vsb, "Could not stat working directory '%s': %s (%d)\n", dname, VAS_errtxt(errno), errno);
else
MGT_Complain(C_ERR, "Could not stat working directory '%s': %s (%d)", dname, VAS_errtxt(errno), errno);
if (vsb) {
VSB_printf(vsb,
"Could not stat working directory '%s': %s (%d)\n",
dname, VAS_errtxt(errno), errno);
} else {
MGT_Complain(C_ERR,
"Could not stat working directory '%s': %s (%d)",
dname, VAS_errtxt(errno), errno);
}
return (1);
}
if (info.f_type != TMPFS_MAGIC) {
if (vsb != NULL)
VSB_printf(vsb, "Working directory not mounted on tmpfs partition\n");
VSB_printf(vsb,
"Working directory not mounted on tmpfs partition\n");
else
MGT_Complain(C_INFO, "Working directory not mounted on tmpfs partition");
MGT_Complain(C_INFO,
"Working directory not mounted on tmpfs partition");
}
vjl_master(JAIL_MASTER_LOW);
return (0);
Expand Down
2 changes: 1 addition & 1 deletion bin/varnishd/mgt/mgt_jail_solaris.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ vjs_init(char **args)

if (args != NULL && *args != NULL) {
for (;*args != NULL; args++) {
if (!strncmp(*args, "worker=", 7)) {
if (MATCH_JAIL_ARG(*args, "worker=")) {
user = priv_str_to_set((*args) + 7, ",", &e);
if (user == NULL)
ARGV_ERR(
Expand Down
6 changes: 3 additions & 3 deletions bin/varnishd/mgt/mgt_jail_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,21 @@ vju_init(char **args)
ARGV_ERR("Unix Jail: Must be root.\n");

for (;*args != NULL; args++) {
if (!strncmp(*args, "user=", 5)) {
if (MATCH_JAIL_ARG(*args, "user=")) {
if (vju_getuid((*args) + 5))
ARGV_ERR(
"Unix jail: %s user not found.\n",
(*args) + 5);
continue;
}
if (!strncmp(*args, "workuser=", 9)) {
if (MATCH_JAIL_ARG(*args, "workuser=")) {
if (vju_getwrkuid((*args) + 9))
ARGV_ERR(
"Unix jail: %s user not found.\n",
(*args) + 9);
continue;
}
if (!strncmp(*args, "ccgroup=", 8)) {
if (MATCH_JAIL_ARG(*args, "ccgroup=")) {
if (vju_getccgid((*args) + 8))
ARGV_ERR(
"Unix jail: %s group not found.\n",
Expand Down
30 changes: 19 additions & 11 deletions doc/sphinx/installation/platformnotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,29 @@ On some platforms it is necessary to adjust the operating system before running
Varnish on it. The systems and steps known to us are described in this section.


Transparent hugepages on Redhat Enterprise Linux 6
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Transparent Hugepage on Linux
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On RHEL6 Transparent Hugepage kernel support is enabled by default.
This is known to cause sporadic crashes of Varnish.
On certain Linux distributions Transparent Hugepage kernel support is enabled
by default. This is known to cause instabilities of Varnish.

It is recommended to disable transparent hugepages on affected
systems. This can be done with
``echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled``
(runtime) or by adding "transparent_hugepage=never" to the kernel boot
line in the "/etc/grub.conf" file (persistent).
It is recommended to disable Transparent Hugepage on affected systems.
If Varnish is the only significant service running on this system, this can be
done during runtime with::

On Debian/Ubuntu systems running 3.2 kernels the default value is "madvise" and
does not need to be changed.
echo never > /sys/kernel/mm/transparent_hugepage/enabled

Alternatively, this can be persisted in your bootloader configuration by adding
``transparent_hugepage=never`` to the kernel command line.

On other systems the default value is ``madvise`` and does not need to be
changed. Either way, the Linux :ref:`ref-varnishd-opt_j` will try to disable
Transparent Hugepage in the ``varnishd`` process.

The general recommendation is to mount the working directory in a ``tmpfs``
partition, usually ``/var/lib/varnish``. By default tmpfs should be mounted with
Transparent Hugepage disabled. Consider mounting the working directory with the
``huge=never`` mount option if that is not the case with your OS vendor.

OpenVZ
~~~~~~
Expand Down
7 changes: 6 additions & 1 deletion doc/sphinx/reference/varnishd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -454,13 +454,18 @@ specific options. Available jails are:

-j solaris,worker=basic

-j <linux[,user=`user`][,ccgroup=`group`][,workuser=`user`]>
-j <linux[,transparent_hugepage=`action`][,<unix jail option>...]>

Default on Linux platforms, it extends the UNIX jail with
Linux-specific mechanisms:

- It warns when *workdir* is not on a ``tmpfs``.
- It tries to keep the process dumpable after dropping privileges.
- It tries to disable Transparent Hugepage in ``varnishd`` by default.

The optional transparent_hugepage argument takes one action among enable,
disable (default) and ignore. Failure to configure Transparent Hugepage is
not a fatal error.

-j <unix[,user=`user`][,ccgroup=`group`][,workuser=`user`]>

Expand Down