From: Kevin Wilson <wkevils@gmail.com>
To: Anatoly Burakov <anatoly.burakov@intel.com>
Cc: dev@dpdk.org, john.mcnamara@intel.com,
bruce.richardson@intel.com, pablo.de.lara.guarch@intel.com,
david.hunt@intel.com, mohammad.abdul.awal@intel.com
Subject: Re: [dpdk-dev] [RFC 9/9] usertools/lib: add GRUB utility library for hugepage config
Date: Tue, 26 Jun 2018 04:09:38 +0300 [thread overview]
Message-ID: <CAGXs5wWj_x9YPeYj8PHNThPfiYSoZirQautgTm+AyDQrgTGGTA@mail.gmail.com> (raw)
In-Reply-To: <02efa4a4e6fab105ae883a855ae1985afc208a31.1529940601.git.anatoly.burakov@intel.com>
Hi, Anatoly,
Thanks for these patches, good work.
Regarding "update-grub": IIRC, this is Ubuntu specific command (and
also used in Debian/Debian based flavors).
In Fedora (RedHat based) recent distros, you use grub2-mkconfig
instead (and there is no "update-grub", IIRC).
If this is true, I would consider adding a comment in the commit log
saying something like "it is for Ubuntu/Debian-based distros".
So maybe in the future someone will add the python code which detects
the OS (using lsb-release, etc) and, in case it is Fedora/RedHat
distro, the grub2-mkconfig util
will be invoked instead.
Regards,
KW
On Mon, Jun 25, 2018 at 6:59 PM, Anatoly Burakov
<anatoly.burakov@intel.com> wrote:
> This library is highly experimental and can kill kittens, but its
> main purpose is to automatically set up GRUB command-line to
> allocate a given number of hugepages at boot time. It works in
> a similar way HugeUtil library does, but instead of committing
> changes to fstab or runtime configuration, it commits its
> changes to GRUB default command-line and updates all GRUB entries
> afterwards. I got it to a state where it's safe to use on my
> system, but see the part above about killing kittens - you have
> been warned :)
>
> No example scripts will currently be provided.
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
> usertools/DPDKConfigLib/GrubHugeUtil.py | 175 ++++++++++++++++++++++++
> 1 file changed, 175 insertions(+)
> create mode 100755 usertools/DPDKConfigLib/GrubHugeUtil.py
>
> diff --git a/usertools/DPDKConfigLib/GrubHugeUtil.py b/usertools/DPDKConfigLib/GrubHugeUtil.py
> new file mode 100755
> index 000000000..4b8e349b8
> --- /dev/null
> +++ b/usertools/DPDKConfigLib/GrubHugeUtil.py
> @@ -0,0 +1,175 @@
> +#!/usr/bin/env python
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2018 Intel Corporation
> +
> +
> +from .PlatformInfo import *
> +from .Util import *
> +import re
> +import os
> +
> +__KERNEL_TRANSPARENT_HP = "/sys/kernel/mm/transparent_hugepage/enabled"
> +_GRUB_CMDLINE_PARAM_NAME = "GRUB_CMDLINE_LINUX_DEFAULT"
> +
> +# local copy of platform info
> +info = PlatformInfo()
> +
> +def _find_linux_default_cmdline():
> + with open("/etc/default/grub") as f:
> + for line in f:
> + line = line.strip()
> + if line.startswith(_GRUB_CMDLINE_PARAM_NAME):
> + return line
> + else:
> + raise RuntimeError("Invalid GRUB default configuration format")
> +
> +
> +def _parse_linux_default_cmdline(line):
> + # get value to the right of equals sign, strip whitespace and quotes,
> + # split into separate keys and make a list of values
> + _, cmdline = kv_split(line, "=")
> + # remove quotes
> + if cmdline[0] == cmdline[-1] == '"':
> + cmdline = cmdline[1:-1]
> +
> + return [kv_split(v, "=") for v in cmdline.split()]
> +
> +
> +def _generate_linux_default_cmdline(cmdline):
> + lines = []
> + cmdline_idx = -1
> + with open("/etc/default/grub") as f:
> + for idx, line in enumerate(f):
> + line = line.strip()
> + lines.extend([line])
> + if line.startswith(_GRUB_CMDLINE_PARAM_NAME):
> + cmdline_idx = idx
> + if cmdline_idx == -1:
> + raise RuntimeError("Invalid GRUB default configuration format")
> +
> + # write the lines back, replacing one we want
> + with open("/etc/default/grub", "w") as f:
> + for idx, line in enumerate(lines):
> + if idx == cmdline_idx:
> + line = cmdline
> + f.write(line + "\n")
> +
> +
> +def _find_transparent_hugepage():
> + if not os.path.exists(__KERNEL_TRANSPARENT_HP):
> + return None
> + value = read_file(__KERNEL_TRANSPARENT_HP)
> + m = re.search(r"\[([a-z]+)\]", value)
> + if not m:
> + raise RuntimeError("BUG: Bad regular expression")
> + return m.group(1)
> +
> +
> +class GrubHugepageConfig:
> + def __init__(self):
> + self.update()
> +
> + def update(self):
> + self.reset()
> +
> + hugepage_sizes = info.hugepage_sizes_supported
> + if len(hugepage_sizes) == 0:
> + raise RuntimeError("Hugepages appear to be unsupported")
> + cmdline = _find_linux_default_cmdline()
> + values = _parse_linux_default_cmdline(cmdline)
> +
> + # parse values in the list
> + self.default_hugepagesz = info.default_hugepage_size
> + self.transparent_hugepage = _find_transparent_hugepage()
> + sizes = []
> + nrs = []
> + for k, v in values:
> + if k == "default_hugepagesz":
> + self.default_hugepagesz = human_readable_to_kilobytes(v)
> + elif k == "transparent_hugepage":
> + self.transparent_hugepage = v
> + elif k == "hugepagesz":
> + sizes.append(human_readable_to_kilobytes(v))
> + elif k == "hugepages":
> + nrs.append(v)
> + if len(sizes) != len(nrs):
> + raise RuntimeError("GRUB hugepage configuration is wrong")
> + detected_hugepages = dict(zip(sizes, map(int, nrs)))
> + self.nr_hugepages = {size: detected_hugepages.get(size, 0)
> + for size in hugepage_sizes}
> +
> + def commit(self):
> + # perform sanity checks - we can't afford invalid data making it into
> + # bootloader config, as that might render user's machine unbootable, so
> + # tread really really carefully
> +
> + # first, check if user didn't add any unexpected hugepage sizes
> + configured_sizes = set(self.nr_hugepages.keys())
> + supported_sizes = set(info.hugepage_sizes_supported)
> +
> + if configured_sizes != supported_sizes:
> + diff = configured_sizes.difference(supported_sizes)
> + raise ValueError("Unsupported hugepage sizes: %s" %
> + [kilobytes_to_human_readable(s) for s in diff])
> +
> + # check if default hugepage is one of the supported ones
> + if self.default_hugepagesz is not None and\
> + self.default_hugepagesz not in configured_sizes:
> + s = kilobytes_to_human_readable(self.default_hugepagesz)
> + raise ValueError("Unsupported default hugepage size: %i" % s)
> +
> + # transparent hugepages support was added in recent kernels, so check
> + # if user is trying to set this
> + if _find_transparent_hugepage() is None and \
> + self.transparent_hugepage is not None:
> + raise ValueError("Transparent hugepages are not unsupported")
> +
> + # OK, parameters look to be valid - let's roll
> +
> + # read and parse current cmdline
> + cmdline = _find_linux_default_cmdline()
> +
> + values = _parse_linux_default_cmdline(cmdline)
> +
> + # clear out old data
> + klist = ["transparent_hugepage", "default_hugepagesz",
> + "hugepage", "hugepagesz"]
> + # iterate over a copy so that we could delete items
> + for k, v in values[:]:
> + if k in klist:
> + values.remove((k, v))
> +
> + # generate new cmdline
> + cmdline = " ".join([("%s=%s" % (k, v)) if v is not None else k
> + for k, v in values])
> +
> + # now, populate cmdline with new data
> + new_items = []
> + for sz, nr in self.nr_hugepages.items():
> + sz = kilobytes_to_human_readable(sz)
> + new_items += "hugepagesz=%s hugepages=%i" % (sz, nr)
> + if self.default_hugepagesz is not None:
> + new_items += "default_hugepagesz=%i" % self.default_hugepagesz
> + if self.transparent_hugepage is not None:
> + new_items += "transparent_hugepage=%s" % self.transparent_hugepage
> +
> + cmdline = "%s %s" % (cmdline, " ".join(new_items))
> +
> + # strip any extraneous whitespace we may have added
> + cmdline = re.sub(r"\s\s+", " ", cmdline).strip()
> +
> + # now, put everything back together
> + cmdline = '%s="%s"' % (_GRUB_CMDLINE_PARAM_NAME, cmdline)
> +
> + # write it to config
> + _generate_linux_default_cmdline(cmdline)
> +
> + # finally, update GRUB
> + if not run(["update-grub"]):
> + raise RuntimeError("Failed to update GRUB")
> + self.update()
> +
> + def reset(self):
> + self.nr_hugepages = {} # pagesz: number
> + self.default_hugepagesz = None
> + self.transparent_hugepage = None
> --
> 2.17.1
next prev parent reply other threads:[~2018-06-26 1:09 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-25 15:59 [dpdk-dev] [RFC 0/9] Modularize and enhance DPDK Python scripts Anatoly Burakov
2018-06-25 15:59 ` [dpdk-dev] [RFC 1/9] usertools: add DPDK config lib python library Anatoly Burakov
2018-06-25 15:59 ` [dpdk-dev] [RFC 2/9] usertools/lib: add platform info library Anatoly Burakov
2018-06-25 15:59 ` [dpdk-dev] [RFC 3/9] usertools/cpu_layout: rewrite to use DPDKConfigLib Anatoly Burakov
2018-06-25 15:59 ` [dpdk-dev] [RFC 4/9] usertools/lib: support FreeBSD for platform info Anatoly Burakov
2018-06-25 15:59 ` [dpdk-dev] [RFC 5/9] usertools/lib: add device information library Anatoly Burakov
2018-06-25 15:59 ` [dpdk-dev] [RFC 6/9] usertools/devbind: switch to using DPDKConfigLib Anatoly Burakov
2018-06-25 15:59 ` [dpdk-dev] [RFC 7/9] usertools/lib: add hugepage information library Anatoly Burakov
2018-06-25 15:59 ` [dpdk-dev] [RFC 8/9] usertools: add hugepage info script Anatoly Burakov
2018-06-25 15:59 ` [dpdk-dev] [RFC 9/9] usertools/lib: add GRUB utility library for hugepage config Anatoly Burakov
2018-06-26 1:09 ` Kevin Wilson [this message]
2018-06-26 9:05 ` Burakov, Anatoly
2018-08-14 10:11 ` [dpdk-dev] [RFC 0/9] Modularize and enhance DPDK Python scripts Burakov, Anatoly
2018-08-28 8:16 ` Burakov, Anatoly
2018-11-15 15:47 ` [dpdk-dev] [RFC v2 " Anatoly Burakov
2018-11-15 15:47 ` [dpdk-dev] [RFC v2 1/9] usertools: add DPDK config lib python library Anatoly Burakov
2018-11-16 0:45 ` Stephen Hemminger
2018-11-16 11:49 ` Burakov, Anatoly
2018-11-16 14:09 ` Wiles, Keith
2018-11-16 14:13 ` Richardson, Bruce
2018-11-16 14:37 ` Burakov, Anatoly
2018-11-16 14:55 ` Thomas Monjalon
2018-11-16 15:41 ` Wiles, Keith
2018-11-16 15:43 ` Burakov, Anatoly
2018-11-16 15:58 ` Thomas Monjalon
2018-11-16 16:10 ` Bruce Richardson
2018-11-16 16:08 ` Bruce Richardson
2018-11-16 15:38 ` Wiles, Keith
2018-11-15 15:47 ` [dpdk-dev] [RFC v2 2/9] usertools/lib: add platform info library Anatoly Burakov
2018-11-15 15:47 ` [dpdk-dev] [RFC v2 3/9] usertools/cpu_layout: rewrite to use DPDKConfigLib Anatoly Burakov
2018-11-15 15:47 ` [dpdk-dev] [RFC v2 4/9] usertools/lib: support FreeBSD for platform info Anatoly Burakov
2018-11-15 15:47 ` [dpdk-dev] [RFC v2 5/9] usertools/lib: add device information library Anatoly Burakov
2018-11-15 15:47 ` [dpdk-dev] [RFC v2 6/9] usertools/devbind: switch to using DPDKConfigLib Anatoly Burakov
2018-11-15 15:47 ` [dpdk-dev] [RFC v2 7/9] usertools/lib: add hugepage information library Anatoly Burakov
2018-11-15 15:47 ` [dpdk-dev] [RFC v2 8/9] usertools: add hugepage info script Anatoly Burakov
2018-11-15 15:47 ` [dpdk-dev] [RFC v2 9/9] usertools/lib: add GRUB utility library for hugepage config Anatoly Burakov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAGXs5wWj_x9YPeYj8PHNThPfiYSoZirQautgTm+AyDQrgTGGTA@mail.gmail.com \
--to=wkevils@gmail.com \
--cc=anatoly.burakov@intel.com \
--cc=bruce.richardson@intel.com \
--cc=david.hunt@intel.com \
--cc=dev@dpdk.org \
--cc=john.mcnamara@intel.com \
--cc=mohammad.abdul.awal@intel.com \
--cc=pablo.de.lara.guarch@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).