mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	kbuild: rust: remove the alloc crate and GlobalAlloc
				
					
				
			Now that we have our own `Allocator`, `Box` and `Vec` types we can remove Rust's `alloc` crate and the `new_uninit` unstable feature. Also remove `Kmalloc`'s `GlobalAlloc` implementation -- we can't remove this in a separate patch, since the `alloc` crate requires a `#[global_allocator]` to set, that implements `GlobalAlloc`. Signed-off-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/r/20241004154149.93856-29-dakr@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
		
							parent
							
								
									8ae740c391
								
							
						
					
					
						commit
						392e34b6bc
					
				
					 5 changed files with 16 additions and 108 deletions
				
			
		|  | @ -15,8 +15,8 @@ always-$(CONFIG_RUST) += libmacros.so | ||||||
| no-clean-files += libmacros.so | no-clean-files += libmacros.so | ||||||
| 
 | 
 | ||||||
| always-$(CONFIG_RUST) += bindings/bindings_generated.rs bindings/bindings_helpers_generated.rs | always-$(CONFIG_RUST) += bindings/bindings_generated.rs bindings/bindings_helpers_generated.rs | ||||||
| obj-$(CONFIG_RUST) += alloc.o bindings.o kernel.o | obj-$(CONFIG_RUST) += bindings.o kernel.o | ||||||
| always-$(CONFIG_RUST) += exports_alloc_generated.h exports_helpers_generated.h \
 | always-$(CONFIG_RUST) += exports_helpers_generated.h \
 | ||||||
|     exports_bindings_generated.h exports_kernel_generated.h |     exports_bindings_generated.h exports_kernel_generated.h | ||||||
| 
 | 
 | ||||||
| always-$(CONFIG_RUST) += uapi/uapi_generated.rs | always-$(CONFIG_RUST) += uapi/uapi_generated.rs | ||||||
|  | @ -53,11 +53,6 @@ endif | ||||||
| core-cfgs = \
 | core-cfgs = \
 | ||||||
|     --cfg no_fp_fmt_parse |     --cfg no_fp_fmt_parse | ||||||
| 
 | 
 | ||||||
| alloc-cfgs = \
 |  | ||||||
|     --cfg no_global_oom_handling \
 |  | ||||||
|     --cfg no_rc \
 |  | ||||||
|     --cfg no_sync |  | ||||||
| 
 |  | ||||||
| quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< | quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< | ||||||
|       cmd_rustdoc = \
 |       cmd_rustdoc = \
 | ||||||
| 	OBJTREE=$(abspath $(objtree)) \
 | 	OBJTREE=$(abspath $(objtree)) \
 | ||||||
|  | @ -81,7 +76,7 @@ quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< | ||||||
| # command-like flags to solve the issue. Meanwhile, we use the non-custom case
 | # command-like flags to solve the issue. Meanwhile, we use the non-custom case
 | ||||||
| # and then retouch the generated files.
 | # and then retouch the generated files.
 | ||||||
| rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ | rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ | ||||||
|     rustdoc-alloc rustdoc-kernel |     rustdoc-kernel | ||||||
| 	$(Q)cp $(srctree)/Documentation/images/logo.svg $(rustdoc_output)/static.files/ | 	$(Q)cp $(srctree)/Documentation/images/logo.svg $(rustdoc_output)/static.files/ | ||||||
| 	$(Q)cp $(srctree)/Documentation/images/COPYING-logo $(rustdoc_output)/static.files/ | 	$(Q)cp $(srctree)/Documentation/images/COPYING-logo $(rustdoc_output)/static.files/ | ||||||
| 	$(Q)find $(rustdoc_output) -name '*.html' -type f -print0 | xargs -0 sed -Ei \
 | 	$(Q)find $(rustdoc_output) -name '*.html' -type f -print0 | xargs -0 sed -Ei \
 | ||||||
|  | @ -108,20 +103,11 @@ rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE | ||||||
| rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE | rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE | ||||||
| 	+$(call if_changed,rustdoc) | 	+$(call if_changed,rustdoc) | ||||||
| 
 | 
 | ||||||
