rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v3 0/2] rust: crates in other kernel directories
@ 2023-11-04 21:11 Martin Rodriguez Reboredo
  2023-11-04 21:11 ` [RFC PATCH v3 1/2] kbuild: Build Rust crates as libraries Martin Rodriguez Reboredo
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Martin Rodriguez Reboredo @ 2023-11-04 21:11 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl
  Cc: linux-kbuild, linux-kernel, rust-for-linux

This RFC provides makes possible to have bindings for kernel subsystems
that are compiled as modules.

Previously, if you wanted to have Rust bindings for a subsystem, like
AMBA for example, you had to put it under `rust/kernel/` so it came
part of the `kernel` crate, but this came with many downsides. Namely
if you compiled said subsystem as a module you've a dependency on it
from `kernel`, which is linked directly on `vmlinux`.

So instead of overpopulating `kernel` with a gazillion modules that
throws you into dire straits you should rather have the bindings in the
same directory as the subsystem you want to bind with and link it to
it.

With this patch Rust sources can be compiled into libraries for them to
be consumed. These libraries are ar archives that follow the `.rlib`
structure, namely a libfoo.rlib thin archive with a foo.foo.o object
and a libfoo.rmeta rustc metadata as members. Such Rust crates get
their symbols exposed and the `bindings` crate is made available for
them.

Also included there's a sample usage of this in another patch, but it
is not meant to be merged as it remains as an example.

If you want to use a crate with your Rust module just add a `rust-libs`
variable in your Makefile with a value of the relative directory of
said crate plus its name, e.g.

    # Link with the foo crate
    rust-libs += ../path/to/foo

Martin Rodriguez Reboredo (2):
  kbuild: Build Rust crates as libraries
  samples: rust: Add USB sample bindings

 .gitignore                      |  2 ++
 Makefile                        |  4 ++--
 drivers/usb/core/Kconfig        |  7 ++++++
 drivers/usb/core/Makefile       |  3 +++
 drivers/usb/core/usb.rs         | 13 ++++++++++
 rust/bindings/bindings_helper.h |  1 +
 samples/rust/Kconfig            | 10 ++++++++
 samples/rust/Makefile           |  3 +++
 samples/rust/rust_usb_simple.rs | 22 +++++++++++++++++
 scripts/Makefile.build          | 42 ++++++++++++++++++++++++++++++---
 scripts/Makefile.lib            | 20 ++++++++++++----
 scripts/Makefile.modfinal       |  9 +++++--
 12 files changed, 125 insertions(+), 11 deletions(-)
 create mode 100644 drivers/usb/core/usb.rs
 create mode 100644 samples/rust/rust_usb_simple.rs

-- 
2.42.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [RFC PATCH v3 1/2] kbuild: Build Rust crates as libraries
  2023-11-04 21:11 [RFC PATCH v3 0/2] rust: crates in other kernel directories Martin Rodriguez Reboredo
@ 2023-11-04 21:11 ` Martin Rodriguez Reboredo
  2023-11-04 21:11 ` [RFC PATCH v3 2/2] samples: rust: Add USB sample bindings Martin Rodriguez Reboredo
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Martin Rodriguez Reboredo @ 2023-11-04 21:11 UTC (permalink / raw)
  To: Masahiro Yamada, Nathan Chancellor, Nick Desaulniers,
	Nicolas Schier, Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, David Gow, Shuah Khan,
	Andrew Davis, Andy Shevchenko, Chuck Lever
  Cc: linux-kbuild, linux-kernel, rust-for-linux

Enables compiling Rust crates as dependencies of kernel modules. These
are also meant to be used as libraries for other parts of the kernel.

For these crates `bindings` is also exposed to them and they get their
symbols exported for them to be used by other code.

When a composite object depends on an `.rlib` file, which by the way is
a current ar archive, Kbuild will compile it from its base Rust source
and archive it.

This makes possible to have Rust bindings for a subsystem that is
compiled either built-in or as a module. They can also be made into
modules by themselves too.

Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
---
v2 -> v3:
- Fixed erroneous dependency on exported symbols from KUnit tests.
v1 -> v2:
- Fixed builtins compilation.
- Added support for building crates as modules.

 .gitignore                |  2 ++
 Makefile                  |  4 ++--
 scripts/Makefile.build    | 42 ++++++++++++++++++++++++++++++++++++---
 scripts/Makefile.lib      | 20 +++++++++++++++----
 scripts/Makefile.modfinal |  9 +++++++--
 5 files changed, 66 insertions(+), 11 deletions(-)

diff --git a/.gitignore b/.gitignore
index 0bbae167bf93..8353b01e2915 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,6 +38,7 @@
 *.o
 *.o.*
 *.patch
+*.rlib
 *.rmeta
 *.rpm
 *.rsi
@@ -53,6 +54,7 @@
 *.zst
 Module.symvers
 modules.order
+exports_*_generated.c
 
 #
 # Top-level generic files
diff --git a/Makefile b/Makefile
index 8a40530868ff..4113a5b93ddc 100644
--- a/Makefile
+++ b/Makefile
@@ -283,7 +283,7 @@ no-compiler-targets := $(no-dot-config-targets) install dtbs_install \
 			headers_install modules_install modules_sign kernelrelease image_name
 no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \
 			  image_name
-single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %.symtypes %/
+single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rlib %.rsi %.s %.symtypes %/
 
 config-build	:=
 mixed-build	:=
@@ -1919,7 +1919,7 @@ $(clean-dirs):
 clean: $(clean-dirs)
 	$(call cmd,rmfiles)
 	@find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
-		\( -name '*.[aios]' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \
+		\( -name '*.[aios]' -o -name '*.rlib' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \
 		-o -name '*.ko.*' \
 		-o -name '*.dtb' -o -name '*.dtbo' \
 		-o -name '*.dtb.S' -o -name '*.dtbo.S' \
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index da37bfa97211..d31b4272a79f 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -20,6 +20,7 @@ always-m :=
 targets :=
 subdir-y :=
 subdir-m :=
+rust-libs :=
 EXTRA_AFLAGS   :=
 EXTRA_CFLAGS   :=
 EXTRA_CPPFLAGS :=
@@ -274,7 +275,7 @@ rust_common_cmd = \
 	-Zcrate-attr='feature($(rust_allowed_features))' \
 	--extern alloc --extern kernel \
 	--crate-type rlib -L $(objtree)/rust/ \
-	--crate-name $(basename $(notdir $@)) \
+	--crate-name $(basename $(notdir $<)) \
 	--out-dir $(dir $@) --emit=dep-info=$(depfile)
 
 # `--emit=obj`, `--emit=asm` and `--emit=llvm-ir` imply a single codegen unit
@@ -285,11 +286,41 @@ rust_common_cmd = \
 # i.e. the outputs we would get for the different single targets (e.g. `.ll`)
 # would not match each other.
 
+rlib_obj = $(dir $@)$*.$*.o
+rlib_meta = $(dir $@)$(patsubst %.rlib,%.rmeta,$(notdir $@))
+
 quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
       cmd_rustc_o_rs = $(rust_common_cmd) --emit=obj=$@ $<
 
+quiet_cmd_ln_rlib_o = SYMLINK $@
+      cmd_ln_rlib_o = ln -s -f $*.$*.o $@
+
 $(obj)/%.o: $(src)/%.rs FORCE
-	$(call if_changed_dep,rustc_o_rs)
+	$(if $(findstring $@,$(crate-obj-m)), \
+		$(call if_changed,ln_rlib_o), $(call if_changed_dep,rustc_o_rs))
+
+quiet_cmd_rustc_rlib_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
+      cmd_rustc_rlib_rs = $(rust_common_cmd) --extern bindings \
+		--emit=obj=$(rlib_obj) --emit=metadata=$(rlib_meta) $<; \
+	rm -f $@; $(AR) cDPrST $@ $(rlib_obj) $(rlib_meta)
+
+quiet_cmd_rlib_exports = EXPORTS $@
+      cmd_rlib_exports = \
+	echo "\#include <linux/module.h>"  > $@; \
+	$(NM) -p --defined-only $(rlib_obj) \
+		| perl -ae '/ (T|R|D) (?!(init|cleanup)_module)/ and' \
+			-e 'print "extern int @F[2]; EXPORT_SYMBOL_GPL(@F[2]);"' >> $@
+
+$(crate-obj-m): $(obj)/%.o: $(obj)/exports_%_generated.o $(obj)/lib%.rlib $(src)/%.rs FORCE
+
+$(obj)/lib%.rlib: $(src)/%.rs FORCE
+	$(call if_changed_dep,rustc_rlib_rs)
+
+$(obj)/exports_%_generated.c: $(obj)/lib%.rlib FORCE
+	$(call if_changed,rlib_exports)
+
+$(obj)/exports_%_generated.o: $(obj)/exports_%_generated.c FORCE
+	$(call if_changed,cc_o_c)
 
 quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
       cmd_rustc_rsi_rs = \
@@ -394,9 +425,14 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
 # To make this rule robust against "Argument list too long" error,
 # remove $(obj)/ prefix, and restore it by a shell command.
 
+# If we have a .rlib for the archive change it for its object member
+crate-obj = $(foreach m, $1, $(if $(findstring .rlib, $m), \
+	$(basename $(m:lib%=%)).$(m:lib%.rlib=%.o),$m))
+
 quiet_cmd_ar_builtin = AR      $@
       cmd_ar_builtin = rm -f $@; \
-	$(if $(real-prereqs), printf "$(obj)/%s " $(patsubst $(obj)/%,%,$(real-prereqs)) | xargs) \
+	$(if $(real-prereqs), printf "$(obj)/%s " \
+		$(call crate-obj, $(patsubst $(obj)/%,%,$(real-prereqs))) | xargs) \
 	$(AR) cDPrST $@
 
 $(obj)/built-in.a: $(real-obj-y) FORCE
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 68d0134bdbf9..3fe419250dbd 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -45,12 +45,17 @@ else
 obj-y		:= $(filter-out %/, $(obj-y))
 endif
 
+crate-obj-y := $(foreach m, $(filter lib%.rlib, $(obj-y)), $(m:lib%.rlib=%.o))
+crate-obj-m := $(foreach m, $(filter lib%.rlib, $(obj-m)), $(m:lib%.rlib=%.o))
+
 # Expand $(foo-objs) $(foo-y) etc. by replacing their individuals
 suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s))))
 # List composite targets that are constructed by combining other targets
 multi-search = $(sort $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $m)))
 # List primitive targets that are compiled from source files
 real-search = $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $(call suffix-search, $m, $2, $3), $m))
+# List exported symbols from .rlib targets
+rlib-exports = $(foreach m, $1, $(if $(findstring .rlib, $m),$(m:lib%.rlib=exports_%_generated.o)) $m)
 
 # If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object
 multi-obj-y := $(call multi-search, $(obj-y), .o, -objs -y)
@@ -59,8 +64,8 @@ multi-obj-ym := $(multi-obj-y) $(multi-obj-m)
 
 # Replace multi-part objects by their individual parts,
 # including built-in.a from subdirectories
-real-obj-y := $(call real-search, $(obj-y), .o, -objs -y)
-real-obj-m := $(call real-search, $(obj-m), .o, -objs -y -m)
+real-obj-y := $(call rlib-exports, $(call real-search, $(obj-y), .o, -objs -y))
+real-obj-m := $(call rlib-exports, $(call real-search, $(obj-m), .o, -objs -y -m))
 
 always-y += $(always-m)
 
@@ -96,6 +101,8 @@ always-y	:= $(addprefix $(obj)/,$(always-y))
 targets		:= $(addprefix $(obj)/,$(targets))
 obj-m		:= $(addprefix $(obj)/,$(obj-m))
 lib-y		:= $(addprefix $(obj)/,$(lib-y))
+crate-obj-y	:= $(addprefix $(obj)/,$(crate-obj-y))
+crate-obj-m	:= $(addprefix $(obj)/,$(crate-obj-m))
 real-obj-y	:= $(addprefix $(obj)/,$(real-obj-y))
 real-obj-m	:= $(addprefix $(obj)/,$(real-obj-m))
 multi-obj-m	:= $(addprefix $(obj)/, $(multi-obj-m))
@@ -210,7 +217,11 @@ _cpp_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj)
 endif
 endif
 
-part-of-module = $(if $(filter $(basename $@).o, $(real-obj-m)),y)
+_rust_libs = $(foreach l, $(rust-libs), -L $(obj)/$(dir $l) --extern $(notdir $(basename $l)))
+
+part-of-module =                                             \
+	$(if $(or $(filter $(basename $@).o, $(real-obj-m)), \
+		$(filter $(basename $@).rlib, $(real-obj-m))),y)
 quiet_modtag = $(if $(part-of-module),[M],   )
 
 modkern_cflags =                                          \
@@ -232,7 +243,8 @@ c_flags        = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
 		 $(_c_flags) $(modkern_cflags)                           \
 		 $(basename_flags) $(modname_flags)
 
-rust_flags     = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg
+rust_flags     = $(_rust_flags) $(modkern_rustflags) $(_rust_libs) \
+		 @$(objtree)/include/generated/rustc_cfg
 
 a_flags        = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
 		 $(_a_flags) $(modkern_aflags)
diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
index b3a6aa8fbe8c..aab17203f5b1 100644
--- a/scripts/Makefile.modfinal
+++ b/scripts/Makefile.modfinal
@@ -19,7 +19,7 @@ __modfinal: $(modules:%.o=%.ko)
 	@:
 
 # modname and part-of-module are set to make c_flags define proper module flags
-modname = $(notdir $(@:.mod.o=))
+modname = $(notdir $*)
 part-of-module = y
 
 quiet_cmd_cc_o_c = CC [M]  $@
@@ -30,11 +30,16 @@ quiet_cmd_cc_o_c = CC [M]  $@
 
 ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
 
+# Symlinks of foo.o that point to foo.foo.o are members of a .rlib archives,
+# so their exports should be added to the module
+ko_objs = $(if $(filter %$(modname).$(modname).o,$(realpath $*.o)),\
+	$(dir $*)exports_$(modname)_generated.o) $(filter %.o, $^)
+
 quiet_cmd_ld_ko_o = LD [M]  $@
       cmd_ld_ko_o +=							\
 	$(LD) -r $(KBUILD_LDFLAGS)					\
 		$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE)		\
-		-T scripts/module.lds -o $@ $(filter %.o, $^);		\
+		-T scripts/module.lds -o $@ $(ko_objs);			\
 	$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
 
 quiet_cmd_btf_ko = BTF [M] $@
-- 
2.42.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [RFC PATCH v3 2/2] samples: rust: Add USB sample bindings
  2023-11-04 21:11 [RFC PATCH v3 0/2] rust: crates in other kernel directories Martin Rodriguez Reboredo
  2023-11-04 21:11 ` [RFC PATCH v3 1/2] kbuild: Build Rust crates as libraries Martin Rodriguez Reboredo
