Commit bec7550c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'docs-5.2-fixes2' of git://git.lwn.net/linux

Pull documentation fixes from Jonathan Corbet:
 "The Sphinx 2.0 release contained a few incompatible API changes that
  broke our extensions and, thus, the documentation build in general.
  Who knew that those deprecation warnings it was outputting actually
  meant we should change something? This set of fixes makes the build
  work again with Sphinx 2.0 and eliminates the warnings for 1.8. As
  part of that, we also need a few fixes to the docs for places where
  the new Sphinx is more strict.

  It is a bit late in the cycle for this kind of change, but it does fix
  problems that people are experiencing now.

  There has been some talk of raising the minimum version of Sphinx we
  support. I don't want to do that abruptly, though, so these changes
  add some glue to continue to support versions back to 1.3. We will be
  adding some infrastructure soon to nudge users of old versions
  forward, with the idea of maybe increasing our minimum version (and
  removing this glue) sometime in the future"

* tag 'docs-5.2-fixes2' of git://git.lwn.net/linux:
  drm/i915: Maintain consistent documentation subsection ordering
  scripts/sphinx-pre-install: make it handle Sphinx versions
  docs: Fix conf.py for Sphinx 2.0
  docs: fix multiple doc build warnings in enumeration.rst
  lib/list_sort: fix kerneldoc build error
  docs: fix numaperf.rst and add it to the doc tree
  doc: Cope with the deprecation of AutoReporter
  doc: Cope with Sphinx logging deprecations
