11use crate :: { error, NonNegativeInteger } ;
2+ use bottlerocket_scalar_derive:: Scalar ;
23use bottlerocket_string_impls_for:: string_impls_for;
34use lazy_static:: lazy_static;
45use regex:: Regex ;
@@ -9,6 +10,8 @@ use std::collections::HashMap;
910/// HugepagesSettings contains hugepages and transparent hugepages related settings.
1011#[ derive( Debug , Clone , PartialEq , Default , Serialize , Deserialize ) ]
1112pub struct HugepagesSettings {
13+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
14+ pub transparent : Option < HugepagesTransparent > ,
1215 #[ serde( flatten) ]
1316 pub hugepages_config : HashMap < HugepageSize , HugepageConfig > ,
1417}
@@ -92,6 +95,86 @@ impl TryFrom<&str> for HugepageSize {
9295
9396string_impls_for ! ( HugepageSize , "HugepageSize" ) ;
9497
98+ /// Supported transparent hugepages knobs in Bottlerocket
99+ #[ derive( Debug , Clone , PartialEq , Default , Serialize , Deserialize ) ]
100+ pub struct HugepagesTransparent {
101+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
102+ pub enabled : Option < TransparentHugepagePolicy > ,
103+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
104+ pub defrag : Option < TransparentHugepageDefragPolicy > ,
105+ }
106+
107+ /// Acceptable transparent hugepages policies
108+ #[ derive( Debug , Clone , Eq , PartialEq , Hash , Serialize , Deserialize , Scalar , Default ) ]
109+ #[ serde( rename_all = "lowercase" ) ]
110+ pub enum TransparentHugepagePolicy {
111+ #[ default]
112+ Never ,
113+ Madvise ,
114+ Always ,
115+ }
116+
117+ #[ cfg( test) ]
118+ mod test_thp_policy {
119+ use super :: TransparentHugepagePolicy ;
120+ use std:: convert:: TryFrom ;
121+ use test_case:: test_case;
122+
123+ #[ test_case( "never" ) ]
124+ #[ test_case( "madvise" ) ]
125+ #[ test_case( "always" ) ]
126+ fn good_policy ( input : & str ) {
127+ assert ! ( TransparentHugepagePolicy :: try_from( input) . is_ok( ) ) ;
128+ }
129+
130+ #[ test_case( "disable" ) ]
131+ #[ test_case( "enable" ) ]
132+ #[ test_case( "" ) ]
133+ #[ test_case( "sometimes" ) ]
134+ #[ test_case( & "a" . repeat( 64 ) ) ]
135+ fn bad_policy ( input : & str ) {
136+ assert ! ( TransparentHugepagePolicy :: try_from( input) . is_err( ) ) ;
137+ }
138+ }
139+
140+ /// Acceptable transparent hugepages defragmentation policies
141+ #[ derive( Debug , Clone , Eq , PartialEq , Hash , Serialize , Deserialize , Scalar , Default ) ]
142+ #[ serde( rename_all = "lowercase" ) ]
143+ pub enum TransparentHugepageDefragPolicy {
144+ #[ default]
145+ Never ,
146+ Madvise ,
147+ Defer ,
148+ #[ serde( rename = "defer+madvise" ) ]
149+ DeferMadvise ,
150+ Always ,
151+ }
152+
153+ #[ cfg( test) ]
154+ mod test_thp_defrag_policy {
155+ use super :: TransparentHugepageDefragPolicy ;
156+ use std:: convert:: TryFrom ;
157+ use test_case:: test_case;
158+
159+ #[ test_case( "never" ) ]
160+ #[ test_case( "madvise" ) ]
161+ #[ test_case( "defer" ) ]
162+ #[ test_case( "defer+madvise" ) ]
163+ #[ test_case( "always" ) ]
164+ fn good_policy ( input : & str ) {
165+ assert ! ( TransparentHugepageDefragPolicy :: try_from( input) . is_ok( ) ) ;
166+ }
167+
168+ #[ test_case( "disable" ) ]
169+ #[ test_case( "enable" ) ]
170+ #[ test_case( "" ) ]
171+ #[ test_case( "sometimes" ) ]
172+ #[ test_case( & "a" . repeat( 64 ) ) ]
173+ fn bad_policy ( input : & str ) {
174+ assert ! ( TransparentHugepageDefragPolicy :: try_from( input) . is_err( ) ) ;
175+ }
176+ }
177+
95178#[ cfg( test) ]
96179mod test_hugepage_size {
97180 use super :: HugepageSize ;
0 commit comments