@ 2023-11-04 21:11 ` Martin Rodriguez Reboredo
  2023-11-05  7:26   ` Greg Kroah-Hartman
  2023-11-13 14:13 ` [RFC PATCH v3 0/2] rust: crates in other kernel directories Masahiro Yamada
  2024-03-15 13:44 ` Johannes Berg
  3 siblings, 1 reply; 8+ messages in thread
From: Martin Rodriguez Reboredo @ 2023-11-04 21:11 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Miguel Ojeda, Alex Gaynor,
	Wedson Almeida Filho, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl
  Cc: linux-kbuild, linux-kernel, Wedson Almeida Filho, linux-usb,
	rust-for-linux

This is a demonstration of the capabilities of doing bindings with
subsystems that may or may not be statically linked.

Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
---
v2 -> v3:
- Generate bindings for USB.
v1 -> v2:
- Added this patch.

 drivers/usb/core/Kconfig        |  7 +++++++
 drivers/usb/core/Makefile       |  3 +++
 drivers/usb/core/usb.rs         | 13 +++++++++++++
 rust/bindings/bindings_helper.h |  1 +
 samples/rust/Kconfig            | 10 ++++++++++
 samples/rust/Makefile           |  3 +++
 samples/rust/rust_usb_simple.rs | 22 ++++++++++++++++++++++
 7 files changed, 59 insertions(+)
 create mode 100644 drivers/usb/core/usb.rs
 create mode 100644 samples/rust/rust_usb_simple.rs

diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index 351ede4b5de2..4b5604282129 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -116,3 +116,10 @@ config USB_AUTOSUSPEND_DELAY
 	  The default value Linux has always had is 2 seconds.  Change
 	  this value if you want a different delay and cannot modify
 	  the command line or module parameter.
+
+config USB_RUST
+	bool "Rust USB bindings"
+	depends on USB && RUST
+	default n
+	help
+	  Enables Rust bindings for USB.
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 7d338e9c0657..00e116913591 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -11,6 +11,7 @@ usbcore-y += phy.o port.o
 usbcore-$(CONFIG_OF)		+= of.o
 usbcore-$(CONFIG_USB_PCI)		+= hcd-pci.o
 usbcore-$(CONFIG_ACPI)		+= usb-acpi.o
+usbcore-$(CONFIG_USB_RUST)		+= libusb.rlib
 
 ifdef CONFIG_USB_ONBOARD_HUB
 usbcore-y			+= ../misc/onboard_usb_hub_pdevs.o
@@ -18,4 +19,6 @@ endif
 
 obj-$(CONFIG_USB)		+= usbcore.o
 
+rust-libs			:= ./usb
+
 obj-$(CONFIG_USB_LEDS_TRIGGER_USBPORT)	+= ledtrig-usbport.o
diff --git a/drivers/usb/core/usb.rs b/drivers/usb/core/usb.rs
new file mode 100644
index 000000000000..3f7ad02153f5
--- /dev/null
+++ b/drivers/usb/core/usb.rs
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! USB devices and drivers.
+//!
+//! C header: [`include/linux/usb.h`](../../../../include/linux/usb.h)
+
+use kernel::bindings;
+
+/// Check if USB is disabled.
+pub fn disabled() -> bool {
+    // SAFETY: FFI call.
+    unsafe { bindings::usb_disabled() != 0 }
+}
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index c41eaab4ddb2..845cdd856981 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -10,6 +10,7 @@
 #include <linux/errname.h>
 #include <linux/slab.h>
 #include <linux/refcount.h>
