@@ -34,6 +34,18 @@ pub trait ModuleParam: core::fmt::Display + core::marker::Sized {
34
34
/// `arg == None` indicates that the parameter was passed without an
35
35
/// argument. If `NOARG_ALLOWED` is set to `false` then `arg` is guaranteed
36
36
/// 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
37
49
fn try_from_param_arg ( arg : Option < & ' static [ u8 ] > ) -> Option < Self > ;
38
50
39
51
/// Get the current value of the parameter for use in the kernel module.
@@ -455,13 +467,14 @@ impl ModuleParam for StringParam {
455
467
fn try_from_param_arg ( arg : Option < & ' static [ u8 ] > ) -> Option < Self > {
456
468
// SAFETY: It is always safe to call [`slab_is_available`](../../../include/linux/slab.h).
457
469
let slab_available = unsafe { crate :: bindings:: slab_is_available ( ) } ;
458
- arg. map ( |arg| {
470
+ arg. and_then ( |arg| {
459
471
if slab_available {
460
472
let mut vec = alloc:: vec:: Vec :: new ( ) ;
473
+ vec. try_reserve_exact ( arg. len ( ) ) . ok ( ) ?;
461
474
vec. extend_from_slice ( arg) ;
462
- StringParam :: Owned ( vec)
475
+ Some ( StringParam :: Owned ( vec) )
463
476
} else {
464
- StringParam :: Ref ( arg)
477
+ Some ( StringParam :: Ref ( arg) )
465
478
}
466
479
} )
467
480
}
0 commit comments