| # We need to allow `rustdoc::broken_intra_doc_links` because some
 | rustdoc-kernel: private rustc_target_flags = \ | ||||||
| # `no_global_oom_handling` functions refer to non-`no_global_oom_handling`
 |  | ||||||
| # functions. Ideally `rustdoc` would have a way to distinguish broken links
 |  | ||||||
| # due to things that are "configured out" vs. entirely non-existing ones.
 |  | ||||||
| rustdoc-alloc: private rustc_target_flags = $(alloc-cfgs) \ |  | ||||||
|     -Arustdoc::broken_intra_doc_links |  | ||||||
| rustdoc-alloc: $(RUST_LIB_SRC)/alloc/src/lib.rs rustdoc-core rustdoc-compiler_builtins FORCE |  | ||||||
| 	+$(call if_changed,rustdoc) |  | ||||||
| 
 |  | ||||||
| rustdoc-kernel: private rustc_target_flags = --extern alloc \ |  | ||||||
|     --extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \
 |     --extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \
 | ||||||
|     --extern bindings --extern uapi |     --extern bindings --extern uapi | ||||||
| rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \ | rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \ | ||||||
|     rustdoc-compiler_builtins rustdoc-alloc $(obj)/libmacros.so \
 |     rustdoc-compiler_builtins $(obj)/libmacros.so \
 | ||||||
|     $(obj)/bindings.o FORCE |     $(obj)/bindings.o FORCE | ||||||
| 	+$(call if_changed,rustdoc) | 	+$(call if_changed,rustdoc) | ||||||
| 
 | 
 | ||||||
|  | @ -165,7 +151,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $< | ||||||
| 	mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \
 | 	mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \
 | ||||||
| 	OBJTREE=$(abspath $(objtree)) \
 | 	OBJTREE=$(abspath $(objtree)) \
 | ||||||
| 	$(RUSTDOC) --test $(rust_flags) \
 | 	$(RUSTDOC) --test $(rust_flags) \
 | ||||||
| 		-L$(objtree)/$(obj) --extern alloc --extern kernel \
 | 		-L$(objtree)/$(obj) --extern kernel \
 | ||||||
| 		--extern build_error --extern macros \
 | 		--extern build_error --extern macros \
 | ||||||
| 		--extern bindings --extern uapi \
 | 		--extern bindings --extern uapi \
 | ||||||
| 		--no-run --crate-name kernel -Zunstable-options \
 | 		--no-run --crate-name kernel -Zunstable-options \
 | ||||||
|  | @ -201,7 +187,7 @@ rusttest-macros: $(src)/macros/lib.rs FORCE | ||||||
| 	+$(call if_changed,rustc_test) | 	+$(call if_changed,rustc_test) | ||||||
| 	+$(call if_changed,rustdoc_test) | 	+$(call if_changed,rustdoc_test) | ||||||
| 
 | 
 | ||||||
| rusttest-kernel: private rustc_target_flags = --extern alloc \ | rusttest-kernel: private rustc_target_flags = \ | ||||||
|     --extern build_error --extern macros --extern bindings --extern uapi |     --extern build_error --extern macros --extern bindings --extern uapi | ||||||
| rusttest-kernel: $(src)/kernel/lib.rs \ | rusttest-kernel: $(src)/kernel/lib.rs \ | ||||||
|     rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \
 |     rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \
 | ||||||
|  | @ -314,9 +300,6 @@ quiet_cmd_exports = EXPORTS $@ | ||||||
| $(obj)/exports_core_generated.h: $(obj)/core.o FORCE | $(obj)/exports_core_generated.h: $(obj)/core.o FORCE | ||||||
| 	$(call if_changed,exports) | 	$(call if_changed,exports) | ||||||
| 
 | 
 | ||||||
| $(obj)/exports_alloc_generated.h: $(obj)/alloc.o FORCE |  | ||||||
| 	$(call if_changed,exports) |  | ||||||
| 
 |  | ||||||
| # Even though Rust kernel modules should never use the bindings directly,
 | # Even though Rust kernel modules should never use the bindings directly,
 | ||||||