+#include <linux/usb.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/workqueue.h>
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig
index b0f74a81c8f9..12116f6fb526 100644
--- a/samples/rust/Kconfig
+++ b/samples/rust/Kconfig
@@ -30,6 +30,16 @@ config SAMPLE_RUST_PRINT
 
 	  If unsure, say N.
 
+config SAMPLE_RUST_USB_SIMPLE
+	tristate "USB simple device driver"
+	help
+	  This option builds the Rust USB simple driver sample.
+
+	  To compile this as a module, choose M here:
+	  the module will be called rust_usb_simple.
+
+	  If unsure, say N.
+
 config SAMPLE_RUST_HOSTPROGS
 	bool "Host programs"
 	help
diff --git a/samples/rust/Makefile b/samples/rust/Makefile
index 03086dabbea4..f1ab58a9ecdd 100644
--- a/samples/rust/Makefile
+++ b/samples/rust/Makefile
@@ -2,5 +2,8 @@
 
 obj-$(CONFIG_SAMPLE_RUST_MINIMAL)		+= rust_minimal.o
 obj-$(CONFIG_SAMPLE_RUST_PRINT)			+= rust_print.o
+obj-$(CONFIG_SAMPLE_RUST_USB_SIMPLE)		+= rust_usb_simple.o
+
+rust-libs					:= ../../drivers/usb/core/usb
 
 subdir-$(CONFIG_SAMPLE_RUST_HOSTPROGS)		+= hostprogs
diff --git a/samples/rust/rust_usb_simple.rs b/samples/rust/rust_usb_simple.rs
new file mode 100644
index 000000000000..3523f81d5eb8
--- /dev/null
+++ b/samples/rust/rust_usb_simple.rs
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust USB sample.
+
+use kernel::prelude::*;
+
+module! {
+    type: UsbSimple,
+    name: "rust_usb_simple",
+    author: "Martin Rodriguez Reboredo",
+    description: "Rust USB sample",
+    license: "GPL v2",
+}
+
+struct UsbSimple;
+
+impl kernel::Module for UsbSimple {
+    fn init(_module: &'static ThisModule) -> Result<Self> {
+        pr_info!("usb enabled: {}", !usb::disabled());
+        Ok(UsbSimple)
+    }
+}
-- 
2.42.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH v3 2/2] samples: rust: Add USB sample bindings
  2023-11-04 21:11 ` [RFC PATCH v3 2/2] samples: rust: Add USB sample bindings Martin Rodriguez Reboredo
@ 2023-11-05  7:26   ` Greg Kroah-Hartman
  0 siblings, 0 replies; 8+ messages in thread
From: Greg Kroah-Hartman @ 2023-11-05  7:26 UTC (permalink / raw)
  To: Martin Rodriguez Reboredo
  Cc: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, linux-kbuild, linux-kernel, Wedson Almeida Filho,
	linux-usb, rust-for-linux

