2021-07-03 22:52:41 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
/*
|
|
|
|
* Non-trivial C macros cannot be used in Rust. Similarly, inlined C functions
|
|
|
|
* cannot be called either. This file explicitly creates functions ("helpers")
|
|
|
|
* that wrap those so that they can be called from Rust.
|
|
|
|
*
|
|
|
|
* Even though Rust kernel modules should never use directly the bindings, some
|
|
|
|
* of these helpers need to be exported because Rust generics and inlined
|
|
|
|
* functions may not get their code generated in the crate where they are
|
|
|
|
* defined. Other helpers, called from non-inline functions, may not be
|
|
|
|
* exported, in principle. However, in general, the Rust compiler does not
|
|
|
|
* guarantee codegen will be performed for a non-inline function either.
|
|
|
|
* Therefore, this file exports all the helpers. In the future, this may be
|
|
|
|
* revisited to reduce the number of exports after the compiler is informed
|
|
|
|
* about the places codegen is required.
|
|
|
|
*
|
|
|
|
* All symbols are exported as GPL-only to guarantee no GPL-only feature is
|
|
|
|
* accidentally exposed.
|
2023-04-27 04:49:23 +08:00
|
|
|
*
|
|
|
|
* Sorted alphabetically.
|
2021-07-03 22:52:41 +08:00
|
|
|
*/
|
|
|
|
|
rust: support running Rust documentation tests as KUnit ones
Rust has documentation tests: these are typically examples of
usage of any item (e.g. function, struct, module...).
They are very convenient because they are just written
alongside the documentation. For instance:
/// Sums two numbers.
///
/// ```
/// assert_eq!(mymod::f(10, 20), 30);
/// ```
pub fn f(a: i32, b: i32) -> i32 {
a + b
}
In userspace, the tests are collected and run via `rustdoc`.
Using the tool as-is would be useful already, since it allows
to compile-test most tests (thus enforcing they are kept
in sync with the code they document) and run those that do not
depend on in-kernel APIs.
However, by transforming the tests into a KUnit test suite,
they can also be run inside the kernel. Moreover, the tests
get to be compiled as other Rust kernel objects instead of
targeting userspace.
On top of that, the integration with KUnit means the Rust
support gets to reuse the existing testing facilities. For
instance, the kernel log would look like:
KTAP version 1
1..1
KTAP version 1
# Subtest: rust_doctests_kernel
1..59
# rust_doctest_kernel_build_assert_rs_0.location: rust/kernel/build_assert.rs:13
ok 1 rust_doctest_kernel_build_assert_rs_0
# rust_doctest_kernel_build_assert_rs_1.location: rust/kernel/build_assert.rs:56
ok 2 rust_doctest_kernel_build_assert_rs_1
# rust_doctest_kernel_init_rs_0.location: rust/kernel/init.rs:122
ok 3 rust_doctest_kernel_init_rs_0
...
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
ok 59 rust_doctest_kernel_types_rs_2
# rust_doctests_kernel: pass:59 fail:0 skip:0 total:59
# Totals: pass:59 fail:0 skip:0 total:59
ok 1 rust_doctests_kernel
Therefore, add support for running Rust documentation tests
in KUnit. Some other notes about the current implementation
and support follow.
The transformation is performed by a couple scripts written
as Rust hostprogs.
Tests using the `?` operator are also supported as usual, e.g.:
/// ```
/// # use kernel::{spawn_work_item, workqueue};
/// spawn_work_item!(workqueue::system(), || pr_info!("x"))?;
/// # Ok::<(), Error>(())
/// ```
The tests are also compiled with Clippy under `CLIPPY=1`, just
like normal code, thus also benefitting from extra linting.
The names of the tests are currently automatically generated.
This allows to reduce the burden for documentation writers,
while keeping them fairly stable for bisection. This is an
improvement over the `rustdoc`-generated names, which include
the line number; but ideally we would like to get `rustdoc` to
provide the Rust item path and a number (for multiple examples
in a single documented Rust item).
In order for developers to easily see from which original line
a failed doctests came from, a KTAP diagnostic line is printed
to the log, containing the location (file and line) of the
original test (i.e. instead of the location in the generated
Rust file):
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
This line follows the syntax for declaring test metadata in the
proposed KTAP v2 spec [1], which may be used for the proposed
KUnit test attributes API [2]. Thus hopefully this will make
migration easier later on (suggested by David [3]).
The original line in that test attribute is figured out by
providing an anchor (suggested by Boqun [4]). The original file
is found by walking the filesystem, checking directory prefixes
to reduce the amount of combinations to check, and it is only
done once per file. Ambiguities are detected and reported.
A notable difference from KUnit C tests is that the Rust tests
appear to assert using the usual `assert!` and `assert_eq!`
macros from the Rust standard library (`core`). We provide
a custom version that forwards the call to KUnit instead.
Importantly, these macros do not require passing context,
unlike the KUnit C ones (i.e. `struct kunit *`). This makes
them easier to use, and readers of the documentation do not need
to care about which testing framework is used. In addition, it
may allow us to test third-party code more easily in the future.
However, a current limitation is that KUnit does not support
assertions in other tasks. Thus we presently simply print an
error to the kernel log if an assertion actually failed. This
should be revisited to properly fail the test, perhaps saving
the context somewhere else, or letting KUnit handle it.
Link: https://lore.kernel.org/lkml/20230420205734.1288498-1-rmoar@google.com/ [1]
Link: https://lore.kernel.org/linux-kselftest/20230707210947.1208717-1-rmoar@google.com/ [2]
Link: https://lore.kernel.org/rust-for-linux/CABVgOSkOLO-8v6kdAGpmYnZUb+LKOX0CtYCo-Bge7r_2YTuXDQ@mail.gmail.com/ [3]
Link: https://lore.kernel.org/rust-for-linux/ZIps86MbJF%2FiGIzd@boqun-archlinux/ [4]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-18 13:27:51 +08:00
|
|
|
#include <kunit/test-bug.h>
|
2021-07-03 22:52:41 +08:00
|
|
|
#include <linux/bug.h>
|
|
|
|
#include <linux/build_bug.h>
|
2023-04-03 17:48:11 +08:00
|
|
|
#include <linux/err.h>
|
2023-06-01 01:44:50 +08:00
|
|
|
#include <linux/errname.h>
|
2023-04-11 13:45:33 +08:00
|
|
|
#include <linux/mutex.h>
|
2023-04-27 04:49:23 +08:00
|
|
|
#include <linux/refcount.h>
|
2023-04-11 13:45:39 +08:00
|
|
|
#include <linux/sched/signal.h>
|
2023-04-27 04:49:23 +08:00
|
|
|
#include <linux/spinlock.h>
|
2023-03-26 11:57:38 +08:00
|
|
|
#include <linux/wait.h>
|
rust: workqueue: add helper for defining work_struct fields
The main challenge with defining `work_struct` fields is making sure
that the function pointer stored in the `work_struct` is appropriate for
the work item type it is embedded in. It needs to know the offset of the
`work_struct` field being used (even if there are several!) so that it
can do a `container_of`, and it needs to know the type of the work item
so that it can call into the right user-provided code. All of this needs
to happen in a way that provides a safe API to the user, so that users
of the workqueue cannot mix up the function pointers.
There are three important pieces that are relevant when doing this:
* The pointer type.
* The work item struct. This is what the pointer points at.
* The `work_struct` field. This is a field of the work item struct.
This patch introduces a separate trait for each piece. The pointer type
is given a `WorkItemPointer` trait, which pointer types need to
implement to be usable with the workqueue. This trait will be
implemented for `Arc` and `Box` in a later patch in this patchset.
Implementing this trait is unsafe because this is where the
`container_of` operation happens, but user-code will not need to
implement it themselves.
The work item struct should then implement the `WorkItem` trait. This
trait is where user-code specifies what they want to happen when a work
item is executed. It also specifies what the correct pointer type is.
Finally, to make the work item struct know the offset of its
`work_struct` field, we use a trait called `HasWork<T, ID>`. If a type
implements this trait, then the type declares that, at the given offset,
there is a field of type `Work<T, ID>`. The trait is marked unsafe
because the OFFSET constant must be correct, but we provide an
`impl_has_work!` macro that can safely implement `HasWork<T>` on a type.
The macro expands to something that only compiles if the specified field
really has the type `Work<T>`. It is used like this:
```
struct MyWorkItem {
work_field: Work<MyWorkItem, 1>,
}
impl_has_work! {
impl HasWork<MyWorkItem, 1> for MyWorkItem { self.work_field }
}
```
Note that since the `Work` type is annotated with an id, you can have
several `work_struct` fields by using a different id for each one.
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2023-08-28 18:48:04 +08:00
|
|
|
#include <linux/workqueue.h>
|
2021-07-03 22:52:41 +08:00
|
|
|
|
|
|
|
__noreturn void rust_helper_BUG(void)
|
|
|
|
{
|
|
|
|
BUG();
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_BUG);
|
|
|
|
|
2023-04-11 13:45:33 +08:00
|
|
|
void rust_helper_mutex_lock(struct mutex *lock)
|
|
|
|
{
|
|
|
|
mutex_lock(lock);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_mutex_lock);
|
|
|
|
|
2023-04-20 01:44:26 +08:00
|
|
|
void rust_helper___spin_lock_init(spinlock_t *lock, const char *name,
|
|
|
|
struct lock_class_key *key)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_DEBUG_SPINLOCK
|
|
|
|
__raw_spin_lock_init(spinlock_check(lock), name, key, LD_WAIT_CONFIG);
|
|
|
|
#else
|
|
|
|
spin_lock_init(lock);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper___spin_lock_init);
|
|
|
|
|
|
|
|
void rust_helper_spin_lock(spinlock_t *lock)
|
|
|
|
{
|
|
|
|
spin_lock(lock);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_spin_lock);
|
|
|
|
|
|
|
|
void rust_helper_spin_unlock(spinlock_t *lock)
|
|
|
|
{
|
|
|
|
spin_unlock(lock);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_spin_unlock);
|
|
|
|
|
2023-03-26 11:57:38 +08:00
|
|
|
void rust_helper_init_wait(struct wait_queue_entry *wq_entry)
|
|
|
|
{
|
|
|
|
init_wait(wq_entry);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_init_wait);
|
|
|
|
|
2023-04-11 13:45:39 +08:00
|
|
|
int rust_helper_signal_pending(struct task_struct *t)
|
|
|
|
{
|
|
|
|
return signal_pending(t);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_signal_pending);
|
|
|
|
|
2022-12-28 14:03:40 +08:00
|
|
|
refcount_t rust_helper_REFCOUNT_INIT(int n)
|
|
|
|
{
|
|
|
|
return (refcount_t)REFCOUNT_INIT(n);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_REFCOUNT_INIT);
|
|
|
|
|
|
|
|
void rust_helper_refcount_inc(refcount_t *r)
|
|
|
|
{
|
|
|
|
refcount_inc(r);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_refcount_inc);
|
|
|
|
|
|
|
|
bool rust_helper_refcount_dec_and_test(refcount_t *r)
|
|
|
|
{
|
|
|
|
return refcount_dec_and_test(r);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_refcount_dec_and_test);
|
|
|
|
|
2023-04-03 17:48:11 +08:00
|
|
|
__force void *rust_helper_ERR_PTR(long err)
|
|
|
|
{
|
|
|
|
return ERR_PTR(err);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_ERR_PTR);
|
|
|
|
|
2023-04-03 17:48:14 +08:00
|
|
|
bool rust_helper_IS_ERR(__force const void *ptr)
|
|
|
|
{
|
|
|
|
return IS_ERR(ptr);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_IS_ERR);
|
|
|
|
|
|
|
|
long rust_helper_PTR_ERR(__force const void *ptr)
|
|
|
|
{
|
|
|
|
return PTR_ERR(ptr);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_PTR_ERR);
|
|
|
|
|
2023-06-01 01:44:50 +08:00
|
|
|
const char *rust_helper_errname(int err)
|
|
|
|
{
|
|
|
|
return errname(err);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_errname);
|
|
|
|
|
2023-04-11 13:45:40 +08:00
|
|
|
struct task_struct *rust_helper_get_current(void)
|
|
|
|
{
|
|
|
|
return current;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_get_current);
|
|
|
|
|
2023-04-11 13:45:39 +08:00
|
|
|
void rust_helper_get_task_struct(struct task_struct *t)
|
|
|
|
{
|
|
|
|
get_task_struct(t);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_get_task_struct);
|
|
|
|
|
|
|
|
void rust_helper_put_task_struct(struct task_struct *t)
|
|
|
|
{
|
|
|
|
put_task_struct(t);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_put_task_struct);
|
|
|
|
|
rust: support running Rust documentation tests as KUnit ones
Rust has documentation tests: these are typically examples of
usage of any item (e.g. function, struct, module...).
They are very convenient because they are just written
alongside the documentation. For instance:
/// Sums two numbers.
///
/// ```
/// assert_eq!(mymod::f(10, 20), 30);
/// ```
pub fn f(a: i32, b: i32) -> i32 {
a + b
}
In userspace, the tests are collected and run via `rustdoc`.
Using the tool as-is would be useful already, since it allows
to compile-test most tests (thus enforcing they are kept
in sync with the code they document) and run those that do not
depend on in-kernel APIs.
However, by transforming the tests into a KUnit test suite,
they can also be run inside the kernel. Moreover, the tests
get to be compiled as other Rust kernel objects instead of
targeting userspace.
On top of that, the integration with KUnit means the Rust
support gets to reuse the existing testing facilities. For
instance, the kernel log would look like:
KTAP version 1
1..1
KTAP version 1
# Subtest: rust_doctests_kernel
1..59
# rust_doctest_kernel_build_assert_rs_0.location: rust/kernel/build_assert.rs:13
ok 1 rust_doctest_kernel_build_assert_rs_0
# rust_doctest_kernel_build_assert_rs_1.location: rust/kernel/build_assert.rs:56
ok 2 rust_doctest_kernel_build_assert_rs_1
# rust_doctest_kernel_init_rs_0.location: rust/kernel/init.rs:122
ok 3 rust_doctest_kernel_init_rs_0
...
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
ok 59 rust_doctest_kernel_types_rs_2
# rust_doctests_kernel: pass:59 fail:0 skip:0 total:59
# Totals: pass:59 fail:0 skip:0 total:59
ok 1 rust_doctests_kernel
Therefore, add support for running Rust documentation tests
in KUnit. Some other notes about the current implementation
and support follow.
The transformation is performed by a couple scripts written
as Rust hostprogs.
Tests using the `?` operator are also supported as usual, e.g.:
/// ```
/// # use kernel::{spawn_work_item, workqueue};
/// spawn_work_item!(workqueue::system(), || pr_info!("x"))?;
/// # Ok::<(), Error>(())
/// ```
The tests are also compiled with Clippy under `CLIPPY=1`, just
like normal code, thus also benefitting from extra linting.
The names of the tests are currently automatically generated.
This allows to reduce the burden for documentation writers,
while keeping them fairly stable for bisection. This is an
improvement over the `rustdoc`-generated names, which include
the line number; but ideally we would like to get `rustdoc` to
provide the Rust item path and a number (for multiple examples
in a single documented Rust item).
In order for developers to easily see from which original line
a failed doctests came from, a KTAP diagnostic line is printed
to the log, containing the location (file and line) of the
original test (i.e. instead of the location in the generated
Rust file):
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
This line follows the syntax for declaring test metadata in the
proposed KTAP v2 spec [1], which may be used for the proposed
KUnit test attributes API [2]. Thus hopefully this will make
migration easier later on (suggested by David [3]).
The original line in that test attribute is figured out by
providing an anchor (suggested by Boqun [4]). The original file
is found by walking the filesystem, checking directory prefixes
to reduce the amount of combinations to check, and it is only
done once per file. Ambiguities are detected and reported.
A notable difference from KUnit C tests is that the Rust tests
appear to assert using the usual `assert!` and `assert_eq!`
macros from the Rust standard library (`core`). We provide
a custom version that forwards the call to KUnit instead.
Importantly, these macros do not require passing context,
unlike the KUnit C ones (i.e. `struct kunit *`). This makes
them easier to use, and readers of the documentation do not need
to care about which testing framework is used. In addition, it
may allow us to test third-party code more easily in the future.
However, a current limitation is that KUnit does not support
assertions in other tasks. Thus we presently simply print an
error to the kernel log if an assertion actually failed. This
should be revisited to properly fail the test, perhaps saving
the context somewhere else, or letting KUnit handle it.
Link: https://lore.kernel.org/lkml/20230420205734.1288498-1-rmoar@google.com/ [1]
Link: https://lore.kernel.org/linux-kselftest/20230707210947.1208717-1-rmoar@google.com/ [2]
Link: https://lore.kernel.org/rust-for-linux/CABVgOSkOLO-8v6kdAGpmYnZUb+LKOX0CtYCo-Bge7r_2YTuXDQ@mail.gmail.com/ [3]
Link: https://lore.kernel.org/rust-for-linux/ZIps86MbJF%2FiGIzd@boqun-archlinux/ [4]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-18 13:27:51 +08:00
|
|
|
struct kunit *rust_helper_kunit_get_current_test(void)
|
|
|
|
{
|
|
|
|
return kunit_get_current_test();
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_kunit_get_current_test);
|
|
|
|
|
rust: workqueue: add helper for defining work_struct fields
The main challenge with defining `work_struct` fields is making sure
that the function pointer stored in the `work_struct` is appropriate for
the work item type it is embedded in. It needs to know the offset of the
`work_struct` field being used (even if there are several!) so that it
can do a `container_of`, and it needs to know the type of the work item
so that it can call into the right user-provided code. All of this needs
to happen in a way that provides a safe API to the user, so that users
of the workqueue cannot mix up the function pointers.
There are three important pieces that are relevant when doing this:
* The pointer type.
* The work item struct. This is what the pointer points at.
* The `work_struct` field. This is a field of the work item struct.
This patch introduces a separate trait for each piece. The pointer type
is given a `WorkItemPointer` trait, which pointer types need to
implement to be usable with the workqueue. This trait will be
implemented for `Arc` and `Box` in a later patch in this patchset.
Implementing this trait is unsafe because this is where the
`container_of` operation happens, but user-code will not need to
implement it themselves.
The work item struct should then implement the `WorkItem` trait. This
trait is where user-code specifies what they want to happen when a work
item is executed. It also specifies what the correct pointer type is.
Finally, to make the work item struct know the offset of its
`work_struct` field, we use a trait called `HasWork<T, ID>`. If a type
implements this trait, then the type declares that, at the given offset,
there is a field of type `Work<T, ID>`. The trait is marked unsafe
because the OFFSET constant must be correct, but we provide an
`impl_has_work!` macro that can safely implement `HasWork<T>` on a type.
The macro expands to something that only compiles if the specified field
really has the type `Work<T>`. It is used like this:
```
struct MyWorkItem {
work_field: Work<MyWorkItem, 1>,
}
impl_has_work! {
impl HasWork<MyWorkItem, 1> for MyWorkItem { self.work_field }
}
```
Note that since the `Work` type is annotated with an id, you can have
several `work_struct` fields by using a different id for each one.
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
2023-08-28 18:48:04 +08:00
|
|
|
void rust_helper_init_work_with_key(struct work_struct *work, work_func_t func,
|
|
|
|
bool onstack, const char *name,
|
|
|
|
struct lock_class_key *key)
|
|
|
|
{
|
|
|
|
__init_work(work, onstack);
|
|
|
|
work->data = (atomic_long_t)WORK_DATA_INIT();
|
|
|
|
lockdep_init_map(&work->lockdep_map, name, key, 0);
|
|
|
|
INIT_LIST_HEAD(&work->entry);
|
|
|
|
work->func = func;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(rust_helper_init_work_with_key);
|
|
|
|
|
2021-07-03 22:52:41 +08:00
|
|
|
/*
|
rust: bindgen: upgrade to 0.65.1
In LLVM 16, anonymous items may return names like `(unnamed union at ..)`
rather than empty names [1], which breaks Rust-enabled builds because
bindgen assumed an empty name instead of detecting them via
`clang_Cursor_isAnonymous` [2]:
$ make rustdoc LLVM=1 CLIPPY=1 -j$(nproc)
RUSTC L rust/core.o
BINDGEN rust/bindings/bindings_generated.rs
BINDGEN rust/bindings/bindings_helpers_generated.rs
BINDGEN rust/uapi/uapi_generated.rs
thread 'main' panicked at '"ftrace_branch_data_union_(anonymous_at__/_/include/linux/compiler_types_h_146_2)" is not a valid Ident', .../proc-macro2-1.0.24/src/fallback.rs:693:9
...
thread 'main' panicked at '"ftrace_branch_data_union_(anonymous_at__/_/include/linux/compiler_types_h_146_2)" is not a valid Ident', .../proc-macro2-1.0.24/src/fallback.rs:693:9
...
This was fixed in bindgen 0.62.0. Therefore, upgrade bindgen to
a more recent version, 0.65.1, to support LLVM 16.
Since bindgen 0.58.0 changed the `--{white,black}list-*` flags to
`--{allow,block}list-*` [3], update them on our side too.
In addition, bindgen 0.61.0 moved its CLI utility into a binary crate
called `bindgen-cli` [4]. Thus update the installation command in the
Quick Start guide.
Moreover, bindgen 0.61.0 changed the default functionality to bind
`size_t` to `usize` [5] and added the `--no-size_t-is-usize` flag
to not bind `size_t` as `usize`. Then bindgen 0.65.0 removed
the `--size_t-is-usize` flag [6]. Thus stop passing the flag to bindgen.
Finally, bindgen 0.61.0 added support for the `noreturn` attribute (in
its different forms) [7]. Thus remove the infinite loop in our Rust
panic handler after calling `BUG()`, since bindgen now correctly
generates a `BUG()` binding that returns `!` instead of `()`.
Link: https://github.com/llvm/llvm-project/commit/19e984ef8f49bc3ccced15621989fa9703b2cd5b [1]
Link: https://github.com/rust-lang/rust-bindgen/pull/2319 [2]
Link: https://github.com/rust-lang/rust-bindgen/pull/1990 [3]
Link: https://github.com/rust-lang/rust-bindgen/pull/2284 [4]
Link: https://github.com/rust-lang/rust-bindgen/commit/cc78b6fdb6e829e5fb8fa1639f2182cb49333569 [5]
Link: https://github.com/rust-lang/rust-bindgen/pull/2408 [6]
Link: https://github.com/rust-lang/rust-bindgen/issues/2094 [7]
Signed-off-by: Aakash Sen Sharma <aakashsensharma@gmail.com>
Closes: https://github.com/Rust-for-Linux/linux/issues/1013
Tested-by: Ariel Miculas <amiculas@cisco.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20230612194311.24826-1-aakashsensharma@gmail.com
[ Reworded commit message. Mentioned the `bindgen-cli` binary crate
change, linked to it and updated the Quick Start guide. Re-added a
deleted "as" word in a code comment and reflowed comment to respect
the maximum length. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-06-13 03:43:11 +08:00
|
|
|
* `bindgen` binds the C `size_t` type as the Rust `usize` type, so we can
|
|
|
|
* use it in contexts where Rust expects a `usize` like slice (array) indices.
|
|
|
|
* `usize` is defined to be the same as C's `uintptr_t` type (can hold any
|
|
|
|
* pointer) but not necessarily the same as `size_t` (can hold the size of any
|
|
|
|
* single object). Most modern platforms use the same concrete integer type for
|
2021-07-03 22:52:41 +08:00
|
|
|
* both of them, but in case we find ourselves on a platform where
|
|
|
|
* that's not true, fail early instead of risking ABI or
|
|
|
|
* integer-overflow issues.
|
|
|
|
*
|
|
|
|
* If your platform fails this assertion, it means that you are in
|
rust: bindgen: upgrade to 0.65.1
In LLVM 16, anonymous items may return names like `(unnamed union at ..)`
rather than empty names [1], which breaks Rust-enabled builds because
bindgen assumed an empty name instead of detecting them via
`clang_Cursor_isAnonymous` [2]:
$ make rustdoc LLVM=1 CLIPPY=1 -j$(nproc)
RUSTC L rust/core.o
BINDGEN rust/bindings/bindings_generated.rs
BINDGEN rust/bindings/bindings_helpers_generated.rs
BINDGEN rust/uapi/uapi_generated.rs
thread 'main' panicked at '"ftrace_branch_data_union_(anonymous_at__/_/include/linux/compiler_types_h_146_2)" is not a valid Ident', .../proc-macro2-1.0.24/src/fallback.rs:693:9
...
thread 'main' panicked at '"ftrace_branch_data_union_(anonymous_at__/_/include/linux/compiler_types_h_146_2)" is not a valid Ident', .../proc-macro2-1.0.24/src/fallback.rs:693:9
...
This was fixed in bindgen 0.62.0. Therefore, upgrade bindgen to
a more recent version, 0.65.1, to support LLVM 16.
Since bindgen 0.58.0 changed the `--{white,black}list-*` flags to
`--{allow,block}list-*` [3], update them on our side too.
In addition, bindgen 0.61.0 moved its CLI utility into a binary crate
called `bindgen-cli` [4]. Thus update the installation command in the
Quick Start guide.
Moreover, bindgen 0.61.0 changed the default functionality to bind
`size_t` to `usize` [5] and added the `--no-size_t-is-usize` flag
to not bind `size_t` as `usize`. Then bindgen 0.65.0 removed
the `--size_t-is-usize` flag [6]. Thus stop passing the flag to bindgen.
Finally, bindgen 0.61.0 added support for the `noreturn` attribute (in
its different forms) [7]. Thus remove the infinite loop in our Rust
panic handler after calling `BUG()`, since bindgen now correctly
generates a `BUG()` binding that returns `!` instead of `()`.
Link: https://github.com/llvm/llvm-project/commit/19e984ef8f49bc3ccced15621989fa9703b2cd5b [1]
Link: https://github.com/rust-lang/rust-bindgen/pull/2319 [2]
Link: https://github.com/rust-lang/rust-bindgen/pull/1990 [3]
Link: https://github.com/rust-lang/rust-bindgen/pull/2284 [4]
Link: https://github.com/rust-lang/rust-bindgen/commit/cc78b6fdb6e829e5fb8fa1639f2182cb49333569 [5]
Link: https://github.com/rust-lang/rust-bindgen/pull/2408 [6]
Link: https://github.com/rust-lang/rust-bindgen/issues/2094 [7]
Signed-off-by: Aakash Sen Sharma <aakashsensharma@gmail.com>
Closes: https://github.com/Rust-for-Linux/linux/issues/1013
Tested-by: Ariel Miculas <amiculas@cisco.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20230612194311.24826-1-aakashsensharma@gmail.com
[ Reworded commit message. Mentioned the `bindgen-cli` binary crate
change, linked to it and updated the Quick Start guide. Re-added a
deleted "as" word in a code comment and reflowed comment to respect
the maximum length. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-06-13 03:43:11 +08:00
|
|
|
* danger of integer-overflow bugs (even if you attempt to add
|
|
|
|
* `--no-size_t-is-usize`). It may be easiest to change the kernel ABI on
|
2021-07-03 22:52:41 +08:00
|
|
|
* your platform such that `size_t` matches `uintptr_t` (i.e., to increase
|
|
|
|
* `size_t`, because `uintptr_t` has to be at least as big as `size_t`).
|
|
|
|
*/
|
|
|
|
static_assert(
|
|
|
|
sizeof(size_t) == sizeof(uintptr_t) &&
|
|
|
|
__alignof__(size_t) == __alignof__(uintptr_t),
|
|
|
|
"Rust code expects C `size_t` to match Rust `usize`"
|
|
|
|
);
|