From 5e64fa9c441ff273f39527f4014d3c3e724d321a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 19 May 2016 20:32:48 +0300 Subject: kernel-doc/rst: fix use of uninitialized value I'm not quite sure why the errors below are happening, but this fixes them. Use of uninitialized value in string ne at ./scripts/kernel-doc line 1819, line 6494. Use of uninitialized value $_[0] in join or string at ./scripts/kernel-doc line 1759, line 6494. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 2fc8fad5195e..babb374c043d 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1803,7 +1803,8 @@ sub output_function_rst(%) { } else { print " ``$parameter``\n"; } - if ($args{'parameterdescs'}{$parameter_name} ne $undescribed) { + if (defined($args{'parameterdescs'}{$parameter_name}) && + $args{'parameterdescs'}{$parameter_name} ne $undescribed) { my $oldprefix = $lineprefix; $lineprefix = " "; output_highlight_rst($args{'parameterdescs'}{$parameter_name}); -- cgit v1.2.3 From 86ae2e38d40ed6bf7c907d126053e6f4b1dc5b6e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 21 Jan 2016 13:05:22 +0200 Subject: kernel-doc: support printing exported and non-exported symbols Currently we use docproc to figure out which symbols are exported, and then docproc calls kernel-doc on specific functions, to get documentation on exported functions. According to git blame and docproc comments, this is due to historical reasons, as functions and their corresponding EXPORT_SYMBOL* may have been in different files. However for more than ten years the recommendation in CodingStyle has been to place the EXPORT_SYMBOL* immediately after the closing function brace line. Additionally, the kernel-doc comments for functions are generally placed above the function definition in the .c files (i.e. where the EXPORT_SYMBOL* is) rather than above the declaration in the .h files. There are some exceptions to this, but AFAICT none of these are included in DocBook documentation using the "!E" docproc directive. Therefore, assuming the EXPORT_SYMBOL* and kernel-doc are with the function definition, kernel-doc can extract the exported vs. not information by making two passes on the input file. Add support for that via the new -export and -internal parameters. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index babb374c043d..3ad54abe0989 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -59,6 +59,12 @@ Output format selection (mutually exclusive): -text Output plain text format. Output selection (mutually exclusive): + -export Only output documentation for symbols that have been + exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() + in the same FILE. + -internal Only output documentation for symbols that have NOT been + exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() + in the same FILE. -function NAME Only output documentation for the given function(s) or DOC: section title(s). All other functions and DOC: sections are ignored. May be specified multiple times. @@ -380,6 +386,7 @@ my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_split_start = '^\s*/\*\*\s*$'; my $doc_split_sect = '\s*\*\s*(@[\w\s]+):(.*)'; my $doc_split_end = '^\s*\*/\s*$'; +my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; my %constants; my %parameterdescs; @@ -444,6 +451,12 @@ while ($ARGV[0] =~ m/^-(.*)/) { $function_only = 2; $function = shift @ARGV; $function_table{$function} = 1; + } elsif ($cmd eq "-export") { # only exported symbols + $function_only = 3; + %function_table = () + } elsif ($cmd eq "-internal") { # only non-exported symbols + $function_only = 4; + %function_table = () } elsif ($cmd eq "-v") { $verbose = 1; } elsif (($cmd eq "-h") || ($cmd eq "--help")) { @@ -1971,8 +1984,10 @@ sub output_declaration { my $functype = shift; my $func = "output_${functype}_$output_mode"; if (($function_only==0) || - ( $function_only == 1 && defined($function_table{$name})) || - ( $function_only == 2 && !($functype eq "function" && defined($function_table{$name})))) + ( ($function_only == 1 || $function_only == 3) && + defined($function_table{$name})) || + ( ($function_only == 2 || $function_only == 4) && + !($functype eq "function" && defined($function_table{$name})))) { &$func(@_); $section_counter++; @@ -2675,6 +2690,16 @@ sub process_file($) { return; } + # two passes for -export and -internal + if ($function_only == 3 || $function_only == 4) { + while () { + if (/$export_symbol/o) { + $function_table{$2} = 1; + } + } + seek(IN, 0, 0); + } + $. = 1; $section_counter = 0; -- cgit v1.2.3 From 22cba31bae9dc357622f09d22b82ca5a112b4fde Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 19 May 2016 15:14:05 +0300 Subject: Documentation/sphinx: add basic working Sphinx configuration and build Add basic configuration and makefile to build documentation from any .rst files under Documentation using Sphinx. For starters, there's just the placeholder index.rst. At the top level Makefile, hook Sphinx documentation targets alongside (but independent of) the DocBook toolchain, having both be run on the various 'make *docs' targets. All Sphinx processing is placed into Documentation/Makefile.sphinx. Both that and the Documentation/DocBook/Makefile are now expected to handle all the documentation targets, explicitly ignoring them if they're not relevant for that particular toolchain. The changes to the existing DocBook Makefile are kept minimal. There is graceful handling of missing Sphinx and rst2pdf (which is needed for pdf output) by checking for the tool and python module, respectively, with informative messages to the user. If the Read the Docs theme (sphinx_rtd_theme) is available, use it, but otherwise gracefully fall back to the Sphinx default theme, with an informative message to the user, and slightly less pretty HTML output. Sphinx can now handle htmldocs, pdfdocs (if rst2pdf is available), epubdocs and xmldocs targets. The output documents are written into per output type subdirectories under Documentation/output. Finally, you can pass options to sphinx-build using the SPHINXBUILD make variable. For example, 'make SPHINXOPTS=-v htmldocs' for more verbose output from Sphinx. This is based on the original work by Jonathan Corbet, but he probably wouldn't recognize this as his own anymore. Signed-off-by: Jani Nikula --- Documentation/DocBook/Makefile | 7 +- Documentation/Makefile.sphinx | 61 +++++++ Documentation/conf.py | 387 +++++++++++++++++++++++++++++++++++++++++ Documentation/index.rst | 23 +++ Makefile | 5 +- 5 files changed, 478 insertions(+), 5 deletions(-) create mode 100644 Documentation/Makefile.sphinx create mode 100644 Documentation/conf.py create mode 100644 Documentation/index.rst diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index d70f9b68174e..e0c7e1e0590b 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -33,10 +33,6 @@ PDF_METHOD = $(prefer-db2x) PS_METHOD = $(prefer-db2x) -### -# The targets that may be used. -PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs - targets += $(DOCBOOKS) BOOKS := $(addprefix $(obj)/,$(DOCBOOKS)) xmldocs: $(BOOKS) @@ -63,6 +59,9 @@ installmandocs: mandocs sort -k 2 -k 1 | uniq -f 1 | sed -e 's: :/:' | \ xargs install -m 644 -t /usr/local/man/man9/ +# no-op for the DocBook toolchain +epubdocs: + ### #External programs used KERNELDOCXMLREF = $(srctree)/scripts/kernel-doc-xml-ref diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx new file mode 100644 index 000000000000..25a7970bfe5c --- /dev/null +++ b/Documentation/Makefile.sphinx @@ -0,0 +1,61 @@ +# -*- makefile -*- +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXBUILD = sphinx-build +SPHINXOPTS = +PAPER = +BUILDDIR = $(obj)/output + +# User-friendly check for sphinx-build +HAVE_SPHINX := $(shell if which $(SPHINXBUILD) >/dev/null 2>&1; then echo 1; else echo 0; fi) + +ifeq ($(HAVE_SPHINX),0) + +.DEFAULT: + $(warning The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable.) + @echo " SKIP Sphinx $@ target." + +else # HAVE_SPHINX + +# User-friendly check for rst2pdf +HAVE_RST2PDF := $(shell if python -c "import rst2pdf" >/dev/null 2>&1; then echo 1; else echo 0; fi) + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/.doctrees $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +quiet_cmd_sphinx = SPHINX $@ + cmd_sphinx = $(SPHINXBUILD) -b $2 $(ALLSPHINXOPTS) $(BUILDDIR)/$2 + +htmldocs: + $(call cmd,sphinx,html) + +pdfdocs: +ifeq ($(HAVE_RST2PDF),0) + $(warning The Python 'rst2pdf' module was not found. Make sure you have the module installed to produce PDF output.) + @echo " SKIP Sphinx $@ target." +else # HAVE_RST2PDF + $(call cmd,sphinx,pdf) +endif # HAVE_RST2PDF + +epubdocs: + $(call cmd,sphinx,epub) + +xmldocs: + $(call cmd,sphinx,xml) + +# no-ops for the Sphinx toolchain +sgmldocs: +psdocs: +mandocs: +installmandocs: + +cleandocs: + $(Q)rm -rf $(BUILDDIR) + +endif # HAVE_SPHINX diff --git a/Documentation/conf.py b/Documentation/conf.py new file mode 100644 index 000000000000..0f0e20757bb1 --- /dev/null +++ b/Documentation/conf.py @@ -0,0 +1,387 @@ +# -*- coding: utf-8 -*- +# +# The Linux Kernel documentation build configuration file, created by +# sphinx-quickstart on Fri Feb 12 13:51:46 2016. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Gracefully handle missing rst2pdf. +try: + import rst2pdf + extensions += ['rst2pdf.pdfbuilder'] +except ImportError: + pass + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'The Linux Kernel' +copyright = '2016, The kernel development community' +author = 'The kernel development community' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '4.5' +# The full version, including alpha/beta/rc tags. +release = '4.5' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['output'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + +primary_domain = 'C' +highlight_language = 'C' + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. + +# The Read the Docs theme is available from +# - https://github.com/snide/sphinx_rtd_theme +# - https://pypi.python.org/pypi/sphinx_rtd_theme +# - python-sphinx-rtd-theme package (on Debian) +try: + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] +except ImportError: + sys.stderr.write('Warning: The Sphinx \'sphinx_rtd_theme\' HTML theme was not found. Make sure you have the theme installed to produce pretty HTML output. Falling back to the default theme.\n') + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' +#html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +#html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +#html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'TheLinuxKerneldoc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', + +# Latex figure (float) alignment +#'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'TheLinuxKernel.tex', 'The Linux Kernel Documentation', + 'The kernel development community', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'thelinuxkernel', 'The Linux Kernel Documentation', + [author], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'TheLinuxKernel', 'The Linux Kernel Documentation', + author, 'TheLinuxKernel', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + + +# -- Options for Epub output ---------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project +epub_author = author +epub_publisher = author +epub_copyright = copyright + +# The basename for the epub file. It defaults to the project name. +#epub_basename = project + +# The HTML theme for the epub output. Since the default themes are not +# optimized for small screen space, using the same theme for HTML and epub +# output is usually not wise. This defaults to 'epub', a theme designed to save +# visual space. +#epub_theme = 'epub' + +# The language of the text. It defaults to the language option +# or 'en' if the language is not set. +#epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +#epub_identifier = '' + +# A unique identification for the text. +#epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +#epub_cover = () + +# A sequence of (type, uri, title) tuples for the guide element of content.opf. +#epub_guide = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_pre_files = [] + +# HTML files that should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_post_files = [] + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 + +# Allow duplicate toc entries. +#epub_tocdup = True + +# Choose between 'default' and 'includehidden'. +#epub_tocscope = 'default' + +# Fix unsupported image types using the Pillow. +#epub_fix_images = False + +# Scale large images. +#epub_max_image_width = 0 + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#epub_show_urls = 'inline' + +# If false, no index is generated. +#epub_use_index = True + +#======= +# rst2pdf +# +# Grouping the document tree into PDF files. List of tuples +# (source start file, target name, title, author, options). +# +# See the Sphinx chapter of http://ralsina.me/static/manual.pdf +# +# FIXME: Do not add the index file here; the result will be too big. Adding +# multiple PDF files here actually tries to get the cross-referencing right +# *between* PDF files. +pdf_documents = [ + ('index', u'Kernel', u'Kernel', u'J. Random Bozo'), +] diff --git a/Documentation/index.rst b/Documentation/index.rst new file mode 100644 index 000000000000..71a276f34c7f --- /dev/null +++ b/Documentation/index.rst @@ -0,0 +1,23 @@ +.. The Linux Kernel documentation master file, created by + sphinx-quickstart on Fri Feb 12 13:51:46 2016. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to The Linux Kernel's documentation! +============================================ + +Nothing for you to see here *yet*. Please move along. + +Contents: + +.. toctree:: + :maxdepth: 2 + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/Makefile b/Makefile index 0f70de63cfdb..8908a51b895a 100644 --- a/Makefile +++ b/Makefile @@ -1412,8 +1412,11 @@ $(help-board-dirs): help-%: # Documentation targets # --------------------------------------------------------------------------- -%docs: scripts_basic FORCE +DOC_TARGETS := xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs +PHONY += $(DOC_TARGETS) +$(DOC_TARGETS): scripts_basic FORCE $(Q)$(MAKE) $(build)=scripts build_docproc build_check-lc_ctype + $(Q)$(MAKE) $(build)=Documentation -f $(srctree)/Documentation/Makefile.sphinx $@ $(Q)$(MAKE) $(build)=Documentation/DocBook $@ else # KBUILD_EXTMOD -- cgit v1.2.3 From 81cd318102aedee64d3bd38d2e04ea333569abfd Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 19 May 2016 20:53:23 +0300 Subject: Documentation: add .gitignore The Sphinx output directory is generated. Signed-off-by: Jani Nikula --- Documentation/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 Documentation/.gitignore diff --git a/Documentation/.gitignore b/Documentation/.gitignore new file mode 100644 index 000000000000..53752db253e3 --- /dev/null +++ b/Documentation/.gitignore @@ -0,0 +1 @@ +output -- cgit v1.2.3 From c56de1db54dfbbdfc02a500388952af16e3a9368 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 18 May 2016 23:30:30 +0300 Subject: Documentation/sphinx: add Sphinx kernel-doc directive extension Add an extension to handle kernel-doc directives, to call kernel-doc according to the arguments and parameters given to the reStructuredText directive. The syntax for the kernel-doc directive is: .. kernel-doc:: FILENAME :export: :internal: :functions: FUNCTION [FUNCTION ...] :doc: SECTION TITLE Of the directive options export, internal, functions, and doc, currently only one option may be given at a time. The FILENAME is relative from the kernel source tree root. The extension notifies Sphinx about the document dependency on FILENAME, causing the document to be rebuilt when the file has been changed. Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 102 +++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Documentation/sphinx/kernel-doc.py diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py new file mode 100644 index 000000000000..87a1332fe934 --- /dev/null +++ b/Documentation/sphinx/kernel-doc.py @@ -0,0 +1,102 @@ +# coding=utf-8 +# +# Copyright © 2016 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# +# Authors: +# Jani Nikula + +import os +import subprocess +import sys + +from docutils import nodes, statemachine +from docutils.parsers.rst import directives +from sphinx.util.compat import Directive + +class KernelDocDirective(Directive): + """Extract kernel-doc comments from the specified file""" + required_argument = 1 + optional_arguments = 4 + option_spec = { + 'doc': directives.unchanged_required, + 'functions': directives.unchanged_required, + 'export': directives.flag, + 'internal': directives.flag, + } + has_content = False + + def run(self): + env = self.state.document.settings.env + cmd = [env.config.kerneldoc_bin, '-rst'] + + filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] + + # Tell sphinx of the dependency + env.note_dependency(os.path.abspath(filename)) + + tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) + source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) + + # FIXME: make this nicer and more robust against errors + if 'export' in self.options: + cmd += ['-export'] + elif 'internal' in self.options: + cmd += ['-internal'] + elif 'doc' in self.options: + cmd += ['-function', str(self.options.get('doc'))] + elif 'functions' in self.options: + for f in str(self.options.get('functions')).split(' '): + cmd += ['-function', f] + + cmd += [filename] + + try: + env.app.verbose('calling kernel-doc \'%s\'' % (" ".join(cmd))) + + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + out, err = p.communicate() + + # assume the kernel sources are utf-8 + out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8') + + if p.returncode != 0: + sys.stderr.write(err) + + env.app.warn('kernel-doc \'%s\' failed with return code %d' % (" ".join(cmd), p.returncode)) + return [nodes.error(None, nodes.paragraph(text = "kernel-doc missing"))] + elif env.config.kerneldoc_verbosity > 0: + sys.stderr.write(err) + + lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) + self.state_machine.insert_input(lines, source) + return [] + except Exception as e: + 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): + app.add_config_value('kerneldoc_bin', None, 'env') + app.add_config_value('kerneldoc_srctree', None, 'env') + app.add_config_value('kerneldoc_verbosity', 1, 'env') + + app.add_directive('kernel-doc', KernelDocDirective) -- cgit v1.2.3 From 24dcdeb28b55afafa9cdf6acedd78cf1aa8f8428 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 May 2016 11:51:47 +0300 Subject: Documentation/sphinx: configure the kernel-doc extension Tell Sphinx where to find the extension, and pass on the kernel src tree and kernel-doc paths to the extension. With this, any .rst files under Documentation may contain the kernel-doc rst directive to include kernel-doc documentation from any source file. While building, it may be handy to pass kernel-doc extension configuration on the command line. For example, 'make SPHINXOPTS="-D kerneldoc_verbosity=0" htmldocs' silences all stderr output from kernel-doc when the kernel-doc exit code is 0. (The stderr will be logged unconditionally when the exit code is non-zero.) Signed-off-by: Jani Nikula --- Documentation/Makefile.sphinx | 4 +++- Documentation/conf.py | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx index 25a7970bfe5c..8a662be9bd87 100644 --- a/Documentation/Makefile.sphinx +++ b/Documentation/Makefile.sphinx @@ -25,7 +25,9 @@ HAVE_RST2PDF := $(shell if python -c "import rst2pdf" >/dev/null 2>&1; then echo # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/.doctrees $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) +KERNELDOC = $(srctree)/scripts/kernel-doc +KERNELDOC_CONF = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC) +ALLSPHINXOPTS = -d $(BUILDDIR)/.doctrees $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . diff --git a/Documentation/conf.py b/Documentation/conf.py index 0f0e20757bb1..8b72577f38f5 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -18,7 +18,7 @@ import os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('sphinx')) # -- General configuration ------------------------------------------------ @@ -28,7 +28,7 @@ import os # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [] +extensions = ['kernel-doc'] # Gracefully handle missing rst2pdf. try: @@ -385,3 +385,9 @@ epub_exclude_files = ['search.html'] pdf_documents = [ ('index', u'Kernel', u'Kernel', u'J. Random Bozo'), ] + +# kernel-doc extension configuration for running Sphinx directly (e.g. by Read +# the Docs). In a normal build, these are supplied from the Makefile via command +# line arguments. +kerneldoc_bin = '../scripts/kernel-doc' +kerneldoc_srctree = '..' -- cgit v1.2.3 From c13ce448c8532965eb4e1115e78cb5b8ff8261a3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sat, 28 May 2016 15:25:41 +0300 Subject: Documentation/sphinx: set version and release properly Read the version and release from the top level Makefile (for use when Sphinx is invoked directly, by e.g. Read the Docs), but override them via Sphinx command line arguments in a normal documentation build. Signed-off-by: Jani Nikula --- Documentation/Makefile.sphinx | 2 +- Documentation/conf.py | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx index 8a662be9bd87..addf32309bc3 100644 --- a/Documentation/Makefile.sphinx +++ b/Documentation/Makefile.sphinx @@ -27,7 +27,7 @@ PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter KERNELDOC = $(srctree)/scripts/kernel-doc KERNELDOC_CONF = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC) -ALLSPHINXOPTS = -d $(BUILDDIR)/.doctrees $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) +ALLSPHINXOPTS = -D version=$(KERNELVERSION) -D release=$(KERNELRELEASE) -d $(BUILDDIR)/.doctrees $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) -c $(srctree)/$(src) $(SPHINXOPTS) $(srctree)/$(src) # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . diff --git a/Documentation/conf.py b/Documentation/conf.py index 8b72577f38f5..6cc41a0555a3 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -60,10 +60,31 @@ author = 'The kernel development community' # |version| and |release|, also used in various other places throughout the # built documents. # -# The short X.Y version. -version = '4.5' -# The full version, including alpha/beta/rc tags. -release = '4.5' +# In a normal build, version and release are are set to KERNELVERSION and +# KERNELRELEASE, respectively, from the Makefile via Sphinx command line +# arguments. +# +# The following code tries to extract the information by reading the Makefile, +# when Sphinx is run directly (e.g. by Read the Docs). +try: + makefile_version = None + makefile_patchlevel = None + for line in open('../Makefile'): + key, val = [x.strip() for x in line.split('=', 2)] + if key == 'VERSION': + makefile_version = val + elif key == 'PATCHLEVEL': + makefile_patchlevel = val + if makefile_version and makefile_patchlevel: + break +except: + pass +finally: + if makefile_version and makefile_patchlevel: + version = release = makefile_version + '.' + makefile_patchlevel + else: + sys.stderr.write('Warning: Could not extract kernel version\n') + version = release = "unknown version" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -- cgit v1.2.3 From 89a66d76109935aad387a5058f120aeb8246ae40 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Sun, 6 Mar 2016 20:29:31 -0700 Subject: sphinx: cheesy script to convert .tmpl files This script uses pandoc to convert existing DocBook template files to RST templates. A couple of sed scripts are need to massage things both before and after the conversion, but the result is then usable with no hand editing. [Jani: Change usage to tmplcvt . Fix escaping for docproc directives. Add support the new kernel-doc extension.] Signed-off-by: Jonathan Corbet Signed-off-by: Jani Nikula --- Documentation/sphinx/convert_template.sed | 14 ++++++++++++++ Documentation/sphinx/post_convert.sed | 19 +++++++++++++++++++ Documentation/sphinx/tmplcvt | 19 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 Documentation/sphinx/convert_template.sed create mode 100644 Documentation/sphinx/post_convert.sed create mode 100755 Documentation/sphinx/tmplcvt diff --git a/Documentation/sphinx/convert_template.sed b/Documentation/sphinx/convert_template.sed new file mode 100644 index 000000000000..d53bb8220a26 --- /dev/null +++ b/Documentation/sphinx/convert_template.sed @@ -0,0 +1,14 @@ +# +# Pandoc doesn't grok or , so convert them +# ahead of time. +# +# Use "$bq" instead of "`" so that pandoc won't mess with it. +# +s%\([^<(]\+\)()%:c:func:$bq\1$bq%g +s%\([^<(]\+\)%:c:func:$bq\1$bq%g +s%struct *\([^<]\+\)%:ref:$bqstruct \1$bq%g +s%\([^<]\+\)%:ref:$bqstruct \1$bq%g +# +# Wrap docproc directives in para and code blocks. +# +s%^\(!.*\)$%DOCPROC: \1% diff --git a/Documentation/sphinx/post_convert.sed b/Documentation/sphinx/post_convert.sed new file mode 100644 index 000000000000..ce17049f6a8e --- /dev/null +++ b/Documentation/sphinx/post_convert.sed @@ -0,0 +1,19 @@ +# +# pandoc thinks that both "_" needs to be escaped. Remove the extra +# backslashes. Also put in proper backquotes now that pandoc won't quote +# them. +# +s/$bq/`/g +s/\\_/_/g +# +# Unwrap docproc directives. +# +s/^``DOCPROC: !E\(.*\)``$/.. kernel-doc:: \1\n :export:/ +s/^``DOCPROC: !I\(.*\)``$/.. kernel-doc:: \1\n :internal:/ +s/^``DOCPROC: !F\([^ ]*\) \(.*\)``$/.. kernel-doc:: \1\n :functions: \2/ +s/^``DOCPROC: !P\([^ ]*\) \(.*\)``$/.. kernel-doc:: \1\n :doc: \2/ +s/^``DOCPROC: \(!.*\)``$/.. WARNING: DOCPROC directive not supported: \1/ +# +# Trim trailing whitespace. +# +s/[[:space:]]*$// diff --git a/Documentation/sphinx/tmplcvt b/Documentation/sphinx/tmplcvt new file mode 100755 index 000000000000..909a73065e0a --- /dev/null +++ b/Documentation/sphinx/tmplcvt @@ -0,0 +1,19 @@ +#!/bin/bash +# +# Convert a template file into something like RST +# +# fix +# feed to pandoc +# fix \_ +# title line? +# + +in=$1 +rst=$2 +tmp=$rst.tmp + +cp $in $tmp +sed --in-place -f convert_template.sed $tmp +pandoc -s -S -f docbook -t rst -o $rst $tmp +sed --in-place -f post_convert.sed $rst +rm $tmp -- cgit v1.2.3 From 2e83ecb834ca923806fd58fab17d9f405767e1d9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 10:15:18 +0300 Subject: sphinx: update docbook->rst conversion script match C domain spec Function references should include the parens (), struct references should not include "struct". Signed-off-by: Jani Nikula --- Documentation/sphinx/convert_template.sed | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/sphinx/convert_template.sed b/Documentation/sphinx/convert_template.sed index d53bb8220a26..0553eabeac79 100644 --- a/Documentation/sphinx/convert_template.sed +++ b/Documentation/sphinx/convert_template.sed @@ -4,10 +4,10 @@ # # Use "$bq" instead of "`" so that pandoc won't mess with it. # -s%\([^<(]\+\)()%:c:func:$bq\1$bq%g -s%\([^<(]\+\)%:c:func:$bq\1$bq%g -s%struct *\([^<]\+\)%:ref:$bqstruct \1$bq%g -s%\([^<]\+\)%:ref:$bqstruct \1$bq%g +s%\([^<(]\+\)()%:c:func:$bq\1()$bq%g +s%\([^<(]\+\)%:c:func:$bq\1()$bq%g +s%struct *\([^<]\+\)%:c:type:$bq\1$bq%g +s%\([^<]\+\)%:c:type:$bq\1$bq%g # # Wrap docproc directives in para and code blocks. # -- cgit v1.2.3 From 30ca7aaf279944da930b587b05d9b325ec7f821d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 10:40:17 +0300 Subject: Documentation/sphinx: nicer referencing of struct in docbook->rst conversion Add "struct" in the label of the reference. Signed-off-by: Jani Nikula --- Documentation/sphinx/convert_template.sed | 10 +++++++--- Documentation/sphinx/post_convert.sed | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Documentation/sphinx/convert_template.sed b/Documentation/sphinx/convert_template.sed index 0553eabeac79..c1503fcca4ec 100644 --- a/Documentation/sphinx/convert_template.sed +++ b/Documentation/sphinx/convert_template.sed @@ -2,12 +2,16 @@ # Pandoc doesn't grok or , so convert them # ahead of time. # -# Use "$bq" instead of "`" so that pandoc won't mess with it. +# Use the following escapes to pass through pandoc: +# $bq = "`" +# $lt = "<" +# $gt = ">" # s%\([^<(]\+\)()%:c:func:$bq\1()$bq%g s%\([^<(]\+\)%:c:func:$bq\1()$bq%g -s%struct *\([^<]\+\)%:c:type:$bq\1$bq%g -s%\([^<]\+\)%:c:type:$bq\1$bq%g +s%struct *\([^<]\+\)%:c:type:$bqstruct \1 $lt\1$gt$bq%g +s%struct \([^<]\+\)%:c:type:$bqstruct \1 $lt\1$gt$bq%g +s%\([^<]\+\)%:c:type:$bqstruct \1 $lt\1$gt$bq%g # # Wrap docproc directives in para and code blocks. # diff --git a/Documentation/sphinx/post_convert.sed b/Documentation/sphinx/post_convert.sed index ce17049f6a8e..392770bac53b 100644 --- a/Documentation/sphinx/post_convert.sed +++ b/Documentation/sphinx/post_convert.sed @@ -1,9 +1,13 @@ # -# pandoc thinks that both "_" needs to be escaped. Remove the extra -# backslashes. Also put in proper backquotes now that pandoc won't quote -# them. +# Unescape. # s/$bq/`/g +s/$lt//g +# +# pandoc thinks that both "_" needs to be escaped. Remove the extra +# backslashes. +# s/\\_/_/g # # Unwrap docproc directives. -- cgit v1.2.3 From 48af606ad8912f90e1539621a26e86672976d8ae Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 14:56:05 +0300 Subject: kernel-doc: add names for states and substates Make the state machine a bit more readable by adding constants for parser states and inline member documentation parser substates. While at it, rename the "split" documentation to "inline" documentation. No functional changes. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 91 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 3ad54abe0989..cb5fd248ac57 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -350,24 +350,29 @@ my $section_counter = 0; my $lineprefix=""; -# states -# 0 - normal code -# 1 - looking for function name -# 2 - scanning field start. -# 3 - scanning prototype. -# 4 - documentation block -# 5 - gathering documentation outside main block +# Parser states +use constant { + STATE_NORMAL => 0, # normal code + STATE_NAME => 1, # looking for function name + STATE_FIELD => 2, # scanning field start + STATE_PROTO => 3, # scanning prototype + STATE_DOCBLOCK => 4, # documentation block + STATE_INLINE => 5, # gathering documentation outside main block +}; my $state; my $in_doc_sect; -# Split Doc State -# 0 - Invalid (Before start or after finish) -# 1 - Is started (the /** was found inside a struct) -# 2 - The @parameter header was found, start accepting multi paragraph text. -# 3 - Finished (the */ was found) -# 4 - Error - Comment without header was found. Spit a warning as it's not -# proper kernel-doc and ignore the rest. -my $split_doc_state; +# Inline documentation state +use constant { + STATE_INLINE_NA => 0, # not applicable ($state != STATE_INLINE) + STATE_INLINE_NAME => 1, # looking for member name (@foo:) + STATE_INLINE_TEXT => 2, # looking for member documentation + STATE_INLINE_END => 3, # done + STATE_INLINE_ERROR => 4, # error - Comment without header was found. + # Spit a warning as it's not + # proper kernel-doc and ignore the rest. +}; +my $inline_doc_state; #declaration types: can be # 'function', 'struct', 'union', 'enum', 'typedef' @@ -383,9 +388,9 @@ my $doc_decl = $doc_com . '(\w+)'; my $doc_sect = $doc_com . '([' . $doc_special . ']?[\w\s]+):(.*)'; my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; -my $doc_split_start = '^\s*/\*\*\s*$'; -my $doc_split_sect = '\s*\*\s*(@[\w\s]+):(.*)'; -my $doc_split_end = '^\s*\*/\s*$'; +my $doc_inline_start = '^\s*/\*\*\s*$'; +my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)'; +my $doc_inline_end = '^\s*\*/\s*$'; my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; my %constants; @@ -2497,8 +2502,8 @@ sub reset_state { $struct_actual = ""; $prototype = ""; - $state = 0; - $split_doc_state = 0; + $state = STATE_NORMAL; + $inline_doc_state = STATE_INLINE_NA; } sub tracepoint_munge($) { @@ -2707,14 +2712,14 @@ sub process_file($) { while (s/\\\s*$//) { $_ .= ; } - if ($state == 0) { + if ($state == STATE_NORMAL) { if (/$doc_start/o) { - $state = 1; # next line is always the function name + $state = STATE_NAME; # next line is always the function name $in_doc_sect = 0; } - } elsif ($state == 1) { # this line is the function name (always) + } elsif ($state == STATE_NAME) {# this line is the function name (always) if (/$doc_block/o) { - $state = 4; + $state = STATE_DOCBLOCK; $contents = ""; if ( $1 eq "" ) { $section = $section_intro; @@ -2728,7 +2733,7 @@ sub process_file($) { $identifier = $1; } - $state = 2; + $state = STATE_FIELD; if (/-(.*)/) { # strip leading/trailing/multiple spaces $descr= $1; @@ -2766,9 +2771,9 @@ sub process_file($) { print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", " - I thought it was a doc line\n"; ++$warnings; - $state = 0; + $state = STATE_NORMAL; } - } elsif ($state == 2) { # look for head: lines, and include content + } elsif ($state == STATE_FIELD) { # look for head: lines, and include content if (/$doc_sect/o) { $newsection = $1; $newcontents = $2; @@ -2806,7 +2811,7 @@ sub process_file($) { } $prototype = ""; - $state = 3; + $state = STATE_PROTO; $brcount = 0; # print STDERR "end of doc comment, looking for prototype\n"; } elsif (/$doc_content/) { @@ -2834,9 +2839,9 @@ sub process_file($) { print STDERR "${file}:$.: warning: bad line: $_"; ++$warnings; } - } elsif ($state == 5) { # scanning for split parameters + } elsif ($state == STATE_INLINE) { # scanning for inline parameters # First line (state 1) needs to be a @parameter - if ($split_doc_state == 1 && /$doc_split_sect/o) { + if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { $section = $1; $contents = $2; if ($contents ne "") { @@ -2846,37 +2851,37 @@ sub process_file($) { } $contents .= "\n"; } - $split_doc_state = 2; + $inline_doc_state = STATE_INLINE_TEXT; # Documentation block end */ - } elsif (/$doc_split_end/) { + } elsif (/$doc_inline_end/) { if (($contents ne "") && ($contents ne "\n")) { dump_section($file, $section, xml_escape($contents)); $section = $section_default; $contents = ""; } - $state = 3; - $split_doc_state = 0; + $state = STATE_PROTO; + $inline_doc_state = STATE_INLINE_NA; # Regular text } elsif (/$doc_content/) { - if ($split_doc_state == 2) { + if ($inline_doc_state == STATE_INLINE_TEXT) { $contents .= $1 . "\n"; - } elsif ($split_doc_state == 1) { - $split_doc_state = 4; + } elsif ($inline_doc_state == STATE_INLINE_NAME) { + $inline_doc_state = STATE_INLINE_ERROR; print STDERR "Warning(${file}:$.): "; print STDERR "Incorrect use of kernel-doc format: $_"; ++$warnings; } } - } elsif ($state == 3) { # scanning for function '{' (end of prototype) - if (/$doc_split_start/) { - $state = 5; - $split_doc_state = 1; + } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype) + if (/$doc_inline_start/) { + $state = STATE_INLINE; + $inline_doc_state = STATE_INLINE_NAME; } elsif ($decl_type eq 'function') { process_state3_function($_, $file); } else { process_state3_type($_, $file); } - } elsif ($state == 4) { + } elsif ($state == STATE_DOCBLOCK) { # Documentation block if (/$doc_block/) { dump_doc_section($file, $section, xml_escape($contents)); @@ -2907,7 +2912,7 @@ sub process_file($) { %sections = (); @sectionlist = (); $prototype = ""; - $state = 0; + $state = STATE_NORMAL; } elsif (/$doc_content/) { -- cgit v1.2.3 From b6c3f456cfed53e9f06f431270c9dcd52010785e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sun, 29 May 2016 22:19:35 +0300 Subject: kernel-doc: add names for output selection Make the output selection a bit more readable by adding constants for the various types of output selection. While at it, actually call the variable for choosing what to output $output_selection. No functional changes. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index cb5fd248ac57..dd08944b0a6f 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -312,7 +312,15 @@ my $no_doc_sections = 0; my @highlights = @highlights_man; my $blankline = $blankline_man; my $modulename = "Kernel API"; -my $function_only = 0; + +use constant { + OUTPUT_ALL => 0, # output all symbols and doc sections + OUTPUT_INCLUDE => 1, # output only specified symbols + OUTPUT_EXCLUDE => 2, # output everything except specified symbols + OUTPUT_EXPORTED => 3, # output exported symbols + OUTPUT_INTERNAL => 4, # output non-exported symbols +}; +my $output_selection = OUTPUT_ALL; my $show_not_found = 0; my @build_time; @@ -449,18 +457,18 @@ while ($ARGV[0] =~ m/^-(.*)/) { } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document $modulename = shift @ARGV; } elsif ($cmd eq "-function") { # to only output specific functions - $function_only = 1; + $output_selection = OUTPUT_INCLUDE; $function = shift @ARGV; $function_table{$function} = 1; - } elsif ($cmd eq "-nofunction") { # to only output specific functions - $function_only = 2; + } elsif ($cmd eq "-nofunction") { # output all except specific functions + $output_selection = OUTPUT_EXCLUDE; $function = shift @ARGV; $function_table{$function} = 1; } elsif ($cmd eq "-export") { # only exported symbols - $function_only = 3; + $output_selection = OUTPUT_EXPORTED; %function_table = () } elsif ($cmd eq "-internal") { # only non-exported symbols - $function_only = 4; + $output_selection = OUTPUT_INTERNAL; %function_table = () } elsif ($cmd eq "-v") { $verbose = 1; @@ -530,15 +538,17 @@ sub dump_doc_section { return; } - if (($function_only == 0) || - ( $function_only == 1 && defined($function_table{$name})) || - ( $function_only == 2 && !defined($function_table{$name}))) + if (($output_selection == OUTPUT_ALL) || + ($output_selection == OUTPUT_INCLUDE && + defined($function_table{$name})) || + ($output_selection == OUTPUT_EXCLUDE && + !defined($function_table{$name}))) { dump_section($file, $name, $contents); output_blockhead({'sectionlist' => \@sectionlist, 'sections' => \%sections, 'module' => $modulename, - 'content-only' => ($function_only != 0), }); + 'content-only' => ($output_selection != OUTPUT_ALL), }); } } @@ -1988,11 +1998,13 @@ sub output_declaration { my $name = shift; my $functype = shift; my $func = "output_${functype}_$output_mode"; - if (($function_only==0) || - ( ($function_only == 1 || $function_only == 3) && - defined($function_table{$name})) || - ( ($function_only == 2 || $function_only == 4) && - !($functype eq "function" && defined($function_table{$name})))) + if (($output_selection == OUTPUT_ALL) || + (($output_selection == OUTPUT_INCLUDE || + $output_selection == OUTPUT_EXPORTED) && + defined($function_table{$name})) || + (($output_selection == OUTPUT_EXCLUDE || + $output_selection == OUTPUT_INTERNAL) && + !($functype eq "function" && defined($function_table{$name})))) { &$func(@_); $section_counter++; @@ -2696,7 +2708,8 @@ sub process_file($) { } # two passes for -export and -internal - if ($function_only == 3 || $function_only == 4) { + if ($output_selection == OUTPUT_EXPORTED || + $output_selection == OUTPUT_INTERNAL) { while () { if (/$export_symbol/o) { $function_table{$2} = 1; @@ -2929,7 +2942,7 @@ sub process_file($) { } if ($initial_section_counter == $section_counter) { print STDERR "${file}:1: warning: no structured comments found\n"; - if (($function_only == 1) && ($show_not_found == 1)) { + if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) { print STDERR " Was looking for '$_'.\n" for keys %function_table; } if ($output_mode eq "xml") { -- cgit v1.2.3 From 9e72184b55df2b5b8ebdcf0470bd43ef32dc518f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sun, 29 May 2016 22:27:35 +0300 Subject: kernel-doc/rst: do not output DOC: section titles for requested ones If the user requests a specific DOC: section by name, do not output its section title. In these cases, the surrounding context already has a heading, and the DOC: section title is only used as an identifier and a heading for clarity in the source file. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index dd08944b0a6f..659d529b99d8 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1764,7 +1764,9 @@ sub output_blockhead_rst(%) { my ($parameter, $section); foreach $section (@{$args{'sectionlist'}}) { - print "**$section**\n\n"; + if ($output_selection != OUTPUT_INCLUDE) { + print "**$section**\n\n"; + } output_highlight_rst($args{'sections'}{$section}); print "\n"; } -- cgit v1.2.3 From a19bce6433c2566dd210f4245525c297ca952574 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 11:28:16 +0300 Subject: kernel-doc/rst: reference functions according to C domain spec The Sphinx C domain spec says function references should include the parens (). Signed-off-by: Jani Nikula --- scripts/kernel-doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 659d529b99d8..e8651d7cf1cd 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -280,7 +280,7 @@ my $blankline_text = ""; # rst-mode my @highlights_rst = ( [$type_constant, "``\$1``"], - [$type_func, "\\:c\\:func\\:`\$1`"], + [$type_func, "\\:c\\:func\\:`\$1()`"], [$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], [$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], [$type_struct, "\\:c\\:type\\:`struct \$1 <\$1>`"], -- cgit v1.2.3 From a7291e7e03f8b45a4b028a410063dc94f9bff8c0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 13:57:06 +0300 Subject: kernel-doc/rst: &foo references are more universal than structs It's possible to use &foo to reference structs, enums, typedefs, etc. in the Sphinx C domain. Thus do not prefix the links with "struct". Signed-off-by: Jani Nikula --- scripts/kernel-doc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e8651d7cf1cd..e7aa792e7f1b 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -283,7 +283,8 @@ my @highlights_rst = ( [$type_func, "\\:c\\:func\\:`\$1()`"], [$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], [$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], - [$type_struct, "\\:c\\:type\\:`struct \$1 <\$1>`"], + # in rst this can refer to any type + [$type_struct, "\\:c\\:type\\:`\$1`"], [$type_param, "**\$1**"] ); my $blankline_rst = "\n"; -- cgit v1.2.3 From 47ae7aed34ee9017e9eeb2ad066786239456a90f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 13:57:18 +0300 Subject: kernel-doc/rst: add support for &union foo and &typedef foo references Let the user use "&union foo" and "&typedef foo" to reference foo. The difference to using "union &foo", "typedef &foo", or just "&foo" (which are valid too) is that "union" and "typedef" become part of the link text. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e7aa792e7f1b..446c0912395e 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -212,6 +212,8 @@ my $type_struct_xml = '\\&((struct\s*)*[_\w]+)'; my $type_env = '(\$\w+)'; my $type_enum_full = '\&(enum)\s*([_\w]+)'; my $type_struct_full = '\&(struct)\s*([_\w]+)'; +my $type_typedef_full = '\&(typedef)\s*([_\w]+)'; +my $type_union_full = '\&(union)\s*([_\w]+)'; # Output conversion substitutions. # One for each output format @@ -283,6 +285,8 @@ my @highlights_rst = ( [$type_func, "\\:c\\:func\\:`\$1()`"], [$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], [$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], + [$type_typedef_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], + [$type_union_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], # in rst this can refer to any type [$type_struct, "\\:c\\:type\\:`\$1`"], [$type_param, "**\$1**"] -- cgit v1.2.3 From f3341dcf3bdcd1209b2911f35e4e970b789c4744 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 16:35:02 +0300 Subject: kernel-doc/rst: add support for struct/union/enum member references Link "&foo->bar", "&foo->bar()", "&foo.bar", and "&foo.bar()" to the struct/union/enum foo definition. The members themselves do not currently have anchors to link to, but this is better than nothing, and promotes a universal notation. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 446c0912395e..e0fd14f6d711 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -214,6 +214,8 @@ my $type_enum_full = '\&(enum)\s*([_\w]+)'; my $type_struct_full = '\&(struct)\s*([_\w]+)'; my $type_typedef_full = '\&(typedef)\s*([_\w]+)'; my $type_union_full = '\&(union)\s*([_\w]+)'; +my $type_member = '\&([_\w]+)((\.|->)[_\w]+)'; +my $type_member_func = $type_member . '\(\)'; # Output conversion substitutions. # One for each output format @@ -282,6 +284,9 @@ my $blankline_text = ""; # rst-mode my @highlights_rst = ( [$type_constant, "``\$1``"], + # Note: need to escape () to avoid func matching later + [$type_member_func, "\\:c\\:type\\:`\$1\$2\\\\(\\\\) <\$1>`"], + [$type_member, "\\:c\\:type\\:`\$1\$2 <\$1>`"], [$type_func, "\\:c\\:func\\:`\$1()`"], [$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], [$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], -- cgit v1.2.3 From 9c9193c49c1f1662b00476b3d0697a1be37c6b08 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 16:56:27 +0300 Subject: kernel-doc/rst: drop redundant unescape in highlighting This bit is already done by xml_unescape() above. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e0fd14f6d711..8f9eac509377 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1796,7 +1796,6 @@ sub output_highlight_rst { if ($line eq "") { print $lineprefix, $blankline; } else { - $line =~ s/\\\\\\/\&/g; print $lineprefix, $line; } print "\n"; -- cgit v1.2.3 From c099ff6989baf286da8eaed5c7b3d18ae60ea2e7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 17:18:17 +0300 Subject: kernel-doc/rst: highlight function/struct/enum purpose lines too Let the user use @foo, &bar, %baz, etc. in the first kernel-doc purpose line too. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 8f9eac509377..76bad55c031e 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1805,6 +1805,7 @@ sub output_highlight_rst { sub output_function_rst(%) { my %args = %{$_[0]}; my ($parameter, $section); + my $oldprefix = $lineprefix; my $start; print ".. c:function:: "; @@ -1829,9 +1830,13 @@ sub output_function_rst(%) { print $type . " " . $parameter; } } - print ")\n\n " . $args{'purpose'} . "\n\n"; + print ")\n\n"; + $lineprefix = " "; + output_highlight_rst($args{'purpose'}); + print "\n"; print ":Parameters:\n\n"; + $lineprefix = " "; foreach $parameter (@{$args{'parameterlist'}}) { my $parameter_name = $parameter; #$parameter_name =~ s/\[.*//; @@ -1844,15 +1849,14 @@ sub output_function_rst(%) { } if (defined($args{'parameterdescs'}{$parameter_name}) && $args{'parameterdescs'}{$parameter_name} ne $undescribed) { - my $oldprefix = $lineprefix; - $lineprefix = " "; output_highlight_rst($args{'parameterdescs'}{$parameter_name}); - $lineprefix = $oldprefix; } else { print "\n _undescribed_\n"; } print "\n"; } + + $lineprefix = $oldprefix; output_section_rst(@_); } @@ -1874,14 +1878,16 @@ sub output_section_rst(%) { sub output_enum_rst(%) { my %args = %{$_[0]}; my ($parameter); + my $oldprefix = $lineprefix; my $count; my $name = "enum " . $args{'enum'}; print "\n\n.. c:type:: " . $name . "\n\n"; - print " " . $args{'purpose'} . "\n\n"; + $lineprefix = " "; + output_highlight_rst($args{'purpose'}); + print "\n"; print "..\n\n:Constants:\n\n"; - my $oldprefix = $lineprefix; $lineprefix = " "; foreach $parameter (@{$args{'parameterlist'}}) { print " `$parameter`\n"; @@ -1892,6 +1898,7 @@ sub output_enum_rst(%) { } print "\n"; } + $lineprefix = $oldprefix; output_section_rst(@_); } @@ -1899,23 +1906,29 @@ sub output_enum_rst(%) { sub output_typedef_rst(%) { my %args = %{$_[0]}; my ($parameter); - my $count; + my $oldprefix = $lineprefix; my $name = "typedef " . $args{'typedef'}; ### FIXME: should the name below contain "typedef" or not? print "\n\n.. c:type:: " . $name . "\n\n"; - print " " . $args{'purpose'} . "\n\n"; + $lineprefix = " "; + output_highlight_rst($args{'purpose'}); + print "\n"; + $lineprefix = $oldprefix; output_section_rst(@_); } sub output_struct_rst(%) { my %args = %{$_[0]}; my ($parameter); + my $oldprefix = $lineprefix; my $name = $args{'type'} . " " . $args{'struct'}; print "\n\n.. c:type:: " . $name . "\n\n"; - print " " . $args{'purpose'} . "\n\n"; + $lineprefix = " "; + output_highlight_rst($args{'purpose'}); + print "\n"; print ":Definition:\n\n"; print " ::\n\n"; @@ -1944,6 +1957,7 @@ sub output_struct_rst(%) { print " };\n\n"; print ":Members:\n\n"; + $lineprefix = " "; foreach $parameter (@{$args{'parameterlist'}}) { ($parameter =~ /^#/) && next; @@ -1953,13 +1967,12 @@ sub output_struct_rst(%) { ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; $type = $args{'parametertypes'}{$parameter}; print " `$type $parameter`" . "\n"; - my $oldprefix = $lineprefix; - $lineprefix = " "; output_highlight_rst($args{'parameterdescs'}{$parameter_name}); - $lineprefix = $oldprefix; print "\n"; } print "\n"; + + $lineprefix = $oldprefix; output_section_rst(@_); } -- cgit v1.2.3 From 13901ef27c354e1bab49a30184ae3b96d96e521a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 08:57:29 +0300 Subject: kernel-doc: do not regard $, %, or & prefixes as special in section names The use of these is confusing in the script, and per this grep, they're not used anywhere anyway: $ git grep " \* [%$&][a-zA-Z0-9_]*:" -- *.[ch] | grep -v "\$\(Id\|Revision\|Date\)" While at it, throw out the constants array, nothing is ever put there again. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 76bad55c031e..f795660dfc7b 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -396,14 +396,12 @@ my $inline_doc_state; # 'function', 'struct', 'union', 'enum', 'typedef' my $decl_type; -my $doc_special = "\@\%\$\&"; - my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. my $doc_end = '\*/'; my $doc_com = '\s*\*\s*'; my $doc_com_body = '\s*\* ?'; my $doc_decl = $doc_com . '(\w+)'; -my $doc_sect = $doc_com . '([' . $doc_special . ']?[\w\s]+):(.*)'; +my $doc_sect = $doc_com . '(\@?[\w\s]+):(.*)'; my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_inline_start = '^\s*/\*\*\s*$'; @@ -411,7 +409,6 @@ my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)'; my $doc_inline_end = '^\s*\*/\s*$'; my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; -my %constants; my %parameterdescs; my @parameterlist; my %sections; @@ -511,11 +508,7 @@ sub dump_section { my $name = shift; my $contents = join "\n", @_; - if ($name =~ m/$type_constant/) { - $name = $1; -# print STDERR "constant section '$1' = '$contents'\n"; - $constants{$name} = $contents; - } elsif ($name =~ m/$type_param/) { + if ($name =~ m/$type_param/) { # print STDERR "parameter def '$1' = '$contents'\n"; $name = $1; $parameterdescs{$name} = $contents; @@ -2528,7 +2521,6 @@ sub dump_function($$) { sub reset_state { $function = ""; - %constants = (); %parameterdescs = (); %parametertypes = (); @parameterlist = (); @@ -2924,7 +2916,6 @@ sub process_file($) { dump_doc_section($file, $section, xml_escape($contents)); $contents = ""; $function = ""; - %constants = (); %parameterdescs = (); %parametertypes = (); @parameterlist = (); @@ -2942,7 +2933,6 @@ sub process_file($) { dump_doc_section($file, $section, xml_escape($contents)); $contents = ""; $function = ""; - %constants = (); %parameterdescs = (); %parametertypes = (); @parameterlist = (); -- cgit v1.2.3 From a0b96c2dbdb2c2511af407a2657d580f16c3b6f1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 22:04:06 +0300 Subject: kernel-doc: fix wrong code indentation No functional changes. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index f795660dfc7b..c154c3205df1 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2878,7 +2878,7 @@ sub process_file($) { substr($contents, 0, 1) eq "\t") { $contents = substr($contents, 1); } - $contents .= "\n"; + $contents .= "\n"; } $inline_doc_state = STATE_INLINE_TEXT; # Documentation block end */ -- cgit v1.2.3 From 830066a7a317e3e8872cb2d21dd24af0815f51f9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 22:04:33 +0300 Subject: kernel-doc/rst: blank lines in output are not needed Current approach leads to two blank lines, while one is enough. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index c154c3205df1..a89ff3ca366c 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1786,12 +1786,7 @@ sub output_highlight_rst { die $@ if $@; foreach $line (split "\n", $contents) { - if ($line eq "") { - print $lineprefix, $blankline; - } else { - print $lineprefix, $line; - } - print "\n"; + print $lineprefix . $line . "\n"; } } -- cgit v1.2.3 From 6450c8957ee3a8f58191c2ed6c5b71c7b7d1b310 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 22:04:42 +0300 Subject: kernel-doc: strip leading blank lines from inline doc comments The inline member markup allows whitespace lines before the actual documentation starts. Strip the leading blank lines. This improves the rst output. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index a89ff3ca366c..e8ea295567a3 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2889,6 +2889,10 @@ sub process_file($) { } elsif (/$doc_content/) { if ($inline_doc_state == STATE_INLINE_TEXT) { $contents .= $1 . "\n"; + # nuke leading blank lines + if ($contents =~ /^\s*$/) { + $contents = ""; + } } elsif ($inline_doc_state == STATE_INLINE_NAME) { $inline_doc_state = STATE_INLINE_ERROR; print STDERR "Warning(${file}:$.): "; -- cgit v1.2.3 From ecbcfba126e857de8dd4996fe31fad782dd6bae0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 26 May 2016 18:30:27 +0300 Subject: kernel-doc/rst: change the output layout Move away from field lists, and simply use **strong emphasis** for section headings on lines of their own. Do not use rst section headings, because their nesting depth depends on the surrounding context, which kernel-doc has no knowledge of. Also, they do not need to end up in any table of contexts or indexes. There are two related immediate benefits. Field lists are typically rendered in two columns, while the new style uses the horizontal width better. With no extra indent on the left, there's no need to be as fussy about it. Field lists are more susceptible to indentation problems than the new style. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e8ea295567a3..4f559de8b173 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1823,23 +1823,23 @@ sub output_function_rst(%) { output_highlight_rst($args{'purpose'}); print "\n"; - print ":Parameters:\n\n"; - $lineprefix = " "; + print "**Parameters**\n\n"; + $lineprefix = " "; foreach $parameter (@{$args{'parameterlist'}}) { my $parameter_name = $parameter; #$parameter_name =~ s/\[.*//; $type = $args{'parametertypes'}{$parameter}; if ($type ne "") { - print " ``$type $parameter``\n"; + print "``$type $parameter``\n"; } else { - print " ``$parameter``\n"; + print "``$parameter``\n"; } if (defined($args{'parameterdescs'}{$parameter_name}) && $args{'parameterdescs'}{$parameter_name} ne $undescribed) { output_highlight_rst($args{'parameterdescs'}{$parameter_name}); } else { - print "\n _undescribed_\n"; + print " _undescribed_\n"; } print "\n"; } @@ -1852,10 +1852,10 @@ sub output_section_rst(%) { my %args = %{$_[0]}; my $section; my $oldprefix = $lineprefix; - $lineprefix = " "; + $lineprefix = ""; foreach $section (@{$args{'sectionlist'}}) { - print ":$section:\n\n"; + print "**$section**\n\n"; output_highlight_rst($args{'sections'}{$section}); print "\n"; } @@ -1875,14 +1875,14 @@ sub output_enum_rst(%) { output_highlight_rst($args{'purpose'}); print "\n"; - print "..\n\n:Constants:\n\n"; - $lineprefix = " "; + print "**Constants**\n\n"; + $lineprefix = " "; foreach $parameter (@{$args{'parameterlist'}}) { - print " `$parameter`\n"; + print "``$parameter``\n"; if ($args{'parameterdescs'}{$parameter} ne $undescribed) { output_highlight_rst($args{'parameterdescs'}{$parameter}); } else { - print " undescribed\n"; + print " _undescribed_\n"; } print "\n"; } @@ -1918,12 +1918,12 @@ sub output_struct_rst(%) { output_highlight_rst($args{'purpose'}); print "\n"; - print ":Definition:\n\n"; - print " ::\n\n"; + print "**Definition**\n\n"; + print "::\n\n"; print " " . $args{'type'} . " " . $args{'struct'} . " {\n"; foreach $parameter (@{$args{'parameterlist'}}) { if ($parameter =~ /^#/) { - print " " . "$parameter\n"; + print " " . "$parameter\n"; next; } @@ -1944,8 +1944,8 @@ sub output_struct_rst(%) { } print " };\n\n"; - print ":Members:\n\n"; - $lineprefix = " "; + print "**Members**\n\n"; + $lineprefix = " "; foreach $parameter (@{$args{'parameterlist'}}) { ($parameter =~ /^#/) && next; @@ -1954,7 +1954,7 @@ sub output_struct_rst(%) { ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; $type = $args{'parametertypes'}{$parameter}; - print " `$type $parameter`" . "\n"; + print "``$type $parameter``\n"; output_highlight_rst($args{'parameterdescs'}{$parameter_name}); print "\n"; } -- cgit v1.2.3 From 0a7263014b3a0e05b52ccef314e2ccf6f4550a8b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sat, 28 May 2016 14:50:20 +0300 Subject: kernel-doc: improve handling of whitespace on the first line param description Handle whitespace on the first line of param text as if it was the empty string. There is no need to add the newline in this case. This improves the rst output in particular, where blank lines may be problematic in parameter lists. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 4f559de8b173..e93e796b17ce 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2814,11 +2814,11 @@ sub process_file($) { $in_doc_sect = 1; $in_purpose = 0; $contents = $newcontents; + while ((substr($contents, 0, 1) eq " ") || + substr($contents, 0, 1) eq "\t") { + $contents = substr($contents, 1); + } if ($contents ne "") { - while ((substr($contents, 0, 1) eq " ") || - substr($contents, 0, 1) eq "\t") { - $contents = substr($contents, 1); - } $contents .= "\n"; } $section = $newsection; -- cgit v1.2.3 From b7886de43c9f8a19685cd6e81135de63b9529911 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sat, 28 May 2016 00:41:50 +0300 Subject: kernel-doc: strip leading whitespace from continued param descs If a param description spans multiple lines, check any leading whitespace in the first continuation line, and remove same amount of whitespace from following lines. This allows indentation in the multi-line parameter descriptions for aesthetical reasons while not causing accidentally significant indentation in the rst output. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e93e796b17ce..f6f37e71dc08 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2701,6 +2701,7 @@ sub process_file($) { my $in_purpose = 0; my $initial_section_counter = $section_counter; my ($orig_file) = @_; + my $leading_space; if (defined($ENV{'SRCTREE'})) { $file = "$ENV{'SRCTREE'}" . "/" . $orig_file; @@ -2822,6 +2823,7 @@ sub process_file($) { $contents .= "\n"; } $section = $newsection; + $leading_space = undef; } elsif (/$doc_end/) { if (($contents ne "") && ($contents ne "\n")) { dump_section($file, $section, xml_escape($contents)); @@ -2856,7 +2858,19 @@ sub process_file($) { $declaration_purpose .= " " . xml_escape($1); $declaration_purpose =~ s/\s+/ /g; } else { - $contents .= $1 . "\n"; + my $cont = $1; + if ($section =~ m/^@/ || $section eq $section_context) { + if (!defined $leading_space) { + if ($cont =~ m/^(\s+)/) { + $leading_space = $1; + } else { + $leading_space = ""; + } + } + + $cont =~ s/^$leading_space//; + } + $contents .= $cont . "\n"; } } else { # i dont know - bad line? ignore. -- cgit v1.2.3 From d4b08e0cd2d74eb652d580607982d5054dc42991 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sat, 28 May 2016 00:48:17 +0300 Subject: kernel-doc/rst: use *undescribed* instead of _undescribed_ The latter isn't special to rst. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index f6f37e71dc08..19cee0cd53a3 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1839,7 +1839,7 @@ sub output_function_rst(%) { $args{'parameterdescs'}{$parameter_name} ne $undescribed) { output_highlight_rst($args{'parameterdescs'}{$parameter_name}); } else { - print " _undescribed_\n"; + print " *undescribed*\n"; } print "\n"; } @@ -1882,7 +1882,7 @@ sub output_enum_rst(%) { if ($args{'parameterdescs'}{$parameter} ne $undescribed) { output_highlight_rst($args{'parameterdescs'}{$parameter}); } else { - print " _undescribed_\n"; + print " *undescribed*\n"; } print "\n"; } -- cgit v1.2.3 From cddfe325afedb67a15fbe1a91e82ffed40236413 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sat, 28 May 2016 10:48:37 +0300 Subject: kernel-doc/rst: remove fixme comment Yes, for our purposes the type should contain typedef. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 19cee0cd53a3..425a94be04f6 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1897,7 +1897,6 @@ sub output_typedef_rst(%) { my $oldprefix = $lineprefix; my $name = "typedef " . $args{'typedef'}; - ### FIXME: should the name below contain "typedef" or not? print "\n\n.. c:type:: " . $name . "\n\n"; $lineprefix = " "; output_highlight_rst($args{'purpose'}); -- cgit v1.2.3 From f624adef3d0b9975076c1ba7549b81ed19e34437 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sun, 29 May 2016 11:35:28 +0300 Subject: kernel-doc: limit the "section header:" detection to a select few kernel-doc currently identifies anything matching "section header:" (specifically a string of word characters and spaces followed by a colon) as a new section in the documentation comment, and renders the section header accordingly. Unfortunately, this turns all uses of colon into sections, mostly unintentionally. Considering the output, erroneously creating sections when not intended is always worse than erroneously not creating sections when intended. For example, a line with "http://example.com" turns into a "http" heading followed by "//example.com" in normal text style, which is quite ugly. OTOH, "WARNING: Beware of the Leopard" is just fine even if "WARNING" does not turn into a heading. It is virtually impossible to change all the kernel-doc comments, either way. The compromise is to pick the most commonly used and depended on section headers (with variants) and accept them as section headers. The accepted section headers are, case insensitive: * description: * context: * return: * returns: Additionally, case sensitive: * @return: All of the above are commonly used in the kernel-doc comments, and will result in worse output if not identified as section headers. Also, kernel-doc already has some special handling for all of them, so there's nothing particularly controversial in adding more special treatment for them. While at it, improve the whitespace handling surrounding section names. Do not consider the whitespace as part of the name. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 425a94be04f6..20136564f264 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -401,7 +401,8 @@ my $doc_end = '\*/'; my $doc_com = '\s*\*\s*'; my $doc_com_body = '\s*\* ?'; my $doc_decl = $doc_com . '(\w+)'; -my $doc_sect = $doc_com . '(\@?[\w\s]+):(.*)'; +# @params and a strictly limited set of supported section names +my $doc_sect = $doc_com . '\s*(\@\w+|description|context|returns?)\s*:(.*)'; my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_inline_start = '^\s*/\*\*\s*$'; @@ -417,6 +418,8 @@ my $sectcheck; my $struct_actual; my $contents = ""; + +# the canonical section names. see also $doc_sect above. my $section_default = "Description"; # default section my $section_intro = "Introduction"; my $section = $section_default; @@ -2798,10 +2801,22 @@ sub process_file($) { $state = STATE_NORMAL; } } elsif ($state == STATE_FIELD) { # look for head: lines, and include content - if (/$doc_sect/o) { + if (/$doc_sect/i) { # case insensitive for supported section names $newsection = $1; $newcontents = $2; + # map the supported section names to the canonical names + if ($newsection =~ m/^description$/i) { + $newsection = $section_default; + } elsif ($newsection =~ m/^context$/i) { + $newsection = $section_context; + } elsif ($newsection =~ m/^returns?$/i) { + $newsection = $section_return; + } elsif ($newsection =~ m/^\@return$/) { + # special: @return is a section, not a param description + $newsection = $section_return; + } + if (($contents ne "") && ($contents ne "\n")) { if (!$in_doc_sect && $verbose) { print STDERR "${file}:$.: warning: contents before sections\n"; -- cgit v1.2.3 From 32217761ee9db0215350dfe1ca4e66f312fb8c54 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Sun, 29 May 2016 09:40:44 +0300 Subject: kernel-doc: concatenate contents of colliding sections If there are multiple sections with the same section name, the current implementation results in several sections by the same heading, with the content duplicated from the last section to all. Even if there's the error message, a more graceful approach is to combine all the identically named sections into one, with concatenated contents. With the supported sections already limited to select few, there are massively fewer collisions than there used to be, but this is still useful for e.g. when function parameters are documented in the middle of a documentation comment, with description spread out above and below. (This is not a recommended documentation style, but used in the kernel nonetheless.) We can now also demote the error to a warning. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 20136564f264..3ac4b57ed76a 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -524,11 +524,13 @@ sub dump_section { } else { # print STDERR "other section '$name' = '$contents'\n"; if (defined($sections{$name}) && ($sections{$name} ne "")) { - print STDERR "${file}:$.: error: duplicate section name '$name'\n"; - ++$errors; + print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; + ++$warnings; + $sections{$name} .= $contents; + } else { + $sections{$name} = $contents; + push @sectionlist, $name; } - $sections{$name} = $contents; - push @sectionlist, $name; } } -- cgit v1.2.3 From 2f4ad40a05265827848200689094348363027069 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 30 May 2016 11:21:06 +0300 Subject: kernel-doc: reset contents and section harder If the documentation comment does not have params or sections, the section heading may leak from the previous documentation comment. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 3ac4b57ed76a..0eb2e7b5bf10 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2763,6 +2763,8 @@ sub process_file($) { } $state = STATE_FIELD; + $contents = ""; + $section = $section_default; if (/-(.*)/) { # strip leading/trailing/multiple spaces $descr= $1; @@ -2960,6 +2962,7 @@ sub process_file($) { elsif (/$doc_end/) { dump_doc_section($file, $section, xml_escape($contents)); + $section = $section_default; $contents = ""; $function = ""; %parameterdescs = (); -- cgit v1.2.3 From ba35018593547eac69998e2571fc95cf620f2220 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 31 May 2016 18:09:12 +0300 Subject: Documentation/sphinx: fix kernel-doc extension on python3 Reconcile differences between python2 and python3 on dealing with stdout, stderr from Popen. This fixes "name 'unicode' is not defined" errors on python3. We'll need to try to keep the extension working on both python-sphinx and python3-sphinx so we don't need two copies. Reported-and-tested-by: Marius Vlad Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index 87a1332fe934..a6e170872c8a 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -23,6 +23,9 @@ # # Authors: # Jani Nikula +# +# Please make sure this works on both python2 and python3. +# import os import subprocess @@ -75,8 +78,10 @@ class KernelDocDirective(Directive): p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out, err = p.communicate() - # assume the kernel sources are utf-8 - out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8') + # python2 needs conversion to unicode. + # python3 with universal_newlines=True returns strings. + if sys.version_info.major < 3: + out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8') if p.returncode != 0: sys.stderr.write(err) -- cgit v1.2.3 From 9cc1a44c03113cb2f3be73650d7c611c3e273ada Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 1 Jun 2016 11:12:42 +0200 Subject: doc/sphinx: Pass right filename as source With this error output becomes almost readable. The line numbers are still totally bonghits, but that's a lot harder to pull out of kerneldoc. We'd essentially have to insert some special markers in the kernel-doc output, split the output along these markers and then insert each block separately using state_machine.insert_input(block, source, first_line) Cc: Jani Nikula Cc: linux-doc@vger.kernel.org Cc: Jonathan Corbet Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index a6e170872c8a..9fc2c27916a9 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -57,7 +57,7 @@ class KernelDocDirective(Directive): env.note_dependency(os.path.abspath(filename)) tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) - source = self.state_machine.input_lines.source(self.lineno - self.state_machine.input_offset - 1) + source = filename # FIXME: make this nicer and more robust against errors if 'export' in self.options: -- cgit v1.2.3 From ebff7f929b2a72fa614f5e95fd34c56c82ac9c36 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 1 Jun 2016 23:46:23 +0200 Subject: scripts/kernel-doc: Remove duplicated DOC: start handling Further up in the state machinery we switch from STATE_NAME to STATE_DOCBLOCK when we match /$doc_block/. Which means this block of code here is entirely unreachable, unless there are multiple DOC: sections within a single kernel-doc comment. Getting a list of all the files with more than one DOC: section using $ git grep -c " * DOC:" | grep -v ":1$" and then doing a full audit of them reveals there are no such comment blocks in the kernel. Supporting multiple DOC: sections in a single kernel-doc comment does not seem like a recommended way of doing things anyway, so nuke the code for simplicity. Cc: Jani Nikula Cc: linux-doc@vger.kernel.org Cc: Jonathan Corbet Signed-off-by: Daniel Vetter [Jani: amended the commit message] Signed-off-by: Jani Nikula --- scripts/kernel-doc | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 0eb2e7b5bf10..9fb26d142a56 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2942,24 +2942,7 @@ sub process_file($) { process_state3_type($_, $file); } } elsif ($state == STATE_DOCBLOCK) { - # Documentation block - if (/$doc_block/) { - dump_doc_section($file, $section, xml_escape($contents)); - $contents = ""; - $function = ""; - %parameterdescs = (); - %parametertypes = (); - @parameterlist = (); - %sections = (); - @sectionlist = (); - $prototype = ""; - if ( $1 eq "" ) { - $section = $section_intro; - } else { - $section = $1; - } - } - elsif (/$doc_end/) + if (/$doc_end/) { dump_doc_section($file, $section, xml_escape($contents)); $section = $section_default; -- cgit v1.2.3 From 16e161c8c67ac3b27cfc096cf07af9bceb144707 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 2 Jun 2016 14:59:18 +0200 Subject: doc/sphinx: Stop touching state_machine internals Instead of just forcefully inserting our kernel-doc input and letting the state machine stumble over it the recommended way is to create ViewList, parse that and then return the list of parsed nodes. Suggested by Jani. Cc: Jani Nikula Cc: linux-doc@vger.kernel.org Cc: Jonathan Corbet Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index 9fc2c27916a9..bd422870101e 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -32,6 +32,7 @@ import subprocess import sys from docutils import nodes, statemachine +from docutils.statemachine import ViewList from docutils.parsers.rst import directives from sphinx.util.compat import Directive @@ -92,8 +93,14 @@ class KernelDocDirective(Directive): sys.stderr.write(err) lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) - self.state_machine.insert_input(lines, source) - return [] + result = ViewList(lines, source) + + node = nodes.section() + node.document = self.state.document + self.state.nested_parse(result, self.content_offset, node) + + return node.children + except Exception as e: env.app.warn('kernel-doc \'%s\' processing failed with: %s' % (" ".join(cmd), str(e))) -- cgit v1.2.3 From b7afa92b55043b71a37a2f658553d3e260859859 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 1 Jun 2016 23:46:24 +0200 Subject: scripts/kernel-doc: Also give functions symbolic names state3 = prototype parsing, so name them accordingly. Cc: Jani Nikula Cc: linux-doc@vger.kernel.org Cc: Jonathan Corbet Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- scripts/kernel-doc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 9fb26d142a56..4da6f952d18b 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2593,7 +2593,7 @@ sub syscall_munge() { } } -sub process_state3_function($$) { +sub process_proto_function($$) { my $x = shift; my $file = shift; @@ -2623,7 +2623,7 @@ sub process_state3_function($$) { } } -sub process_state3_type($$) { +sub process_proto_type($$) { my $x = shift; my $file = shift; @@ -2937,9 +2937,9 @@ sub process_file($) { $state = STATE_INLINE; $inline_doc_state = STATE_INLINE_NAME; } elsif ($decl_type eq 'function') { - process_state3_function($_, $file); + process_proto_function($_, $file); } else { - process_state3_type($_, $file); + process_proto_type($_, $file); } } elsif ($state == STATE_DOCBLOCK) { if (/$doc_end/) -- cgit v1.2.3 From fac8434dab9645905d0f1f6baaa0f2e27daca435 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 May 2016 02:28:36 -0400 Subject: Documentation: Fix some grammar mistakes in sync_file.txt There are two sentences in the Sync File documentation where the english is a little off. This patch is an attempt to fix these. Signed-off-by: Javier Martinez Canillas Reviewed-by: Gustavo Padovan Signed-off-by: Jonathan Corbet --- Documentation/sync_file.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/sync_file.txt b/Documentation/sync_file.txt index eaf8297dbca2..e8e2ebafe5fa 100644 --- a/Documentation/sync_file.txt +++ b/Documentation/sync_file.txt @@ -6,8 +6,8 @@ This document serves as a guide for device drivers writers on what the sync_file API is, and how drivers can support it. Sync file is the carrier of -the fences(struct fence) that needs to synchronized between drivers or across -process boundaries. +the fences(struct fence) that are needed to synchronize between drivers or +across process boundaries. The sync_file API is meant to be used to send and receive fence information to/from userspace. It enables userspace to do explicit fencing, where instead @@ -32,7 +32,7 @@ in-fences and out-fences Sync files can go either to or from userspace. When a sync_file is sent from the driver to userspace we call the fences it contains 'out-fences'. They are related to a buffer that the driver is processing or is going to process, so -the driver an create out-fence to be able to notify, through fence_signal(), +the driver creates an out-fence to be able to notify, through fence_signal(), when it has finished using (or processing) that buffer. Out-fences are fences that the driver creates. -- cgit v1.2.3 From 3610a2add39365a0f153154c60169a66c616d50f Mon Sep 17 00:00:00 2001 From: Mike Danese Date: Thu, 19 May 2016 21:54:51 -0700 Subject: mpssd: fix buffer overflow warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compilation emits a warning in function ‘snprintf’, inlined from ‘set_cmdline’ at ../Documentation/mic/mpssd/mpssd.c:1541:9: /usr/include/x86_64-linux-gnu/bits/stdio2.h:64:10: warning: call to __builtin___snprintf_chk will always overflow destination buffer This was introduced in commit f4a66c204482 ("misc: mic: Update MIC host daemon with COSM changes") and is fixed by reverting the changes to the size argument of these snprintf statements. Cc: Ashutosh Dixit Signed-off-by: Mike Danese Signed-off-by: Jonathan Corbet --- Documentation/mic/mpssd/mpssd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/mic/mpssd/mpssd.c b/Documentation/mic/mpssd/mpssd.c index 30fb842a976d..49db1def1721 100644 --- a/Documentation/mic/mpssd/mpssd.c +++ b/Documentation/mic/mpssd/mpssd.c @@ -1538,9 +1538,9 @@ set_cmdline(struct mic_info *mic) len = snprintf(buffer, PATH_MAX, "clocksource=tsc highres=off nohz=off "); - len += snprintf(buffer + len, PATH_MAX, + len += snprintf(buffer + len, PATH_MAX - len, "cpufreq_on;corec6_off;pc3_off;pc6_off "); - len += snprintf(buffer + len, PATH_MAX, + len += snprintf(buffer + len, PATH_MAX - len, "ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0", mic->id + 1); -- cgit v1.2.3 From d81749ea8b1537a382535983a269fc69c696fa0e Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 23 May 2016 13:37:58 -0700 Subject: doc: clarify that trace_events= takes a comma-separated list It took me browsing through the source code to determine that I was, indeed, using the wrong delimiter in my command lines. So I might as well document it for the next person. Signed-off-by: Brian Norris Acked-by: Steven Rostedt Signed-off-by: Jonathan Corbet --- Documentation/kernel-parameters.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c958d1c..a2a662d4da83 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -3992,8 +3992,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. trace_event=[event-list] [FTRACE] Set and start specified trace events in order - to facilitate early boot debugging. - See also Documentation/trace/events.txt + to facilitate early boot debugging. The event-list is a + comma separated list of trace events to enable. See + also Documentation/trace/events.txt trace_options=[option-list] [FTRACE] Enable or disable tracer options at boot. -- cgit v1.2.3 From 49e48419ad0f1dd91f04bf932a4becae3cde514f Mon Sep 17 00:00:00 2001 From: Andy Deng Date: Sun, 29 May 2016 23:45:10 +0800 Subject: Documentation/zh_CN: update Chinese version CodingStyle Chinese version CodingStyle is a little outdate, it should be updated. This patch sync with the latest CodingStyle of all changes, new chapters (chapter 19 and chapter 20) have been translated. Signed-off-by: Andy Deng Signed-off-by: Jonathan Corbet --- Documentation/zh_CN/CodingStyle | 581 ++++++++++++++++++++++++---------------- 1 file changed, 350 insertions(+), 231 deletions(-) diff --git a/Documentation/zh_CN/CodingStyle b/Documentation/zh_CN/CodingStyle index 654afd72eb24..bbb9d6ae05ca 100644 --- a/Documentation/zh_CN/CodingStyle +++ b/Documentation/zh_CN/CodingStyle @@ -24,34 +24,33 @@ Documentation/CodingStyle的中文翻译 Linux内核代码风格 -这是一个简短的文档,描述了linux内核的首选代码风格。代码风格是因人而异的,而且我 -不愿意把我的观点强加给任何人,不过这里所讲述的是我必须要维护的代码所遵守的风格, -并且我也希望绝大多数其他代码也能遵守这个风格。请在写代码时至少考虑一下本文所述的 -风格。 +这是一个简短的文档,描述了 linux 内核的首选代码风格。代码风格是因人而异的,而且我 +不愿意把自己的观点强加给任何人,但这就像我去做任何事情都必须遵循的原则那样,我也 +希望在绝大多数事上保持这种的态度。请(在写代码时)至少考虑一下这里的代码风格。 -首先,我建议你打印一份GNU代码规范,然后不要读它。烧了它,这是一个具有重大象征性 -意义的动作。 +首先,我建议你打印一份 GNU 代码规范,然后不要读。烧了它,这是一个具有重大象征性意义 +的动作。 不管怎样,现在我们开始: - 第一章:缩进 + 第一章:缩进 -制表符是8个字符,所以缩进也是8个字符。有些异端运动试图将缩进变为4(乃至2)个字符 -深,这几乎相当于尝试将圆周率的值定义为3。 +制表符是 8 个字符,所以缩进也是 8 个字符。有些异端运动试图将缩进变为 4(甚至 2!) +个字符深,这几乎相当于尝试将圆周率的值定义为 3。 理由:缩进的全部意义就在于清楚的定义一个控制块起止于何处。尤其是当你盯着你的屏幕 -连续看了20小时之后,你将会发现大一点的缩进会使你更容易分辨缩进。 +连续看了 20 小时之后,你将会发现大一点的缩进会使你更容易分辨缩进。 -现在,有些人会抱怨8个字符的缩进会使代码向右边移动的太远,在80个字符的终端屏幕上 -就很难读这样的代码。这个问题的答案是,如果你需要3级以上的缩进,不管用何种方式你 +现在,有些人会抱怨 8 个字符的缩进会使代码向右边移动的太远,在 80 个字符的终端屏幕上 +就很难读这样的代码。这个问题的答案是,如果你需要 3 级以上的缩进,不管用何种方式你 的代码已经有问题了,应该修正你的程序。 -简而言之,8个字符的缩进可以让代码更容易阅读,还有一个好处是当你的函数嵌套太深的 +简而言之,8 个字符的缩进可以让代码更容易阅读,还有一个好处是当你的函数嵌套太深的 时候可以给你警告。留心这个警告。 -在switch语句中消除多级缩进的首选的方式是让“switch”和从属于它的“case”标签对齐于同 -一列,而不要“两次缩进”“case”标签。比如: +在 switch 语句中消除多级缩进的首选的方式是让 “switch” 和从属于它的 “case” 标签 +对齐于同一列,而不要 “两次缩进” “case” 标签。比如: switch (suffix) { case 'G': @@ -70,7 +69,6 @@ Documentation/CodingStyle的中文翻译 break; } - 不要把多个语句放在一行里,除非你有什么东西要隐藏: if (condition) do_this; @@ -79,7 +77,7 @@ Documentation/CodingStyle的中文翻译 也不要在一行里放多个赋值语句。内核代码风格超级简单。就是避免可能导致别人误读的表 达式。 -除了注释、文档和Kconfig之外,不要使用空格来缩进,前面的例子是例外,是有意为之。 +除了注释、文档和 Kconfig 之外,不要使用空格来缩进,前面的例子是例外,是有意为之。 选用一个好的编辑器,不要在行尾留空格。 @@ -88,27 +86,18 @@ Documentation/CodingStyle的中文翻译 代码风格的意义就在于使用平常使用的工具来维持代码的可读性和可维护性。 -每一行的长度的限制是80列,我们强烈建议您遵守这个惯例。 +每一行的长度的限制是 80 列,我们强烈建议您遵守这个惯例。 -长于80列的语句要打散成有意义的片段。每个片段要明显短于原来的语句,而且放置的位置 -也明显的靠右。同样的规则也适用于有很长参数列表的函数头。长字符串也要打散成较短的 -字符串。唯一的例外是超过80列可以大幅度提高可读性并且不会隐藏信息的情况。 - -void fun(int a, int b, int c) -{ - if (condition) - printk(KERN_WARNING "Warning this is a long printk with " - "3 parameters a: %u b: %u " - "c: %u \n", a, b, c); - else - next_statement; -} +长于 80 列的语句要打散成有意义的片段。除非超过 80 列能显著增加可读性,并且不会隐藏 +信息。子片段要明显短于母片段,并明显靠右。这同样适用于有着很长参数列表的函数头。 +然而,绝对不要打散对用户可见的字符串,例如 printk 信息,因为这将导致无法 grep 这些 +信息。 第三章:大括号和空格的放置 C语言风格中另外一个常见问题是大括号的放置。和缩进大小不同,选择或弃用某种放置策 -略并没有多少技术上的原因,不过首选的方式,就像Kernighan和Ritchie展示给我们的,是 -把起始大括号放在行尾,而把结束大括号放在行首,所以: +略并没有多少技术上的原因,不过首选的方式,就像 Kernighan 和 Ritchie 展示给我们的, +是把起始大括号放在行尾,而把结束大括号放在行首,所以: if (x is true) { we do y @@ -134,12 +123,12 @@ C语言风格中另外一个常见问题是大括号的放置。和缩进大小 body of function } -全世界的异端可能会抱怨这个不一致性是……呃……不一致的,不过所有思维健全的人都知道( -a)K&R是_正确的_,并且(b)K&R是正确的。此外,不管怎样函数都是特殊的(在C语言中 -,函数是不能嵌套的)。 +全世界的异端可能会抱怨这个不一致性是……呃……不一致的,不过所有思维健全的人都知道 +(a) K&R 是 _正确的_,并且 (b) K&R 是正确的。此外,不管怎样函数都是特殊的(C +函数是不能嵌套的)。 -注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,也就是do语句中的 -“while”或者if语句中的“else”,像这样: +注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,也就是 do 语句中的 +“while” 或者 if 语句中的 “else”,像这样: do { body of do-loop @@ -158,41 +147,50 @@ a)K&R是_正确的_,并且(b)K&R是正确的。此外,不管怎样函 理由:K&R。 也请注意这种大括号的放置方式也能使空(或者差不多空的)行的数量最小化,同时不失可 -读性。因此,由于你的屏幕上的新行是不可再生资源(想想25行的终端屏幕),你将会有更 +读性。因此,由于你的屏幕上的新行是不可再生资源(想想 25 行的终端屏幕),你将会有更 多的空行来放置注释。 当只有一个单独的语句的时候,不用加不必要的大括号。 -if (condition) - action(); + if (condition) + action(); + +和 + + if (condition) + do_this(); + else + do_that(); -这点不适用于本身为某个条件语句的一个分支的单独语句。这时需要在两个分支里都使用大 -括号。 +这并不适用于只有一个条件分支是单语句的情况;这时所有分支都要使用大括号: -if (condition) { - do_this(); - do_that(); -} else { - otherwise(); -} + if (condition) { + do_this(); + do_that(); + } else { + otherwise(); + } 3.1:空格 -Linux内核的空格使用方式(主要)取决于它是用于函数还是关键字。(大多数)关键字后 -要加一个空格。值得注意的例外是sizeof、typeof、alignof和__attribute__,这些关键字 -某些程度上看起来更像函数(它们在Linux里也常常伴随小括号而使用,尽管在C语言里这样 -的小括号不是必需的,就像“struct fileinfo info”声明过后的“sizeof info”)。 +Linux 内核的空格使用方式(主要)取决于它是用于函数还是关键字。(大多数)关键字后 +要加一个空格。值得注意的例外是 sizeof、typeof、alignof 和 __attribute__,这些 +关键字某些程度上看起来更像函数(它们在 Linux 里也常常伴随小括号而使用,尽管在 C 里 +这样的小括号不是必需的,就像 “struct fileinfo info” 声明过后的 “sizeof info”)。 所以在这些关键字之后放一个空格: + if, switch, case, for, do, while -但是不要在sizeof、typeof、alignof或者__attribute__这些关键字之后放空格。例如, + +但是不要在 sizeof、typeof、alignof 或者 __attribute__ 这些关键字之后放空格。例如, + s = sizeof(struct file); 不要在小括号里的表达式两侧加空格。这是一个反例: s = sizeof( struct file ); -当声明指针类型或者返回指针类型的函数时,“*”的首选使用方式是使之靠近变量名或者函 +当声明指针类型或者返回指针类型的函数时,“*” 的首选使用方式是使之靠近变量名或者函 数名,而不是靠近类型名。例子: char *linux_banner; @@ -204,15 +202,18 @@ Linux内核的空格使用方式(主要)取决于它是用于函数还是关 = + - < > * / % | & ^ <= >= == != ? : 但是一元操作符后不要加空格: + & * + - ~ ! sizeof typeof alignof __attribute__ defined 后缀自加和自减一元操作符前不加空格: + ++ -- 前缀自加和自减一元操作符后不加空格: + ++ -- -“.”和“->”结构体成员操作符前后不加空格。 +‘.’ 和 “->” 结构体成员操作符前后不加空格。 不要在行尾留空白。有些可以自动缩进的编辑器会在新行的行首加入适量的空白,然后你 就可以直接在那一行输入代码。不过假如你最后没有在那一行输入代码,有些编辑器就不 @@ -225,23 +226,23 @@ Linux内核的空格使用方式(主要)取决于它是用于函数还是关 第四章:命名 -C是一个简朴的语言,你的命名也应该这样。和Modula-2和Pascal程序员不同,C程序员不使 -用类似ThisVariableIsATemporaryCounter这样华丽的名字。C程序员会称那个变量为“tmp” -,这样写起来会更容易,而且至少不会令其难于理解。 +C是一个简朴的语言,你的命名也应该这样。和 Modula-2 和 Pascal 程序员不同,C 程序员 +不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字。C 程序员会称那个变量 +为 “tmp”,这样写起来会更容易,而且至少不会令其难于理解。 不过,虽然混用大小写的名字是不提倡使用的,但是全局变量还是需要一个具描述性的名字 -。称一个全局函数为“foo”是一个难以饶恕的错误。 +。称一个全局函数为 “foo” 是一个难以饶恕的错误。 全局变量(只有当你真正需要它们的时候再用它)需要有一个具描述性的名字,就像全局函 -数。如果你有一个可以计算活动用户数量的函数,你应该叫它“count_active_users()”或者 -类似的名字,你不应该叫它“cntuser()”。 +数。如果你有一个可以计算活动用户数量的函数,你应该叫它 “count_active_users()” +或者类似的名字,你不应该叫它 “cntuser()”。 在函数名中包含函数类型(所谓的匈牙利命名法)是脑子出了问题——编译器知道那些类型而 且能够检查那些类型,这样做只能把程序员弄糊涂了。难怪微软总是制造出有问题的程序。 本地变量名应该简短,而且能够表达相关的含义。如果你有一些随机的整数型的循环计数器 -,它应该被称为“i”。叫它“loop_counter”并无益处,如果它没有被误解的可能的话。类似 -的,“tmp”可以用来称呼任意类型的临时变量。 +,它应该被称为 “i”。叫它 “loop_counter” 并无益处,如果它没有被误解的可能的话。 +类似的,“tmp” 可以用来称呼任意类型的临时变量。 如果你怕混淆了你的本地变量名,你就遇到另一个问题了,叫做函数增长荷尔蒙失衡综合症 。请看第六章(函数)。 @@ -249,9 +250,9 @@ C是一个简朴的语言,你的命名也应该这样。和Modula-2和Pascal 第五章:Typedef -不要使用类似“vps_t”之类的东西。 +不要使用类似 “vps_t” 之类的东西。 -对结构体和指针使用typedef是一个错误。当你在代码里看到: +对结构体和指针使用 typedef 是一个错误。当你在代码里看到: vps_t a; @@ -261,91 +262,91 @@ C是一个简朴的语言,你的命名也应该这样。和Modula-2和Pascal struct virtual_container *a; -你就知道“a”是什么了。 +你就知道 “a” 是什么了。 -很多人认为typedef“能提高可读性”。实际不是这样的。它们只在下列情况下有用: +很多人认为 typedef “能提高可读性”。实际不是这样的。它们只在下列情况下有用: - (a) 完全不透明的对象(这种情况下要主动使用typedef来隐藏这个对象实际上是什么)。 + (a) 完全不透明的对象(这种情况下要主动使用 typedef 来隐藏这个对象实际上是什么)。 - 例如:“pte_t”等不透明对象,你只能用合适的访问函数来访问它们。 + 例如:“pte_t” 等不透明对象,你只能用合适的访问函数来访问它们。 - 注意!不透明性和“访问函数”本身是不好的。我们使用pte_t等类型的原因在于真的是 + 注意!不透明性和“访问函数”本身是不好的。我们使用 pte_t 等类型的原因在于真的是 完全没有任何共用的可访问信息。 - (b) 清楚的整数类型,如此,这层抽象就可以帮助消除到底是“int”还是“long”的混淆。 + (b) 清楚的整数类型,如此,这层抽象就可以帮助消除到底是 “int” 还是 “long” 的混淆。 - u8/u16/u32是完全没有问题的typedef,不过它们更符合类别(d)而不是这里。 + u8/u16/u32 是完全没有问题的 typedef,不过它们更符合类别 (d) 而不是这里。 - 再次注意!要这样做,必须事出有因。如果某个变量是“unsigned long“,那么没有必要 + 再次注意!要这样做,必须事出有因。如果某个变量是 “unsigned long“,那么没有必要 typedef unsigned long myflags_t; - 不过如果有一个明确的原因,比如它在某种情况下可能会是一个“unsigned int”而在 - 其他情况下可能为“unsigned long”,那么就不要犹豫,请务必使用typedef。 + 不过如果有一个明确的原因,比如它在某种情况下可能会是一个 “unsigned int” 而在 + 其他情况下可能为 “unsigned long”,那么就不要犹豫,请务必使用 typedef。 (c) 当你使用sparse按字面的创建一个新类型来做类型检查的时候。 (d) 和标准C99类型相同的类型,在某些例外的情况下。 - 虽然让眼睛和脑筋来适应新的标准类型比如“uint32_t”不需要花很多时间,可是有些 + 虽然让眼睛和脑筋来适应新的标准类型比如 “uint32_t” 不需要花很多时间,可是有些 人仍然拒绝使用它们。 - 因此,Linux特有的等同于标准类型的“u8/u16/u32/u64”类型和它们的有符号类型是被 + 因此,Linux 特有的等同于标准类型的 “u8/u16/u32/u64” 类型和它们的有符号类型是被 允许的——尽管在你自己的新代码中,它们不是强制要求要使用的。 当编辑已经使用了某个类型集的已有代码时,你应该遵循那些代码中已经做出的选择。 (e) 可以在用户空间安全使用的类型。 - 在某些用户空间可见的结构体里,我们不能要求C99类型而且不能用上面提到的“u32” - 类型。因此,我们在与用户空间共享的所有结构体中使用__u32和类似的类型。 + 在某些用户空间可见的结构体里,我们不能要求C99类型而且不能用上面提到的 “u32” + 类型。因此,我们在与用户空间共享的所有结构体中使用 __u32 和类似的类型。 -可能还有其他的情况,不过基本的规则是永远不要使用typedef,除非你可以明确的应用上 +可能还有其他的情况,不过基本的规则是永远不要使用 typedef,除非你可以明确的应用上 述某个规则中的一个。 总的来说,如果一个指针或者一个结构体里的元素可以合理的被直接访问到,那么它们就不 -应该是一个typedef。 +应该是一个 typedef。 第六章:函数 函数应该简短而漂亮,并且只完成一件事情。函数应该可以一屏或者两屏显示完(我们都知 -道ISO/ANSI屏幕大小是80x24),只做一件事情,而且把它做好。 +道 ISO/ANSI 屏幕大小是 80x24),只做一件事情,而且把它做好。 一个函数的最大长度是和该函数的复杂度和缩进级数成反比的。所以,如果你有一个理论上 -很简单的只有一个很长(但是简单)的case语句的函数,而且你需要在每个case里做很多很 -小的事情,这样的函数尽管很长,但也是可以的。 +很简单的只有一个很长(但是简单)的 case 语句的函数,而且你需要在每个 case 里做 +很多很小的事情,这样的函数尽管很长,但也是可以的。 不过,如果你有一个复杂的函数,而且你怀疑一个天分不是很高的高中一年级学生可能甚至 搞不清楚这个函数的目的,你应该严格的遵守前面提到的长度限制。使用辅助函数,并为之 取个具描述性的名字(如果你觉得它们的性能很重要的话,可以让编译器内联它们,这样的 效果往往会比你写一个复杂函数的效果要好。) -函数的另外一个衡量标准是本地变量的数量。此数量不应超过5-10个,否则你的函数就有 +函数的另外一个衡量标准是本地变量的数量。此数量不应超过 5-10 个,否则你的函数就有 问题了。重新考虑一下你的函数,把它分拆成更小的函数。人的大脑一般可以轻松的同时跟 -踪7个不同的事物,如果再增多的话,就会糊涂了。即便你聪颖过人,你也可能会记不清你2 -个星期前做过的事情。 +踪 7 个不同的事物,如果再增多的话,就会糊涂了。即便你聪颖过人,你也可能会记不清你 +2 个星期前做过的事情。 -在源文件里,使用空行隔开不同的函数。如果该函数需要被导出,它的EXPORT*宏应该紧贴 +在源文件里,使用空行隔开不同的函数。如果该函数需要被导出,它的 EXPORT* 宏应该紧贴 在它的结束大括号之下。比如: -int system_is_up(void) -{ - return system_state == SYSTEM_RUNNING; -} -EXPORT_SYMBOL(system_is_up); + int system_is_up(void) + { + return system_state == SYSTEM_RUNNING; + } + EXPORT_SYMBOL(system_is_up); -在函数原型中,包含函数名和它们的数据类型。虽然C语言里没有这样的要求,在Linux里这 +在函数原型中,包含函数名和它们的数据类型。虽然C语言里没有这样的要求,在 Linux 里这 是提倡的做法,因为这样可以很简单的给读者提供更多的有价值的信息。 第七章:集中的函数退出途径 -虽然被某些人声称已经过时,但是goto语句的等价物还是经常被编译器所使用,具体形式是 +虽然被某些人声称已经过时,但是 goto 语句的等价物还是经常被编译器所使用,具体形式是 无条件跳转指令。 -当一个函数从多个位置退出并且需要做一些通用的清理工作的时候,goto的好处就显现出来 -了。 +当一个函数从多个位置退出,并且需要做一些类似清理的常见操作时,goto 语句就很方便了。 +如果并不需要清理操作,那么直接 return 即可。 理由是: @@ -354,26 +355,37 @@ EXPORT_SYMBOL(system_is_up); - 可以避免由于修改时忘记更新某个单独的退出点而导致的错误 - 减轻了编译器的工作,无需删除冗余代码;) -int fun(int a) -{ - int result = 0; - char *buffer = kmalloc(SIZE); - - if (buffer == NULL) - return -ENOMEM; - - if (condition1) { - while (loop1) { - ... + int fun(int a) + { + int result = 0; + char *buffer; + + buffer = kmalloc(SIZE, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + if (condition1) { + while (loop1) { + ... + } + result = 1; + goto out_buffer; } - result = 1; - goto out; + ... + out_buffer: + kfree(buffer); + return result; } - ... -out: - kfree(buffer); - return result; -} + +一个需要注意的常见错误是“一个 err 错误”,就像这样: + + err: + kfree(foo->bar); + kfree(foo); + return ret; + +这段代码的错误是,在某些退出路径上 “foo” 是 NULL。通常情况下,通过把它分离成两个 +错误标签 “err_bar:” 和 “err_foo:” 来修复这个错误。 第八章:注释 @@ -386,10 +398,10 @@ out: 加太多。你应该做的,是把注释放在函数的头部,告诉人们它做了什么,也可以加上它做这 些事情的原因。 -当注释内核API函数时,请使用kernel-doc格式。请看 -Documentation/kernel-doc-nano-HOWTO.txt和scripts/kernel-doc以获得详细信息。 +当注释内核API函数时,请使用 kernel-doc 格式。请看 +Documentation/kernel-doc-nano-HOWTO.txt和scripts/kernel-doc 以获得详细信息。 -Linux的注释风格是C89“/* ... */”风格。不要使用C99风格“// ...”注释。 +Linux的注释风格是 C89 “/* ... */” 风格。不要使用 C99 风格 “// ...” 注释。 长(多行)的首选注释风格是: @@ -402,6 +414,15 @@ Linux的注释风格是C89“/* ... */”风格。不要使用C99风格“// ... * with beginning and ending almost-blank lines. */ +对于在 net/ 和 drivers/net/ 的文件,首选的长(多行)注释风格有些不同。 + + /* The preferred comment style for files in net/ and drivers/net + * looks like this. + * + * It is nearly the same as the generally preferred comment style, + * but there is no initial almost-blank line. + */ + 注释数据也是很重要的,不管是基本类型还是衍生类型。为了方便实现这一点,每一行应只 声明一个数据(不要使用逗号来一次声明多个数据)。这样你就有空间来为每个数据写一段 小注释来解释它们的用途了。 @@ -409,49 +430,63 @@ Linux的注释风格是C89“/* ... */”风格。不要使用C99风格“// ... 第九章:你已经把事情弄糟了 -这没什么,我们都是这样。可能你的使用了很长时间Unix的朋友已经告诉你“GNU emacs”能 -自动帮你格式化C源代码,而且你也注意到了,确实是这样,不过它所使用的默认值和我们 -想要的相去甚远(实际上,甚至比随机打的还要差——无数个猴子在GNU emacs里打字永远不 -会创造出一个好程序)(译注:请参考Infinite Monkey Theorem) - -所以你要么放弃GNU emacs,要么改变它让它使用更合理的设定。要采用后一个方案,你可 -以把下面这段粘贴到你的.emacs文件里。 - -(defun linux-c-mode () - "C mode with adjusted defaults for use with the Linux kernel." - (interactive) - (c-mode) - (c-set-style "K&R") - (setq tab-width 8) - (setq indent-tabs-mode t) - (setq c-basic-offset 8)) - -这样就定义了M-x linux-c-mode命令。当你hack一个模块的时候,如果你把字符串 --*- linux-c -*-放在头两行的某个位置,这个模式将会被自动调用。如果你希望在你修改 -/usr/src/linux里的文件时魔术般自动打开linux-c-mode的话,你也可能需要添加 - -(setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" . linux-c-mode) - auto-mode-alist)) - -到你的.emacs文件里。 - -不过就算你尝试让emacs正确的格式化代码失败了,也并不意味着你失去了一切:还可以用“ -indent”。 - -不过,GNU indent也有和GNU emacs一样有问题的设定,所以你需要给它一些命令选项。不 -过,这还不算太糟糕,因为就算是GNU indent的作者也认同K&R的权威性(GNU的人并不是坏 -人,他们只是在这个问题上被严重的误导了),所以你只要给indent指定选项“-kr -i8” -(代表“K&R,8个字符缩进”),或者使用“scripts/Lindent”,这样就可以以最时髦的方式 +这没什么,我们都是这样。可能你的使用了很长时间 Unix 的朋友已经告诉你 “GNU emacs” 能 +自动帮你格式化 C 源代码,而且你也注意到了,确实是这样,不过它所使用的默认值和我们 +想要的相去甚远(实际上,甚至比随机打的还要差——无数个猴子在 GNU emacs 里打字永远不 +会创造出一个好程序)(译注:请参考 Infinite Monkey Theorem) + +所以你要么放弃 GNU emacs,要么改变它让它使用更合理的设定。要采用后一个方案,你可 +以把下面这段粘贴到你的 .emacs 文件里。 + +(defun c-lineup-arglist-tabs-only (ignored) + "Line up argument lists by tabs, not spaces" + (let* ((anchor (c-langelem-pos c-syntactic-element)) + (column (c-langelem-2nd-pos c-syntactic-element)) + (offset (- (1+ column) anchor)) + (steps (floor offset c-basic-offset))) + (* (max steps 1) + c-basic-offset))) + +(add-hook 'c-mode-common-hook + (lambda () + ;; Add kernel style + (c-add-style + "linux-tabs-only" + '("linux" (c-offsets-alist + (arglist-cont-nonempty + c-lineup-gcc-asm-reg + c-lineup-arglist-tabs-only)))))) + +(add-hook 'c-mode-hook + (lambda () + (let ((filename (buffer-file-name))) + ;; Enable kernel mode for the appropriate files + (when (and filename + (string-match (expand-file-name "~/src/linux-trees") + filename)) + (setq indent-tabs-mode t) + (setq show-trailing-whitespace t) + (c-set-style "linux-tabs-only"))))) + +这会让 emacs 在 ~/src/linux-trees 目录下的 C 源文件获得更好的内核代码风格。 + +不过就算你尝试让 emacs 正确的格式化代码失败了,也并不意味着你失去了一切:还可以用 +“indent”。 + +不过,GNU indent 也有和 GNU emacs 一样有问题的设定,所以你需要给它一些命令选项。不 +过,这还不算太糟糕,因为就算是 GNU indent 的作者也认同 K&R 的权威性(GNU 的人并不是 +坏人,他们只是在这个问题上被严重的误导了),所以你只要给 indent 指定选项 “-kr -i8” +(代表 “K&R,8 个字符缩进”),或者使用 “scripts/Lindent”,这样就可以以最时髦的方式 缩进源代码。 -“indent”有很多选项,特别是重新格式化注释的时候,你可能需要看一下它的手册页。不过 -记住:“indent”不能修正坏的编程习惯。 +“indent” 有很多选项,特别是重新格式化注释的时候,你可能需要看一下它的手册页。不过 +记住:“indent” 不能修正坏的编程习惯。 - 第十章:Kconfig配置文件 + 第十章:Kconfig 配置文件 -对于遍布源码树的所有Kconfig*配置文件来说,它们缩进方式与C代码相比有所不同。紧挨 -在“config”定义下面的行缩进一个制表符,帮助信息则再多缩进2个空格。比如: +对于遍布源码树的所有 Kconfig* 配置文件来说,它们缩进方式与 C 代码相比有所不同。紧挨 +在 “config” 定义下面的行缩进一个制表符,帮助信息则再多缩进 2 个空格。比如: config AUDIT bool "Auditing support" @@ -470,7 +505,7 @@ config ADFS_FS_RW depends on ADFS_FS ... -要查看配置文件的完整文档,请看Documentation/kbuild/kconfig-language.txt。 +要查看配置文件的完整文档,请看 Documentation/kbuild/kconfig-language.txt。 第十一章:数据结构 @@ -489,11 +524,11 @@ config ADFS_FS_RW 很多数据结构实际上有2级引用计数,它们通常有不同“类”的用户。子类计数器统计子类用 户的数量,每当子类计数器减至零时,全局计数器减一。 -这种“多级引用计数”的例子可以在内存管理(“struct mm_struct”:mm_users和mm_count) +这种“多级引用计数”的例子可以在内存管理(“struct mm_struct”:mm_users 和 mm_count) 和文件系统(“struct super_block”:s_count和s_active)中找到。 记住:如果另一个执行线索可以找到你的数据结构,但是这个数据结构没有引用计数器,这 -里几乎肯定是一个bug。 +里几乎肯定是一个 bug。 第十二章:宏,枚举和RTL @@ -508,102 +543,128 @@ config ADFS_FS_RW 一般的,如果能写成内联函数就不要写成像函数的宏。 -含有多个语句的宏应该被包含在一个do-while代码块里: +含有多个语句的宏应该被包含在一个 do-while 代码块里: -#define macrofun(a, b, c) \ - do { \ - if (a == 5) \ - do_this(b, c); \ - } while (0) + #define macrofun(a, b, c) \ + do { \ + if (a == 5) \ + do_this(b, c); \ + } while (0) 使用宏的时候应避免的事情: 1) 影响控制流程的宏: -#define FOO(x) \ - do { \ - if (blah(x) < 0) \ - return -EBUGGERED; \ - } while(0) + #define FOO(x) \ + do { \ + if (blah(x) < 0) \ + return -EBUGGERED; \ + } while (0) 非常不好。它看起来像一个函数,不过却能导致“调用”它的函数退出;不要打乱读者大脑里 的语法分析器。 2) 依赖于一个固定名字的本地变量的宏: -#define FOO(val) bar(index, val) + #define FOO(val) bar(index, val) 可能看起来像是个不错的东西,不过它非常容易把读代码的人搞糊涂,而且容易导致看起来 不相关的改动带来错误。 -3) 作为左值的带参数的宏: FOO(x) = y;如果有人把FOO变成一个内联函数的话,这种用 +3) 作为左值的带参数的宏: FOO(x) = y;如果有人把 FOO 变成一个内联函数的话,这种用 法就会出错了。 4) 忘记了优先级:使用表达式定义常量的宏必须将表达式置于一对小括号之内。带参数的 宏也要注意此类问题。 -#define CONSTANT 0x4000 -#define CONSTEXP (CONSTANT | 3) + #define CONSTANT 0x4000 + #define CONSTEXP (CONSTANT | 3) + +5) 在宏里定义类似函数的本地变量时命名冲突: -cpp手册对宏的讲解很详细。Gcc internals手册也详细讲解了RTL(译注:register + #define FOO(x) \ + ({ \ + typeof(x) ret; \ + ret = calc_ret(x); \ + (ret); \ + }) + +ret 是本地变量的通用名字 - __foo_ret 更不容易与一个已存在的变量冲突。 + +cpp 手册对宏的讲解很详细。gcc internals 手册也详细讲解了 RTL(译注:register transfer language),内核里的汇编语言经常用到它。 第十三章:打印内核消息 内核开发者应该是受过良好教育的。请一定注意内核信息的拼写,以给人以好的印象。不要 -用不规范的单词比如“dont”,而要用“do not”或者“don't”。保证这些信息简单、明了、无 -歧义。 +用不规范的单词比如 “dont”,而要用 “do not”或者 “don't”。保证这些信息简单、明了、 +无歧义。 内核信息不必以句号(译注:英文句号,即点)结束。 -在小括号里打印数字(%d)没有任何价值,应该避免这样做。 +在小括号里打印数字 (%d) 没有任何价值,应该避免这样做。 -里有一些驱动模型诊断宏,你应该使用它们,以确保信息对应于正确的 -设备和驱动,并且被标记了正确的消息级别。这些宏有:dev_err(), dev_warn(), -dev_info()等等。对于那些不和某个特定设备相关连的信息,定义了 -pr_debug()和pr_info()。 + 里有一些驱动模型诊断宏,你应该使用它们,以确保信息对应于正确的 +设备和驱动,并且被标记了正确的消息级别。这些宏有:dev_err(),dev_warn(), +dev_info() 等等。对于那些不和某个特定设备相关连的信息, 定义了 +pr_notice(),pr_info(),pr_warn(),pr_err() 和其他。 -写出好的调试信息可以是一个很大的挑战;当你写出来之后,这些信息在远程除错的时候 -就会成为极大的帮助。当DEBUG符号没有被定义的时候,这些信息不应该被编译进内核里 -(也就是说,默认地,它们不应该被包含在内)。如果你使用dev_dbg()或者pr_debug(), -就能自动达到这个效果。很多子系统拥有Kconfig选项来启用-DDEBUG。还有一个相关的惯例 -是使用VERBOSE_DEBUG来添加dev_vdbg()消息到那些已经由DEBUG启用的消息之上。 +写出好的调试信息可以是一个很大的挑战;一旦你写出后,这些信息在远程除错时能提供极大 +的帮助。然而打印调试信息的处理方式同打印非调试信息不同。其他 pr_XXX() 函数能无条件地 +打印,pr_debug() 却不;默认情况下它不会被编译,除非定义了 DEBUG 或设定了 +CONFIG_DYNAMIC_DEBUG。实际这同样是为了 dev_dbg(),一个相关约定是在一个已经开启了 +DEBUG 时,使用 VERBOSE_DEBUG 来添加 dev_vdbg()。 + +许多子系统拥有 Kconfig 调试选项来开启 -DDEBUG 在对应的 Makefile 里面;在其他 +情况下,特殊文件使用 #define DEBUG。当一条调试信息需要被无条件打印时,例如,如果 +已经包含一个调试相关的 #ifdef 条件,printk(KERN_DEBUG ...) 就可被使用。 第十四章:分配内存 -内核提供了下面的一般用途的内存分配函数:kmalloc(),kzalloc(),kcalloc()和 -vmalloc()。请参考API文档以获取有关它们的详细信息。 +内核提供了下面的一般用途的内存分配函数: +kmalloc(),kzalloc(),kmalloc_array(),kcalloc(),vmalloc() 和 vzalloc()。 +请参考 API 文档以获取有关它们的详细信息。 传递结构体大小的首选形式是这样的: p = kmalloc(sizeof(*p), ...); -另外一种传递方式中,sizeof的操作数是结构体的名字,这样会降低可读性,并且可能会引 -入bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的sizeof的结果不变。 +另外一种传递方式中,sizeof 的操作数是结构体的名字,这样会降低可读性,并且可能会引 +入 bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的 sizeof 的结果不变。 -强制转换一个void指针返回值是多余的。C语言本身保证了从void指针到其他任何指针类型 +强制转换一个 void 指针返回值是多余的。C 语言本身保证了从 void 指针到其他任何指针类型 的转换是没有问题的。 +分配一个数组的首选形式是这样的: + + p = kmalloc_array(n, sizeof(...), ...); + +分配一个零长数组的首选形式是这样的: + + p = kcalloc(n, sizeof(...), ...); + +两种形式检查分配大小 n * sizeof(...) 的溢出,如果溢出返回 NULL。 + 第十五章:内联弊病 -有一个常见的误解是内联函数是gcc提供的可以让代码运行更快的一个选项。虽然使用内联 +有一个常见的误解是内联函数是 gcc 提供的可以让代码运行更快的一个选项。虽然使用内联 函数有时候是恰当的(比如作为一种替代宏的方式,请看第十二章),不过很多情况下不是 -这样。inline关键字的过度使用会使内核变大,从而使整个系统运行速度变慢。因为大内核 +这样。inline 关键字的过度使用会使内核变大,从而使整个系统运行速度变慢。因为大内核 会占用更多的指令高速缓存(译注:一级缓存通常是指令缓存和数据缓存分开的)而且会导 -致pagecache的可用内存减少。想象一下,一次pagecache未命中就会导致一次磁盘寻址,将 -耗时5毫秒。5毫秒的时间内CPU能执行很多很多指令。 +致 pagecache 的可用内存减少。想象一下,一次pagecache未命中就会导致一次磁盘寻址, +将耗时 5 毫秒。5 毫秒的时间内 CPU 能执行很多很多指令。 -一个基本的原则是如果一个函数有3行以上,就不要把它变成内联函数。这个原则的一个例 +一个基本的原则是如果一个函数有 3 行以上,就不要把它变成内联函数。这个原则的一个例 外是,如果你知道某个参数是一个编译时常量,而且因为这个常量你确定编译器在编译时能 -优化掉你的函数的大部分代码,那仍然可以给它加上inline关键字。kmalloc()内联函数就 +优化掉你的函数的大部分代码,那仍然可以给它加上 inline 关键字。kmalloc() 内联函数就 是一个很好的例子。 -人们经常主张给static的而且只用了一次的函数加上inline,如此不会有任何损失,因为没 -有什么好权衡的。虽然从技术上说这是正确的,但是实际上这种情况下即使不加inline gcc -也可以自动使其内联。而且其他用户可能会要求移除inline,由此而来的争论会抵消inline +人们经常主张给 static 的而且只用了一次的函数加上 inline,如此不会有任何损失,因为没 +有什么好权衡的。虽然从技术上说这是正确的,但是实际上这种情况下即使不加 inline gcc +也可以自动使其内联。而且其他用户可能会要求移除 inline,由此而来的争论会抵消 inline 自身的潜在价值,得不偿失。 @@ -613,37 +674,37 @@ vmalloc()。请参考API文档以获取有关它们的详细信息。 的一个值可以表示为一个错误代码整数(-Exxx=失败,0=成功)或者一个“成功”布尔值( 0=失败,非0=成功)。 -混合使用这两种表达方式是难于发现的bug的来源。如果C语言本身严格区分整形和布尔型变 -量,那么编译器就能够帮我们发现这些错误……不过C语言不区分。为了避免产生这种bug,请 +混合使用这两种表达方式是难于发现的 bug 的来源。如果 C 语言本身严格区分整形和布尔型变 +量,那么编译器就能够帮我们发现这些错误……不过 C 语言不区分。为了避免产生这种 bug,请 遵循下面的惯例: 如果函数的名字是一个动作或者强制性的命令,那么这个函数应该返回错误代码整 数。如果是一个判断,那么函数应该返回一个“成功”布尔值。 -比如,“add work”是一个命令,所以add_work()函数在成功时返回0,在失败时返回-EBUSY。 -类似的,因为“PCI device present”是一个判断,所以pci_dev_present()函数在成功找到 -一个匹配的设备时应该返回1,如果找不到时应该返回0。 +比如,“add work” 是一个命令,所以 add_work() 函数在成功时返回 0,在失败时返回 -EBUSY。 +类似的,因为 “PCI device present” 是一个判断,所以 pci_dev_present() 函数在成功找到 +一个匹配的设备时应该返回 1,如果找不到时应该返回 0。 所有导出(译注:EXPORT)的函数都必须遵守这个惯例,所有的公共函数也都应该如此。私 有(static)函数不需要如此,但是我们也推荐这样做。 返回值是实际计算结果而不是计算是否成功的标志的函数不受此惯例的限制。一般的,他们 通过返回一些正常值范围之外的结果来表示出错。典型的例子是返回指针的函数,他们使用 -NULL或者ERR_PTR机制来报告错误。 +NULL 或者 ERR_PTR 机制来报告错误。 第十七章:不要重新发明内核宏 -头文件include/linux/kernel.h包含了一些宏,你应该使用它们,而不要自己写一些它们的 +头文件 include/linux/kernel.h 包含了一些宏,你应该使用它们,而不要自己写一些它们的 变种。比如,如果你需要计算一个数组的长度,使用这个宏 - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 类似的,如果你要计算某结构体成员的大小,使用 - #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) + #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) -还有可以做严格的类型检查的min()和max()宏,如果你需要可以使用它们。你可以自己看看 +还有可以做严格的类型检查的 min() 和 max() 宏,如果你需要可以使用它们。你可以自己看看 那个头文件里还定义了什么你可以拿来用的东西,如果有定义的话,你就不应在你的代码里 自己重新定义。 @@ -653,42 +714,100 @@ NULL或者ERR_PTR机制来报告错误。 有一些编辑器可以解释嵌入在源文件里的由一些特殊标记标明的配置信息。比如,emacs 能够解释被标记成这样的行: --*- mode: c -*- + -*- mode: c -*- 或者这样的: -/* -Local Variables: -compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" -End: -*/ + /* + Local Variables: + compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" + End: + */ -Vim能够解释这样的标记: +Vim 能够解释这样的标记: -/* vim:set sw=8 noet */ + /* vim:set sw=8 noet */ 不要在源代码中包含任何这样的内容。每个人都有他自己的编辑器配置,你的源文件不应 该覆盖别人的配置。这包括有关缩进和模式配置的标记。人们可以使用他们自己定制的模 式,或者使用其他可以产生正确的缩进的巧妙方法。 + 第十九章:内联汇编 + +在特定架构的代码中,你也许需要内联汇编来使用 CPU 接口和平台相关功能。在需要 +这么做时,不要犹豫。然而,当 C 可以完成工作时,不要无端地使用内联汇编。如果 +可能,你可以并且应该用 C 和硬件交互。 + +考虑去写通用一点的内联汇编作为简明的辅助函数,而不是重复写下它们的细节。记住 +内联汇编可以使用 C 参数。 + +大而特殊的汇编函数应该放在 .S 文件中,对应 C 的原型定义在 C 头文件中。汇编 +函数的 C 原型应该使用 “asmlinkage”。 + +你可能需要将你的汇编语句标记为 volatile,来阻止 GCC 在没发现任何副作用后就 +移除了它。你不必总是这样做,虽然,这样可以限制不必要的优化。 + +在写一个包含多条指令的单个内联汇编语句时,把每条指令用引号字符串分离,并写在 +单独一行,在每个字符串结尾,除了 \n\t 结尾之外,在汇编输出中适当地缩进下 +一条指令: + + asm ("magic %reg1, #42\n\t" + "more_magic %reg2, %reg3" + : /* outputs */ : /* inputs */ : /* clobbers */); + + + 第二十章:条件编译 + +只要可能,就不要在 .c 文件里面使用预处理条件;这样做让代码更难阅读并且逻辑难以 +跟踪。替代方案是,在头文件定义函数在这些 .c 文件中使用这类的条件表达式,提供空 +操作的桩版本(译注:桩程序,是指用来替换一部分功能的程序段)在 #else 情况下, +再从 .c 文件中无条件地调用这些函数。编译器会避免生成任何桩调用的代码,产生一致 +的结果,但逻辑将更加清晰。 + +宁可编译整个函数,而不是部分函数或部分表达式。而不是在一个表达式添加 ifdef, +解析部分或全部表达式到一个单独的辅助函数,并应用条件到该函数内。 + +如果你有一个在特定配置中可能是未使用的函数或变量,编译器将警告它定义了但未使用, +标记这个定义为 __maybe_unused 而不是将它包含在一个预处理条件中。(然而,如果 +一个函数或变量总是未使用的,就直接删除它。) + +在代码中,可能的情况下,使用 IS_ENABLED 宏来转化某个 Kconfig 标记为 C 的布尔 +表达式,并在正常的 C 条件中使用它: + + if (IS_ENABLED(CONFIG_SOMETHING)) { + ... + } + +编译器会无条件地做常数合并,就像使用 #ifdef 那样,包含或排除代码块,所以这不会 +带来任何运行时开销。然而,这种方法依旧允许 C 编译器查看块内的代码,并检查它的正确 +性(语法,类型,符号引用,等等)。因此,如果条件不满足,代码块内的引用符号将不存在, +你必须继续使用 #ifdef。 + +在任何有意义的 #if 或 #ifdef 块的末尾(超过几行),在 #endif 同一行的后面写下 +注释,指出该条件表达式被使用。例如: + + #ifdef CONFIG_SOMETHING + ... + #endif /* CONFIG_SOMETHING */ + 附录 I:参考 -The C Programming Language, 第二版, 作者Brian W. Kernighan和Denni -M. Ritchie. Prentice Hall, Inc., 1988. ISBN 0-13-110362-8 (软皮), -0-13-110370-9 (硬皮). URL: http://cm.bell-labs.com/cm/cs/cbook/ +The C Programming Language, 第二版 +作者:Brian W. Kernighan 和 Denni M. Ritchie. +Prentice Hall, Inc., 1988. +ISBN 0-13-110362-8 (软皮), 0-13-110370-9 (硬皮). -The Practice of Programming 作者Brian W. Kernighan和Rob Pike. Addison-Wesley, -Inc., 1999. ISBN 0-201-61586-X. URL: http://cm.bell-labs.com/cm/cs/tpop/ +The Practice of Programming +作者:Brian W. Kernighan 和 Rob Pike. +Addison-Wesley, Inc., 1999. +ISBN 0-201-61586-X. -cpp,gcc,gcc internals和indent的GNU手册——和K&R及本文相符合的部分,全部可以在 -http://www.gnu.org/manual/找到 +GNU 手册 - 遵循 K&R 标准和此文本 - cpp, gcc, gcc internals and indent, +都可以从 http://www.gnu.org/manual/ 找到 WG14是C语言的国际标准化工作组,URL: http://www.open-std.org/JTC1/SC22/WG14/ -Kernel CodingStyle,作者greg@kroah.com发表于OLS 2002: +Kernel CodingStyle,作者 greg@kroah.com 发表于OLS 2002: http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ - --- -最后更新于2007年7月13日。 -- cgit v1.2.3 From f3e6a55c3653b071705e266473b87696786dfd99 Mon Sep 17 00:00:00 2001 From: Niklas Söderlund Date: Fri, 3 Jun 2016 12:03:10 +0200 Subject: Documentation: dmaengine: fix typo for device_resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Niklas Söderlund Signed-off-by: Jonathan Corbet --- Documentation/dmaengine/provider.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/dmaengine/provider.txt b/Documentation/dmaengine/provider.txt index 122b7f4876bb..91ce82d5f0c4 100644 --- a/Documentation/dmaengine/provider.txt +++ b/Documentation/dmaengine/provider.txt @@ -323,7 +323,7 @@ supported. * device_resume - Resumes a transfer on the channel - This command should operate synchronously on the channel, - pausing right away the work of the given channel + resuming right away the work of the given channel * device_terminate_all - Aborts all the pending and ongoing transfers on the channel -- cgit v1.2.3 From 0b0f5f29b282b18d26ce698e1aab0267234f77bf Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 3 Jun 2016 22:21:34 +0200 Subject: scripts/kernel-doc: Add option to inject line numbers Opt-in since this wreaks the rst output and must be removed by consumers again. This is useful to adjust the linenumbers for included kernel-doc snippets in shinx. With that sphinx error message will be accurate when there's issues with the rst-ness of the kernel-doc comments. Especially when transitioning a new docbook .tmpl to .rst this is extremely useful, since you can just use your editors compilation quickfix list to accurately jump from error to error. v2: - Also make sure that we filter the LINENO for purpose/at declaration start so it only shows for selected blocks, not all of them (Jani). While at it make it a notch more accurate. - Avoid undefined $lineno issues. I tried filtering these out at the callsite, but Jani spotted more when linting the entire kernel. Unamed unions and similar things aren't stored consistently and end up with an undefined line number (but also no kernel-doc text, just the parameter type). Simplify things and filter undefined line numbers in print_lineno() to catch them all. v3: Fix LINENO 0 issue for kernel-doc comments without @param: lines or any other special sections that directly jump to the description after the "name - purpose" line. Only really possible for functions without parameters. Noticed by Jani. Cc: Jani Nikula Cc: linux-doc@vger.kernel.org Cc: Jonathan Corbet Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- scripts/kernel-doc | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 4da6f952d18b..5192213c5005 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -74,6 +74,8 @@ Output selection (mutually exclusive): Output selection modifiers: -no-doc-sections Do not output DOC: sections. + -enable-lineno Enable output of #define LINENO lines. Only works with + reStructuredText format. Other parameters: -v Verbose output, more warnings and other information. @@ -319,6 +321,7 @@ my $verbose = 0; my $output_mode = "man"; my $output_preformatted = 0; my $no_doc_sections = 0; +my $enable_lineno = 0; my @highlights = @highlights_man; my $blankline = $blankline_man; my $modulename = "Kernel API"; @@ -351,6 +354,7 @@ my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', # CAVEAT EMPTOR! Some of the others I localised may not want to be, which # could cause "use of undefined value" or other bugs. my ($function, %function_table, %parametertypes, $declaration_purpose); +my $declaration_start_line; my ($type, $declaration_name, $return_type); my ($newsection, $newcontents, $prototype, $brcount, %source_map); @@ -411,13 +415,16 @@ my $doc_inline_end = '^\s*\*/\s*$'; my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; my %parameterdescs; +my %parameterdesc_start_lines; my @parameterlist; my %sections; my @sectionlist; +my %section_start_lines; my $sectcheck; my $struct_actual; my $contents = ""; +my $new_start_line = 0; # the canonical section names. see also $doc_sect above. my $section_default = "Description"; # default section @@ -486,6 +493,8 @@ while ($ARGV[0] =~ m/^-(.*)/) { usage(); } elsif ($cmd eq '-no-doc-sections') { $no_doc_sections = 1; + } elsif ($cmd eq '-enable-lineno') { + $enable_lineno = 1; } elsif ($cmd eq '-show-not-found') { $show_not_found = 1; } @@ -503,6 +512,13 @@ sub get_kernel_version() { return $version; } +# +sub print_lineno { + my $lineno = shift; + if ($enable_lineno && defined($lineno)) { + print "#define LINENO " . $lineno . "\n"; + } +} ## # dumps section contents to arrays/hashes intended for that purpose. # @@ -516,11 +532,15 @@ sub dump_section { $name = $1; $parameterdescs{$name} = $contents; $sectcheck = $sectcheck . $name . " "; + $parameterdesc_start_lines{$name} = $new_start_line; + $new_start_line = 0; } elsif ($name eq "@\.\.\.") { # print STDERR "parameter def '...' = '$contents'\n"; $name = "..."; $parameterdescs{$name} = $contents; $sectcheck = $sectcheck . $name . " "; + $parameterdesc_start_lines{$name} = $new_start_line; + $new_start_line = 0; } else { # print STDERR "other section '$name' = '$contents'\n"; if (defined($sections{$name}) && ($sections{$name} ne "")) { @@ -530,6 +550,8 @@ sub dump_section { } else { $sections{$name} = $contents; push @sectionlist, $name; + $section_start_lines{$name} = $new_start_line; + $new_start_line = 0; } } } @@ -1775,6 +1797,7 @@ sub output_blockhead_rst(%) { if ($output_selection != OUTPUT_INCLUDE) { print "**$section**\n\n"; } + print_lineno($section_start_lines{$section}); output_highlight_rst($args{'sections'}{$section}); print "\n"; } @@ -1824,6 +1847,7 @@ sub output_function_rst(%) { } } print ")\n\n"; + print_lineno($declaration_start_line); $lineprefix = " "; output_highlight_rst($args{'purpose'}); print "\n"; @@ -1840,6 +1864,9 @@ sub output_function_rst(%) { } else { print "``$parameter``\n"; } + + print_lineno($parameterdesc_start_lines{$parameter_name}); + if (defined($args{'parameterdescs'}{$parameter_name}) && $args{'parameterdescs'}{$parameter_name} ne $undescribed) { output_highlight_rst($args{'parameterdescs'}{$parameter_name}); @@ -1861,6 +1888,7 @@ sub output_section_rst(%) { foreach $section (@{$args{'sectionlist'}}) { print "**$section**\n\n"; + print_lineno($section_start_lines{$section}); output_highlight_rst($args{'sections'}{$section}); print "\n"; } @@ -1876,6 +1904,7 @@ sub output_enum_rst(%) { my $name = "enum " . $args{'enum'}; print "\n\n.. c:type:: " . $name . "\n\n"; + print_lineno($declaration_start_line); $lineprefix = " "; output_highlight_rst($args{'purpose'}); print "\n"; @@ -1903,6 +1932,7 @@ sub output_typedef_rst(%) { my $name = "typedef " . $args{'typedef'}; print "\n\n.. c:type:: " . $name . "\n\n"; + print_lineno($declaration_start_line); $lineprefix = " "; output_highlight_rst($args{'purpose'}); print "\n"; @@ -1918,6 +1948,7 @@ sub output_struct_rst(%) { my $name = $args{'type'} . " " . $args{'struct'}; print "\n\n.. c:type:: " . $name . "\n\n"; + print_lineno($declaration_start_line); $lineprefix = " "; output_highlight_rst($args{'purpose'}); print "\n"; @@ -1958,6 +1989,7 @@ sub output_struct_rst(%) { ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; $type = $args{'parametertypes'}{$parameter}; + print_lineno($parameterdesc_start_lines{$parameter_name}); print "``$type $parameter``\n"; output_highlight_rst($args{'parameterdescs'}{$parameter_name}); print "\n"; @@ -2745,11 +2777,14 @@ sub process_file($) { if (/$doc_start/o) { $state = STATE_NAME; # next line is always the function name $in_doc_sect = 0; + $declaration_start_line = $. + 1; } } elsif ($state == STATE_NAME) {# this line is the function name (always) if (/$doc_block/o) { $state = STATE_DOCBLOCK; $contents = ""; + $new_start_line = $. + 1; + if ( $1 eq "" ) { $section = $section_intro; } else { @@ -2763,8 +2798,11 @@ sub process_file($) { } $state = STATE_FIELD; + # if there's no @param blocks need to set up default section + # here $contents = ""; $section = $section_default; + $new_start_line = $. + 1; if (/-(.*)/) { # strip leading/trailing/multiple spaces $descr= $1; @@ -2833,6 +2871,7 @@ sub process_file($) { $in_doc_sect = 1; $in_purpose = 0; $contents = $newcontents; + $new_start_line = $.; while ((substr($contents, 0, 1) eq " ") || substr($contents, 0, 1) eq "\t") { $contents = substr($contents, 1); @@ -2866,6 +2905,7 @@ sub process_file($) { dump_section($file, $section, xml_escape($contents)); $section = $section_default; $contents = ""; + $new_start_line = $.; } else { $contents .= "\n"; } @@ -2900,6 +2940,7 @@ sub process_file($) { if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { $section = $1; $contents = $2; + $new_start_line = $.; if ($contents ne "") { while ((substr($contents, 0, 1) eq " ") || substr($contents, 0, 1) eq "\t") { -- cgit v1.2.3 From d90368f2fa7ded7c56d214aef087e88bba5199e7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 3 Jun 2016 22:21:35 +0200 Subject: doc/sphinx: Track line-number of starting blocks Design is pretty simple: kernel-doc inserts breadcrumbs with line numbers, and sphinx picks them up. At first I went with a sphinx comment, but inserting those at random places seriously upsets the parser, and must be filtered. Hence why this version now uses "#define LINEO " since one of these ever escape into output it's pretty clear there is a bug. It seems to work well, and at least the 2-3 errors where sphinx complained about something that was not correct in kernel-doc text the line numbers matched up perfectly. v2: Instead of noodling around in the parser state machine, create a ViewList and parse it ourselves. This seems to be the recommended way, per Jani's suggestion. v3: - Split out ViewList pach. Splitting the kernel-doc changes from the sphinx ones isn't possible, since emitting the LINENO lines wreaks havoc with the rst formatting. We must filter them. - Improve the regex per Jani's suggestions, and compile it just once for speed. - Now that LINENO lines are eaten, also add them to function parameter descriptions. Much less content and offset than for in-line struct member descriptions, but still nice to know which exact continuation line upsets sphinx. - Simplify/clarify the line +/-1 business a bit. v4: Split out the scripts/kernel-doc changes and make line-numbers opt-in, as suggested by Jani. Cc: Jani Nikula Cc: linux-doc@vger.kernel.org Cc: Jonathan Corbet Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index bd422870101e..4adfb0e91ecc 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -30,6 +30,7 @@ import os import subprocess import sys +import re from docutils import nodes, statemachine from docutils.statemachine import ViewList @@ -50,7 +51,7 @@ class KernelDocDirective(Directive): def run(self): env = self.state.document.settings.env - cmd = [env.config.kerneldoc_bin, '-rst'] + cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] @@ -93,7 +94,19 @@ class KernelDocDirective(Directive): sys.stderr.write(err) lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) - result = ViewList(lines, source) + result = ViewList() + + lineoffset = 0; + line_regex = re.compile("^#define LINENO ([0-9]+)$") + for line in lines: + match = line_regex.search(line) + if match: + # sphinx counts lines from 0 + lineoffset = int(match.group(1)) - 1 + # we must eat our comments since the upset the markup + else: + result.append(line, source, lineoffset) + lineoffset += 1 node = nodes.section() node.document = self.state.document -- cgit v1.2.3 From c9de4a82c852d621975f5978157f689e0550a48e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 18 May 2016 06:37:47 -0700 Subject: docs: self-protection: rename "leak" to "exposure" The meaning of "leak" can be both "untracked resource allocation" and "memory content disclosure". This document's use was entirely of the latter meaning, so avoid the confusion by using the Common Weakness Enumeration name for this: Information Exposure (CWE-200). Additionally adds a section on structure randomization. Signed-off-by: Kees Cook Signed-off-by: Jonathan Corbet --- Documentation/security/self-protection.txt | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/Documentation/security/self-protection.txt b/Documentation/security/self-protection.txt index babd6378ec05..3010576c9fca 100644 --- a/Documentation/security/self-protection.txt +++ b/Documentation/security/self-protection.txt @@ -183,8 +183,9 @@ provide meaningful defenses. ### Canaries, blinding, and other secrets It should be noted that things like the stack canary discussed earlier -are technically statistical defenses, since they rely on a (leakable) -secret value. +are technically statistical defenses, since they rely on a secret value, +and such values may become discoverable through an information exposure +flaw. Blinding literal values for things like JITs, where the executable contents may be partially under the control of userspace, need a similar @@ -199,8 +200,8 @@ working?) in order to maximize their success. Since the location of kernel memory is almost always instrumental in mounting a successful attack, making the location non-deterministic raises the difficulty of an exploit. (Note that this in turn makes -the value of leaks higher, since they may be used to discover desired -memory locations.) +the value of information exposures higher, since they may be used to +discover desired memory locations.) #### Text and module base @@ -222,14 +223,21 @@ become more difficult to locate. Much of the kernel's dynamic memory (e.g. kmalloc, vmalloc, etc) ends up being relatively deterministic in layout due to the order of early-boot initializations. If the base address of these areas is not the same -between boots, targeting them is frustrated, requiring a leak specific -to the region. +between boots, targeting them is frustrated, requiring an information +exposure specific to the region. + +#### Structure layout + +By performing a per-build randomization of the layout of sensitive +structures, attacks must either be tuned to known kernel builds or expose +enough kernel memory to determine structure layouts before manipulating +them. -## Preventing Leaks +## Preventing Information Exposures Since the locations of sensitive structures are the primary target for -attacks, it is important to defend against leaks of both kernel memory +attacks, it is important to defend against exposure of both kernel memory addresses and kernel memory contents (since they may contain kernel addresses or other sensitive things like canary values). @@ -250,8 +258,8 @@ sure structure holes are cleared. When releasing memory, it is best to poison the contents (clear stack on syscall return, wipe heap memory on a free), to avoid reuse attacks that rely on the old contents of memory. This frustrates many uninitialized -variable attacks, stack info leaks, heap info leaks, and use-after-free -attacks. +variable attacks, stack content exposures, heap content exposures, and +use-after-free attacks. ### Destination tracking -- cgit v1.2.3 From 8569de68e79e94cce6709831edd94accb6942ade Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 9 Jun 2016 13:35:05 -0600 Subject: docs: kernel-doc: Add "example" and "note" to the magic section types Lots of kerneldoc entries use "example:" or "note:" as section headers. Until such a time as we can make them use proper markup, make them work as intended. Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 5192213c5005..27757c21551a 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -406,7 +406,8 @@ my $doc_com = '\s*\*\s*'; my $doc_com_body = '\s*\* ?'; my $doc_decl = $doc_com . '(\w+)'; # @params and a strictly limited set of supported section names -my $doc_sect = $doc_com . '\s*(\@\w+|description|context|returns?)\s*:(.*)'; +my $doc_sect = $doc_com . + '\s*(\@\w+|description|context|returns?|notes?|examples?)\s*:(.*)'; my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_inline_start = '^\s*/\*\*\s*$'; -- cgit v1.2.3 From 5668604a6cab13dd5385b8c03a7d55bf92ff0496 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 Jun 2016 11:28:13 +0300 Subject: kernel-doc: remove old debug cruft from dump_section() No functional changes. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 27757c21551a..ac18eb5ed776 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -529,21 +529,18 @@ sub dump_section { my $contents = join "\n", @_; if ($name =~ m/$type_param/) { -# print STDERR "parameter def '$1' = '$contents'\n"; $name = $1; $parameterdescs{$name} = $contents; $sectcheck = $sectcheck . $name . " "; $parameterdesc_start_lines{$name} = $new_start_line; $new_start_line = 0; } elsif ($name eq "@\.\.\.") { -# print STDERR "parameter def '...' = '$contents'\n"; $name = "..."; $parameterdescs{$name} = $contents; $sectcheck = $sectcheck . $name . " "; $parameterdesc_start_lines{$name} = $new_start_line; $new_start_line = 0; } else { -# print STDERR "other section '$name' = '$contents'\n"; if (defined($sections{$name}) && ($sections{$name} ne "")) { print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; ++$warnings; -- cgit v1.2.3 From 95b6be9d198d964fafd9cbf1dd4d1968291e255c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 Jun 2016 11:14:05 +0300 Subject: kernel-doc: do not warn about duplicate default section names Since commit 32217761ee9db0215350dfe1ca4e66f312fb8c54 Author: Jani Nikula Date: Sun May 29 09:40:44 2016 +0300 kernel-doc: concatenate contents of colliding sections we started getting (more) errors on duplicate section names, especially on the default section name "Description": include/net/mac80211.h:3174: warning: duplicate section name 'Description' This is usually caused by a slightly unorthodox placement of parameter descriptions, like in the above case, and kernel-doc resetting back to the default section more than once within a kernel-doc comment. Ignore warnings on the duplicate section name automatically assigned by kernel-doc, and only consider explicitly user assigned duplicate section names an issue. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index ac18eb5ed776..710615f3a4ff 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -542,8 +542,11 @@ sub dump_section { $new_start_line = 0; } else { if (defined($sections{$name}) && ($sections{$name} ne "")) { - print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; - ++$warnings; + # Only warn on user specified duplicate section names. + if ($name ne $section_default) { + print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; + ++$warnings; + } $sections{$name} .= $contents; } else { $sections{$name} = $contents; -- cgit v1.2.3 From da9726ecfba202514d984129c3537b028519cdb8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 7 Jun 2016 10:29:59 +0300 Subject: kernel-doc: add missing semi-colons in option parsing Signed-off-by: Jani Nikula --- scripts/kernel-doc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 710615f3a4ff..a6f82c812c15 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -484,10 +484,10 @@ while ($ARGV[0] =~ m/^-(.*)/) { $function_table{$function} = 1; } elsif ($cmd eq "-export") { # only exported symbols $output_selection = OUTPUT_EXPORTED; - %function_table = () + %function_table = (); } elsif ($cmd eq "-internal") { # only non-exported symbols $output_selection = OUTPUT_INTERNAL; - %function_table = () + %function_table = (); } elsif ($cmd eq "-v") { $verbose = 1; } elsif (($cmd eq "-h") || ($cmd eq "--help")) { -- cgit v1.2.3 From 1ad560e43c911e19751df65dd2af21341d02eac5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 7 Jun 2016 10:53:39 +0300 Subject: kernel-doc: abstract filename mapping Reduce duplication in follow-up work. No functional changes. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index a6f82c812c15..516d95fcefb7 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2730,26 +2730,35 @@ sub local_unescape($) { return $text; } -sub process_file($) { +sub map_filename($) { my $file; - my $identifier; - my $func; - my $descr; - my $in_purpose = 0; - my $initial_section_counter = $section_counter; my ($orig_file) = @_; - my $leading_space; if (defined($ENV{'SRCTREE'})) { $file = "$ENV{'SRCTREE'}" . "/" . $orig_file; - } - else { + } else { $file = $orig_file; } + if (defined($source_map{$file})) { $file = $source_map{$file}; } + return $file; +} + +sub process_file($) { + my $file; + my $identifier; + my $func; + my $descr; + my $in_purpose = 0; + my $initial_section_counter = $section_counter; + my ($orig_file) = @_; + my $leading_space; + + $file = map_filename($orig_file); + if (!open(IN,"<$file")) { print STDERR "Error: Cannot open file $file\n"; ++$errors; -- cgit v1.2.3 From 88c2b57da4ce3c8b5f849dc5356bdea9e2ed1134 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 7 Jun 2016 11:00:52 +0300 Subject: kernel-doc: add support for specifying extra files for EXPORT_SYMBOLs If the kernel-doc comments for functions are not in the same file as the EXPORT_SYMBOL statements, the -export and -internal output selections do not work as expected. This is typically the case when the kernel-doc comments are in header files next to the function declarations and the EXPORT_SYMBOL statements are next to the function definitions in the source files. Let the user specify additional source files in which to look for the EXPORT_SYMBOLs using the new -export-file FILE option, which may be given multiple times. The pathological example for this is include/net/mac80211.h, which has all the kernel-doc documentation for the exported functions defined in a plethora of source files net/mac80211/*.c. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 516d95fcefb7..9708a87c7069 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -61,10 +61,10 @@ Output format selection (mutually exclusive): Output selection (mutually exclusive): -export Only output documentation for symbols that have been exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() - in the same FILE. + in the same FILE or any -export-file FILE. -internal Only output documentation for symbols that have NOT been exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() - in the same FILE. + in the same FILE or any -export-file FILE. -function NAME Only output documentation for the given function(s) or DOC: section title(s). All other functions and DOC: sections are ignored. May be specified multiple times. @@ -76,6 +76,9 @@ Output selection modifiers: -no-doc-sections Do not output DOC: sections. -enable-lineno Enable output of #define LINENO lines. Only works with reStructuredText format. + -export-file FILE Specify an additional FILE in which to look for + EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(). To be used with + -export or -internal. May be specified multiple times. Other parameters: -v Verbose output, more warnings and other information. @@ -336,6 +339,8 @@ use constant { my $output_selection = OUTPUT_ALL; my $show_not_found = 0; +my @export_file_list; + my @build_time; if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) && (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') { @@ -488,6 +493,9 @@ while ($ARGV[0] =~ m/^-(.*)/) { } elsif ($cmd eq "-internal") { # only non-exported symbols $output_selection = OUTPUT_INTERNAL; %function_table = (); + } elsif ($cmd eq "-export-file") { + my $file = shift @ARGV; + push(@export_file_list, $file); } elsif ($cmd eq "-v") { $verbose = 1; } elsif (($cmd eq "-h") || ($cmd eq "--help")) { @@ -2747,6 +2755,25 @@ sub map_filename($) { return $file; } +sub process_export_file($) { + my ($orig_file) = @_; + my $file = map_filename($orig_file); + + if (!open(IN,"<$file")) { + print STDERR "Error: Cannot open file $file\n"; + ++$errors; + return; + } + + while () { + if (/$export_symbol/) { + $function_table{$2} = 1; + } + } + + close(IN); +} + sub process_file($) { my $file; my $identifier; @@ -3081,6 +3108,14 @@ if (open(SOURCE_MAP, "<.tmp_filelist.txt")) { close(SOURCE_MAP); } +if ($output_selection == OUTPUT_EXPORTED || + $output_selection == OUTPUT_INTERNAL) { + foreach (@export_file_list) { + chomp; + process_export_file($_); + } +} + foreach (@ARGV) { chomp; process_file($_); -- cgit v1.2.3 From c9b2cfb3faece55df7f50b4ab76bc00ac8e06700 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 7 Jun 2016 11:05:53 +0300 Subject: kernel-doc: unify all EXPORT_SYMBOL scanning to one place Scan all input files for EXPORT_SYMBOLs along with the explicitly specified export files before actually parsing anything. Signed-off-by: Jani Nikula --- scripts/kernel-doc | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 9708a87c7069..932b3f34ff06 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -61,10 +61,10 @@ Output format selection (mutually exclusive): Output selection (mutually exclusive): -export Only output documentation for symbols that have been exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() - in the same FILE or any -export-file FILE. + in any input FILE or -export-file FILE. -internal Only output documentation for symbols that have NOT been exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() - in the same FILE or any -export-file FILE. + in any input FILE or -export-file FILE. -function NAME Only output documentation for the given function(s) or DOC: section title(s). All other functions and DOC: sections are ignored. May be specified multiple times. @@ -2792,17 +2792,6 @@ sub process_file($) { return; } - # two passes for -export and -internal - if ($output_selection == OUTPUT_EXPORTED || - $output_selection == OUTPUT_INTERNAL) { - while () { - if (/$export_symbol/o) { - $function_table{$2} = 1; - } - } - seek(IN, 0, 0); - } - $. = 1; $section_counter = 0; @@ -3110,6 +3099,9 @@ if (open(SOURCE_MAP, "<.tmp_filelist.txt")) { if ($output_selection == OUTPUT_EXPORTED || $output_selection == OUTPUT_INTERNAL) { + + push(@export_file_list, @ARGV); + foreach (@export_file_list) { chomp; process_export_file($_); -- cgit v1.2.3 From 06173fe33a3fd239540bd188f1f12a39e99b6c83 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 8 Jun 2016 13:38:28 +0300 Subject: Documentation/sphinx: remove unnecessary temporary variable Leftover cruft. No functional changes. Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index 4adfb0e91ecc..2856376cc62c 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -59,7 +59,6 @@ class KernelDocDirective(Directive): env.note_dependency(os.path.abspath(filename)) tab_width = self.options.get('tab-width', self.state.document.settings.tab_width) - source = filename # FIXME: make this nicer and more robust against errors if 'export' in self.options: @@ -105,7 +104,7 @@ class KernelDocDirective(Directive): lineoffset = int(match.group(1)) - 1 # we must eat our comments since the upset the markup else: - result.append(line, source, lineoffset) + result.append(line, filename, lineoffset) lineoffset += 1 node = nodes.section() -- cgit v1.2.3 From 057de5c4dd536bdf29275ec75910737087594860 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 8 Jun 2016 10:25:40 +0300 Subject: Documentation/sphinx: use a more sensible string split in kernel-doc extension Using the default str.split doesn't return empty strings like the current version does. Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index 2856376cc62c..d6a76f9a0ba5 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -68,7 +68,7 @@ class KernelDocDirective(Directive): elif 'doc' in self.options: cmd += ['-function', str(self.options.get('doc'))] elif 'functions' in self.options: - for f in str(self.options.get('functions')).split(' '): + for f in str(self.options.get('functions')).split(): cmd += ['-function', f] cmd += [filename] -- cgit v1.2.3 From 03d35d9ec4ae50afeafc3ab26d8207b7069f3cba Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 7 Jun 2016 12:13:56 +0300 Subject: Documentation/sphinx: add support for specifying extra export files Let the user specify file patterns where to look for the EXPORT_SYMBOLs in addition to the file with kernel-doc comments. This is directly based on the -export-file FILE option added to kernel-doc in "kernel-doc: add support for specifying extra files for EXPORT_SYMBOLs", but we extend that with globbing patterns in the Sphinx extension. The file patterns are added as options to the :export: and :internal: arguments of the kernel-doc directive. For example, to extract the documentation of exported functions from include/net/mac80211.h: .. kernel-doc:: include/net/mac80211.h :export: net/mac80211/*.c Without the file pattern, no exported functions would be found, as the EXPORT_SYMBOLs are placed in the various source files under net/mac80211. The matched files are also added as dependencies on the document in Sphinx, as they may affect the output. This is one of the reasons to do the globbing in the Sphinx extension instead of in scripts/kernel-doc. The file pattern remains optional, and is not needed if the kernel-doc comments and EXPORT_SYMBOLs are placed in the source file passed in as the main argument to the kernel-doc directive. This is the most common case across the kernel source tree. Signed-off-by: Jani Nikula --- Documentation/sphinx/kernel-doc.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index d6a76f9a0ba5..dedb24e3bb7a 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -31,6 +31,7 @@ import os import subprocess import sys import re +import glob from docutils import nodes, statemachine from docutils.statemachine import ViewList @@ -44,8 +45,8 @@ class KernelDocDirective(Directive): option_spec = { 'doc': directives.unchanged_required, 'functions': directives.unchanged_required, - 'export': directives.flag, - 'internal': directives.flag, + 'export': directives.unchanged, + 'internal': directives.unchanged, } has_content = False @@ -54,6 +55,7 @@ class KernelDocDirective(Directive): cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] + export_file_patterns = [] # Tell sphinx of the dependency env.note_dependency(os.path.abspath(filename)) @@ -63,14 +65,21 @@ class KernelDocDirective(Directive): # FIXME: make this nicer and more robust against errors if 'export' in self.options: cmd += ['-export'] + export_file_patterns = str(self.options.get('export')).split() elif 'internal' in self.options: cmd += ['-internal'] + export_file_patterns = str(self.options.get('internal')).split() elif 'doc' in self.options: cmd += ['-function', str(self.options.get('doc'))] elif 'functions' in self.options: for f in str(self.options.get('functions')).split(): cmd += ['-function', f] + for pattern in export_file_patterns: + for f in glob.glob(env.config.kerneldoc_srctree + '/' + pattern): + env.note_dependency(os.path.abspath(f)) + cmd += ['-export-file', f] + cmd += [filename] try: -- cgit v1.2.3 From 0cea220cf739c8b64d1d9ad75f4817621d3dc897 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 22 Jun 2016 15:14:15 +0300 Subject: Documentation/sphinx: drop modindex, we don't have python modules The modindex is for python modules. Signed-off-by: Jani Nikula --- Documentation/index.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/Documentation/index.rst b/Documentation/index.rst index 71a276f34c7f..1139a7ea39ec 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -18,6 +18,4 @@ Indices and tables ================== * :ref:`genindex` -* :ref:`modindex` * :ref:`search` - -- cgit v1.2.3 From ebc88ef05c825024a5d95285459b8c842c095c0f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 22 Jun 2016 15:41:48 +0300 Subject: Documentation: add top level 'make help' output for Sphinx While there's slight overlap with the DocBook help now, this can stay intact when the DocBook help goes away. Signed-off-by: Jani Nikula --- Documentation/DocBook/Makefile | 4 ++-- Documentation/Makefile.sphinx | 8 ++++++++ Makefile | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index e0c7e1e0590b..496d4295ec38 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -218,7 +218,7 @@ silent_gen_xml = : ### # Help targets as used by the top-level makefile dochelp: - @echo ' Linux kernel internal documentation in different formats:' + @echo ' Linux kernel internal documentation in different formats (DocBook):' @echo ' htmldocs - HTML' @echo ' pdfdocs - PDF' @echo ' psdocs - Postscript' @@ -227,7 +227,7 @@ dochelp: @echo ' installmandocs - install man pages generated by mandocs' @echo ' cleandocs - clean all generated DocBook files' @echo - @echo 'make DOCBOOKS="s1.xml s2.xml" [target] Generate only docs s1.xml s2.xml' + @echo ' make DOCBOOKS="s1.xml s2.xml" [target] Generate only docs s1.xml s2.xml' @echo ' valid values for DOCBOOKS are: $(DOCBOOKS)' diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx index addf32309bc3..810c11f0d37f 100644 --- a/Documentation/Makefile.sphinx +++ b/Documentation/Makefile.sphinx @@ -60,4 +60,12 @@ installmandocs: cleandocs: $(Q)rm -rf $(BUILDDIR) +dochelp: + @echo ' Linux kernel internal documentation in different formats (Sphinx):' + @echo ' htmldocs - HTML' + @echo ' pdfdocs - PDF' + @echo ' epubdocs - EPUB' + @echo ' xmldocs - XML' + @echo ' cleandocs - clean all generated files' + endif # HAVE_SPHINX diff --git a/Makefile b/Makefile index 8908a51b895a..f7f393c40886 100644 --- a/Makefile +++ b/Makefile @@ -1364,6 +1364,8 @@ help: @$(MAKE) $(build)=$(package-dir) help @echo '' @echo 'Documentation targets:' + @$(MAKE) -f $(srctree)/Documentation/Makefile.sphinx dochelp + @echo '' @$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp @echo '' @echo 'Architecture specific targets ($(SRCARCH)):' -- cgit v1.2.3 From c9b2ffc02287771e70eb27132c47df6d5c7d91fb Mon Sep 17 00:00:00 2001 From: Marc MERLIN Date: Fri, 11 Mar 2016 23:04:19 -0800 Subject: bcache: documentation updates and corrections Bcache documentation updates: - Added new HOWTO/COOKBOOK section - fixed a few typos - /sys/block/bcache0/cache_mode is /sys/block/bcache0/bcache/cache_mode Signed-off-by: Marc MERLIN Signed-off-by: Jonathan Corbet --- Documentation/bcache.txt | 160 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 152 insertions(+), 8 deletions(-) diff --git a/Documentation/bcache.txt b/Documentation/bcache.txt index 32b6c3189d98..0aba405d3368 100644 --- a/Documentation/bcache.txt +++ b/Documentation/bcache.txt @@ -1,4 +1,4 @@ -Say you've got a big slow raid 6, and an X-25E or three. Wouldn't it be +Say you've got a big slow raid 6, and an ssd or three. Wouldn't it be nice if you could use them as cache... Hence bcache. Wiki and git repositories are at: @@ -8,7 +8,7 @@ Wiki and git repositories are at: It's designed around the performance characteristics of SSDs - it only allocates in erase block sized buckets, and it uses a hybrid btree/log to track cached -extants (which can be anywhere from a single sector to the bucket size). It's +extents (which can be anywhere from a single sector to the bucket size). It's designed to avoid random writes at all costs; it fills up an erase block sequentially, then issues a discard before reusing it. @@ -55,7 +55,10 @@ immediately. Without udev, you can manually register devices like this: Registering the backing device makes the bcache device show up in /dev; you can now format it and use it as normal. But the first time using a new bcache device, it'll be running in passthrough mode until you attach it to a cache. -See the section on attaching. +If you are thinking about using bcache later, it is recommended to setup all your +slow devices as bcache backing devices without a cache, and you can choose to add +a caching device later. +See 'ATTACHING' section below. The devices show up as: @@ -72,12 +75,14 @@ To get started: mount /dev/bcache0 /mnt You can control bcache devices through sysfs at /sys/block/bcache/bcache . +You can also control them through /sys/fs//bcache// . Cache devices are managed as sets; multiple caches per set isn't supported yet but will allow for mirroring of metadata and dirty data in the future. Your new cache set shows up as /sys/fs/bcache/ -ATTACHING: +ATTACHING +--------- After your cache device and backing device are registered, the backing device must be attached to your cache set to enable caching. Attaching a backing @@ -105,7 +110,8 @@ but all the cached data will be invalidated. If there was dirty data in the cache, don't expect the filesystem to be recoverable - you will have massive filesystem corruption, though ext4's fsck does work miracles. -ERROR HANDLING: +ERROR HANDLING +-------------- Bcache tries to transparently handle IO errors to/from the cache device without affecting normal operation; if it sees too many errors (the threshold is @@ -127,7 +133,143 @@ the backing devices to passthrough mode. writeback mode). It currently doesn't do anything intelligent if it fails to read some of the dirty data, though. -TROUBLESHOOTING PERFORMANCE: + +HOWTO/COOKBOOK +-------------- + +A) Your bcache doesn't start. + Starting and starting a bcache with a missing caching device + +Registering the backing device doesn't help, it's already there, you just need +to force it to run without the cache: +host:~# echo /dev/sdb1 > /sys/fs/bcache/register +[ 119.844831] bcache: register_bcache() error opening /dev/sdb1: device already registered + +Next, you try to register your caching device if it's present. However if it's +absent, or registration fails for some reason, you can still start your bcache +without its cache, like so: +host:/sys/block/sdb/sdb1/bcache# echo 1 > running + + +B) Bcache not finding its cache and not starting + +This does not work: +host:/sys/block/md5/bcache# echo 0226553a-37cf-41d5-b3ce-8b1e944543a8 > attach +[ 1933.455082] bcache: bch_cached_dev_attach() Couldn't find uuid for md5 in set +[ 1933.478179] bcache: __cached_dev_store() Can't attach 0226553a-37cf-41d5-b3ce-8b1e944543a8 +[ 1933.478179] : cache set not found + +In this case, the caching device was simply not registered at boot or +disappeared and came back, and needs to be (re-)registered: +host:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register + + +C) Corrupt bcache caching device crashes the kernel on startup/boot + +You'll have to wipe the caching device, start the backing device without the +cache, and you can re-attach the cleaned up caching device then. This does +require booting with a kernel/rescue media where bcache is disabled +since it will otherwise try to access your device and probably crash +again before you have a chance to wipe it. +(or if you plan ahead, compile a backup kernel with bcache disabled and keep it +in your grub config for a rainy day) +If bcache is not available in the kernel, a filesystem on the backing device is +still available at an 8KiB offset. So either via a loopdev of the backing device +created with --offset 8K or by temporarily increasing the start sector of the +partition by 16 (512byte sectors). + +This is how you wipe the caching device: +host:~# wipefs -a /dev/sdh2 +16 bytes were erased at offset 0x1018 (bcache) +they were: c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81 + +After you boot back with bcache enabled, you recreate the cache and attach it: +host:~# make-bcache -C /dev/sdh2 +UUID: 7be7e175-8f4c-4f99-94b2-9c904d227045 +Set UUID: 5bc072a8-ab17-446d-9744-e247949913c1 +version: 0 +nbuckets: 106874 +block_size: 1 +bucket_size: 1024 +nr_in_set: 1 +nr_this_dev: 0 +first_bucket: 1 +[ 650.511912] bcache: run_cache_set() invalidating existing data +[ 650.549228] bcache: register_cache() registered cache device sdh2 + +start backing device with missing cache: +host:/sys/block/md5/bcache# echo 1 > running + +attach new cache: +host:/sys/block/md5/bcache# echo 5bc072a8-ab17-446d-9744-e247949913c1 > attach +[ 865.276616] bcache: bch_cached_dev_attach() Caching md5 as bcache0 on set 5bc072a8-ab17-446d-9744-e247949913c1 + + +D) Remove or replace a caching device + +host:/sys/block/sda/sda7/bcache# echo 1 > detach +[ 695.872542] bcache: cached_dev_detach_finish() Caching disabled for sda7 + +host:~# wipefs -a /dev/nvme0n1p4 +wipefs: error: /dev/nvme0n1p4: probing initialization failed: Device or resource busy +Ooops, it's disabled, but not unregistered, so it's still protected + +We need to go and unregister it: +host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# ls -l cache0 +lrwxrwxrwx 1 root root 0 Feb 25 18:33 cache0 -> ../../../devices/pci0000:00/0000:00:1d.0/0000:70:00.0/nvme/nvme0/nvme0n1/nvme0n1p4/bcache/ +host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# echo 1 > stop +kernel: [ 917.041908] bcache: cache_set_free() Cache set b7ba27a1-2398-4649-8ae3-0959f57ba128 unregistered + +Now we can wipe it: +host:~# wipefs -a /dev/nvme0n1p4 +/dev/nvme0n1p4: 16 bytes were erased at offset 0x00001018 (bcache): c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81 + + +E) dmcrypt and bcache + +First setup bcache unencrypted and then install dmcrypt on top of /dev/bcache +This will work faster than if you dmcrypt both the backing and caching +devices and then install bcache on top. + + +F) Stop/free a registered bcache to wipe and/or recreate it +(or maybe you need to free up all bcache references so that you can have fdisk +run and re-register a changed partition table, which won't work if there are any +active backing or caching devices left on it) + +1) Is it present in /dev/bcache* ? (there are times where it won't be) +If so, it's easy: +host:/sys/block/bcache0/bcache# echo 1 > stop + +2) But if your backing device is gone, this won't work: +host:/sys/block/bcache0# cd bcache +bash: cd: bcache: No such file or directory + +In this case, you may have to unregister the dmcrypt block device that +references this bcache to free it up: +host:~# dmsetup remove oldds1 +bcache: bcache_device_free() bcache0 stopped +bcache: cache_set_free() Cache set 5bc072a8-ab17-446d-9744-e247949913c1 unregistered + +This causes the backing bcache to be removed from /sys/fs/bcache and then it can +be reused + +3) In other cases, you can also look in /sys/fs/bcache/: +host:/sys/fs/bcache# ls -l */{cache?,bdev?} +lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/bdev1 -> ../../../devices/virtual/block/dm-1/bcache/ +lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/cache0 -> ../../../devices/virtual/block/dm-4/bcache/ +lrwxrwxrwx 1 root root 0 Mar 5 09:39 5bc072a8-ab17-446d-9744-e247949913c1/cache0 -> ../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0/ata10/host9/target9:0:0/9:0:0:0/block/sdl/sdl2/bcache/ + +The device names will show which UUID is relevant, cd in that directory +and stop the cache: +host:/sys/fs/bcache/5bc072a8-ab17-446d-9744-e247949913c1# echo 1 > stop +this will free up bcache references and let you reuse the partition for other +purposes. + + + +TROUBLESHOOTING PERFORMANCE +--------------------------- Bcache has a bunch of config options and tunables. The defaults are intended to be reasonable for typical desktop and server workloads, but they're not what you @@ -140,7 +282,7 @@ want for getting the best possible numbers when benchmarking. maturity, but simply because in writeback mode you'll lose data if something happens to your SSD) - # echo writeback > /sys/block/bcache0/cache_mode + # echo writeback > /sys/block/bcache0/bcache/cache_mode - Bad performance, or traffic not going to the SSD that you'd expect @@ -193,7 +335,9 @@ want for getting the best possible numbers when benchmarking. Solution: warm the cache by doing writes, or use the testing branch (there's a fix for the issue there). -SYSFS - BACKING DEVICE: + +SYSFS - BACKING DEVICE +---------------------- Available at /sys/block//bcache, /sys/block/bcache*/bcache and (if attached) /sys/fs/bcache//bdev* -- cgit v1.2.3 From c0b8c9a3447ad379869f21884b86ec97c7b8db7a Mon Sep 17 00:00:00 2001 From: Eric Wheeler Date: Fri, 11 Mar 2016 23:43:47 -0800 Subject: bcache: documentation formatting, edited for clarity, stripe alignment notes Signed-off-by: Eric Wheeler Cc: Marc MERLIN Signed-off-by: Jonathan Corbet --- Documentation/bcache.txt | 161 ++++++++++++++++++++++++++++------------------- 1 file changed, 97 insertions(+), 64 deletions(-) diff --git a/Documentation/bcache.txt b/Documentation/bcache.txt index 0aba405d3368..a9259b562d5c 100644 --- a/Documentation/bcache.txt +++ b/Documentation/bcache.txt @@ -137,48 +137,60 @@ the backing devices to passthrough mode. HOWTO/COOKBOOK -------------- -A) Your bcache doesn't start. - Starting and starting a bcache with a missing caching device +A) Starting a bcache with a missing caching device -Registering the backing device doesn't help, it's already there, you just need +If registering the backing device doesn't help, it's already there, you just need to force it to run without the cache: -host:~# echo /dev/sdb1 > /sys/fs/bcache/register -[ 119.844831] bcache: register_bcache() error opening /dev/sdb1: device already registered + host:~# echo /dev/sdb1 > /sys/fs/bcache/register + [ 119.844831] bcache: register_bcache() error opening /dev/sdb1: device already registered -Next, you try to register your caching device if it's present. However if it's -absent, or registration fails for some reason, you can still start your bcache -without its cache, like so: -host:/sys/block/sdb/sdb1/bcache# echo 1 > running +Next, you try to register your caching device if it's present. However +if it's absent, or registration fails for some reason, you can still +start your bcache without its cache, like so: + host:/sys/block/sdb/sdb1/bcache# echo 1 > running +Note that this may cause data loss if you were running in writeback mode. -B) Bcache not finding its cache and not starting -This does not work: -host:/sys/block/md5/bcache# echo 0226553a-37cf-41d5-b3ce-8b1e944543a8 > attach -[ 1933.455082] bcache: bch_cached_dev_attach() Couldn't find uuid for md5 in set -[ 1933.478179] bcache: __cached_dev_store() Can't attach 0226553a-37cf-41d5-b3ce-8b1e944543a8 -[ 1933.478179] : cache set not found +B) Bcache does not find its cache -In this case, the caching device was simply not registered at boot or -disappeared and came back, and needs to be (re-)registered: -host:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register + host:/sys/block/md5/bcache# echo 0226553a-37cf-41d5-b3ce-8b1e944543a8 > attach + [ 1933.455082] bcache: bch_cached_dev_attach() Couldn't find uuid for md5 in set + [ 1933.478179] bcache: __cached_dev_store() Can't attach 0226553a-37cf-41d5-b3ce-8b1e944543a8 + [ 1933.478179] : cache set not found +In this case, the caching device was simply not registered at boot +or disappeared and came back, and needs to be (re-)registered: + host:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register -C) Corrupt bcache caching device crashes the kernel on startup/boot -You'll have to wipe the caching device, start the backing device without the -cache, and you can re-attach the cleaned up caching device then. This does -require booting with a kernel/rescue media where bcache is disabled -since it will otherwise try to access your device and probably crash -again before you have a chance to wipe it. -(or if you plan ahead, compile a backup kernel with bcache disabled and keep it -in your grub config for a rainy day) -If bcache is not available in the kernel, a filesystem on the backing device is -still available at an 8KiB offset. So either via a loopdev of the backing device -created with --offset 8K or by temporarily increasing the start sector of the -partition by 16 (512byte sectors). +C) Corrupt bcache crashes the kernel at device registration time: + +This should never happen. If it does happen, then you have found a bug! +Please report it to the bcache development list: linux-bcache@vger.kernel.org + +Be sure to provide as much information that you can including kernel dmesg +output if available so that we may assist. + + +D) Recovering data without bcache: + +If bcache is not available in the kernel, a filesystem on the backing +device is still available at an 8KiB offset. So either via a loopdev +of the backing device created with --offset 8K, or any value defined by +--data-offset when you originally formatted bcache with `make-bcache`. + +For example: + losetup -o 8192 /dev/loop0 /dev/your_bcache_backing_dev + +This should present your unmodified backing device data in /dev/loop0 + +If your cache is in writethrough mode, then you can safely discard the +cache device without loosing data. + + +E) Wiping a cache device -This is how you wipe the caching device: host:~# wipefs -a /dev/sdh2 16 bytes were erased at offset 0x1018 (bcache) they were: c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81 @@ -205,56 +217,60 @@ host:/sys/block/md5/bcache# echo 5bc072a8-ab17-446d-9744-e247949913c1 > attach [ 865.276616] bcache: bch_cached_dev_attach() Caching md5 as bcache0 on set 5bc072a8-ab17-446d-9744-e247949913c1 -D) Remove or replace a caching device +F) Remove or replace a caching device -host:/sys/block/sda/sda7/bcache# echo 1 > detach -[ 695.872542] bcache: cached_dev_detach_finish() Caching disabled for sda7 + host:/sys/block/sda/sda7/bcache# echo 1 > detach + [ 695.872542] bcache: cached_dev_detach_finish() Caching disabled for sda7 -host:~# wipefs -a /dev/nvme0n1p4 -wipefs: error: /dev/nvme0n1p4: probing initialization failed: Device or resource busy -Ooops, it's disabled, but not unregistered, so it's still protected + host:~# wipefs -a /dev/nvme0n1p4 + wipefs: error: /dev/nvme0n1p4: probing initialization failed: Device or resource busy + Ooops, it's disabled, but not unregistered, so it's still protected We need to go and unregister it: -host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# ls -l cache0 -lrwxrwxrwx 1 root root 0 Feb 25 18:33 cache0 -> ../../../devices/pci0000:00/0000:00:1d.0/0000:70:00.0/nvme/nvme0/nvme0n1/nvme0n1p4/bcache/ -host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# echo 1 > stop -kernel: [ 917.041908] bcache: cache_set_free() Cache set b7ba27a1-2398-4649-8ae3-0959f57ba128 unregistered + host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# ls -l cache0 + lrwxrwxrwx 1 root root 0 Feb 25 18:33 cache0 -> ../../../devices/pci0000:00/0000:00:1d.0/0000:70:00.0/nvme/nvme0/nvme0n1/nvme0n1p4/bcache/ + host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# echo 1 > stop + kernel: [ 917.041908] bcache: cache_set_free() Cache set b7ba27a1-2398-4649-8ae3-0959f57ba128 unregistered Now we can wipe it: -host:~# wipefs -a /dev/nvme0n1p4 -/dev/nvme0n1p4: 16 bytes were erased at offset 0x00001018 (bcache): c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81 + host:~# wipefs -a /dev/nvme0n1p4 + /dev/nvme0n1p4: 16 bytes were erased at offset 0x00001018 (bcache): c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81 + +G) dm-crypt and bcache -E) dmcrypt and bcache +First setup bcache unencrypted and then install dmcrypt on top of +/dev/bcache This will work faster than if you dmcrypt both the backing +and caching devices and then install bcache on top. [benchmarks?] -First setup bcache unencrypted and then install dmcrypt on top of /dev/bcache -This will work faster than if you dmcrypt both the backing and caching -devices and then install bcache on top. +H) Stop/free a registered bcache to wipe and/or recreate it -F) Stop/free a registered bcache to wipe and/or recreate it -(or maybe you need to free up all bcache references so that you can have fdisk -run and re-register a changed partition table, which won't work if there are any -active backing or caching devices left on it) +Suppose that you need to free up all bcache references so that you can +fdisk run and re-register a changed partition table, which won't work +if there are any active backing or caching devices left on it: 1) Is it present in /dev/bcache* ? (there are times where it won't be) + If so, it's easy: -host:/sys/block/bcache0/bcache# echo 1 > stop + host:/sys/block/bcache0/bcache# echo 1 > stop 2) But if your backing device is gone, this won't work: -host:/sys/block/bcache0# cd bcache -bash: cd: bcache: No such file or directory + host:/sys/block/bcache0# cd bcache + bash: cd: bcache: No such file or directory In this case, you may have to unregister the dmcrypt block device that references this bcache to free it up: -host:~# dmsetup remove oldds1 -bcache: bcache_device_free() bcache0 stopped -bcache: cache_set_free() Cache set 5bc072a8-ab17-446d-9744-e247949913c1 unregistered + host:~# dmsetup remove oldds1 + bcache: bcache_device_free() bcache0 stopped + bcache: cache_set_free() Cache set 5bc072a8-ab17-446d-9744-e247949913c1 unregistered -This causes the backing bcache to be removed from /sys/fs/bcache and then it can -be reused +This causes the backing bcache to be removed from /sys/fs/bcache and +then it can be reused. This would be true of any block device stacking +where bcache is a lower device. 3) In other cases, you can also look in /sys/fs/bcache/: + host:/sys/fs/bcache# ls -l */{cache?,bdev?} lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/bdev1 -> ../../../devices/virtual/block/dm-1/bcache/ lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/cache0 -> ../../../devices/virtual/block/dm-4/bcache/ @@ -262,9 +278,10 @@ lrwxrwxrwx 1 root root 0 Mar 5 09:39 5bc072a8-ab17-446d-9744-e247949913c1/cache The device names will show which UUID is relevant, cd in that directory and stop the cache: -host:/sys/fs/bcache/5bc072a8-ab17-446d-9744-e247949913c1# echo 1 > stop -this will free up bcache references and let you reuse the partition for other -purposes. + host:/sys/fs/bcache/5bc072a8-ab17-446d-9744-e247949913c1# echo 1 > stop + +This will free up bcache references and let you reuse the partition for +other purposes. @@ -275,6 +292,22 @@ Bcache has a bunch of config options and tunables. The defaults are intended to be reasonable for typical desktop and server workloads, but they're not what you want for getting the best possible numbers when benchmarking. + - Backing device alignment + + The default metadata size in bcache is 8k. If your backing device is + RAID based, then be sure to align this by a multiple of your stride + width using `make-bcache --data-offset`. If you intend to expand your + disk array in the future, then multiply a series of primes by your + raid stripe size to get the disk multiples that you would like. + + For example: If you have a 64k stripe size, then the following offset + would provide alignment for many common RAID5 data spindle counts: + 64k * 2*2*2*3*3*5*7 bytes = 161280k + + That space is wasted, but for only 157.5MB you can grow your RAID 5 + volume to the following data-spindle counts without re-aligning: + 3,4,5,6,7,8,9,10,12,14,15,18,20,21 ... + - Bad write performance If write performance is not what you expected, you probably wanted to be @@ -382,7 +415,7 @@ sequential_merge against all new requests to determine which new requests are sequential continuations of previous requests for the purpose of determining sequential cutoff. This is necessary if the sequential cutoff value is greater than the - maximum acceptable sequential size for any single request. + maximum acceptable sequential size for any single request. state The backing device can be in one of four different states: @@ -469,7 +502,7 @@ bucket_size Size of buckets cache<0..n> - Symlink to each of the cache devices comprising this cache set. + Symlink to each of the cache devices comprising this cache set. cache_available_percent Percentage of cache device which doesn't contain dirty data, and could -- cgit v1.2.3 From a37376f32687cb4043e72f5f761df5cc52e08073 Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Fri, 17 Jun 2016 09:40:02 +0800 Subject: Documentation: fix wrong value in md.txt In the current Documentation/md.txt, the lower limit value of stripe_cache_size is 16 and the default value is 128, but when I update kernel to the latest mainline version and RAID5 array is created by mdadm, then execute the following commands, it shows an error and a difference respectively. 1) set stripe_cache_size to 16 [root@localhost ~]# echo 16 > /sys/block/md0/md/stripe_cache_size bash: echo: write error: Invalid argument 2) read the default value of stripe_cache_size [root@localhost ~]# cat /sys/block/md0/md/stripe_cache_size 256 I read drivers/md/raid5.c and find the following related code: 1) in function 'raid5_set_cache_size': if (size <= 16 || size > 32768) return -EINVAL; 2) #define NR_STRIPES 256 So the lower limit value of stripe_cache_size should be 17 and the default value should be 256. Signed-off-by: Tiezhu Yang Signed-off-by: Jonathan Corbet --- Documentation/md.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/md.txt b/Documentation/md.txt index 1a2ada46aaed..d6e2fcf27337 100644 --- a/Documentation/md.txt +++ b/Documentation/md.txt @@ -602,7 +602,7 @@ These currently include stripe_cache_size (currently raid5 only) number of entries in the stripe cache. This is writable, but - there are upper and lower limits (32768, 16). Default is 128. + there are upper and lower limits (32768, 17). Default is 256. strip_cache_active (currently raid5 only) number of active entries in the stripe cache preread_bypass_threshold (currently raid5 only) -- cgit v1.2.3 From 072baa037110bbb814b342cd478fe3ffdf84fdf9 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Sat, 11 Jun 2016 02:56:37 +0200 Subject: Documentation: tiny typo fix in usb/gadget_multi.txt Signed-off-by: Michal Nazarewicz Signed-off-by: Jonathan Corbet --- Documentation/usb/gadget_multi.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/usb/gadget_multi.txt b/Documentation/usb/gadget_multi.txt index 5faf514047e9..b3146dd7aa43 100644 --- a/Documentation/usb/gadget_multi.txt +++ b/Documentation/usb/gadget_multi.txt @@ -36,7 +36,7 @@ configuration with CDC ECM which should work better under Linux. ** Windows host drivers -For the gadget two work under Windows two conditions have to be met: +For the gadget to work under Windows two conditions have to be met: *** Detecting as composite gadget -- cgit v1.2.3 From 17defc282fe6e6ac93edbad8873ce89ef86b2490 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 23 Jun 2016 15:36:04 +0300 Subject: Documentation: add meta-documentation for Sphinx and kernel-doc Describe Sphinx, reStructuredText, the kernel-doc extension, the kernel-doc structured documentation comments, etc. The kernel-doc parts are based on kernel-doc-nano-HOWTO.txt, by Tim . Signed-off-by: Jani Nikula Signed-off-by: Jonathan Corbet --- Documentation/index.rst | 1 + Documentation/kernel-documentation.rst | 562 +++++++++++++++++++++++++++++++++ 2 files changed, 563 insertions(+) create mode 100644 Documentation/kernel-documentation.rst diff --git a/Documentation/index.rst b/Documentation/index.rst index 1139a7ea39ec..f92854f01773 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -13,6 +13,7 @@ Contents: .. toctree:: :maxdepth: 2 + kernel-documentation Indices and tables ================== diff --git a/Documentation/kernel-documentation.rst b/Documentation/kernel-documentation.rst new file mode 100644 index 000000000000..ad3506c13b11 --- /dev/null +++ b/Documentation/kernel-documentation.rst @@ -0,0 +1,562 @@ +========================== +Linux Kernel Documentation +========================== + +Introduction +============ + +The Linux kernel uses `Sphinx`_ to generate pretty documentation from +`reStructuredText`_ files under ``Documentation``. To build the documentation in +HTML or PDF formats, use ``make htmldocs`` or ``make pdfdocs``. The generated +documentation is placed in ``Documentation/output``. + +.. _Sphinx: http://www.sphinx-doc.org/ +.. _reStructuredText: http://docutils.sourceforge.net/rst.html + +The reStructuredText files may contain directives to include structured +documentation comments, or kernel-doc comments, from source files. Usually these +are used to describe the functions and types and design of the code. The +kernel-doc comments have some special structure and formatting, but beyond that +they are also treated as reStructuredText. + +There is also the deprecated DocBook toolchain to generate documentation from +DocBook XML template files under ``Documentation/DocBook``. The DocBook files +are to be converted to reStructuredText, and the toolchain is slated to be +removed. + +Finally, there are thousands of plain text documentation files scattered around +``Documentation``. Some of these will likely be converted to reStructuredText +over time, but the bulk of them will remain in plain text. + +Sphinx Build +============ + +The usual way to generate the documentation is to run ``make htmldocs`` or +``make pdfdocs``. There are also other formats available, see the documentation +section of ``make help``. The generated documentation is placed in +format-specific subdirectories under ``Documentation/output``. + +To generate documentation, Sphinx (``sphinx-build``) must obviously be +installed. For prettier HTML output, the Read the Docs Sphinx theme +(``sphinx_rtd_theme``) is used if available. For PDF output, ``rst2pdf`` is also +needed. All of these are widely available and packaged in distributions. + +To pass extra options to Sphinx, you can use the ``SPHINXOPTS`` make +variable. For example, use ``make SPHINXOPTS=-v htmldocs`` to get more verbose +output. + +To remove the generated documentation, run ``make cleandocs``. + +Writing Documentation +===================== + +Adding new documentation can be as simple as: + +1. Add a new ``.rst`` file somewhere under ``Documentation``. +2. Refer to it from the Sphinx main `TOC tree`_ in ``Documentation/index.rst``. + +.. _TOC tree: http://www.sphinx-doc.org/en/stable/markup/toctree.html + +This is usually good enough for simple documentation (like the one you're +reading right now), but for larger documents it may be advisable to create a +subdirectory (or use an existing one). For example, the graphics subsystem +documentation is under ``Documentation/gpu``, split to several ``.rst`` files, +and has a separate ``index.rst`` (with a ``toctree`` of its own) referenced from +the main index. + +See the documentation for `Sphinx`_ and `reStructuredText`_ on what you can do +with them. In particular, the Sphinx `reStructuredText Primer`_ is a good place +to get started with reStructuredText. There are also some `Sphinx specific +markup constructs`_. + +.. _reStructuredText Primer: http://www.sphinx-doc.org/en/stable/rest.html +.. _Sphinx specific markup constructs: http://www.sphinx-doc.org/en/stable/markup/index.html + +Specific guidelines for the kernel documentation +------------------------------------------------ + +Here are some specific guidelines for the kernel documentation: + +* Please don't go overboard with reStructuredText markup. Keep it simple. + +* Please stick to this order of heading adornments: + + 1. ``=`` with overline for document title:: + + ============== + Document title + ============== + + 2. ``=`` for chapters:: + + Chapters + ======== + + 3. ``-`` for sections:: + + Section + ------- + + 4. ``~`` for subsections:: + + Subsection + ~~~~~~~~~~ + + Although RST doesn't mandate a specific order ("Rather than imposing a fixed + number and order of section title adornment styles, the order enforced will be + the order as encountered."), having the higher levels the same overall makes + it easier to follow the documents. + + +Including kernel-doc comments +============================= + +The Linux kernel source files may contain structured documentation comments, or +kernel-doc comments to describe the functions and types and design of the +code. The documentation comments may be included to any of the reStructuredText +documents using a dedicated kernel-doc Sphinx directive extension. + +The kernel-doc directive is of the format:: + + .. kernel-doc:: source + :option: + +The *source* is the path to a source file, relative to the kernel source +tree. The following directive options are supported: + +export: *[source-pattern ...]* + Include documentation for all functions in *source* that have been exported + using ``EXPORT_SYMBOL`` or ``EXPORT_SYMBOL_GPL`` either in *source* or in any + of the files specified by *source-pattern*. + + The *source-pattern* is useful when the kernel-doc comments have been placed + in header files, while ``EXPORT_SYMBOL`` and ``EXPORT_SYMBOL_GPL`` are next to + the function definitions. + + Examples:: + + .. kernel-doc:: lib/bitmap.c + :export: + + .. kernel-doc:: include/net/mac80211.h + :export: net/mac80211/*.c + +internal: *[source-pattern ...]* + Include documentation for all functions and types in *source* that have + **not** been exported using ``EXPORT_SYMBOL`` or ``EXPORT_SYMBOL_GPL`` either + in *source* or in any of the files specified by *source-pattern*. + + Example:: + + .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c + :internal: + +doc: *title* + Include documentation for the ``DOC:`` paragraph identified by *title* in + *source*. Spaces are allowed in *title*; do not quote the *title*. The *title* + is only used as an identifier for the paragraph, and is not included in the + output. Please make sure to have an appropriate heading in the enclosing + reStructuredText document. + + Example:: + + .. kernel-doc:: drivers/gpu/drm/i915/intel_audio.c + :doc: High Definition Audio over HDMI and Display Port + +functions: *function* *[...]* + Include documentation for each *function* in *source*. + + Example:: + + .. kernel-doc:: lib/bitmap.c + :functions: bitmap_parselist bitmap_parselist_user + +Without options, the kernel-doc directive includes all documentation comments +from the source file. + +The kernel-doc extension is included in the kernel source tree, at +``Documentation/sphinx/kernel-doc.py``. Internally, it uses the +``scripts/kernel-doc`` script to extract the documentation comments from the +source. + +Writing kernel-doc comments +=========================== + +In order to provide embedded, "C" friendly, easy to maintain, but consistent and +extractable overview, function and type documentation, the Linux kernel has +adopted a consistent style for documentation comments. The format for this +documentation is called the kernel-doc format, described below. This style +embeds the documentation within the source files, using a few simple conventions +for adding documentation paragraphs and documenting functions and their +parameters, structures and unions and their members, enumerations, and typedefs. + +.. note:: The kernel-doc format is deceptively similar to gtk-doc or Doxygen, + yet distinctively different, for historical reasons. The kernel source + contains tens of thousands of kernel-doc comments. Please stick to the style + described here. + +The ``scripts/kernel-doc`` script is used by the Sphinx kernel-doc extension in +the documentation build to extract this embedded documentation into the various +HTML, PDF, and other format documents. + +In order to provide good documentation of kernel functions and data structures, +please use the following conventions to format your kernel-doc comments in the +Linux kernel source. + +How to format kernel-doc comments +--------------------------------- + +The opening comment mark ``/**`` is reserved for kernel-doc comments. Only +comments so marked will be considered by the ``kernel-doc`` tool. Use it only +for comment blocks that contain kernel-doc formatted comments. The usual ``*/`` +should be used as the closing comment marker. The lines in between should be +prefixed by `` * `` (space star space). + +The function and type kernel-doc comments should be placed just before the +function or type being described. The overview kernel-doc comments may be freely +placed at the top indentation level. + +Example kernel-doc function comment:: + + /** + * foobar() - Brief description of foobar. + * @arg: Description of argument of foobar. + * + * Longer description of foobar. + * + * Return: Description of return value of foobar. + */ + int foobar(int arg) + +The format is similar for documentation for structures, enums, paragraphs, +etc. See the sections below for details. + +The kernel-doc structure is extracted from the comments, and proper `Sphinx C +Domain`_ function and type descriptions with anchors are generated for them. The +descriptions are filtered for special kernel-doc highlights and +cross-references. See below for details. + +.. _Sphinx C Domain: http://www.sphinx-doc.org/en/stable/domains.html + +Highlights and cross-references +------------------------------- + +The following special patterns are recognized in the kernel-doc comment +descriptive text and converted to proper reStructuredText markup and `Sphinx C +Domain`_ references. + +.. attention:: The below are **only** recognized within kernel-doc comments, + **not** within normal reStructuredText documents. + +``funcname()`` + Function reference. + +``@parameter`` + Name of a function parameter. (No cross-referencing, just formatting.) + +``%CONST`` + Name of a constant. (No cross-referencing, just formatting.) + +``$ENVVAR`` + Name of an environment variable. (No cross-referencing, just formatting.) + +``&struct name`` + Structure reference. + +``&enum name`` + Enum reference. + +``&typedef name`` + Typedef reference. + +``&struct_name->member`` or ``&struct_name.member`` + Structure or union member reference. The cross-reference will be to the struct + or union definition, not the member directly. + +``&name`` + A generic type reference. Prefer using the full reference described above + instead. This is mostly for legacy comments. + +Cross-referencing from reStructuredText +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To cross-reference the functions and types defined in the kernel-doc comments +from reStructuredText documents, please use the `Sphinx C Domain`_ +references. For example:: + + See function :c:func:`foo` and struct/union/enum/typedef :c:type:`bar`. + +While the type reference works with just the type name, without the +struct/union/enum/typedef part in front, you may want to use:: + + See :c:type:`struct foo `. + See :c:type:`union bar `. + See :c:type:`enum baz `. + See :c:type:`typedef meh `. + +This will produce prettier links, and is in line with how kernel-doc does the +cross-references. + +For further details, please refer to the `Sphinx C Domain`_ documentation. + +Function documentation +---------------------- + +The general format of a function and function-like macro kernel-doc comment is:: + + /** + * function_name() - Brief description of function. + * @arg1: Describe the first argument. + * @arg2: Describe the second argument. + * One can provide multiple line descriptions + * for arguments. + * + * A longer description, with more discussion of the function function_name() + * that might be useful to those using or modifying it. Begins with an + * empty comment line, and may include additional embedded empty + * comment lines. + * + * The longer description may have multiple paragraphs. + * + * Return: Describe the return value of foobar. + * + * The return value description can also have multiple paragraphs, and should + * be placed at the end of the comment block. + */ + +The brief description following the function name may span multiple lines, and +ends with an ``@argument:`` description, a blank comment line, or the end of the +comment block. + +The kernel-doc function comments describe each parameter to the function, in +order, with the ``@argument:`` descriptions. The ``@argument:`` descriptions +must begin on the very next line following the opening brief function +description line, with no intervening blank comment lines. The ``@argument:`` +descriptions may span multiple lines. The continuation lines may contain +indentation. If a function parameter is ``...`` (varargs), it should be listed +in kernel-doc notation as: ``@...:``. + +The return value, if any, should be described in a dedicated section at the end +of the comment starting with "Return:". + +Structure, union, and enumeration documentation +----------------------------------------------- + +The general format of a struct, union, and enum kernel-doc comment is:: + + /** + * struct struct_name - Brief description. + * @member_name: Description of member member_name. + * + * Description of the structure. + */ + +Below, "struct" is used to mean structs, unions and enums, and "member" is used +to mean struct and union members as well as enumerations in an enum. + +The brief description following the structure name may span multiple lines, and +ends with a ``@member:`` description, a blank comment line, or the end of the +comment block. + +The kernel-doc data structure comments describe each member of the structure, in +order, with the ``@member:`` descriptions. The ``@member:`` descriptions must +begin on the very next line following the opening brief function description +line, with no intervening blank comment lines. The ``@member:`` descriptions may +span multiple lines. The continuation lines may contain indentation. + +In-line member documentation comments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The structure members may also be documented in-line within the definition:: + + /** + * struct foo - Brief description. + * @foo: The Foo member. + */ + struct foo { + int foo; + /** + * @bar: The Bar member. + */ + int bar; + /** + * @baz: The Baz member. + * + * Here, the member description may contain several paragraphs. + */ + int baz; + } + +Private members +~~~~~~~~~~~~~~~ + +Inside a struct description, you can use the "private:" and "public:" comment +tags. Structure fields that are inside a "private:" area are not listed in the +generated output documentation. The "private:" and "public:" tags must begin +immediately following a ``/*`` comment marker. They may optionally include +comments between the ``:`` and the ending ``*/`` marker. + +Example:: + + /** + * struct my_struct - short description + * @a: first member + * @b: second member + * + * Longer description + */ + struct my_struct { + int a; + int b; + /* private: internal use only */ + int c; + }; + + +Typedef documentation +--------------------- + +The general format of a typedef kernel-doc comment is:: + + /** + * typedef type_name - Brief description. + * + * Description of the type. + */ + +Overview documentation comments +------------------------------- + +To facilitate having source code and comments close together, you can include +kernel-doc documentation blocks that are free-form comments instead of being +kernel-doc for functions, structures, unions, enums, or typedefs. This could be +used for something like a theory of operation for a driver or library code, for +example. + +This is done by using a ``DOC:`` section keyword with a section title. + +The general format of an overview or high-level documentation comment is:: + + /** + * DOC: Theory of Operation + * + * The whizbang foobar is a dilly of a gizmo. It can do whatever you + * want it to do, at any time. It reads your mind. Here's how it works. + * + * foo bar splat + * + * The only drawback to this gizmo is that is can sometimes damage + * hardware, software, or its subject(s). + */ + +The title following ``DOC:`` acts as a heading within the source file, but also +as an identifier for extracting the documentation comment. Thus, the title must +be unique within the file. + +Recommendations +--------------- + +We definitely need kernel-doc formatted documentation for functions that are +exported to loadable modules using ``EXPORT_SYMBOL`` or ``EXPORT_SYMBOL_GPL``. + +We also look to provide kernel-doc formatted documentation for functions +externally visible to other kernel files (not marked "static"). + +We also recommend providing kernel-doc formatted documentation for private (file +"static") routines, for consistency of kernel source code layout. But this is +lower priority and at the discretion of the MAINTAINER of that kernel source +file. + +Data structures visible in kernel include files should also be documented using +kernel-doc formatted comments. + +DocBook XML [DEPRECATED] +======================== + +.. attention:: + + This section describes the deprecated DocBook XML toolchain. Please do not + create new DocBook XML template files. Please consider converting existing + DocBook XML templates files to Sphinx/reStructuredText. + +Converting DocBook to Sphinx +---------------------------- + +Over time, we expect all of the documents under ``Documentation/DocBook`` to be +converted to Sphinx and reStructuredText. For most DocBook XML documents, a good +enough solution is to use the simple ``Documentation/sphinx/tmplcvt`` script, +which uses ``pandoc`` under the hood. For example:: + + $ cd Documentation/sphinx + $ ./tmplcvt ../DocBook/in.tmpl ../out.rst + +Then edit the resulting rst files to fix any remaining issues, and add the +document in the ``toctree`` in ``Documentation/index.rst``. + +Components of the kernel-doc system +----------------------------------- + +Many places in the source tree have extractable documentation in the form of +block comments above functions. The components of this system are: + +- ``scripts/kernel-doc`` + + This is a perl script that hunts for the block comments and can mark them up + directly into reStructuredText, DocBook, man, text, and HTML. (No, not + texinfo.) + +- ``Documentation/DocBook/*.tmpl`` + + These are XML template files, which are normal XML files with special + place-holders for where the extracted documentation should go. + +- ``scripts/docproc.c`` + + This is a program for converting XML template files into XML files. When a + file is referenced it is searched for symbols exported (EXPORT_SYMBOL), to be + able to distinguish between internal and external functions. + + It invokes kernel-doc, giving it the list of functions that are to be + documented. + + Additionally it is used to scan the XML template files to locate all the files + referenced herein. This is used to generate dependency information as used by + make. + +- ``Makefile`` + + The targets 'xmldocs', 'psdocs', 'pdfdocs', and 'htmldocs' are used to build + DocBook XML files, PostScript files, PDF files, and html files in + Documentation/DocBook. The older target 'sgmldocs' is equivalent to 'xmldocs'. + +- ``Documentation/DocBook/Makefile`` + + This is where C files are associated with SGML templates. + +How to use kernel-doc comments in DocBook XML template files +------------------------------------------------------------ + +DocBook XML template files (\*.tmpl) are like normal XML files, except that they +can contain escape sequences where extracted documentation should be inserted. + +``!E`` is replaced by the documentation, in ````, for +functions that are exported using ``EXPORT_SYMBOL``: the function list is +collected from files listed in ``Documentation/DocBook/Makefile``. + +``!I`` is replaced by the documentation for functions that are **not** +exported using ``EXPORT_SYMBOL``. + +``!D`` is used to name additional files to search for functions +exported using ``EXPORT_SYMBOL``. + +``!F `` is replaced by the documentation, in +````, for the functions listed. + +``!P
`` is replaced by the contents of the ``DOC:`` +section titled ``
`` from ````. Spaces are allowed in +``
``; do not quote the ``
``. + +``!C`` is replaced by nothing, but makes the tools check that all DOC: +sections and documented functions, symbols, etc. are used. This makes sense to +use when you use ``!F`` or ``!P`` only and want to verify that all documentation +is included. -- cgit v1.2.3 From 0249a764485744b3f5babb02ced0fe6c199d89f7 Mon Sep 17 00:00:00 2001 From: Markus Heiser Date: Thu, 30 Jun 2016 14:00:22 +0200 Subject: doc-rst: flat-table directive - initial implementation Implements the reST flat-table directive. The ``flat-table`` is a double-stage list similar to the ``list-table`` with some additional features: * column-span: with the role ``cspan`` a cell can be extended through additional columns * row-span: with the role ``rspan`` a cell can be extended through additional rows * auto span rightmost cell of a table row over the missing cells on the right side of that table-row. With Option ``:fill-cells:`` this behavior can changed from *auto span* to *auto fill*, which automaticly inserts (empty) list tables The *list tables* formats are double stage lists. Compared to the ASCII-art they migth be less comfortable for readers of the text-files. Their advantage is, that they are easy to create/modify and that the diff of a modification is much more meaningfull, because it is limited to the modified content. The initial implementation was taken from the sphkerneldoc project [1] [1] https://github.com/return42/sphkerneldoc/commits/master/scripts/site-python/linuxdoc/rstFlatTable.py Signed-off-by: Markus Heiser [jc: fixed typos and misspellings in the docs] Signed-off-by: Jonathan Corbet --- Documentation/conf.py | 2 +- Documentation/kernel-documentation.rst | 86 ++++++++ Documentation/sphinx/rstFlatTable.py | 365 +++++++++++++++++++++++++++++++++ 3 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 Documentation/sphinx/rstFlatTable.py diff --git a/Documentation/conf.py b/Documentation/conf.py index 6cc41a0555a3..792b6338ef19 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -28,7 +28,7 @@ sys.path.insert(0, os.path.abspath('sphinx')) # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['kernel-doc'] +extensions = ['kernel-doc', 'rstFlatTable'] # Gracefully handle missing rst2pdf. try: diff --git a/Documentation/kernel-documentation.rst b/Documentation/kernel-documentation.rst index ad3506c13b11..391decc66a18 100644 --- a/Documentation/kernel-documentation.rst +++ b/Documentation/kernel-documentation.rst @@ -107,6 +107,92 @@ Here are some specific guidelines for the kernel documentation: the order as encountered."), having the higher levels the same overall makes it easier to follow the documents. +list tables +----------- + +We recommend the use of *list table* formats. The *list table* formats are +double-stage lists. Compared to the ASCII-art they might not be as +comfortable for +readers of the text files. Their advantage is that they are easy to +create or modify and that the diff of a modification is much more meaningful, +because it is limited to the modified content. + +The ``flat-table`` is a double-stage list similar to the ``list-table`` with +some additional features: + +* column-span: with the role ``cspan`` a cell can be extended through + additional columns + +* row-span: with the role ``rspan`` a cell can be extended through + additional rows + +* auto span rightmost cell of a table row over the missing cells on the right + side of that table-row. With Option ``:fill-cells:`` this behavior can + changed from *auto span* to *auto fill*, which automatically inserts (empty) + cells instead of spanning the last cell. + +options: + +* ``:header-rows:`` [int] count of header rows +* ``:stub-columns:`` [int] count of stub columns +* ``:widths:`` [[int] [int] ... ] widths of columns +* ``:fill-cells:`` instead of auto-spanning missing cells, insert missing cells + +roles: + +* ``:cspan:`` [int] additional columns (*morecols*) +* ``:rspan:`` [int] additional rows (*morerows*) + +The example below shows how to use this markup. The first level of the staged +list is the *table-row*. In the *table-row* there is only one markup allowed, +the list of the cells in this *table-row*. Exceptions are *comments* ( ``..`` ) +and *targets* (e.g. a ref to ``:ref:`last row ``` / :ref:`last row +`). + +.. code-block:: rst + + .. flat-table:: table title + :widths: 2 1 1 3 + + * - head col 1 + - head col 2 + - head col 3 + - head col 4 + + * - column 1 + - field 1.1 + - field 1.2 with autospan + + * - column 2 + - field 2.1 + - :rspan:`1` :cspan:`1` field 2.2 - 3.3 + + * .. _`last row`: + + - column 3 + +Rendered as: + + .. flat-table:: table title + :widths: 2 1 1 3 + + * - head col 1 + - head col 2 + - head col 3 + - head col 4 + + * - column 1 + - field 1.1 + - field 1.2 with autospan + + * - column 2 + - field 2.1 + - :rspan:`1` :cspan:`1` field 2.2 - 3.3 + + * .. _`last row`: + + - column 3 + Including kernel-doc comments ============================= diff --git a/Documentation/sphinx/rstFlatTable.py b/Documentation/sphinx/rstFlatTable.py new file mode 100644 index 000000000000..26db852e3c74 --- /dev/null +++ b/Documentation/sphinx/rstFlatTable.py @@ -0,0 +1,365 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8; mode: python -*- +# pylint: disable=C0330, R0903, R0912 + +u""" + flat-table + ~~~~~~~~~~ + + Implementation of the ``flat-table`` reST-directive. + + :copyright: Copyright (C) 2016 Markus Heiser + :license: GPL Version 2, June 1991 see linux/COPYING for details. + + The ``flat-table`` (:py:class:`FlatTable`) is a double-stage list similar to + the ``list-table`` with some additional features: + + * *column-span*: with the role ``cspan`` a cell can be extended through + additional columns + + * *row-span*: with the role ``rspan`` a cell can be extended through + additional rows + + * *auto span* rightmost cell of a table row over the missing cells on the + right side of that table-row. With Option ``:fill-cells:`` this behavior + can changed from *auto span* to *auto fill*, which automaticly inserts + (empty) cells instead of spanning the last cell. + + Options: + + * header-rows: [int] count of header rows + * stub-columns: [int] count of stub columns + * widths: [[int] [int] ... ] widths of columns + * fill-cells: instead of autospann missing cells, insert missing cells + + roles: + + * cspan: [int] additionale columns (*morecols*) + * rspan: [int] additionale rows (*morerows*) +""" + +# ============================================================================== +# imports +# ============================================================================== + +import sys + +from docutils import nodes +from docutils.parsers.rst import directives, roles +from docutils.parsers.rst.directives.tables import Table +from docutils.utils import SystemMessagePropagation + +# ============================================================================== +# common globals +# ============================================================================== + +# The version numbering follows numbering of the specification +# (Documentation/books/kernel-doc-HOWTO). +__version__ = '1.0' + +PY3 = sys.version_info[0] == 3 +PY2 = sys.version_info[0] == 2 + +if PY3: + # pylint: disable=C0103, W0622 + unicode = str + basestring = str + +# ============================================================================== +def setup(app): +# ============================================================================== + + app.add_directive("flat-table", FlatTable) + roles.register_local_role('cspan', c_span) + roles.register_local_role('rspan', r_span) + +# ============================================================================== +def c_span(name, rawtext, text, lineno, inliner, options=None, content=None): +# ============================================================================== + # pylint: disable=W0613 + + options = options if options is not None else {} + content = content if content is not None else [] + nodelist = [colSpan(span=int(text))] + msglist = [] + return nodelist, msglist + +# ============================================================================== +def r_span(name, rawtext, text, lineno, inliner, options=None, content=None): +# ============================================================================== + # pylint: disable=W0613 + + options = options if options is not None else {} + content = content if content is not None else [] + nodelist = [rowSpan(span=int(text))] + msglist = [] + return nodelist, msglist + + +# ============================================================================== +class rowSpan(nodes.General, nodes.Element): pass # pylint: disable=C0103,C0321 +class colSpan(nodes.General, nodes.Element): pass # pylint: disable=C0103,C0321 +# ============================================================================== + +# ============================================================================== +class FlatTable(Table): +# ============================================================================== + + u"""FlatTable (``flat-table``) directive""" + + option_spec = { + 'name': directives.unchanged + , 'class': directives.class_option + , 'header-rows': directives.nonnegative_int + , 'stub-columns': directives.nonnegative_int + , 'widths': directives.positive_int_list + , 'fill-cells' : directives.flag } + + def run(self): + + if not self.content: + error = self.state_machine.reporter.error( + 'The "%s" directive is empty; content required.' % self.name, + nodes.literal_block(self.block_text, self.block_text), + line=self.lineno) + return [error] + + title, messages = self.make_title() + node = nodes.Element() # anonymous container for parsing + self.state.nested_parse(self.content, self.content_offset, node) + + tableBuilder = ListTableBuilder(self) + tableBuilder.parseFlatTableNode(node) + tableNode = tableBuilder.buildTableNode() + # SDK.CONSOLE() # print --> tableNode.asdom().toprettyxml() + if title: + tableNode.insert(0, title) + return [tableNode] + messages + + +# ============================================================================== +class ListTableBuilder(object): +# ============================================================================== + + u"""Builds a table from a double-stage list""" + + def __init__(self, directive): + self.directive = directive + self.rows = [] + self.max_cols = 0 + + def buildTableNode(self): + + colwidths = self.directive.get_column_widths(self.max_cols) + stub_columns = self.directive.options.get('stub-columns', 0) + header_rows = self.directive.options.get('header-rows', 0) + + table = nodes.table() + tgroup = nodes.tgroup(cols=len(colwidths)) + table += tgroup + + + for colwidth in colwidths: + colspec = nodes.colspec(colwidth=colwidth) + # FIXME: It seems, that the stub method only works well in the + # absence of rowspan (observed by the html buidler, the docutils-xml + # build seems OK). This is not extraordinary, because there exists + # no table directive (except *this* flat-table) which allows to + # define coexistent of rowspan and stubs (there was no use-case + # before flat-table). This should be reviewed (later). + if stub_columns: + colspec.attributes['stub'] = 1 + stub_columns -= 1 + tgroup += colspec + stub_columns = self.directive.options.get('stub-columns', 0) + + if header_rows: + thead = nodes.thead() + tgroup += thead + for row in self.rows[:header_rows]: + thead += self.buildTableRowNode(row) + + tbody = nodes.tbody() + tgroup += tbody + + for row in self.rows[header_rows:]: + tbody += self.buildTableRowNode(row) + return table + + def buildTableRowNode(self, row_data, classes=None): + classes = [] if classes is None else classes + row = nodes.row() + for cell in row_data: + if cell is None: + continue + cspan, rspan, cellElements = cell + + attributes = {"classes" : classes} + if rspan: + attributes['morerows'] = rspan + if cspan: + attributes['morecols'] = cspan + entry = nodes.entry(**attributes) + entry.extend(cellElements) + row += entry + return row + + def raiseError(self, msg): + error = self.directive.state_machine.reporter.error( + msg + , nodes.literal_block(self.directive.block_text + , self.directive.block_text) + , line = self.directive.lineno ) + raise SystemMessagePropagation(error) + + def parseFlatTableNode(self, node): + u"""parses the node from a :py:class:`FlatTable` directive's body""" + + if len(node) != 1 or not isinstance(node[0], nodes.bullet_list): + self.raiseError( + 'Error parsing content block for the "%s" directive: ' + 'exactly one bullet list expected.' % self.directive.name ) + + for rowNum, rowItem in enumerate(node[0]): + row = self.parseRowItem(rowItem, rowNum) + self.rows.append(row) + self.roundOffTableDefinition() + + def roundOffTableDefinition(self): + u"""Round off the table definition. + + This method rounds off the table definition in :py:member:`rows`. + + * This method inserts the needed ``None`` values for the missing cells + arising from spanning cells over rows and/or columns. + + * recount the :py:member:`max_cols` + + * Autospan or fill (option ``fill-cells``) missing cells on the right + side of the table-row + """ + + y = 0 + while y < len(self.rows): + x = 0 + + while x < len(self.rows[y]): + cell = self.rows[y][x] + if cell is None: + x += 1 + continue + cspan, rspan = cell[:2] + # handle colspan in current row + for c in range(cspan): + try: + self.rows[y].insert(x+c+1, None) + except: # pylint: disable=W0702 + # the user sets ambiguous rowspans + pass # SDK.CONSOLE() + # handle colspan in spanned rows + for r in range(rspan): + for c in range(cspan + 1): + try: + self.rows[y+r+1].insert(x+c, None) + except: # pylint: disable=W0702 + # the user sets ambiguous rowspans + pass # SDK.CONSOLE() + x += 1 + y += 1 + + # Insert the missing cells on the right side. For this, first + # re-calculate the max columns. + + for row in self.rows: + if self.max_cols < len(row): + self.max_cols = len(row) + + # fill with empty cells or cellspan? + + fill_cells = False + if 'fill-cells' in self.directive.options: + fill_cells = True + + for row in self.rows: + x = self.max_cols - len(row) + if x and not fill_cells: + if row[-1] is None: + row.append( ( x - 1, 0, []) ) + else: + cspan, rspan, content = row[-1] + row[-1] = (cspan + x, rspan, content) + elif x and fill_cells: + for i in range(x): + row.append( (0, 0, nodes.comment()) ) + + def pprint(self): + # for debugging + retVal = "[ " + for row in self.rows: + retVal += "[ " + for col in row: + if col is None: + retVal += ('%r' % col) + retVal += "\n , " + else: + content = col[2][0].astext() + if len (content) > 30: + content = content[:30] + "..." + retVal += ('(cspan=%s, rspan=%s, %r)' + % (col[0], col[1], content)) + retVal += "]\n , " + retVal = retVal[:-2] + retVal += "]\n , " + retVal = retVal[:-2] + return retVal + "]" + + def parseRowItem(self, rowItem, rowNum): + row = [] + childNo = 0 + error = False + cell = None + target = None + + for child in rowItem: + if (isinstance(child , nodes.comment) + or isinstance(child, nodes.system_message)): + pass + elif isinstance(child , nodes.target): + target = child + elif isinstance(child, nodes.bullet_list): + childNo += 1 + cell = child + else: + error = True + break + + if childNo != 1 or error: + self.raiseError( + 'Error parsing content block for the "%s" directive: ' + 'two-level bullet list expected, but row %s does not ' + 'contain a second-level bullet list.' + % (self.directive.name, rowNum + 1)) + + for cellItem in cell: + cspan, rspan, cellElements = self.parseCellItem(cellItem) + if target is not None: + cellElements.insert(0, target) + row.append( (cspan, rspan, cellElements) ) + return row + + def parseCellItem(self, cellItem): + # search and remove cspan, rspan colspec from the first element in + # this listItem (field). + cspan = rspan = 0 + if not len(cellItem): + return cspan, rspan, [] + for elem in cellItem[0]: + if isinstance(elem, colSpan): + cspan = elem.get("span") + elem.parent.remove(elem) + continue + if isinstance(elem, rowSpan): + rspan = elem.get("span") + elem.parent.remove(elem) + continue + return cspan, rspan, cellItem[:] -- cgit v1.2.3 From 05d0066a5787189bb31a5808c1e9b3157561c184 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 29 Jun 2016 18:05:56 +0900 Subject: Doc: PM: Fix a typo in intel_powerclamp.txt This patch fix a spelling typo in intel_powerclamp.txt Signed-off-by: Masanari Iida Signed-off-by: Jonathan Corbet --- Documentation/thermal/intel_powerclamp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/thermal/intel_powerclamp.txt b/Documentation/thermal/intel_powerclamp.txt index 332de4a39b5a..60073dc9f748 100644 --- a/Documentation/thermal/intel_powerclamp.txt +++ b/Documentation/thermal/intel_powerclamp.txt @@ -121,7 +121,7 @@ time is considered largely as a non-causal system where its behavior cannot be based on the past or current input. Therefore, the intel_powerclamp driver attempts to enforce the desired idle time instantly as given input (target idle ratio). After injection, -powerclamp moniors the actual idle for a given time window and adjust +powerclamp monitors the actual idle for a given time window and adjust the next injection accordingly to avoid over/under correction. When used in a causal control system, such as a temperature control, -- cgit v1.2.3 From 19abdb15f3c781565f375db2e13d6c9f8bcbb561 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 30 Jun 2016 13:07:33 -0600 Subject: Add .pyc files to .gitignore Signed-off-by: Jonathan Corbet --- Documentation/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/.gitignore b/Documentation/.gitignore index 53752db253e3..e74fec8693b2 100644 --- a/Documentation/.gitignore +++ b/Documentation/.gitignore @@ -1 +1,2 @@ output +*.pyc -- cgit v1.2.3 From a569bf69f069a86a6914453cc1ab5371d173caf1 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 1 Jul 2016 15:03:34 +0300 Subject: Documentation: add cleanmediadocs to the documentation targets This was broken when updating the documentation targets for the Sphinx build, and moving from %docs target pattern to explicitly listed targets. Cc: Markus Heiser Cc: Mauro Carvalho Chehab Fixes: 22cba31bae9d ("Documentation/sphinx: add basic working Sphinx configuration and build") Signed-off-by: Jani Nikula Signed-off-by: Jonathan Corbet --- Documentation/Makefile.sphinx | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx index 810c11f0d37f..6c203745b6c6 100644 --- a/Documentation/Makefile.sphinx +++ b/Documentation/Makefile.sphinx @@ -56,6 +56,7 @@ sgmldocs: psdocs: mandocs: installmandocs: +cleanmediadocs: cleandocs: $(Q)rm -rf $(BUILDDIR) diff --git a/Makefile b/Makefile index f7f393c40886..34bc4e22ec0b 100644 --- a/Makefile +++ b/Makefile @@ -1414,7 +1414,7 @@ $(help-board-dirs): help-%: # Documentation targets # --------------------------------------------------------------------------- -DOC_TARGETS := xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs +DOC_TARGETS := xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs cleanmediadocs PHONY += $(DOC_TARGETS) $(DOC_TARGETS): scripts_basic FORCE $(Q)$(MAKE) $(build)=scripts build_docproc build_check-lc_ctype -- cgit v1.2.3 From 6387872c86ea6698ed8faa3ccad1d1bd60f762f7 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 1 Jul 2016 15:24:44 +0300 Subject: Documentation/sphinx: skip build if user requested specific DOCBOOKS If the user requested specific DocBooks to be built using 'make DOCBOOKS=foo.xml htmldocs', assume no Sphinx build is desired. This check is transitional, and can be removed once we drop the DocBook build. Cc: Markus Heiser Cc: Mauro Carvalho Chehab Fixes: 22cba31bae9d ("Documentation/sphinx: add basic working Sphinx configuration and build") Signed-off-by: Jani Nikula Signed-off-by: Jonathan Corbet --- Documentation/Makefile.sphinx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/Makefile.sphinx b/Documentation/Makefile.sphinx index 6c203745b6c6..d8d13c92a178 100644 --- a/Documentation/Makefile.sphinx +++ b/Documentation/Makefile.sphinx @@ -17,6 +17,12 @@ ifeq ($(HAVE_SPHINX),0) $(warning The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable.) @echo " SKIP Sphinx $@ target." +else ifneq ($(DOCBOOKS),) + +# Skip Sphinx build if the user explicitly requested DOCBOOKS. +.DEFAULT: + @echo " SKIP Sphinx $@ target (DOCBOOKS specified)." + else # HAVE_SPHINX # User-friendly check for rst2pdf -- cgit v1.2.3 From a039ba34a349821fcbf949e7904117d0b14354f4 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 1 Jul 2016 20:28:18 +0900 Subject: Doc: ocfs: Fix typo in filesystems/ocfs2-online-filecheck.txt This patch fix some spelling typo found in ocfs2-online-filecheck.txt Signed-off-by: Masanari Iida Signed-off-by: Jonathan Corbet --- Documentation/filesystems/ocfs2-online-filecheck.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/filesystems/ocfs2-online-filecheck.txt b/Documentation/filesystems/ocfs2-online-filecheck.txt index 1ab07860430d..139fab175c8a 100644 --- a/Documentation/filesystems/ocfs2-online-filecheck.txt +++ b/Documentation/filesystems/ocfs2-online-filecheck.txt @@ -5,12 +5,12 @@ This document will describe OCFS2 online file check feature. Introduction ============ -OCFS2 is often used in high-availaibility systems. However, OCFS2 usually +OCFS2 is often used in high-availability systems. However, OCFS2 usually converts the filesystem to read-only when encounters an error. This may not be necessary, since turning the filesystem read-only would affect other running processes as well, decreasing availability. Then, a mount option (errors=continue) is introduced, which would return the --EIO errno to the calling process and terminate furhter processing so that the +-EIO errno to the calling process and terminate further processing so that the filesystem is not corrupted further. The filesystem is not converted to read-only, and the problematic file's inode number is reported in the kernel log. The user can try to check/fix this file via online filecheck feature. @@ -44,7 +44,7 @@ There is a sysfs directory for each OCFS2 file system mounting: /sys/fs/ocfs2//filecheck -Here, indicates the name of OCFS2 volumn device which has been already +Here, indicates the name of OCFS2 volume device which has been already mounted. The file above would accept inode numbers. This could be used to communicate with kernel space, tell which file(inode number) will be checked or fixed. Currently, three operations are supported, which includes checking @@ -76,14 +76,14 @@ The output is like this: This time, the column indicates whether this fix is successful or not. 3. The record cache is used to store the history of check/fix results. It's -defalut size is 10, and can be adjust between the range of 10 ~ 100. You can +default size is 10, and can be adjust between the range of 10 ~ 100. You can adjust the size like this: # echo "" > /sys/fs/ocfs2//filecheck/set Fixing stuff ============ -On receivng the inode, the filesystem would read the inode and the +On receiving the inode, the filesystem would read the inode and the file metadata. In case of errors, the filesystem would fix the errors and report the problems it fixed in the kernel log. As a precautionary measure, the inode must first be checked for errors before performing a final fix. -- cgit v1.2.3 From fb054c5a95ba336ce2f29c98aee3eb042d725d0f Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 5 Jul 2016 20:55:30 +0900 Subject: workqueue: Fix a typo in workqueue.txt This patch fixes a spelling typo in workqueue.txt Signed-off-by: Masanari Iida Acked-by: Tejun Heo Signed-off-by: Jonathan Corbet --- Documentation/workqueue.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/workqueue.txt b/Documentation/workqueue.txt index 5e0e05c5183e..c49e3178178d 100644 --- a/Documentation/workqueue.txt +++ b/Documentation/workqueue.txt @@ -169,7 +169,7 @@ resources, scheduled and executed. WQ_UNBOUND Work items queued to an unbound wq are served by the special - woker-pools which host workers which are not bound to any + worker-pools which host workers which are not bound to any specific CPU. This makes the wq behave as a simple execution context provider without concurrency management. The unbound worker-pools try to start execution of work items as soon as -- cgit v1.2.3 From 547218864afb2745d9d137f005f3380ef96b26ab Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Jul 2016 13:12:45 -0300 Subject: doc-rst: add an option to ignore DocBooks when generating docs Sometimes, we want to do a partial build, instead of building everything. However, right now, if one wants to build just Sphinx books, it will build also the DocBooks. Add an option to allow to ignore all DocBooks when building documentation. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- Documentation/DocBook/Makefile | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 496d4295ec38..01bab5014a4a 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -6,6 +6,8 @@ # To add a new book the only step required is to add the book to the # list of DOCBOOKS. +ifeq ($(IGNORE_DOCBOOKS),) + DOCBOOKS := z8530book.xml device-drivers.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ writing_usb_driver.xml networking.xml \ @@ -215,6 +217,20 @@ silent_gen_xml = : -e "s/>/\\>/g"; \ echo "") > $@ +else + +# Needed, due to cleanmediadocs +include Documentation/DocBook/media/Makefile + +htmldocs: +pdfdocs: +psdocs: +xmldocs: +installmandocs: + +endif # IGNORE_DOCBOOKS + + ### # Help targets as used by the top-level makefile dochelp: @@ -229,6 +245,9 @@ dochelp: @echo @echo ' make DOCBOOKS="s1.xml s2.xml" [target] Generate only docs s1.xml s2.xml' @echo ' valid values for DOCBOOKS are: $(DOCBOOKS)' + @echo + @echo " make IGNORE_DOCBOOKS=1 [target] Don't generate docs from Docbook" + @echo ' This is useful to generate only the ReST docs (Sphinx)' ### -- cgit v1.2.3 From fd7db68b9363a80d3c6f3b55e05ec56211ea6254 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Sun, 17 Jul 2016 19:24:02 -0600 Subject: docs: Get rid of some kernel-documentation warnings Sphinx wants to interpret all literal blocks as being in the chosen language and complains when an attempt to parse a block fails. kernel-documentation.rst has a few blocks that are not in C; make that explicit to shut down the associated warnings. Signed-off-by: Jonathan Corbet --- Documentation/kernel-documentation.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/kernel-documentation.rst b/Documentation/kernel-documentation.rst index 391decc66a18..c4eb5049da39 100644 --- a/Documentation/kernel-documentation.rst +++ b/Documentation/kernel-documentation.rst @@ -366,6 +366,8 @@ Domain`_ references. Cross-referencing from reStructuredText ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. highlight:: none + To cross-reference the functions and types defined in the kernel-doc comments from reStructuredText documents, please use the `Sphinx C Domain`_ references. For example:: @@ -388,6 +390,8 @@ For further details, please refer to the `Sphinx C Domain`_ documentation. Function documentation ---------------------- +.. highlight:: c + The general format of a function and function-like macro kernel-doc comment is:: /** @@ -568,6 +572,8 @@ DocBook XML [DEPRECATED] Converting DocBook to Sphinx ---------------------------- +.. highlight:: none + Over time, we expect all of the documents under ``Documentation/DocBook`` to be converted to Sphinx and reStructuredText. For most DocBook XML documents, a good enough solution is to use the simple ``Documentation/sphinx/tmplcvt`` script, -- cgit v1.2.3 From e7ca311e376c81a51ce031c569f336bdadf5ea98 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 15 Jul 2016 10:19:30 +0200 Subject: kernel-doc: Fix up warning output While trying to make gpu docs warning free I stumbled over one output which wasn't following proper compiler error output standards. Fix it up for more quickfix awesomeness. Cc: Jonathan Corbet Cc: Jani Nikula Cc: linux-doc@vger.kernel.org Signed-off-by: Daniel Vetter Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 932b3f34ff06..7388e88a1f50 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2994,7 +2994,7 @@ sub process_file($) { } } elsif ($inline_doc_state == STATE_INLINE_NAME) { $inline_doc_state = STATE_INLINE_ERROR; - print STDERR "Warning(${file}:$.): "; + print STDERR "${file}:$.: warning: "; print STDERR "Incorrect use of kernel-doc format: $_"; ++$warnings; } -- cgit v1.2.3 From e6507a00fd08986ce003012a10af78cc7e47eee8 Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Tue, 12 Jul 2016 12:05:59 +0200 Subject: Documentation: add watermark_scale_factor to the list of vm systcl file Commit 795ae7a0de6b ("mm: scale kswapd watermarks in proportion to memory") properly added the description of the new knob to Documentation/sysctl/vm.txt, but forgot to add it to the list of files in /proc/sys/vm. Let's fix that. Signed-off-by: Jerome Marchand Acked-by: Johannes Weiner Signed-off-by: Jonathan Corbet --- Documentation/sysctl/vm.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 720355cbdf45..95ccbe6d79ce 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -61,6 +61,7 @@ Currently, these files are in /proc/sys/vm: - swappiness - user_reserve_kbytes - vfs_cache_pressure +- watermark_scale_factor - zone_reclaim_mode ============================================================== -- cgit v1.2.3 From 47d6d752b9e20dbe8a2acd22e887be81a6f39de9 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 19 Jul 2016 13:42:54 +0200 Subject: doc/sphinx: Enable keep_warnings Unfortunately warnings generated after parsing in sphinx can end up with entirely bogus files and line numbers as sources. Strangely for outright errors this is not a problem. Trying to convert warnings to errors also doesn't fix it. The only way to get useful output out of sphinx to be able to root cause the error seems to be enabling keep_warnings, which inserts a System Message into the actual output. Not pretty at all, but I don't really want to fix up core rst/sphinx code, and this gets the job done meanwhile. Cc: Markus Heiser Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Signed-off-by: Daniel Vetter Signed-off-by: Jonathan Corbet --- Documentation/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/conf.py b/Documentation/conf.py index 792b6338ef19..49c242cf18c5 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -125,7 +125,7 @@ pygments_style = 'sphinx' #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +keep_warnings = True # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False -- cgit v1.2.3 From 8ed292fe864e9ed7d335515e97590122a56d7cba Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Wed, 20 Jul 2016 16:43:41 -0600 Subject: docs: deprecate kernel-doc-nano-HOWTO.txt Now that the new Sphinx world order is taking over, the information in kernel-doc-nano-HOWTO.txt is outmoded. I hate to remove it altogether, since it's one of those files that people expect to find. But we can add a warning and fix all the other pointers to it. Reminded-by: Daniel Vetter Signed-off-by: Jonathan Corbet --- Documentation/00-INDEX | 4 ++-- Documentation/CodingStyle | 2 +- Documentation/development-process/4.Coding | 2 +- Documentation/kernel-doc-nano-HOWTO.txt | 3 +++ Documentation/zh_CN/CodingStyle | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index cd077ca0e1b8..cb9a6c6fa83b 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -255,10 +255,10 @@ kbuild/ - directory with info about the kernel build process. kdump/ - directory with mini HowTo on getting the crash dump code to work. -kernel-doc-nano-HOWTO.txt - - mini HowTo on generation and location of kernel documentation files. kernel-docs.txt - listing of various WWW + books that document kernel internals. +kernel-documentation.rst + - how to write and format reStructuredText kernel documentation kernel-parameters.txt - summary listing of command line / boot prompt args for the kernel. kernel-per-CPU-kthreads.txt diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle index 9a70ddd16584..a096836723ca 100644 --- a/Documentation/CodingStyle +++ b/Documentation/CodingStyle @@ -458,7 +458,7 @@ of the function, telling people what it does, and possibly WHY it does it. When commenting the kernel API functions, please use the kernel-doc format. -See the files Documentation/kernel-doc-nano-HOWTO.txt and scripts/kernel-doc +See the files Documentation/kernel-documentation.rst and scripts/kernel-doc for details. Linux style for comments is the C89 "/* ... */" style. diff --git a/Documentation/development-process/4.Coding b/Documentation/development-process/4.Coding index e3cb6a56653a..9a3ee77cefb1 100644 --- a/Documentation/development-process/4.Coding +++ b/Documentation/development-process/4.Coding @@ -346,7 +346,7 @@ which have not been so documented, there is no harm in adding kerneldoc comments for the future; indeed, this can be a useful activity for beginning kernel developers. The format of these comments, along with some information on how to create kerneldoc templates can be found in the file -Documentation/kernel-doc-nano-HOWTO.txt. +Documentation/kernel-documentation.rst. Anybody who reads through a significant amount of existing kernel code will note that, often, comments are most notable by their absence. Once again, diff --git a/Documentation/kernel-doc-nano-HOWTO.txt b/Documentation/kernel-doc-nano-HOWTO.txt index 78f69cdc9b3f..062e3af271b7 100644 --- a/Documentation/kernel-doc-nano-HOWTO.txt +++ b/Documentation/kernel-doc-nano-HOWTO.txt @@ -1,3 +1,6 @@ +NOTE: this document is outdated and will eventually be removed. See +Documentation/kernel-documentation.rst for current information. + kernel-doc nano-HOWTO ===================== diff --git a/Documentation/zh_CN/CodingStyle b/Documentation/zh_CN/CodingStyle index bbb9d6ae05ca..12717791baac 100644 --- a/Documentation/zh_CN/CodingStyle +++ b/Documentation/zh_CN/CodingStyle @@ -399,7 +399,7 @@ C是一个简朴的语言,你的命名也应该这样。和 Modula-2 和 Pasca 些事情的原因。 当注释内核API函数时,请使用 kernel-doc 格式。请看 -Documentation/kernel-doc-nano-HOWTO.txt和scripts/kernel-doc 以获得详细信息。 +Documentation/kernel-documentation.rst和scripts/kernel-doc 以获得详细信息。 Linux的注释风格是 C89 “/* ... */” 风格。不要使用 C99 风格 “// ...” 注释。 -- cgit v1.2.3 From f42ddca7bebcc069f470143434c119c96cd15bb5 Mon Sep 17 00:00:00 2001 From: Markus Heiser Date: Wed, 20 Jul 2016 12:38:58 +0200 Subject: doc-rst: kernel-doc directive, fix state machine reporter Add a reporter replacement that assigns the correct source name and line number to a system message, as recorded in a ViewList. [1] http://mid.gmane.org/CAKMK7uFMQ2wOp99t-8v06Om78mi9OvRZWuQsFJD55QA20BB3iw@mail.gmail.com Signed-off-by: Markus Heiser Tested-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- Documentation/sphinx/kernel-doc.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py index dedb24e3bb7a..f6920c0af6ee 100644 --- a/Documentation/sphinx/kernel-doc.py +++ b/Documentation/sphinx/kernel-doc.py @@ -37,6 +37,7 @@ from docutils import nodes, statemachine from docutils.statemachine import ViewList from docutils.parsers.rst import directives from sphinx.util.compat import Directive +from sphinx.ext.autodoc import AutodocReporter class KernelDocDirective(Directive): """Extract kernel-doc comments from the specified file""" @@ -117,12 +118,17 @@ class KernelDocDirective(Directive): lineoffset += 1 node = nodes.section() - node.document = self.state.document - self.state.nested_parse(result, self.content_offset, node) + buf = 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.title_styles, self.state.memo.section_level = [], 0 + try: + self.state.nested_parse(result, 0, node, match_titles=1) + finally: + self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = buf return node.children - except Exception as e: + 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"))] -- cgit v1.2.3 From 29310a50752de76314f51555b72044d11f6cba49 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Wed, 20 Jul 2016 16:56:21 -0600 Subject: Revert "doc/sphinx: Enable keep_warnings" This reverts commit 47d6d752b9e20dbe8a2acd22e887be81a6f39de9. Commit f42ddca7bebc (doc-rst: kernel-doc directive, fix state machine reporter) from Marcus Heiser provides a better fix, so this configuration change is no longer needed. --- Documentation/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/conf.py b/Documentation/conf.py index 49c242cf18c5..792b6338ef19 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -125,7 +125,7 @@ pygments_style = 'sphinx' #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -keep_warnings = True +#keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False -- cgit v1.2.3 From a88b1672d4ddf9895eb53e6980926d5e960dea8e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 22 Jul 2016 11:46:36 -0300 Subject: doc-rst: kernel-doc: fix handling of address_space tags The RST cpp:function handler is very pedantic: it doesn't allow any macros like __user on it: Documentation/media/kapi/dtv-core.rst:28: WARNING: Error when parsing function declaration. If the function has no return type: Error in declarator or parameters and qualifiers Invalid definition: Expecting "(" in parameters_and_qualifiers. [error at 8] ssize_t dvb_ringbuffer_pkt_read_user (struct dvb_ringbuffer * rbuf, size_t idx, int offset, u8 __user * buf, size_t len) --------^ If the function has a return type: Error in declarator or parameters and qualifiers If pointer to member declarator: Invalid definition: Expected '::' in pointer to member (function). [error at 37] ssize_t dvb_ringbuffer_pkt_read_user (struct dvb_ringbuffer * rbuf, size_t idx, int offset, u8 __user * buf, size_t len) -------------------------------------^ If declarator-id: Invalid definition: Expecting "," or ")" in parameters_and_qualifiers, got "*". [error at 102] ssize_t dvb_ringbuffer_pkt_read_user (struct dvb_ringbuffer * rbuf, size_t idx, int offset, u8 __user * buf, size_t len) ------------------------------------------------------------------------------------------------------^ So, we have to remove it from the function prototype. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 7388e88a1f50..4f2e9049e8fa 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1848,6 +1848,10 @@ sub output_function_rst(%) { } $count++; $type = $args{'parametertypes'}{$parameter}; + + # RST doesn't like address_space tags at function prototypes + $type =~ s/__(user|kernel|iomem|percpu|pmem|rcu)\s*//; + if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { # pointer-to-function print $1 . $parameter . ") (" . $2; -- cgit v1.2.3