parents 2b28601d 551bd336
...@@ -31,6 +31,7 @@ the Linux memory management. ...@@ -31,6 +31,7 @@ the Linux memory management.
ksm ksm
memory-hotplug memory-hotplug
numa_memory_policy numa_memory_policy
numaperf
pagemap pagemap
soft-dirty soft-dirty
transhuge transhuge
......
...@@ -15,7 +15,7 @@ characteristics. Some memory may share the same node as a CPU, and others ...@@ -15,7 +15,7 @@ characteristics. Some memory may share the same node as a CPU, and others
are provided as memory only nodes. While memory only nodes do not provide are provided as memory only nodes. While memory only nodes do not provide
CPUs, they may still be local to one or more compute nodes relative to CPUs, they may still be local to one or more compute nodes relative to
other nodes. The following diagram shows one such example of two compute other nodes. The following diagram shows one such example of two compute
nodes with local memory and a memory only node for each of compute node: nodes with local memory and a memory only node for each of compute node::
+------------------+ +------------------+ +------------------+ +------------------+
| Compute Node 0 +-----+ Compute Node 1 | | Compute Node 0 +-----+ Compute Node 1 |
......
...@@ -37,7 +37,7 @@ needs_sphinx = '1.3' ...@@ -37,7 +37,7 @@ needs_sphinx = '1.3'
extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'cdomain', 'kfigure', 'sphinx.ext.ifconfig'] extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'cdomain', 'kfigure', 'sphinx.ext.ifconfig']
# The name of the math extension changed on Sphinx 1.4 # The name of the math extension changed on Sphinx 1.4
if major == 1 and minor > 3: if (major == 1 and minor > 3) or (major > 1):
extensions.append("sphinx.ext.imgmath") extensions.append("sphinx.ext.imgmath")
else: else:
extensions.append("sphinx.ext.pngmath") extensions.append("sphinx.ext.pngmath")
......
...@@ -423,7 +423,7 @@ will be enumerated to depends on the device ID returned by _HID. ...@@ -423,7 +423,7 @@ will be enumerated to depends on the device ID returned by _HID.
For example, the following ACPI sample might be used to enumerate an lm75-type For example, the following ACPI sample might be used to enumerate an lm75-type
I2C temperature sensor and match it to the driver using the Device Tree I2C temperature sensor and match it to the driver using the Device Tree
namespace link: namespace link::
Device (TMP0) Device (TMP0)
{ {
......
...@@ -37,7 +37,19 @@ import glob ...@@ -37,7 +37,19 @@ import glob
from docutils import nodes, statemachine from docutils import nodes, statemachine
from docutils.statemachine import ViewList from docutils.statemachine import ViewList
from docutils.parsers.rst import directives, Directive from docutils.parsers.rst import directives, Directive
from sphinx.ext.autodoc import AutodocReporter
#
# AutodocReporter is only good up to Sphinx 1.7
#
import sphinx
Use_SSI = sphinx.__version__[:3] >= '1.7'
if Use_SSI:
from sphinx.util.docutils import switch_source_input
else:
from sphinx.ext.autodoc import AutodocReporter
import kernellog
__version__ = '1.0' __version__ = '1.0'
...@@ -90,7 +102,8 @@ class KernelDocDirective(Directive): ...@@ -90,7 +102,8 @@ class KernelDocDirective(Directive):
cmd += [filename] cmd += [filename]
try: try:
env.app.verbose('calling kernel-doc \'%s\'' % (" ".join(cmd))) kernellog.verbose(env.app,
'calling kernel-doc \'%s\'' % (" ".join(cmd)))
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate() out, err = p.communicate()
...@@ -100,7 +113,8 @@ class KernelDocDirective(Directive): ...@@ -100,7 +113,8 @@ class KernelDocDirective(Directive):
if p.returncode != 0: if p.returncode != 0:
sys.stderr.write(err) sys.stderr.write(err)
env.app.warn('kernel-doc \'%s\' failed with return code %d' % (" ".join(cmd), p.returncode)) kernellog.warn(env.app,
'kernel-doc \'%s\' failed with return code %d' % (" ".join(cmd), p.returncode))
return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))] return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))]
elif env.config.kerneldoc_verbosity > 0: elif env.config.kerneldoc_verbosity > 0:
sys.stderr.write(err) sys.stderr.write(err)
...@@ -121,20 +135,28 @@ class KernelDocDirective(Directive): ...@@ -121,20 +135,28 @@ class KernelDocDirective(Directive):
lineoffset += 1 lineoffset += 1
node = nodes.section() node = nodes.section()
buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter self.do_parse(result, node)
return node.children
except Exception as e: # pylint: disable=W0703
kernellog.warn(env.app, 'kernel-doc \'%s\' processing failed with: %s' %
(" ".join(cmd), str(e)))
return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))]
def do_parse(self, result, node):
if Use_SSI:
with switch_source_input(self.state, result):
self.state.nested_parse(result, 0, node, match_titles=1)
else:
save = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter
self.state.memo.reporter = AutodocReporter(result, self.state.memo.reporter) self.state.memo.reporter = AutodocReporter(result, self.state.memo.reporter)
self.state.memo.title_styles, self.state.memo.section_level = [], 0 self.state.memo.title_styles, self.state.memo.section_level = [], 0
try: try:
self.state.nested_parse(result, 0, node, match_titles=1) self.state.nested_parse(result, 0, node, match_titles=1)
finally: finally:
self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = buf self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = save
return node.children
except Exception as e: # pylint: disable=W0703
env.app.warn('kernel-doc \'%s\' processing failed with: %s' %
(" ".join(cmd), str(e)))
return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))]
def setup(app): def setup(app):
app.add_config_value('kerneldoc_bin', None, 'env') app.add_config_value('kerneldoc_bin', None, 'env')
......
# SPDX-License-Identifier: GPL-2.0
#
# Sphinx has deprecated its older logging interface, but the replacement
# only goes back to 1.6. So here's a wrapper layer to keep around for
# as long as we support 1.4.
#
import sphinx
if sphinx.__version__[:3] >= '1.6':
UseLogging = True
from sphinx.util import logging
logger = logging.getLogger('kerneldoc')
else:
UseLogging = False
def warn(app, message):
if UseLogging:
logger.warning(message)
else:
app.warn(message)
def verbose(app, message):
if UseLogging:
logger.verbose(message)
else:
app.verbose(message)
...@@ -60,6 +60,8 @@ import sphinx ...@@ -60,6 +60,8 @@ import sphinx
from sphinx.util.nodes import clean_astext from sphinx.util.nodes import clean_astext
from six import iteritems from six import iteritems
import kernellog
PY3 = sys.version_info[0] == 3 PY3 = sys.version_info[0] == 3
if PY3: if PY3:
...@@ -171,20 +173,20 @@ def setupTools(app): ...@@ -171,20 +173,20 @@ def setupTools(app):
This function is called once, when the builder is initiated. This function is called once, when the builder is initiated.
""" """
global dot_cmd, convert_cmd # pylint: disable=W0603 global dot_cmd, convert_cmd # pylint: disable=W0603
app.verbose("kfigure: check installed tools ...") kernellog.verbose(app, "kfigure: check installed tools ...")
dot_cmd = which('dot') dot_cmd = which('dot')
convert_cmd = which('convert') convert_cmd = which('convert')
if dot_cmd: if dot_cmd:
app.verbose("use dot(1) from: " + dot_cmd) kernellog.verbose(app, "use dot(1) from: " + dot_cmd)
else: else:
app.warn("dot(1) not found, for better output quality install " kernellog.warn(app, "dot(1) not found, for better output quality install "
"graphviz from http://www.graphviz.org") "graphviz from http://www.graphviz.org")
if convert_cmd: if convert_cmd:
app.verbose("use convert(1) from: " + convert_cmd) kernellog.verbose(app, "use convert(1) from: " + convert_cmd)
else: else:
app.warn( kernellog.warn(app,
"convert(1) not found, for SVG to PDF conversion install " "convert(1) not found, for SVG to PDF conversion install "
"ImageMagick (https://www.imagemagick.org)") "ImageMagick (https://www.imagemagick.org)")
...@@ -220,12 +222,13 @@ def convert_image(img_node, translator, src_fname=None): ...@@ -220,12 +222,13 @@ def convert_image(img_node, translator, src_fname=None):
# in kernel builds, use 'make SPHINXOPTS=-v' to see verbose messages # in kernel builds, use 'make SPHINXOPTS=-v' to see verbose messages
app.verbose('assert best format for: ' + img_node['uri']) kernellog.verbose(app, 'assert best format for: ' + img_node['uri'])
if in_ext == '.dot': if in_ext == '.dot':
if not dot_cmd: if not dot_cmd:
app.verbose("dot from graphviz not available / include DOT raw.") kernellog.verbose(app,
"dot from graphviz not available / include DOT raw.")
img_node.replace_self(file2literal(src_fname)) img_node.replace_self(file2literal(src_fname))
elif translator.builder.format == 'latex': elif translator.builder.format == 'latex':
...@@ -252,7 +255,8 @@ def convert_image(img_node, translator, src_fname=None): ...@@ -252,7 +255,8 @@ def convert_image(img_node, translator, src_fname=None):
if translator.builder.format == 'latex': if translator.builder.format == 'latex':
if convert_cmd is None: if convert_cmd is None:
app.verbose("no SVG to PDF conversion available / include SVG raw.") kernellog.verbose(app,
"no SVG to PDF conversion available / include SVG raw.")
img_node.replace_self(file2literal(src_fname)) img_node.replace_self(file2literal(src_fname))
else: else:
dst_fname = path.join(translator.builder.outdir, fname + '.pdf') dst_fname = path.join(translator.builder.outdir, fname + '.pdf')
...@@ -265,18 +269,19 @@ def convert_image(img_node, translator, src_fname=None): ...@@ -265,18 +269,19 @@ def convert_image(img_node, translator, src_fname=None):
_name = dst_fname[len(translator.builder.outdir) + 1:] _name = dst_fname[len(translator.builder.outdir) + 1:]
if isNewer(dst_fname, src_fname): if isNewer(dst_fname, src_fname):
app.verbose("convert: {out}/%s already exists and is newer" % _name) kernellog.verbose(app,
"convert: {out}/%s already exists and is newer" % _name)
else: else:
ok = False ok = False
mkdir(path.dirname(dst_fname)) mkdir(path.dirname(dst_fname))
if in_ext == '.dot': if in_ext == '.dot':
app.verbose('convert DOT to: {out}/' + _name) kernellog.verbose(app, 'convert DOT to: {out}/' + _name)
ok = dot2format(app, src_fname, dst_fname) ok = dot2format(app, src_fname, dst_fname)
elif in_ext == '.svg': elif in_ext == '.svg':
app.verbose('convert SVG to: {out}/' + _name) kernellog.verbose(app, 'convert SVG to: {out}/' + _name)
ok = svg2pdf(app, src_fname, dst_fname) ok = svg2pdf(app, src_fname, dst_fname)
if not ok: if not ok:
...@@ -305,7 +310,8 @@ def dot2format(app, dot_fname, out_fname): ...@@ -305,7 +310,8 @@ def dot2format(app, dot_fname, out_fname):
with open(out_fname, "w") as out: with open(out_fname, "w") as out:
exit_code = subprocess.call(cmd, stdout = out) exit_code = subprocess.call(cmd, stdout = out)
if exit_code != 0: if exit_code != 0:
app.warn("Error #%d when calling: %s" % (exit_code, " ".join(cmd))) kernellog.warn(app,
"Error #%d when calling: %s" % (exit_code, " ".join(cmd)))
return bool(exit_code == 0) return bool(exit_code == 0)
def svg2pdf(app, svg_fname, pdf_fname): def svg2pdf(app, svg_fname, pdf_fname):
...@@ -322,7 +328,7 @@ def svg2pdf(app, svg_fname, pdf_fname): ...@@ -322,7 +328,7 @@ def svg2pdf(app, svg_fname, pdf_fname):
# use stdout and stderr from parent # use stdout and stderr from parent
exit_code = subprocess.call(cmd) exit_code = subprocess.call(cmd)
if exit_code != 0: if exit_code != 0:
app.warn("Error #%d when calling: %s" % (exit_code, " ".join(cmd))) kernellog.warn(app, "Error #%d when calling: %s" % (exit_code, " ".join(cmd)))
return bool(exit_code == 0) return bool(exit_code == 0)
...@@ -415,15 +421,15 @@ def visit_kernel_render(self, node): ...@@ -415,15 +421,15 @@ def visit_kernel_render(self, node):
app = self.builder.app app = self.builder.app
srclang = node.get('srclang') srclang = node.get('srclang')
app.verbose('visit kernel-render node lang: "%s"' % (srclang)) kernellog.verbose(app, 'visit kernel-render node lang: "%s"' % (srclang))
tmp_ext = RENDER_MARKUP_EXT.get(srclang, None) tmp_ext = RENDER_MARKUP_EXT.get(srclang, None)
if tmp_ext is None: if tmp_ext is None:
app.warn('kernel-render: "%s" unknown / include raw.' % (srclang)) kernellog.warn(app, 'kernel-render: "%s" unknown / include raw.' % (srclang))
return return
if not dot_cmd and tmp_ext == '.dot': if not dot_cmd and tmp_ext == '.dot':
app.verbose("dot from graphviz not available / include raw.") kernellog.verbose(app, "dot from graphviz not available / include raw.")
return return
literal_block = node[0] literal_block = node[0]
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
* macros. Do **not** mass change existing definitions just to update the style. * macros. Do **not** mass change existing definitions just to update the style.
* *
* Layout * Layout
* '''''' * ~~~~~~
* *
* Keep helper macros near the top. For example, _PIPE() and friends. * Keep helper macros near the top. For example, _PIPE() and friends.
* *
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
* style. Use lower case in hexadecimal values. * style. Use lower case in hexadecimal values.
* *
* Naming * Naming
* '''''' * ~~~~~~
* *
* Try to name registers according to the specs. If the register name changes in * Try to name registers according to the specs. If the register name changes in
* the specs from platform to another, stick to the original name. * the specs from platform to another, stick to the original name.
...@@ -97,7 +97,7 @@ ...@@ -97,7 +97,7 @@
* suffix to the name. For example, ``_SKL`` or ``_GEN8``. * suffix to the name. For example, ``_SKL`` or ``_GEN8``.
* *
* Examples * Examples
* '''''''' * ~~~~~~~~
* *
* (Note that the values in the example are indented using spaces instead of * (Note that the values in the example are indented using spaces instead of
* TABs to avoid misalignment in generated documentation. Use TABs in the * TABs to avoid misalignment in generated documentation. Use TABs in the
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* costly and simplifies things. We can revisit this in the future. * costly and simplifies things. We can revisit this in the future.
* *
* Layout * Layout
* '''''' * ~~~~~~
* *
* Keep things in this file ordered by WA type, as per the above (context, GT, * Keep things in this file ordered by WA type, as per the above (context, GT,
* display, register whitelist, batchbuffer). Then, inside each type, keep the * display, register whitelist, batchbuffer). Then, inside each type, keep the
......
...@@ -120,7 +120,8 @@ static void merge_final(void *priv, cmp_func cmp, struct list_head *head, ...@@ -120,7 +120,8 @@ static void merge_final(void *priv, cmp_func cmp, struct list_head *head,
* The latter offers a chance to save a few cycles in the comparison * The latter offers a chance to save a few cycles in the comparison
* (which is used by e.g. plug_ctx_cmp() in block/blk-mq.c). * (which is used by e.g. plug_ctx_cmp() in block/blk-mq.c).
* *
* A good way to write a multi-word comparison is * A good way to write a multi-word comparison is::
*
* if (a->high != b->high) * if (a->high != b->high)
* return a->high > b->high; * return a->high > b->high;
* if (a->middle != b->middle) * if (a->middle != b->middle)
......
...@@ -13,7 +13,7 @@ use strict; ...@@ -13,7 +13,7 @@ use strict;
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
my $virtenv_dir = "sphinx_1.4"; my $conf = "Documentation/conf.py";
my $requirement_file = "Documentation/sphinx/requirements.txt"; my $requirement_file = "Documentation/sphinx/requirements.txt";
# #
...@@ -26,7 +26,9 @@ my $need = 0; ...@@ -26,7 +26,9 @@ my $need = 0;
my $optional = 0; my $optional = 0;
my $need_symlink = 0; my $need_symlink = 0;
my $need_sphinx = 0; my $need_sphinx = 0;
my $rec_sphinx_upgrade = 0;
my $install = ""; my $install = "";
my $virtenv_dir = "sphinx_";
# #
# Command line arguments # Command line arguments
...@@ -201,13 +203,15 @@ sub check_missing_tex($) ...@@ -201,13 +203,15 @@ sub check_missing_tex($)
} }
} }
sub check_sphinx() sub get_sphinx_fname()
{ {
return if findprog("sphinx-build"); my $fname = "sphinx-build";
return $fname if findprog($fname);
if (findprog("sphinx-build-3")) { $fname = "sphinx-build-3";
if (findprog($fname)) {
$need_symlink = 1; $need_symlink = 1;
return; return $fname;
} }
if ($virtualenv) { if ($virtualenv) {
...@@ -219,6 +223,73 @@ sub check_sphinx() ...@@ -219,6 +223,73 @@ sub check_sphinx()
} else { } else {
add_package("python-sphinx", 0); add_package("python-sphinx", 0);
} }
return "";
}
sub check_sphinx()
{
my $min_version;
my $rec_version;
my $cur_version;
open IN, $conf or die "Can't open $conf";
while (<IN>) {
if (m/^\s*needs_sphinx\s*=\s*[\'\"]([\d\.]+)[\'\"]/) {
$min_version=$1;
last;
}
}
close IN;
die "Can't get needs_sphinx version from $conf" if (!$min_version);
open IN, $requirement_file or die "Can't open $requirement_file";
while (<IN>) {
if (m/^\s*Sphinx\s*==\s*([\d\.]+)$/) {
$rec_version=$1;
last;
}
}
close IN;
die "Can't get recommended sphinx version from $requirement_file" if (!$min_version);
$virtenv_dir .= $rec_version;
my $sphinx = get_sphinx_fname();
return if ($sphinx eq "");
open IN, "$sphinx --version 2>&1 |" or die "$sphinx returned an error";
while (<IN>) {
if (m/^\s*sphinx-build\s+([\d\.]+)$/) {
$cur_version=$1;
last;
}
# Sphinx 1.2.x uses a different format
if (m/^\s*Sphinx.*\s+([\d\.]+)$/) {
$cur_version=$1;
last;
}
}
close IN;
die "$sphinx didn't return its version" if (!$cur_version);
printf "Sphinx version %s (minimal: %s, recommended >= %s)\n",
$cur_version, $min_version, $rec_version;
if ($cur_version lt $min_version) {
print "Warning: Sphinx version should be >= $min_version\n\n";
$need_sphinx = 1;
return;
}
if ($cur_version lt $rec_version) {
print "Warning: It is recommended at least Sphinx version $rec_version.\n";
print " To upgrade, use:\n\n";
$rec_sphinx_upgrade = 1;
}
} }
# #
...@@ -540,7 +611,7 @@ sub check_needs() ...@@ -540,7 +611,7 @@ sub check_needs()
printf "\tsudo ln -sf %s /usr/bin/sphinx-build\n\n", printf "\tsudo ln -sf %s /usr/bin/sphinx-build\n\n",
which("sphinx-build-3"); which("sphinx-build-3");
} }
if ($need_sphinx) { if ($need_sphinx || $rec_sphinx_upgrade) {
my $activate = "$virtenv_dir/bin/activate"; my $activate = "$virtenv_dir/bin/activate";
if (-e "$ENV{'PWD'}/$activate") { if (-e "$ENV{'PWD'}/$activate") {
printf "\nNeed to activate virtualenv with:\n"; printf "\nNeed to activate virtualenv with:\n";
...@@ -554,7 +625,8 @@ sub check_needs() ...@@ -554,7 +625,8 @@ sub check_needs()
printf "\t$virtualenv $virtenv_dir\n"; printf "\t$virtualenv $virtenv_dir\n";
printf "\t. $activate\n"; printf "\t. $activate\n";
printf "\tpip install -r $requirement_file\n"; printf "\tpip install -r $requirement_file\n";
$need++;
$need++ if (!$rec_sphinx_upgrade);
} }
} }
printf "\n"; printf "\n";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment