Skip to content

Commit

Permalink
Merge branch 'rust-next' of https://github.com/Rust-for-Linux/linux.git
Browse files Browse the repository at this point in the history
# Conflicts:
#	Documentation/process/changes.rst
#	samples/Kconfig
#	samples/Makefile
  • Loading branch information
Stephen Rothwell committed Jan 28, 2022
2 parents f5a2b9b + ced9f62 commit 84f50d0
Show file tree
Hide file tree
Showing 162 changed files with 33,512 additions and 58 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
*.o
*.o.*
*.patch
*.rmeta
*.s
*.so
*.so.dbg
Expand Down Expand Up @@ -96,6 +97,7 @@ modules.order
!.gitattributes
!.gitignore
!.mailmap
!.rustfmt.toml

#
# Generated include files
Expand Down Expand Up @@ -161,3 +163,6 @@ x509.genkey

# Documentation toolchain
sphinx_*/

# Rust analyzer configuration
/rust-project.json
12 changes: 12 additions & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
edition = "2021"
newline_style = "Unix"

# Unstable options that help catching some mistakes in formatting and that we may want to enable
# when they become stable.
#
# They are kept here since they are useful to run from time to time.
#format_code_in_doc_comments = true
#reorder_impl_items = true
#comment_width = 100
#wrap_comments = true
#normalize_comments = true
3 changes: 3 additions & 0 deletions Documentation/doc-guide/kernel-doc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ when it is embedded in source files.
reasons. The kernel source contains tens of thousands of kernel-doc
comments. Please stick to the style described here.

.. note:: kernel-doc does not cover Rust code: please see
Documentation/rust/docs.rst instead.

The kernel-doc structure is extracted from the comments, and proper
`Sphinx C Domain`_ function and type descriptions with anchors are
generated from them. The descriptions are filtered for special kernel-doc
Expand Down
1 change: 1 addition & 0 deletions Documentation/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ merged much easier.
maintainer/index
fault-injection/index
livepatch/index
rust/index


Kernel API documentation
Expand Down
4 changes: 4 additions & 0 deletions Documentation/kbuild/kbuild.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ CFLAGS_MODULE
-------------
Additional module specific options to use for $(CC).

KRUSTFLAGS
----------
Additional options to the Rust compiler (for built-in and modules).

LDFLAGS_MODULE
--------------
Additional options used for $(LD) when linking modules.
Expand Down
42 changes: 42 additions & 0 deletions Documentation/process/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ you probably needn't concern yourself with pcmciautils.
====================== =============== ========================================
GNU C 5.1 gcc --version
Clang/LLVM (optional) 11.0.0 clang --version
Rust (optional) 1.58.0 rustc --version
bindgen (optional) 0.56.0 bindgen --version
GNU make 3.81 make --version
binutils 2.23 ld -v
flex 2.5.35 flex --version
Expand Down Expand Up @@ -78,6 +80,29 @@ kernels. Older releases aren't guaranteed to work, and we may drop workarounds
from the kernel that were used to support older versions. Please see additional
docs on :ref:`Building Linux with Clang/LLVM <kbuild_llvm>`.

Rust (optional)
---------------

A particular version of the Rust toolchain is required. Newer versions may or
may not work because the kernel depends on some unstable Rust features, for
the moment.

Each Rust toolchain comes with several "components", some of which are required
(like ``rustc``) and some that are optional. The ``rust-src`` component (which
is optional) needs to be installed to build the kernel. Other components are
useful for developing.

Please see :ref:`Documentation/rust/quick-start.rst <rust_quick_start>` for
instructions on how to satify the build requirements of Rust support. In
particular, the Makefile target 'rustavailable' is useful to check why the Rust
toolchain may not be detected.

bindgen (optional)
------------------

``bindgen`` is used to generate the Rust bindings to the C side of the kernel.
It depends on ``libclang``.

Make
----

Expand Down Expand Up @@ -340,6 +365,13 @@ Sphinx
Please see :ref:`sphinx_install` in :ref:`Documentation/doc-guide/sphinx.rst <sphinxdoc>`
for details about Sphinx requirements.

rustdoc
-------

``rustdoc`` is used to generate the documentation for Rust code. Please see
:ref:`Documentation/rust/general-information.rst <rust_general_information>`
for more information.

Getting updated software
========================

Expand All @@ -356,6 +388,16 @@ Clang/LLVM

- :ref:`Getting LLVM <getting_llvm>`.

Rust
----

- :ref:`Documentation/rust/quick-start.rst <rust_quick_start>`.

bindgen
-------

- :ref:`Documentation/rust/quick-start.rst <rust_quick_start>`.

Make
----

Expand Down
35 changes: 35 additions & 0 deletions Documentation/rust/arch-support.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.. _rust_arch_support:

Arch Support
============

Currently, the Rust compiler (``rustc``) uses LLVM for code generation,
which limits the supported architectures that can be targeted. In addition,
support for building the kernel with LLVM/Clang varies (see :ref:`kbuild_llvm`).
This support is needed for ``bindgen`` which uses ``libclang``.

Below is a general summary of architectures that currently work. Level of
support corresponds to ``S`` values in the ``MAINTAINERS`` file.

