aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-09-27 03:30:08 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-27 12:09:34 -0400
commit2313c2793d290a8cc37c428f8622c53f3fe1d6dc (patch)
tree7c58eadcd07a5b51defac8b455b75e0e72d09c42 /arch
parent7fc2368d1d0dce7a778beb2fba3acac8fa7a34b6 (diff)
x86: mtrr_cleanup optimization, v2
fix hpa's t61 with 4g ram: change layout from (n - 1)*chunksize + chunk_size - NC to n*chunksize - NC Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c79
1 files changed, 37 insertions, 42 deletions
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index cc135572882a..93d575ac61a3 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -970,6 +970,8 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
970 /* try to append some small hole */ 970 /* try to append some small hole */
971 range0_basek = state->range_startk; 971 range0_basek = state->range_startk;
972 range0_sizek = ALIGN(state->range_sizek, chunk_sizek); 972 range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
973
974 /* no increase */
973 if (range0_sizek == state->range_sizek) { 975 if (range0_sizek == state->range_sizek) {
974 if (debug_print) 976 if (debug_print)
975 printk(KERN_DEBUG "rangeX: %016lx - %016lx\n", 977 printk(KERN_DEBUG "rangeX: %016lx - %016lx\n",
@@ -980,13 +982,13 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
980 return 0; 982 return 0;
981 } 983 }
982 984
983 range0_sizek -= chunk_sizek; 985 /* only cut back, when it is not the last */
984 if (range0_sizek && sizek) { 986 if (sizek) {
985 while (range0_basek + range0_sizek > (basek + sizek)) { 987 while (range0_basek + range0_sizek > (basek + sizek)) {
986 range0_sizek -= chunk_sizek; 988 range0_sizek -= chunk_sizek;
987 if (!range0_sizek) 989 if (!range0_sizek)
988 break; 990 break;
989 } 991 }
990 } 992 }
991 993
992 if (range0_sizek) { 994 if (range0_sizek) {
@@ -1000,46 +1002,39 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
1000 } 1002 }
1001 1003
1002 range_basek = range0_basek + range0_sizek; 1004 range_basek = range0_basek + range0_sizek;
1003 range_sizek = chunk_sizek;
1004 1005
1005 if (range_basek + range_sizek > basek && 1006 /* one hole in the middle */
1006 range_basek + range_sizek <= (basek + sizek)) { 1007 if (range_basek > basek && range_basek <= (basek + sizek))
1007 /* one hole */ 1008 second_sizek = range_basek - basek;
1008 second_basek = basek;
1009 second_sizek = range_basek + range_sizek - basek;
1010 }
1011 1009
1012 /* if last piece, only could one hole near end */ 1010 if (range0_sizek > state->range_sizek) {
1013 if ((second_basek || !basek) && 1011 unsigned long hole_basek, hole_sizek;
1014 range_sizek - (state->range_sizek - range0_sizek) - second_sizek < 1012
1015 (chunk_sizek >> 1)) { 1013 /* one hole in middle or at end */
1016 /* 1014 hole_sizek = range0_sizek - state->range_sizek - second_sizek;
1017 * one hole in middle (second_sizek is 0) or at end 1015 if (hole_sizek) {
1018 * (second_sizek is 0 ) 1016 hole_basek = range_basek - hole_sizek - second_sizek;
1019 */ 1017 if (debug_print)
1020 hole_sizek = range_sizek - (state->range_sizek - range0_sizek) 1018 printk(KERN_DEBUG "hole: %016lx - %016lx\n",
1021 - second_sizek; 1019 hole_basek<<10,
1022 hole_basek = range_basek + range_sizek - hole_sizek 1020 (hole_basek + hole_sizek)<<10);
1023 - second_sizek; 1021 state->reg = range_to_mtrr(state->reg, hole_basek,
1024 } else { 1022 hole_sizek,
1025 /* fallback for big hole, or several holes */ 1023 MTRR_TYPE_UNCACHABLE);
1024 }
1025 } else {
1026 /* need to handle left over */
1026 range_sizek = state->range_sizek - range0_sizek; 1027 range_sizek = state->range_sizek - range0_sizek;
1027 second_basek = 0;
1028 second_sizek = 0;
1029 }
1030 1028
1031 if (debug_print) 1029 if (range_sizek) {
1032 printk(KERN_DEBUG "range: %016lx - %016lx\n", range_basek<<10, 1030 if (debug_print)
1033 (range_basek + range_sizek)<<10); 1031 printk(KERN_DEBUG "range: %016lx - %016lx\n",
1034 state->reg = range_to_mtrr(state->reg, range_basek, range_sizek, 1032 range_basek<<10,
1033 (range_basek + range_sizek)<<10);
1034 state->reg = range_to_mtrr(state->reg, range_basek,
1035 range_sizek,
1035 MTRR_TYPE_WRBACK); 1036 MTRR_TYPE_WRBACK);
1036 if (hole_sizek) { 1037 }
1037 if (debug_print)
1038 printk(KERN_DEBUG "hole: %016lx - %016lx\n",
1039 hole_basek<<10, (hole_basek + hole_sizek)<<10);
1040 state->reg = range_to_mtrr(state->reg, hole_basek, hole_sizek,
1041 MTRR_TYPE_UNCACHABLE);
1042
1043 } 1038 }
1044 1039
1045 return second_sizek; 1040 return second_sizek;