On Sat, Nov 04, 2023 at 06:11:59PM -0300, Martin Rodriguez Reboredo wrote:
> This is a demonstration of the capabilities of doing bindings with
> subsystems that may or may not be statically linked.
> 
> Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
> ---
> v2 -> v3:
> - Generate bindings for USB.
> v1 -> v2:
> - Added this patch.

I know you are just using this for an example, but here's some
USB-specific things that you might want to clean up for when you submit
this as a "real" binding sometime in the future:

> +config USB_RUST
> +	bool "Rust USB bindings"

This is a "USB Host" binding.  We have both USB host mode (when you plug
a USB device into a system running Linux), and USB gadget mode (when
Linux is running on the USB device you plug into any other USB system).

So please be specific here, this should be "USB_HOST_RUST" and then
later, "USB_GADGET_RUST".

> +	depends on USB && RUST
> +	default n

Again, "default n" is the default, never list it again.


> +	help
> +	  Enables Rust bindings for USB.

USB Host, not all of USB.

> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
> index 7d338e9c0657..00e116913591 100644
> --- a/drivers/usb/core/Makefile
> +++ b/drivers/usb/core/Makefile
> @@ -11,6 +11,7 @@ usbcore-y += phy.o port.o
>  usbcore-$(CONFIG_OF)		+= of.o
>  usbcore-$(CONFIG_USB_PCI)		+= hcd-pci.o
>  usbcore-$(CONFIG_ACPI)		+= usb-acpi.o
> +usbcore-$(CONFIG_USB_RUST)		+= libusb.rlib
>  
>  ifdef CONFIG_USB_ONBOARD_HUB
>  usbcore-y			+= ../misc/onboard_usb_hub_pdevs.o
> @@ -18,4 +19,6 @@ endif
>  
>  obj-$(CONFIG_USB)		+= usbcore.o
>  
> +rust-libs			:= ./usb

Why the "./", why not just ":= usb" ?

> +config SAMPLE_RUST_USB_SIMPLE
> +	tristate "USB simple device driver"
> +	help
> +	  This option builds the Rust USB simple driver sample.

Rust USB simple host driver sample.

>  subdir-$(CONFIG_SAMPLE_RUST_HOSTPROGS)		+= hostprogs
> diff --git a/samples/rust/rust_usb_simple.rs b/samples/rust/rust_usb_simple.rs
> new file mode 100644
> index 000000000000..3523f81d5eb8
> --- /dev/null
> +++ b/samples/rust/rust_usb_simple.rs
> @@ -0,0 +1,22 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Rust USB sample.
> +
> +use kernel::prelude::*;
> +
> +module! {
> +    type: UsbSimple,

"USBSimple" please.  I thought I said that before.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH v3 0/2] rust: crates in other kernel directories
  2023-11-04 21:11 [RFC PATCH v3 0/2] rust: crates in other kernel directories Martin Rodriguez Reboredo
  2023-11-04 21:11 ` [RFC PATCH v3 1/2] kbuild: Build Rust crates as libraries Martin Rodriguez Reboredo
  2023-11-04 21:11 ` [RFC PATCH v3 2/2] samples: rust: Add USB sample bindings Martin Rodriguez Reboredo
