Changeset 7 for trunk/kernel/mm/ppm.c
- Timestamp:
- Apr 26, 2017, 2:15:50 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/ppm.c
r1 r7 91 91 static void ppm_free_pages_nolock( page_t * page ) 92 92 { 93 page_t * buddy; // searched buddy page descriptor 94 uint32_t buddy_index; // buddy page index 95 page_t * current; // current (merged) page descriptor 96 uint32_t current_index; // current (merged) page index 97 uint32_t current_order; // current (merget) page order 98 93 99 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 94 100 page_t * pages_tbl = ppm->pages_tbl; 95 uint32_t page_order = page->order; 96 uint32_t page_index = (uint32_t)(page - ppm->pages_tbl); 97 98 page_t * block; 99 uint32_t block_index; 100 uint32_t current_order; 101 102 // update page descriptor flag 101 102 // update released page descriptor flags 103 103 page_set_flag( page , PG_FREE ); 104 104 105 // update free_lists 106 for( current_order = page_order ; current_order < CONFIG_PPM_MAX_ORDER ; current_order++ ) 105 // search the buddy page descriptor 106 // - merge with current page descriptor if found 107 // - exit to release the current page descriptor if not found 108 current = page , 109 current_index = (uint32_t)(page - ppm->pages_tbl); 110 for( current_order = page->order ; 111 current_order < CONFIG_PPM_MAX_ORDER ; 112 current_order++ ) 107 113 { 108 block_index = page_index ^ (1 << current_order); 109 block = pages_tbl + block_index; 110 111 if( page_is_flag( block , PG_FREE ) || (block->order != current_order) ) break; 112 113 list_unlink( &block->list ); 114 buddy_index = current_index ^ (1 << current_order); 115 buddy = pages_tbl + buddy_index; 116 117 if( !page_is_flag( buddy , PG_FREE ) || (buddy->order != current_order) ) break; 118 119 // remove buddy from free list 120 list_unlink( &buddy->list ); 114 121 ppm->free_pages_nr[current_order] --; 115 122 ppm->total_free_pages -= (1 << current_order); 116 123 117 block->order = 0; 118 page_index &= block_index; 119 } 120 121 block = pages_tbl + page_index; 122 block->order = current_order; 123 124 list_add_first( &ppm->free_pages_root[current_order] , &block->list ); 124 // merge buddy with current 125 buddy->order = 0; 126 current_index &= buddy_index; 127 } 128 129 // update merged page descriptor order 130 current = pages_tbl + current_index; 131 current->order = current_order; 132 133 // insert current in free list 134 list_add_first( &ppm->free_pages_root[current_order] , ¤t->list ); 125 135 ppm->free_pages_nr[current_order] ++; 126 136 ppm->total_free_pages += (1 << current_order); … … 128 138 } // end ppm_free_pages_nolock() 129 139 130 ////////////////////////////// ///140 ////////////////////////////// 131 141 void ppm_init( ppm_t * ppm, 132 142 uint32_t pages_nr, // total pages number … … 148 158 ppm->free_pages_nr[i] = 0; 149 159 } 160 161 #if( CONFIG_PPM_DEBUG ) 162 ppm_print( ppm , "after reset" ); 163 #endif 150 164 151 165 // initialize dirty_list as empty … … 166 180 // set pages numbers 167 181 ppm->pages_nr = pages_nr; 168 ppm->pages_offset = pages_offset;182 ppm->pages_offset = reserved_pages; 169 183 170 184 // initialises all page descriptors in pages_tbl[] 171 // TODO Peut-on accélérer ces monstrueuses boucle ? [AG]172 185 for( i = 0 ; i < pages_nr ; i++ ) 173 186 { 174 187 page_init( &ppm->pages_tbl[i] ); 188 189 // TODO optimisation : make only a partial init [AG] 190 // complete the initialisation when page is allocated [AG] 191 // ppm->pages_tbl[i].flags = 0; 175 192 } 176 193 177 // set PG_RESERVED flag for reserved pages (kernel code & pages_tbl[]) 194 // - set PG_RESERVED flag for reserved pages (kernel code & pages_tbl[]) 195 // - release all other pages to populate the free lists 178 196 for( i = 0 ; i < reserved_pages ; i++) 179 197 { 180 198 page_set_flag( &ppm->pages_tbl[i] , PG_RESERVED ); 181 199 } 182 183 // initialise the free lists by releasing all non reserved pages 184 for( i = 0 ; i < pages_nr ; i++ ) 185 { 186 page_t * page = &ppm->pages_tbl[i]; 187 if( page_is_flag( page , PG_RESERVED) ) ppm_free_pages_nolock( page ); 188 } 200 for( i = reserved_pages ; i < pages_nr ; i++ ) 201 { 202 ppm_free_pages_nolock( &ppm->pages_tbl[i] ); 203 204 // TODO optimisation : decompose this enormous set of small pages 205 // to a set big pages with various order values 206 } 207 208 // check consistency 209 ppm_assert_order( ppm ); 210 211 kinit_dmsg("\n[INFO] %s : done in cluster %x at cycle %d\n", 212 __FUNCTION__ , local_cxy , hal_time_stamp() ); 213 214 #if( CONFIG_PPM_DEBUG ) 215 ppm_print( ppm , "after init" ); 216 #endif 217 189 218 } // end ppm_init() 190 219 … … 198 227 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 199 228 200 if( ppm->signature != PPM_SIGNATURE ) 201 { 202 printk("\n[PANIC] in %s : PPM non initialised in cluster %x\n", 203 __FUNCTION__ , local_cxy ); 204 hal_core_sleep(); 205 } 206 207 if( order >= CONFIG_PPM_MAX_ORDER ) 208 { 209 printk("\n[PANIC] in %s : illegal order argument in cluster %x\n", 210 __FUNCTION__ , local_cxy ); 211 hal_core_sleep(); 212 } 229 assert( (ppm->signature == PPM_SIGNATURE) , __FUNCTION__ , "PPM non initialised" ); 230 231 assert( (order < CONFIG_PPM_MAX_ORDER) , __FUNCTION__ , "illegal order argument" ); 213 232 214 233 page_t * block = NULL; 234 235 ppm_dmsg("\n[INFO] %s : enters / order = %d\n", 236 __FUNCTION__ , order ); 237 238 #if( CONFIG_PPM_DEBUG ) 239 ppm_print( ppm , "before allocation" ); 240 #endif 215 241 216 242 // take lock protecting free lists 217 243 spinlock_lock( &ppm->free_lock ); 218 244 219 // find a block larger or equalto requested size245 // find a free block equal or larger to requested size 220 246 for( current_order = order ; current_order < CONFIG_PPM_MAX_ORDER ; current_order ++ ) 221 247 { … … 264 290 spinlock_unlock( &ppm->free_lock ); 265 291 292 ppm_dmsg("\n[INFO] %s : base = %x / order = %d\n", 293 __FUNCTION__ , (uint32_t)ppm_page2base( block ) , order ); 294 295 #if CONFIG_PPM_DEBUG 296 ppm_print( ppm , "after allocation" ); 297 #endif 298 266 299 return block; 267 300 } // end pmm_alloc-pages() … … 282 315 } 283 316 284 ///////////////////////////// 285 void ppm_print( ppm_t * ppm ) 317 //////////////////////////// 318 void ppm_print( ppm_t * ppm, 319 char * string ) 286 320 { 287 321 uint32_t order; … … 292 326 spinlock_lock( &ppm->free_lock ); 293 327 294 printk(" *** PPM state in cluster %x: pages = %d / offset = %d / free = %d ***\n",295 local_cxy , ppm->pages_nr , ppm->pages_offset , ppm->total_free_pages );328 printk("\n*** PPM state in cluster %x %s : pages = %d / offset = %d / free = %d ***\n", 329 local_cxy , string , ppm->pages_nr , ppm->pages_offset , ppm->total_free_pages ); 296 330 297 331 for( order = 0 ; order < CONFIG_PPM_MAX_ORDER ; order++ ) 298 332 { 299 printk("- order = %d / free_pages = %d [ \n",333 printk("- order = %d / free_pages = %d [", 300 334 order , ppm->free_pages_nr[order] ); 301 335 … … 311 345 // release lock protecting free lists 312 346 spinlock_unlock( &ppm->free_lock ); 313 } 314 315 //////////////////////////////////////// 316 void ppm_assert_order(struct ppm_s *ppm) 347 348 } // end ppm_print() 349 350 //////////////////////////u///////// 351 void ppm_assert_order( ppm_t * ppm ) 317 352 { 318 353 uint32_t order; … … 328 363 page = LIST_ELEMENT( iter , page_t , list ); 329 364 330 if( page->order != order ) 331 { 332 printk("%s detected inconsistency at order %d, page %d\n", 333 __FUNCTION__, order , page - ppm->pages_tbl ); 334 } 365 assert( (page->order == order) , __FUNCTION__ , "PPM inconsistency" ); 335 366 } 336 367 } 337 return; 338 } 339 368 369 } // end ppm_assert_order() 370
Note: See TracChangeset
for help on using the changeset viewer.