Skip to content

Commit 4eb727d

Browse files
committed
kbuild: rust: split up helpers.c
This patch splits up the rust helpers C file. When rebasing patch sets on upstream linux, merge conflicts in helpers.c is common and time consuming [1]. Thus, split the file so that each kernel component can live in a separate file. This patch lists helper files explicitly and thus conflicts in the file list is still likely. However, they should be more simple to resolve than the conflicts usually seen in helpers.c. Link: https://rust-for-linux.zulipchat.com/#narrow/stream/288089-General/topic/Splitting.20up.20helpers.2Ec/near/426694012 [1] Signed-off-by: Andreas Hindborg <[email protected]>
1 parent fec50db commit 4eb727d

File tree

16 files changed

+246
-188
lines changed

16 files changed

+246
-188
lines changed

rust/Makefile

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,22 @@ rustdoc_output := $(objtree)/Documentation/output/rust/rustdoc
66
obj-$(CONFIG_RUST) += core.o compiler_builtins.o
77
always-$(CONFIG_RUST) += exports_core_generated.h
88

9-
# Missing prototypes are expected in the helpers since these are exported
10-
# for Rust only, thus there is no header nor prototypes.
11-
obj-$(CONFIG_RUST) += helpers.o
12-
CFLAGS_REMOVE_helpers.o = -Wmissing-prototypes -Wmissing-declarations
9+
RUST_HELPERS := \
10+
bug \
11+
build_assert \
12+
build_bug \
13+
err \
14+
kunit \
15+
mutex \
16+
refcount \
17+
signal \
18+
spinlock\
19+
task \
20+
wait \
21+
workqueue
22+
23+
export RUST_HELPERS
24+
obj-y += helpers/
1325

1426
always-$(CONFIG_RUST) += libmacros.so
1527
no-clean-files += libmacros.so
@@ -339,6 +351,10 @@ quiet_cmd_bindgen = BINDGEN $@
339351
-o $@ -- $(bindgen_c_flags_final) -DMODULE \
340352
$(bindgen_target_cflags) $(bindgen_target_extra)
341353