@ 2023-11-13 14:13 ` Masahiro Yamada
  2024-02-18 16:11   ` Martin Rodriguez Reboredo
  2024-03-15 13:44 ` Johannes Berg
  3 siblings, 1 reply; 8+ messages in thread
From: Masahiro Yamada @ 2023-11-13 14:13 UTC (permalink / raw)
  To: Martin Rodriguez Reboredo
  Cc: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, linux-kbuild, linux-kernel, rust-for-linux

On Sun, Nov 5, 2023 at 6:12 AM Martin Rodriguez Reboredo
<yakoyoku@gmail.com> wrote:
>
> This RFC provides makes possible to have bindings for kernel subsystems
> that are compiled as modules.
>
> Previously, if you wanted to have Rust bindings for a subsystem, like
> AMBA for example, you had to put it under `rust/kernel/` so it came
> part of the `kernel` crate, but this came with many downsides. Namely
> if you compiled said subsystem as a module you've a dependency on it
> from `kernel`, which is linked directly on `vmlinux`.
>
> So instead of overpopulating `kernel` with a gazillion modules that
> throws you into dire straits you should rather have the bindings in the
> same directory as the subsystem you want to bind with and link it to
> it.
>
> With this patch Rust sources can be compiled into libraries for them to
> be consumed. These libraries are ar archives that follow the `.rlib`
> structure, namely a libfoo.rlib thin archive with a foo.foo.o object
> and a libfoo.rmeta rustc metadata as members. Such Rust crates get
> their symbols exposed and the `bindings` crate is made available for
> them.
>
> Also included there's a sample usage of this in another patch, but it
> is not meant to be merged as it remains as an example.
>
> If you want to use a crate with your Rust module just add a `rust-libs`
> variable in your Makefile with a value of the relative directory of
> said crate plus its name, e.g.
>
>     # Link with the foo crate
>     rust-libs += ../path/to/foo




I will not provide a line-by-line review.


Just one thing I'd like to point out.

You assume the library (drivers/usb/core/*)
is built before its consumers (samples/rust/*).

If Kbuild ends up with building lib consumers first,
it will be a build error.



Kbuild descends into multiple directories in parallel building.

You cannot predict which directory is built first.








> Martin Rodriguez Reboredo (2):
>   kbuild: Build Rust crates as libraries
>   samples: rust: Add USB sample bindings
>
>  .gitignore                      |  2 ++
>  Makefile                        |  4 ++--
>  drivers/usb/core/Kconfig        |  7 ++++++
>  drivers/usb/core/Makefile       |  3 +++
>  drivers/usb/core/usb.rs         | 13 ++++++++++
>  rust/bindings/bindings_helper.h |  1 +
>  samples/rust/Kconfig            | 10 ++++++++
>  samples/rust/Makefile           |  3 +++
>  samples/rust/rust_usb_simple.rs | 22 +++++++++++++++++
>  scripts/Makefile.build          | 42 ++++++++++++++++++++++++++++++---
>  scripts/Makefile.lib            | 20 ++++++++++++----
>  scripts/Makefile.modfinal       |  9 +++++--
>  12 files changed, 125 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/usb/core/usb.rs
>  create mode 100644 samples/rust/rust_usb_simple.rs
>
> --
> 2.42.1
>


-- 
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH v3 0/2] rust: crates in other kernel directories
  2023-11-13 14:13 ` [RFC PATCH v3 0/2] rust: crates in other kernel directories Masahiro Yamada
@ 2024-02-18 16:11   ` Martin Rodriguez Reboredo
  2024-02-19  9:05     ` Masahiro Yamada
  0 siblings, 1 reply; 8+ messages in thread
From: Martin Rodriguez Reboredo @ 2024-02-18 16:11 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, linux-kbuild, linux-kernel, rust-for-linux