.. list-table::
:widths: 10 10 10
:header-rows: 1

* - Architecture
- Level of support
- Constraints
* - ``arm``
- Maintained
- ``armv6`` and compatible only, ``RUST_OPT_LEVEL >= 2``
* - ``arm64``
- Maintained
- None
* - ``powerpc``
- Maintained
- ``ppc64le`` only, ``RUST_OPT_LEVEL < 2`` requires ``CONFIG_THREAD_SHIFT=15``
* - ``riscv``
- Maintained
- ``riscv64`` only
* - ``x86``
- Maintained
- ``x86_64`` only
Binary file added Documentation/rust/assets/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Documentation/rust/assets/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Documentation/rust/assets/rust-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
151 changes: 151 additions & 0 deletions Documentation/rust/coding-guidelines.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
.. _rust_coding_guidelines:

Coding Guidelines
=================

This document describes how to write Rust code in the kernel.


Style & formatting
------------------

The code should be formatted using ``rustfmt``. In this way, a person
contributing from time to time to the kernel does not need to learn and
remember one more style guide. More importantly, reviewers and maintainers
do not need to spend time pointing out style issues anymore, and thus
less patch roundtrips may be needed to land a change.

.. note:: Conventions on comments and documentation are not checked by
``rustfmt``. Thus those are still needed to be taken care of.

The default settings of ``rustfmt`` are used. This means the idiomatic Rust
style is followed. For instance, 4 spaces are used for indentation rather
than tabs.

It is convenient to instruct editors/IDEs to format while typing,
when saving or at commit time. However, if for some reason reformatting
the entire kernel Rust sources is needed at some point, the following can be
run::

make LLVM=1 rustfmt

It is also possible to check if everything is formatted (printing a diff
otherwise), for instance for a CI, with::

make LLVM=1 rustfmtcheck

Like ``clang-format`` for the rest of the kernel, ``rustfmt`` works on
individual files, and does not require a kernel configuration. Sometimes it may
even work with broken code.


Code documentation
------------------

Rust kernel code is not documented like C kernel code (i.e. via kernel-doc).
Instead, the usual system for documenting Rust code is used: the ``rustdoc``
tool, which uses Markdown (a lightweight markup language).

To learn Markdown, there are many guides available out there. For instance,
the one at:

https://commonmark.org/help/

This is how a well-documented Rust function may look like::

/// Returns the contained [`Some`] value, consuming the `self` value,
/// without checking that the value is not [`None`].
///
/// # Safety
///
/// Calling this method on [`None`] is *[undefined behavior]*.
///
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
///
/// # Examples
///
/// ```
/// let x = Some("air");
/// assert_eq!(unsafe { x.unwrap_unchecked() }, "air");
/// ```
pub unsafe fn unwrap_unchecked(self) -> T {
match self {
Some(val) => val,

// SAFETY: the safety contract must be upheld by the caller.
None => unsafe { hint::unreachable_unchecked() },
}
}

This example showcases a few ``rustdoc`` features and some conventions followed
in the kernel:

- The first paragraph must be a single sentence briefly describing what
the documented item does. Further explanations must go in extra paragraphs.

- Unsafe functions must document their safety preconditions under
a ``# Safety`` section.

- While not shown here, if a function may panic, the conditions under which
that happens must be described under a ``# Panics`` section.

Please note that panicking should be very rare and used only with a good
reason. In almost all cases, a fallible approach should be used, typically
returning a ``Result``.

- If providing examples of usage would help readers, they must be written in
a section called ``# Examples``.

- Rust items (functions, types, constants...) must be linked appropriately
(``rustdoc`` will create a link automatically).

- Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment
describing why the code inside is sound.

While sometimes the reason might look trivial and therefore unneeded, writing
these comments is not just a good way of documenting what has been taken into
account, but most importantly, it provides a way to know that there are
no *extra* implicit constraints.

To learn more about how to write documentation for Rust and extra features,
please take a look at the ``rustdoc`` `book`_.

.. _book: https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html


Naming
------

Rust kernel code follows the usual Rust naming conventions:

https://rust-lang.github.io/api-guidelines/naming.html

When existing C concepts (e.g. macros, functions, objects...) are wrapped into
a Rust abstraction, a name as close as reasonably possible to the C side should
be used in order to avoid confusion and to improve readability when switching
back and forth between the C and Rust sides. For instance, macros such as
``pr_info`` from C are named the same in the Rust side.

Having said that, casing should be adjusted to follow the Rust naming
conventions, and namespacing introduced by modules and types should not be
repeated in the item names. For instance, when wrapping constants like:

.. code-block:: c
#define GPIO_LINE_DIRECTION_IN 0
#define GPIO_LINE_DIRECTION_OUT 1
The equivalent in Rust may look like (ignoring documentation):

.. code-block:: rust
pub mod gpio {
pub enum LineDirection {
In = bindings::GPIO_LINE_DIRECTION_IN as _,
Out = bindings::GPIO_LINE_DIRECTION_OUT as _,
}
}
That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as
``gpio::LineDirection::In``. In particular, it should not be named
``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``.
Loading

0 comments on commit 84f50d0

Please sign in to comment.