@@ -547,49 +547,44 @@ static void store_slot_info(struct mem_vector *region, unsigned long image_size)
547547static void
548548process_gb_huge_pages (struct mem_vector * region , unsigned long image_size )
549549{
550- unsigned long addr , size = 0 ;
550+ unsigned long pud_start , pud_end , gb_huge_pages ;
551551 struct mem_vector tmp ;
552- int i = 0 ;
553552
554553 if (!IS_ENABLED (CONFIG_X86_64 ) || !max_gb_huge_pages ) {
555554 store_slot_info (region , image_size );
556555 return ;
557556 }
558557
559- addr = ALIGN (region -> start , PUD_SIZE );
560- /* Did we raise the address above the passed in memory entry? */
561- if (addr < region -> start + region -> size )
562- size = region -> size - (addr - region -> start );
563-
564- /* Check how many 1GB huge pages can be filtered out: */
565- while (size >= PUD_SIZE && max_gb_huge_pages ) {
566- size -= PUD_SIZE ;
567- max_gb_huge_pages -- ;
568- i ++ ;
569- }
558+ /* Are there any 1GB pages in the region? */
559+ pud_start = ALIGN (region -> start , PUD_SIZE );
560+ pud_end = ALIGN_DOWN (region -> start + region -> size , PUD_SIZE );
570561
571562 /* No good 1GB huge pages found: */
572- if (! i ) {
563+ if (pud_start >= pud_end ) {
573564 store_slot_info (region , image_size );
574565 return ;
575566 }
576567
577- /*
578- * Skip those 'i'*1GB good huge pages, and continue checking and
579- * processing the remaining head or tail part of the passed region
580- * if available.
581- */
582-
583- if (addr >= region -> start + image_size ) {
568+ /* Check if the head part of the region is usable. */
569+ if (pud_start >= region -> start + image_size ) {
584570 tmp .start = region -> start ;
585- tmp .size = addr - region -> start ;
571+ tmp .size = pud_start - region -> start ;
586572 store_slot_info (& tmp , image_size );
587573 }
588574
589- size = region -> size - (addr - region -> start ) - i * PUD_SIZE ;
590- if (size >= image_size ) {
591- tmp .start = addr + i * PUD_SIZE ;
592- tmp .size = size ;
575+ /* Skip the good 1GB pages. */
576+ gb_huge_pages = (pud_end - pud_start ) >> PUD_SHIFT ;
577+ if (gb_huge_pages > max_gb_huge_pages ) {
578+ pud_end = pud_start + (max_gb_huge_pages << PUD_SHIFT );
579+ max_gb_huge_pages = 0 ;
580+ } else {
581+ max_gb_huge_pages -= gb_huge_pages ;
582+ }
583+
584+ /* Check if the tail part of the region is usable. */
585+ if (region -> start + region -> size >= pud_end + image_size ) {
586+ tmp .start = pud_end ;
587+ tmp .size = region -> start + region -> size - pud_end ;
593588 store_slot_info (& tmp , image_size );
594589 }
595590}
0 commit comments