On 11/13/23 11:13, Masahiro Yamada wrote:
> [...]
> 
> I will not provide a line-by-line review.
> 
> 
> Just one thing I'd like to point out.
> 
> You assume the library (drivers/usb/core/*)
> is built before its consumers (samples/rust/*).
> 
> If Kbuild ends up with building lib consumers first,
> it will be a build error.
> 
> 
> 
> Kbuild descends into multiple directories in parallel building.
> 
> You cannot predict which directory is built first.
> 
> [...]

Thinking with what you've said the same thing might apply to any Rust
written code that depends on crates under the `rust` dir. Adding
Make dependencies to object code made from `.rs` will be required if so,
assuming that Kbuild is intelligent enough to build the crates first.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH v3 0/2] rust: crates in other kernel directories
  2024-02-18 16:11   ` Martin Rodriguez Reboredo
@ 2024-02-19  9:05     ` Masahiro Yamada
  0 siblings, 0 replies; 8+ messages in thread
From: Masahiro Yamada @ 2024-02-19  9:05 UTC (permalink / raw)
  To: Martin Rodriguez Reboredo
  Cc: Miguel Ojeda, Alex Gaynor, Wedson Almeida Filho, Boqun Feng,
	Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Alice Ryhl, linux-kbuild, linux-kernel, rust-for-linux

On Mon, Feb 19, 2024 at 1:11 AM Martin Rodriguez Reboredo
<yakoyoku@gmail.com> wrote:
>
> On 11/13/23 11:13, Masahiro Yamada wrote:
> > [...]
> >
> > I will not provide a line-by-line review.
> >
> >
> > Just one thing I'd like to point out.
> >
> > You assume the library (drivers/usb/core/*)
> > is built before its consumers (samples/rust/*).
> >
> > If Kbuild ends up with building lib consumers first,
> > it will be a build error.
> >
> >
> >
> > Kbuild descends into multiple directories in parallel building.
> >
> > You cannot predict which directory is built first.
> >
> > [...]
>
> Thinking with what you've said the same thing might apply to any Rust
> written code that depends on crates under the `rust` dir. Adding
> Make dependencies to object code made from `.rs` will be required if so,
> assuming that Kbuild is intelligent enough to build the crates first.


rust/Makefile specifies dependencies between crates.

I do not know how to specify crate dependencies
across multiple Makefiles, like you did in
drivers/usb/core/Makefile and samples/rust/Makefile.



-- 
Best Regards
Masahiro Yamada

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH v3 0/2] rust: crates in other kernel directories
  2023-11-04 21:11 [RFC PATCH v3 0/2] rust: crates in other kernel directories Martin Rodriguez Reboredo
                   ` (2 preceding siblings ...)
  2023-11-13 14:13 ` [RFC PATCH v3 0/2] rust: crates in other kernel directories Masahiro Yamada
@ 2024-03-15 13:44 ` Johannes Berg
  3 siblings, 0 replies; 8+ messages in thread
From: Johannes Berg @ 2024-03-15 13:44 UTC (permalink / raw)
  To: Martin Rodriguez Reboredo, Miguel Ojeda, Alex Gaynor,
	Wedson Almeida Filho, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl
  Cc: linux-kbuild, linux-kernel, rust-for-linux

Hi,

So I realize this is an old patch, but I didn't find another version,
and discussions seemed ongoing at least a month ago. I also came across
it pretty randomly.

Anyway, question:

> If you want to use a crate with your Rust module just add a `rust-libs`
> variable in your Makefile with a value of the relative directory of
> said crate plus its name, e.g.
> 
>     # Link with the foo crate
>     rust-libs += ../path/to/foo

Should this perhaps be relative to the kernel's root dir instead? 

If I'm reading this correctly, then a hypothetical rust wireless driver
that lives in

  drivers/net/wireless/<vendor>/<name>/

using some wireless rust infrastructure would probably end up with
something like

  rust-libs += ../../../../../net/mac80211/rust/

or whatever, which seems rather odd vs.

  rust-libs += net/mac80211/rust/

Seems to me that chances are that subsystems/drivers that have rust
infrastructure will not necessarily have them close to each other, like
in this example?

You have this in the sample too:

+rust-libs					:= ../../drivers/usb/core/usb

but it's less pronounced since it's just samples/rust/ :)

johannes

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-03-15 14:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-04 21:11 [RFC PATCH v3 0/2] rust: crates in other kernel directories Martin Rodriguez Reboredo
2023-11-04 21:11 ` [RFC PATCH v3 1/2] kbuild: Build Rust crates as libraries Martin Rodriguez Reboredo
2023-11-04 21:11 ` [RFC PATCH v3 2/2] samples: rust: Add USB sample bindings Martin Rodriguez Reboredo
2023-11-05  7:26   ` Greg Kroah-Hartman
2023-11-13 14:13 ` [RFC PATCH v3 0/2] rust: crates in other kernel directories Masahiro Yamada
2024-02-18 16:11   ` Martin Rodriguez Reboredo
2024-02-19  9:05     ` Masahiro Yamada
2024-03-15 13:44 ` Johannes Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).