@@ -34,6 +34,18 @@ pub trait ModuleParam: core::fmt::Display + core::marker::Sized {
3434 /// `arg == None` indicates that the parameter was passed without an
3535 /// argument. If `NOARG_ALLOWED` is set to `false` then `arg` is guaranteed
3636 /// to always be `Some(_)`.
37+ ///
38+ /// Parameters passed at boot time will be set before [`kmalloc`] is
39+ /// available (even if the module is loaded at a later time). However, in
40+ /// this case, the argument buffer will be valid for the entire lifetime of
41+ /// the kernel. So implementations of this method which need to allocate
42+ /// should first check that the allocator is available (with
43+ /// [`crate::bindings::slab_is_available`]) and when it is not available
44+ /// provide an alternative implementation which doesn't allocate. In cases
45+ /// where the allocator is not available it is safe to save references to
46+ /// `arg` in `Self`, but in other cases a copy should be made.
47+ ///
48+ /// [`kmalloc`]: ../../../include/linux/slab.h
3749 fn try_from_param_arg ( arg : Option < & ' static [ u8 ] > ) -> Option < Self > ;
3850
3951 /// Get the current value of the parameter for use in the kernel module.
@@ -455,13 +467,14 @@ impl ModuleParam for StringParam {
455467 fn try_from_param_arg ( arg : Option < & ' static [ u8 ] > ) -> Option < Self > {
456468 // SAFETY: It is always safe to call [`slab_is_available`](../../../include/linux/slab.h).
457469 let slab_available = unsafe { crate :: bindings:: slab_is_available ( ) } ;
458- arg. map ( |arg| {
470+ arg. and_then ( |arg| {
459471 if slab_available {
460472 let mut vec = alloc:: vec:: Vec :: new ( ) ;
473+ vec. try_reserve_exact ( arg. len ( ) ) . ok ( ) ?;
461474 vec. extend_from_slice ( arg) ;
462- StringParam :: Owned ( vec)
475+ Some ( StringParam :: Owned ( vec) )
463476 } else {
464- StringParam :: Ref ( arg)
477+ Some ( StringParam :: Ref ( arg) )
465478 }
466479 } )
467480 }
0 commit comments