x86: break mtrr_cleanup() to several small functions.
PATCH 1/1 x86: break mtrr_cleanup() to several small functions.
Ingo said mtrr_cleanup() is some big and ugly.
so break it into more functions and make it more readable.
Signed-off-by Yinghai Lu <[email protected]>
--- arch/x86/kernel/cpu/mtrr/main.c | 346 +++++++++++++++++++--------------------- 1 file changed, 171 insertions(+), 175 deletions(-)
arch/x86/kernel/cpu/mtrr/main.c +171 -175
@@ -803,6 +803,7 @@ x86_get_mtrr_mem_range(struct res_range }static struct res_range __initdata range[RANGE_NUM ]; +static int __initdata nr_range;#ifdef CONFIG_MTRR_SANITIZER
@@ -1206,39 +1207,43 @@ struct mtrr_cleanup_result {#define PSHIFT (PAGE_SHIFT - 10)static struct mtrr_cleanup_result __initdata result[NUM_RESULT ]; -static struct res_range __initdata range_new[RANGE_NUM ];static unsigned long __initdata min_loss_pfn[RANGE_NUM ]; -static int __init mtrr_cleanup (unsigned address_bits) +static void __init print_out_mtrr_range_state (void ) { -unsigned long extra_remove_base, extra_remove_size; -unsigned long base, size, def, dummy; -mtrr_type type; -int nr_range, nr_range_new; -u64 chunk_size, gran_size; -unsigned long range_sums, range_sums_new; -int index_good; -int num_reg_good;int i; +char start_factor ='K' , size_factor ='K' ; +unsigned long start_base, size_base; +mtrr_type type; -/* extra one for all 0 */ -int num[MTRR_NUM_TYPES +1 ]; +for (i =0 ; i < num_var_ranges; i++) { -if (!is_cpu (INTEL ) || enable_mtrr_cleanup <1 ) -return 0 ; -rdmsr (MTRRdefType_MSR, def, dummy); - def &=0xff ; -if (def !=MTRR_TYPE_UNCACHABLE ) -return 0 ; + size_base = range_state[i].size_pfn << (PAGE_SHIFT -10 ); +if (!size_base) +continue ; -/* get it and store it aside */ -memset (range_state,0 ,sizeof (range_state)); -for (i =0 ; i < num_var_ranges; i++) { - mtrr_if->get (i, &base, &size, &type); - range_state[i].base_pfn = base; - range_state[i].size_pfn = size; - range_state[i].type = type; + size_base =to_size_factor (size_base, &size_factor), + start_base = range_state[i].base_pfn << (PAGE_SHIFT -10 ); + start_base =to_size_factor (start_base, &start_factor), + type = range_state[i].type; + +printk (KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n" , + i, start_base, start_factor, + size_base, size_factor, + (type ==MTRR_TYPE_UNCACHABLE ) ?"UC" : + ((type ==MTRR_TYPE_WRPROT ) ?"WP" : + ((type ==MTRR_TYPE_WRBACK ) ?"WB" :"Other" )) + ); } +} + +static int __init mtrr_need_cleanup (void ) +{ +int i; +mtrr_type type; +unsigned long size; +/* extra one for all 0 */ +int num[MTRR_NUM_TYPES +1 ];/* check entries number */ memset (num,0 ,sizeof (num));
@@ -1263,30 +1268,134 @@ static int __init mtrr_cleanup(unsigned num_var_ranges - num[MTRR_NUM_TYPES])return 0 ; -/* print original var MTRRs at first, for debugging: */ -printk (KERN_DEBUG "original variable MTRRs\n" ); -for (i =0 ; i < num_var_ranges; i++) { -char start_factor ='K' , size_factor ='K' ; -unsigned long start_base, size_base; +return 1 ; +} - size_base = range_state[i].size_pfn << (PAGE_SHIFT -10 ); -if (!size_base) -continue ; +static unsigned long __initdata range_sums; +static void __init mtrr_calc_range_state (u64 chunk_size,u64 gran_size, +unsigned long extra_remove_base, +unsigned long extra_remove_size, +int i) +{ +int num_reg; +static struct res_range range_new[RANGE_NUM ]; +static int nr_range_new; +unsigned long range_sums_new; + +/* convert ranges to var ranges state */ + num_reg =x86_setup_var_mtrrs (range, nr_range, + chunk_size, gran_size); + +/* we got new setting in range_state, check it */ +memset (range_new,0 ,sizeof (range_new)); + nr_range_new =x86_get_mtrr_mem_range (range_new,0 , + extra_remove_base, extra_remove_size); + range_sums_new =sum_ranges (range_new, nr_range_new); + + result[i].chunk_sizek = chunk_size >>10 ; + result[i].gran_sizek = gran_size >>10 ; + result[i].num_reg = num_reg; +if (range_sums < range_sums_new) { + result[i].lose_cover_sizek = + (range_sums_new - range_sums) <<PSHIFT ; + result[i].bad =1 ; + }else + result[i].lose_cover_sizek = + (range_sums - range_sums_new) <<PSHIFT ; + +/* double check it */ +if (!result[i].bad && !result[i].lose_cover_sizek) { +if (nr_range_new != nr_range || +memcmp (range, range_new,sizeof (range))) + result[i].bad =1 ; + } - size_base =to_size_factor (size_base, &size_factor), - start_base = range_state[i].base_pfn << (PAGE_SHIFT -10 ); - start_base =to_size_factor (start_base, &start_factor), - type = range_state[i].type; +if (!result[i].bad && (range_sums - range_sums_new < + min_loss_pfn[num_reg])) { + min_loss_pfn[num_reg] = + range_sums - range_sums_new; + } +} -printk (KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n" , - i, start_base, start_factor, - size_base, size_factor, - (type ==MTRR_TYPE_UNCACHABLE ) ?"UC" : - ((type ==MTRR_TYPE_WRPROT ) ?"WP" : - ((type ==MTRR_TYPE_WRBACK ) ?"WB" :"Other" )) - ); +static void __init mtrr_print_out_one_result (int i) +{ +char gran_factor, chunk_factor, lose_factor; +unsigned long gran_base, chunk_base, lose_base; + + gran_base =to_size_factor (result[i].gran_sizek, &gran_factor), + chunk_base =to_size_factor (result[i].chunk_sizek, &chunk_factor), + lose_base =to_size_factor (result[i].lose_cover_sizek, &lose_factor), +printk (KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t" , + result[i].bad ?"*BAD*" :" " , + gran_base, gran_factor, chunk_base, chunk_factor); +printk (KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n" , + result[i].num_reg, result[i].bad ?"-" :"" , + lose_base, lose_factor); +} + +static int __init mtrr_search_optimal_index (void ) +{ +int i; +int num_reg_good; +int index_good; + +if (nr_mtrr_spare_reg >= num_var_ranges) + nr_mtrr_spare_reg = num_var_ranges -1 ; + num_reg_good =-1 ; +for (i = num_var_ranges - nr_mtrr_spare_reg; i >0 ; i--) { +if (!min_loss_pfn[i]) + num_reg_good = i; + } + + index_good =-1 ; +if (num_reg_good !=-1 ) { +for (i =0 ; i <NUM_RESULT ; i++) { +if (!result[i].bad && + result[i].num_reg == num_reg_good && + !result[i].lose_cover_sizek) { + index_good = i; +break ; + } + } + } + +return index_good; +} + + +static int __init mtrr_cleanup (unsigned address_bits) +{ +unsigned long extra_remove_base, extra_remove_size; +unsigned long base, size, def, dummy; +mtrr_type type; +u64 chunk_size, gran_size; +int index_good; +int i; + +if (!is_cpu (INTEL ) || enable_mtrr_cleanup <1 ) +return 0 ; +rdmsr (MTRRdefType_MSR, def, dummy); + def &=0xff ; +if (def !=MTRR_TYPE_UNCACHABLE ) +return 0 ; + +/* get it and store it aside */ +memset (range_state,0 ,sizeof (range_state)); +for (i =0 ; i < num_var_ranges; i++) { + mtrr_if->get (i, &base, &size, &type); + range_state[i].base_pfn = base; + range_state[i].size_pfn = size; + range_state[i].type = type; } +/* check if we need handle it and can handle it */ +if (!mtrr_need_cleanup ()) +return 0 ; + +/* print original var MTRRs at first, for debugging: */ +printk (KERN_DEBUG "original variable MTRRs\n" ); +print_out_mtrr_range_state (); +memset (range,0 ,sizeof (range)); extra_remove_size =0 ; extra_remove_base =1 << (32 -PAGE_SHIFT );
@@ -1309,176 +1418,64 @@ static int __init mtrr_cleanup(unsigned range_sums >> (20 - PAGE_SHIFT));if (mtrr_chunk_size && mtrr_gran_size) { -int num_reg; -char gran_factor, chunk_factor, lose_factor; -unsigned long gran_base, chunk_base, lose_base; - - debug_print++; -/* convert ranges to var ranges state */ - num_reg =x86_setup_var_mtrrs (range, nr_range, mtrr_chunk_size, - mtrr_gran_size); + i =0 ; +mtrr_calc_range_state (mtrr_chunk_size, mtrr_gran_size, + extra_remove_base, extra_remove_size, i); -/* we got new setting in range_state, check it */ -memset (range_new,0 ,sizeof (range_new)); - nr_range_new =x86_get_mtrr_mem_range (range_new,0 , - extra_remove_base, - extra_remove_size); - range_sums_new =sum_ranges (range_new, nr_range_new); +mtrr_print_out_one_result (i); - i =0 ; - result[i].chunk_sizek = mtrr_chunk_size >>10 ; - result[i].gran_sizek = mtrr_gran_size >>10 ; - result[i].num_reg = num_reg; -if (range_sums < range_sums_new) { - result[i].lose_cover_sizek = - (range_sums_new - range_sums) <<PSHIFT ; - result[i].bad =1 ; - }else - result[i].lose_cover_sizek = - (range_sums - range_sums_new) <<PSHIFT ; - - gran_base =to_size_factor (result[i].gran_sizek, &gran_factor), - chunk_base =to_size_factor (result[i].chunk_sizek, &chunk_factor), - lose_base =to_size_factor (result[i].lose_cover_sizek, &lose_factor), -printk (KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t" , - result[i].bad?"*BAD*" :" " , - gran_base, gran_factor, chunk_base, chunk_factor); -printk (KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n" , - result[i].num_reg, result[i].bad?"-" :"" , - lose_base, lose_factor);if (!result[i].bad) {set_var_mtrr_all (address_bits);return 1 ; }printk (KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, " "will find optimal one\n" ); - debug_print--; -memset (result,0 ,sizeof (result[0 ])); } i =0 ;memset (min_loss_pfn,0xff ,sizeof (min_loss_pfn));memset (result,0 ,sizeof (result));for (gran_size = (1ULL <<16 ); gran_size < (1ULL <<32 ); gran_size <<=1 ) { -char gran_factor; -unsigned long gran_base; - -if (debug_print) - gran_base =to_size_factor (gran_size >>10 , &gran_factor);for (chunk_size = gran_size; chunk_size < (1ULL <<32 ); chunk_size <<=1 ) { -int num_reg; -if (debug_print) { -char chunk_factor; -unsigned long chunk_base; - - chunk_base =to_size_factor (chunk_size>>10 , &chunk_factor), -printk (KERN_INFO "\n" ); -printk (KERN_INFO "gran_size: %ld%c chunk_size: %ld%c \n" , - gran_base, gran_factor, chunk_base, chunk_factor); - }if (i >=NUM_RESULT )continue ; -/* convert ranges to var ranges state */ - num_reg =x86_setup_var_mtrrs (range, nr_range, - chunk_size, gran_size); - -/* we got new setting in range_state, check it */ -memset (range_new,0 ,sizeof (range_new)); - nr_range_new =x86_get_mtrr_mem_range (range_new,0 , - extra_remove_base, extra_remove_size); - range_sums_new =sum_ranges (range_new, nr_range_new); - - result[i].chunk_sizek = chunk_size >>10 ; - result[i].gran_sizek = gran_size >>10 ; - result[i].num_reg = num_reg; -if (range_sums < range_sums_new) { - result[i].lose_cover_sizek = - (range_sums_new - range_sums) <<PSHIFT ; - result[i].bad =1 ; - }else - result[i].lose_cover_sizek = - (range_sums - range_sums_new) <<PSHIFT ; - -/* double check it */ -if (!result[i].bad && !result[i].lose_cover_sizek) { -if (nr_range_new != nr_range || -memcmp (range, range_new,sizeof (range))) - result[i].bad =1 ; +mtrr_calc_range_state (chunk_size, gran_size, + extra_remove_base, extra_remove_size, i); +if (debug_print) { +mtrr_print_out_one_result (i); +printk (KERN_INFO "\n" ); } -if (!result[i].bad && (range_sums - range_sums_new < - min_loss_pfn[num_reg])) { - min_loss_pfn[num_reg] = - range_sums - range_sums_new; - } i++; } } -/* print out all */ -for (i =0 ; i <NUM_RESULT ; i++) { -char gran_factor, chunk_factor, lose_factor; -unsigned long gran_base, chunk_base, lose_base; - - gran_base =to_size_factor (result[i].gran_sizek, &gran_factor), - chunk_base =to_size_factor (result[i].chunk_sizek, &chunk_factor), - lose_base =to_size_factor (result[i].lose_cover_sizek, &lose_factor), -printk (KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t" , - result[i].bad?"*BAD*" :" " , - gran_base, gran_factor, chunk_base, chunk_factor); -printk (KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n" , - result[i].num_reg, result[i].bad?"-" :"" , - lose_base, lose_factor); - } -/* try to find the optimal index */ -if (nr_mtrr_spare_reg >= num_var_ranges) - nr_mtrr_spare_reg = num_var_ranges -1 ; - num_reg_good =-1 ; -for (i = num_var_ranges - nr_mtrr_spare_reg; i >0 ; i--) { -if (!min_loss_pfn[i]) - num_reg_good = i; - } - - index_good =-1 ; -if (num_reg_good !=-1 ) { -for (i =0 ; i <NUM_RESULT ; i++) { -if (!result[i].bad && - result[i].num_reg == num_reg_good && - !result[i].lose_cover_sizek) { - index_good = i; -break ; - } - } - } + index_good =mtrr_search_optimal_index ();if (index_good !=-1 ) { -char gran_factor, chunk_factor, lose_factor; -unsigned long gran_base, chunk_base, lose_base; -printk (KERN_INFO "Found optimal setting for mtrr clean up\n" ); i = index_good; - gran_base =to_size_factor (result[i].gran_sizek, &gran_factor), - chunk_base =to_size_factor (result[i].chunk_sizek, &chunk_factor), - lose_base =to_size_factor (result[i].lose_cover_sizek, &lose_factor), -printk (KERN_INFO "gran_size: %ld%c \tchunk_size: %ld%c \t" , - gran_base, gran_factor, chunk_base, chunk_factor); -printk (KERN_CONT "num_reg: %d \tlose RAM: %ld%c\n" , - result[i].num_reg, lose_base, lose_factor); +mtrr_print_out_one_result (i); +/* convert ranges to var ranges state */ chunk_size = result[i].chunk_sizek; chunk_size <<=10 ; gran_size = result[i].gran_sizek; gran_size <<=10 ; - debug_print++;x86_setup_var_mtrrs (range, nr_range, chunk_size, gran_size); - debug_print--;set_var_mtrr_all (address_bits); +printk (KERN_DEBUG "New variable MTRRs\n" ); +print_out_mtrr_range_state ();return 1 ; + }else { +/* print out all */ +for (i =0 ; i <NUM_RESULT ; i++) +mtrr_print_out_one_result (i); }printk (KERN_INFO "mtrr_cleanup: can not find optimal value\n" );
@@ -1562,7 +1559,6 @@ int __init mtrr_trim_uncached_memory(uns {unsigned long i, base, size, highest_pfn =0 , def, dummy;mtrr_type type; -int nr_range;u64 total_trim_size;/* extra one for all 0 */