x86: break up mtrr_cleanup() into several small functions.
authorYinghai Lu <yinghai@kernel.org>
Wed, 15 Oct 2008 01:59:18 +0000 (18:59 -0700)
committerIngo Molnar <mingo@elte.hu>
Tue, 28 Oct 2008 15:30:57 +0000 (16:30 +0100)
Ingo said mtrr_cleanup() is big and ugly.

so break it up into more functions and make it more readable.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/cpu/mtrr/main.c

index c78c04821ea18a58266b812fef480aa0b5ec0fbb..1159e269e596bc05d9b82d3ed633a434c67d1649 100644 (file)
@@ -803,6 +803,7 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_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,29 +1268,133 @@ static int __init mtrr_cleanup(unsigned address_bits)
                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;
 
-               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;
+       /* 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;
+       }
 
-               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"))
-                       );
+       if (!result[i].bad && (range_sums - range_sums_new <
+                               min_loss_pfn[num_reg])) {
+               min_loss_pfn[num_reg] =
+                       range_sums - range_sums_new;
        }
+}
+
+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;
@@ -1309,176 +1418,64 @@ static int __init mtrr_cleanup(unsigned address_bits)
               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(unsigned long end_pfn)
 {
        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 */