354+
quiet_cmd_cat = CAT $@
355+
cmd_cat = \
356+
cat $(patsubst %,$(srctree)/$(src)/helpers/%.c, $(RUST_HELPERS)) > $@
357+
342358
$(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \
343359
$(shell grep -Ev '^#|^$$' $(srctree)/$(src)/bindgen_parameters)
344360
$(obj)/bindings/bindings_generated.rs: private bindgen_target_extra = ; \
@@ -353,9 +369,9 @@ $(obj)/uapi/uapi_generated.rs: $(src)/uapi/uapi_helper.h \
353369
$(src)/bindgen_parameters FORCE
354370
$(call if_changed_dep,bindgen)
355371

356-
# See `CFLAGS_REMOVE_helpers.o` above. In addition, Clang on C does not warn
357-
# with `-Wmissing-declarations` (unlike GCC), so it is not strictly needed here
358-
# given it is `libclang`; but for consistency, future Clang changes and/or
372+
# See `ccflags-remove-y` in helpers/Makefile . In addition, Clang on C does not
373+
# warn with `-Wmissing-declarations` (unlike GCC), so it is not strictly needed
374+
# here given it is `libclang`; but for consistency, future Clang changes and/or
359375
# a potential future GCC backend for `bindgen`, we disable it too.
360376
$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_flags = \
361377
--blocklist-type '.*' --allowlist-var '' \
@@ -364,9 +380,13 @@ $(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_cflags = \
364380
-I$(objtree)/$(obj) -Wno-missing-prototypes -Wno-missing-declarations
365381
$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_extra = ; \
366382
sed -Ei 's/pub fn rust_helper_([a-zA-Z0-9_]*)/#[link_name="rust_helper_\1"]\n pub fn \1/g' $@
367-
$(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers.c FORCE
383+
$(obj)/bindings/bindings_helpers_generated.rs: $(obj)/helpers/helpers_combined.c FORCE
368384
$(call if_changed_dep,bindgen)
369385

386+
targets += helpers/helpers_combined.c
387+
$(obj)/helpers/helpers_combined.c: $(patsubst %,$(src)/helpers/%.c, $(RUST_HELPERS)) FORCE
388+
$(call if_changed,cat)
389+
370390
quiet_cmd_exports = EXPORTS $@
371391
cmd_exports = \
372392
$(NM) -p --defined-only $< \

rust/helpers.c

Lines changed: 0 additions & 180 deletions
This file was deleted.

rust/helpers/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
# Note: `RUST_HELPERS` is defined in `../Makefile`
3+
4+
# Missing prototypes are expected in the helpers since these are exported
5+
# for Rust only, thus there is no header nor prototypes.
6+
obj-$(CONFIG_RUST) += $(patsubst %,%.o, $(RUST_HELPERS))
7+
ccflags-remove-y += -Wmissing-prototypes -Wmissing-declarations

rust/helpers/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Rust Helpers
2+
3+
Non-trivial C macros cannot be used in Rust. Similarly, inlined C functions
4+
cannot be called either. The files in this directory explicitly create functions
5+
("helpers") that wrap those so that they can be called from Rust.
6+
7+
Even though Rust kernel modules should never use directly the bindings, some
8+
of these helpers need to be exported because Rust generics and inlined
9+
functions may not get their code generated in the crate where they are
10+
defined. Other helpers, called from non-inline functions, may not be
11+
exported, in principle. However, in general, the Rust compiler does not
12+
guarantee codegen will be performed for a non-inline function either.
13+
Therefore, this file exports all the helpers. In the future, this may be
14+
revisited to reduce the number of exports after the compiler is informed
15+
about the places codegen is required.
16+
17+
All symbols are exported as GPL-only to guarantee no GPL-only feature is
18+
accidentally exposed.

rust/helpers/bug.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/bug.h>
4+
5+
__noreturn void rust_helper_BUG(void)
6+
{
7+
BUG();
8+
}
9+
EXPORT_SYMBOL_GPL(rust_helper_BUG);

rust/helpers/build_assert.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/build_bug.h>
4+
5+
/*
6+
* `bindgen` binds the C `size_t` type as the Rust `usize` type, so we can
7+
* use it in contexts where Rust expects a `usize` like slice (array) indices.
8+
* `usize` is defined to be the same as C's `uintptr_t` type (can hold any
9+
* pointer) but not necessarily the same as `size_t` (can hold the size of any
10+
* single object). Most modern platforms use the same concrete integer type for
11+
* both of them, but in case we find ourselves on a platform where
12+
* that's not true, fail early instead of risking ABI or
13+
* integer-overflow issues.
14+
*
15+
* If your platform fails this assertion, it means that you are in
16+
* danger of integer-overflow bugs (even if you attempt to add
17+
* `--no-size_t-is-usize`). It may be easiest to change the kernel ABI on
18+
* your platform such that `size_t` matches `uintptr_t` (i.e., to increase
19+
* `size_t`, because `uintptr_t` has to be at least as big as `size_t`).
20+
*/
21+
static_assert(
22+
sizeof(size_t) == sizeof(uintptr_t) &&
23+
__alignof__(size_t) == __alignof__(uintptr_t),
24+
"Rust code expects C `size_t` to match Rust `usize`"
25+
);

rust/helpers/build_bug.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/export.h>
4+
#include <linux/errname.h>
5+
6+
const char *rust_helper_errname(int err)
7+
{
8+
return errname(err);
9+
}
10+
EXPORT_SYMBOL_GPL(rust_helper_errname);

rust/helpers/err.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/err.h>
4+
#include <linux/export.h>
5+
6+
__force void *rust_helper_ERR_PTR(long err)
7+
{
8+
return ERR_PTR(err);
9+
}
10+
EXPORT_SYMBOL_GPL(rust_helper_ERR_PTR);
11+
12+
bool rust_helper_IS_ERR(__force const void *ptr)
13+
{
14+
return IS_ERR(ptr);
15+
}
16+
EXPORT_SYMBOL_GPL(rust_helper_IS_ERR);
17+
18+
long rust_helper_PTR_ERR(__force const void *ptr)
19+
{
20+
return PTR_ERR(ptr);
21+
}
22+
EXPORT_SYMBOL_GPL(rust_helper_PTR_ERR);

rust/helpers/kunit.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <kunit/test-bug.h>
4+
#include <linux/export.h>
5+
6+
struct kunit *rust_helper_kunit_get_current_test(void)
7+
{
8+
return kunit_get_current_test();
9+
}
10+
EXPORT_SYMBOL_GPL(rust_helper_kunit_get_current_test);

rust/helpers/mutex.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/export.h>
4+
#include <linux/mutex.h>
5+
6+
void rust_helper_mutex_lock(struct mutex *lock)
7+
{
8+
mutex_lock(lock);
9+
}
10+
EXPORT_SYMBOL_GPL(rust_helper_mutex_lock);

0 commit comments

Comments
 (0)