@@ -490,23 +490,43 @@ fn main() -> ExitCode {
490490}
491491
492492/// What the posture does in an environment: the knobs it sets (each posture
493- /// knob the environment leaves unset) and the ones the environment already
494- /// sets .
493+ /// knob the environment leaves unset), the ones the environment already sets,
494+ /// and notes on the knobs it set to something other than the table's value .
495495struct PosturePlan {
496496 set : Vec < ( & ' static str , & ' static str ) > ,
497497 env : Vec < String > ,
498+ notes : Vec < String > ,
498499}
499500
500- fn posture_plan ( env : impl Fn ( & str ) -> Option < String > ) -> PosturePlan {
501+ /// The posture against the environment `env` and the host `target` (bytes):
502+ /// the precomputed-tree cache's cap follows the target
503+ /// ([`prover::lfm::whir_block_tree::posture_tree_cache_cap`]).
504+ fn posture_plan ( env : impl Fn ( & str ) -> Option < String > , target : impl Fn ( ) -> u64 ) -> PosturePlan {
505+ use prover:: lfm:: whir_block_tree:: { POSTURE , POSTURE_TREE_CACHE_KNOB , posture_tree_cache_cap} ;
501506 let mut plan = PosturePlan {
502507 set : Vec :: new ( ) ,
503508 env : Vec :: new ( ) ,
509+ notes : Vec :: new ( ) ,
504510 } ;
505- for & ( name, value) in prover:: lfm:: whir_block_tree:: POSTURE {
506- match env ( name) {
507- Some ( v) => plan. env . push ( format ! ( "{name}={v}" ) ) ,
508- None => plan. set . push ( ( name, value) ) ,
511+ for & ( name, value) in POSTURE {
512+ if let Some ( v) = env ( name) {
513+ plan. env . push ( format ! ( "{name}={v}" ) ) ;
514+ continue ;
515+ }
516+ if name == POSTURE_TREE_CACHE_KNOB {
517+ let target = target ( ) ;
518+ let cap = posture_tree_cache_cap ( target) ;
519+ if cap != value {
520+ plan. notes . push ( format ! (
521+ "BLOCK POSTURE: {name}={cap}, not {value}: the host target is {:.1} GiB \
522+ (LAMBDA_VM_BLOCK_SPILL_TARGET_GIB, else the cgroup or MemTotal less 10 GiB)",
523+ target as f64 / ( 1u64 << 30 ) as f64
524+ ) ) ;
525+ }
526+ plan. set . push ( ( name, cap) ) ;
527+ continue ;
509528 }
529+ plan. set . push ( ( name, value) ) ;
510530 }
511531 plan
512532}
@@ -520,7 +540,10 @@ fn posture_plan(env: impl Fn(&str) -> Option<String>) -> PosturePlan {
520540///
521541/// Sets environment variables: no other thread may exist.
522542unsafe fn apply_posture ( ) -> Vec < String > {
523- let plan = posture_plan ( |name| std:: env:: var ( name) . ok ( ) ) ;
543+ let plan = posture_plan (
544+ |name| std:: env:: var ( name) . ok ( ) ,
545+ prover:: block_whir:: spill_target_bytes,
546+ ) ;
524547 for ( name, value) in & plan. set {
525548 // SAFETY: the caller's: no other thread exists.
526549 unsafe { std:: env:: set_var ( name, value) } ;
@@ -537,11 +560,13 @@ unsafe fn apply_posture() -> Vec<String> {
537560 w. join ( " " )
538561 }
539562 } ;
540- vec ! [ format!(
563+ let mut lines = vec ! [ format!(
541564 "BLOCK POSTURE SET: {} · from the environment: {} · jemalloc: {decay}" ,
542565 words( plan. set. iter( ) . map( |( n, v) | format!( "{n}={v}" ) ) . collect( ) ) ,
543566 words( plan. env) ,
544- ) ]
567+ ) ] ;
568+ lines. extend ( plan. notes ) ;
569+ lines
545570}
546571
547572fn hex ( bytes : & [ u8 ] ) -> String {
@@ -1677,14 +1702,37 @@ mod tests {
16771702 #[ test]
16781703 fn the_posture_sets_only_unset_knobs ( ) {
16791704 use prover:: lfm:: whir_block_tree:: POSTURE ;
1680- let all = posture_plan ( |_| None ) ;
1705+ let roomy = || 110u64 << 30 ;
1706+ let all = posture_plan ( |_| None , roomy) ;
16811707 assert_eq ! ( all. set, POSTURE . to_vec( ) ) ;
1682- assert ! ( all. env. is_empty( ) ) ;
1683- let mine = posture_plan ( |n| ( n == "TABLE_PARALLELISM" ) . then ( || "8" . to_string ( ) ) ) ;
1708+ assert ! ( all. env. is_empty( ) && all. notes. is_empty( ) ) ;
1709+ let mine = posture_plan (
1710+ |n| ( n == "TABLE_PARALLELISM" ) . then ( || "8" . to_string ( ) ) ,
1711+ roomy,
1712+ ) ;
16841713 assert ! ( mine. set. iter( ) . all( |( n, _) | * n != "TABLE_PARALLELISM" ) ) ;
16851714 assert_eq ! ( mine. env, vec![ "TABLE_PARALLELISM=8" . to_string( ) ] ) ;
16861715 }
16871716
1717+ /// The precomputed-tree cache's posture follows the host target: 64
1718+ /// entries from a 64 GiB target up, 16 below it (with a note), and a value
1719+ /// the environment sets is left alone.
1720+ #[ test]
1721+ fn the_tree_cache_posture_follows_the_host_target ( ) {
1722+ use prover:: lfm:: whir_block_tree:: POSTURE_TREE_CACHE_KNOB as CAP ;
1723+ let none = |_: & str | None ;
1724+ let cap = |plan : & PosturePlan | plan. set . iter ( ) . find ( |( n, _) | * n == CAP ) . map ( |( _, v) | * v) ;
1725+ let big = posture_plan ( none, || 64u64 << 30 ) ;
1726+ assert_eq ! ( cap( & big) , Some ( "64" ) ) ;
1727+ assert ! ( big. notes. is_empty( ) ) ;
1728+ let small = posture_plan ( none, || 38u64 << 30 ) ;
1729+ assert_eq ! ( cap( & small) , Some ( "16" ) ) ;
1730+ assert_eq ! ( small. notes. len( ) , 1 , "the note says why" ) ;
1731+ let set = posture_plan ( |n| ( n == CAP ) . then ( || "32" . to_string ( ) ) , || 38u64 << 30 ) ;
1732+ assert_eq ! ( cap( & set) , None , "the environment's value stays" ) ;
1733+ assert_eq ! ( set. env, vec![ format!( "{CAP}=32" ) ] ) ;
1734+ }
1735+
16881736 /// The binary runs the allocator posture it compiles in: jemalloc never
16891737 /// purges (`opt.dirty_decay_ms` and `opt.muzzy_decay_ms` are -1), unless
16901738 /// `_RJEM_MALLOC_CONF` says otherwise. Deleting the `malloc_conf` export
0 commit comments