| # symbols from the `bindings` crate and the C helpers need to be exported
 | # symbols from the `bindings` crate and the C helpers need to be exported
 | ||||||
| # because Rust generics and inlined functions may not get their code generated
 | # because Rust generics and inlined functions may not get their code generated
 | ||||||
|  | @ -363,7 +346,7 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L | ||||||
| 
 | 
 | ||||||
| rust-analyzer: | rust-analyzer: | ||||||
| 	$(Q)$(srctree)/scripts/generate_rust_analyzer.py \
 | 	$(Q)$(srctree)/scripts/generate_rust_analyzer.py \
 | ||||||
| 		--cfgs='core=$(core-cfgs)' --cfgs='alloc=$(alloc-cfgs)' \
 | 		--cfgs='core=$(core-cfgs)' \
 | ||||||
| 		$(realpath $(srctree)) $(realpath $(objtree)) \
 | 		$(realpath $(srctree)) $(realpath $(objtree)) \
 | ||||||
| 		$(rustc_sysroot) $(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \
 | 		$(rustc_sysroot) $(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \
 | ||||||
| 		$(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json | 		$(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json | ||||||
|  | @ -401,12 +384,6 @@ $(obj)/compiler_builtins.o: private rustc_objcopy = -w -W '__*' | ||||||
| $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE | $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE | ||||||
| 	+$(call if_changed_rule,rustc_library) | 	+$(call if_changed_rule,rustc_library) | ||||||
| 
 | 
 | ||||||
| $(obj)/alloc.o: private skip_clippy = 1 |  | ||||||
| $(obj)/alloc.o: private skip_flags = -Wunreachable_pub |  | ||||||
| $(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs) |  | ||||||
| $(obj)/alloc.o: $(RUST_LIB_SRC)/alloc/src/lib.rs $(obj)/compiler_builtins.o FORCE |  | ||||||
| 	+$(call if_changed_rule,rustc_library) |  | ||||||
| 
 |  | ||||||
| $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE | $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE | ||||||
| 	+$(call if_changed_rule,rustc_library) | 	+$(call if_changed_rule,rustc_library) | ||||||
| 
 | 
 | ||||||
|  | @ -421,9 +398,9 @@ $(obj)/uapi.o: $(src)/uapi/lib.rs \ | ||||||
|     $(obj)/uapi/uapi_generated.rs FORCE |     $(obj)/uapi/uapi_generated.rs FORCE | ||||||
| 	+$(call if_changed_rule,rustc_library) | 	+$(call if_changed_rule,rustc_library) | ||||||
| 
 | 
 | ||||||
| $(obj)/kernel.o: private rustc_target_flags = --extern alloc \ | $(obj)/kernel.o: private rustc_target_flags = \ | ||||||
|     --extern build_error --extern macros --extern bindings --extern uapi |     --extern build_error --extern macros --extern bindings --extern uapi | ||||||
| $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o $(obj)/build_error.o \ | $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \ | ||||||
|     $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE |     $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE | ||||||
| 	+$(call if_changed_rule,rustc_library) | 	+$(call if_changed_rule,rustc_library) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -16,7 +16,6 @@ | ||||||
| #define EXPORT_SYMBOL_RUST_GPL(sym) extern int sym; EXPORT_SYMBOL_GPL(sym) | #define EXPORT_SYMBOL_RUST_GPL(sym) extern int sym; EXPORT_SYMBOL_GPL(sym) | ||||||
| 
 | 
 | ||||||
| #include "exports_core_generated.h" | #include "exports_core_generated.h" | ||||||
| #include "exports_alloc_generated.h" |  | ||||||
| #include "exports_helpers_generated.h" | #include "exports_helpers_generated.h" | ||||||
| #include "exports_bindings_generated.h" | #include "exports_bindings_generated.h" | ||||||
| #include "exports_kernel_generated.h" | #include "exports_kernel_generated.h" | ||||||
|  |  | ||||||
|  | @ -8,8 +8,8 @@ | ||||||
| //!
 | //!
 | ||||||
| //! Reference: <https://docs.kernel.org/core-api/memory-allocation.html>
 | //! Reference: <https://docs.kernel.org/core-api/memory-allocation.html>
 | ||||||
| 
 | 
 | ||||||
| use super::{flags::*, Flags}; | use super::Flags; | ||||||
| use core::alloc::{GlobalAlloc, Layout}; | use core::alloc::Layout; | ||||||
| use core::ptr; | use core::ptr; | ||||||
| use core::ptr::NonNull; | use core::ptr::NonNull; | ||||||
| 
 | 
 | ||||||
|  | @ -54,23 +54,6 @@ fn aligned_size(new_layout: Layout) -> usize { | ||||||
|     layout.size() |     layout.size() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Calls `krealloc` with a proper size to alloc a new object aligned to `new_layout`'s alignment.
 |  | ||||||
| ///
 |  | ||||||
| /// # Safety
 |  | ||||||
| ///
 |  | ||||||
| /// - `ptr` can be either null or a pointer which has been allocated by this allocator.
 |  | ||||||
| /// - `new_layout` must have a non-zero size.
 |  | ||||||
| pub(crate) unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, flags: Flags) -> *mut u8 { |  | ||||||
|     let size = aligned_size(new_layout); |  | ||||||
| 
 |  | ||||||
|     // SAFETY:
 |  | ||||||
|     // - `ptr` is either null or a pointer returned from a previous `k{re}alloc()` by the
 |  | ||||||
|     //   function safety requirement.
 |  | ||||||
|     // - `size` is greater than 0 since it's from `layout.size()` (which cannot be zero according
 |  | ||||||
|     //   to the function safety requirement)
 |  | ||||||
|     unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags.0) as *mut u8 } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// # Invariants
 | /// # Invariants
 | ||||||
| ///
 | ///
 | ||||||
| /// One of the following: `krealloc`, `vrealloc`, `kvrealloc`.
 | /// One of the following: `krealloc`, `vrealloc`, `kvrealloc`.
 | ||||||
|  | @ -156,43 +139,6 @@ unsafe fn realloc( | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SAFETY: TODO.
 |  | ||||||
| unsafe impl GlobalAlloc for Kmalloc { |  | ||||||
|     unsafe fn alloc(&self, layout: Layout) -> *mut u8 { |  | ||||||
|         // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety
 |  | ||||||
|         // requirement.
 |  | ||||||
|         unsafe { krealloc_aligned(ptr::null_mut(), layout, GFP_KERNEL) } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { |  | ||||||
|         // SAFETY: TODO.
 |  | ||||||
|         unsafe { |  | ||||||
|             bindings::kfree(ptr as *const core::ffi::c_void); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { |  | ||||||
|         // SAFETY:
 |  | ||||||
|         // - `new_size`, when rounded up to the nearest multiple of `layout.align()`, will not
 |  | ||||||
|         //   overflow `isize` by the function safety requirement.
 |  | ||||||
|         // - `layout.align()` is a proper alignment (i.e. not zero and must be a power of two).
 |  | ||||||
|         let layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) }; |  | ||||||
| 
 |  | ||||||
|         // SAFETY:
 |  | ||||||
|         // - `ptr` is either null or a pointer allocated by this allocator by the function safety
 |  | ||||||
|         //   requirement.
 |  | ||||||
|         // - the size of `layout` is not zero because `new_size` is not zero by the function safety
 |  | ||||||
|         //   requirement.
 |  | ||||||
|         unsafe { krealloc_aligned(ptr, layout, GFP_KERNEL) } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { |  | ||||||
|         // SAFETY: `ptr::null_mut()` is null and `layout` has a non-zero size by the function safety
 |  | ||||||
|         // requirement.
 |  | ||||||
|         unsafe { krealloc_aligned(ptr::null_mut(), layout, GFP_KERNEL | __GFP_ZERO) } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that
 | // SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that
 | ||||||
| // - memory remains valid until it is explicitly freed,
 | // - memory remains valid until it is explicitly freed,
 | ||||||
| // - passing a pointer to a valid memory allocation is OK,
 | // - passing a pointer to a valid memory allocation is OK,
 | ||||||
|  | @ -240,10 +186,3 @@ unsafe fn realloc( | ||||||
|         unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags) } |         unsafe { ReallocFunc::KVREALLOC.call(ptr, layout, old_layout, flags) } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #[global_allocator] |  | ||||||
| static ALLOCATOR: Kmalloc = Kmalloc; |  | ||||||
| 
 |  | ||||||
| // See <https://github.com/rust-lang/rust/pull/86844>.
 |  | ||||||
| #[no_mangle] |  | ||||||
| static __rust_no_alloc_shim_is_unstable: u8 = 0; |  | ||||||
|  |  | ||||||
|  | @ -248,7 +248,7 @@ $(obj)/%.lst: $(obj)/%.c FORCE | ||||||
| # Compile Rust sources (.rs) | # Compile Rust sources (.rs) | ||||||
| # --------------------------------------------------------------------------- | # --------------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| rust_allowed_features := arbitrary_self_types,lint_reasons,new_uninit | rust_allowed_features := arbitrary_self_types,lint_reasons | ||||||
| 
 | 
 | ||||||
| # `--out-dir` is required to avoid temporaries being created by `rustc` in the | # `--out-dir` is required to avoid temporaries being created by `rustc` in the | ||||||
| # current working directory, which may be not accessible in the out-of-tree | # current working directory, which may be not accessible in the out-of-tree | ||||||
|  | @ -258,7 +258,7 @@ rust_common_cmd = \ | ||||||
| 	-Zallow-features=$(rust_allowed_features) \ | 	-Zallow-features=$(rust_allowed_features) \ | ||||||
| 	-Zcrate-attr=no_std \ | 	-Zcrate-attr=no_std \ | ||||||
| 	-Zcrate-attr='feature($(rust_allowed_features))' \ | 	-Zcrate-attr='feature($(rust_allowed_features))' \ | ||||||
| 	-Zunstable-options --extern force:alloc --extern kernel \ | 	-Zunstable-options --extern kernel \ | ||||||
| 	--crate-type rlib -L $(objtree)/rust/ \ | 	--crate-type rlib -L $(objtree)/rust/ \ | ||||||
| 	--crate-name $(basename $(notdir $@)) \ | 	--crate-name $(basename $(notdir $@)) \ | ||||||
| 	--sysroot=/dev/null \ | 	--sysroot=/dev/null \ | ||||||
|  |  | ||||||
|  | @ -64,13 +64,6 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): | ||||||
|         [], |         [], | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     append_crate( |  | ||||||
|         "alloc", |  | ||||||
|         sysroot_src / "alloc" / "src" / "lib.rs", |  | ||||||
|         ["core", "compiler_builtins"], |  | ||||||
|         cfg=crates_cfgs.get("alloc", []), |  | ||||||
|     ) |  | ||||||
| 
 |  | ||||||
|     append_crate( |     append_crate( | ||||||
|         "macros", |         "macros", | ||||||
|         srctree / "rust" / "macros" / "lib.rs", |         srctree / "rust" / "macros" / "lib.rs", | ||||||
|  | @ -96,7 +89,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): | ||||||
|     append_crate( |     append_crate( | ||||||
|         "kernel", |         "kernel", | ||||||
|         srctree / "rust" / "kernel" / "lib.rs", |         srctree / "rust" / "kernel" / "lib.rs", | ||||||
|         ["core", "alloc", "macros", "build_error", "bindings"], |         ["core", "macros", "build_error", "bindings"], | ||||||
|         cfg=cfg, |         cfg=cfg, | ||||||
|     ) |     ) | ||||||
|     crates[-1]["source"] = { |     crates[-1]["source"] = { | ||||||
|  | @ -133,7 +126,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): | ||||||
|             append_crate( |             append_crate( | ||||||
|                 name, |                 name, | ||||||
|                 path, |                 path, | ||||||
|                 ["core", "alloc", "kernel"], |                 ["core", "kernel"], | ||||||
|                 cfg=cfg, |                 cfg=cfg, | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Danilo Krummrich
						Danilo Krummrich