diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-09-27 23:26:06 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-09-28 03:12:27 -0400 |
commit | 8f0afaa58e912bbe7d5b0bad9fb024337edf363e (patch) | |
tree | 11d5a33258fb4871958bf5d50b0ce5494aaac56f /arch/x86/kernel/cpu/mtrr/main.c | |
parent | 54d45ff4208836e62536fc40b0141586dbf6641f (diff) |
x86: mtrr_cleanup hole size should be less than half of chunk_size, v2
v2: should check with half of range0 size instead of chunk_size
So don't have silly big hole.
in hpa's case we could auto detect instead of adding mtrr_chunk_size in
command line.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/cpu/mtrr/main.c')
-rw-r--r-- | arch/x86/kernel/cpu/mtrr/main.c | 74 |
1 files changed, 43 insertions, 31 deletions
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index aff46b99ff01..bccf57f5b615 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c | |||
@@ -992,22 +992,17 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek, | |||
992 | /* only cut back, when it is not the last */ | 992 | /* only cut back, when it is not the last */ |
993 | if (sizek) { | 993 | if (sizek) { |
994 | while (range0_basek + range0_sizek > (basek + sizek)) { | 994 | while (range0_basek + range0_sizek > (basek + sizek)) { |
995 | range0_sizek -= chunk_sizek; | 995 | if (range0_sizek >= chunk_sizek) |
996 | range0_sizek -= chunk_sizek; | ||
997 | else | ||
998 | range0_sizek = 0; | ||
999 | |||
996 | if (!range0_sizek) | 1000 | if (!range0_sizek) |
997 | break; | 1001 | break; |
998 | } | 1002 | } |
999 | } | 1003 | } |
1000 | 1004 | ||
1001 | if (range0_sizek) { | 1005 | second_try: |
1002 | if (debug_print) | ||
1003 | printk(KERN_DEBUG "range0: %016lx - %016lx\n", | ||
1004 | range0_basek<<10, | ||
1005 | (range0_basek + range0_sizek)<<10); | ||
1006 | state->reg = range_to_mtrr(state->reg, range0_basek, | ||
1007 | range0_sizek, MTRR_TYPE_WRBACK); | ||
1008 | |||
1009 | } | ||
1010 | |||
1011 | range_basek = range0_basek + range0_sizek; | 1006 | range_basek = range0_basek + range0_sizek; |
1012 | 1007 | ||
1013 | /* one hole in the middle */ | 1008 | /* one hole in the middle */ |
@@ -1015,33 +1010,50 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek, | |||
1015 | second_sizek = range_basek - basek; | 1010 | second_sizek = range_basek - basek; |
1016 | 1011 | ||
1017 | if (range0_sizek > state->range_sizek) { | 1012 | if (range0_sizek > state->range_sizek) { |
1018 | unsigned long hole_basek, hole_sizek; | ||
1019 | 1013 | ||
1020 | /* one hole in middle or at end */ | 1014 | /* one hole in middle or at end */ |
1021 | hole_sizek = range0_sizek - state->range_sizek - second_sizek; | 1015 | hole_sizek = range0_sizek - state->range_sizek - second_sizek; |
1022 | if (hole_sizek) { | 1016 | |
1023 | hole_basek = range_basek - hole_sizek - second_sizek; | 1017 | /* hole size should be less than half of range0 size */ |
1024 | if (debug_print) | 1018 | if (hole_sizek > (range0_sizek >> 1) && |
1025 | printk(KERN_DEBUG "hole: %016lx - %016lx\n", | 1019 | range0_sizek >= chunk_sizek) { |
1026 | hole_basek<<10, | 1020 | range0_sizek -= chunk_sizek; |
1027 | (hole_basek + hole_sizek)<<10); | 1021 | second_sizek = 0; |
1028 | state->reg = range_to_mtrr(state->reg, hole_basek, | 1022 | hole_sizek = 0; |
1029 | hole_sizek, | 1023 | |
1030 | MTRR_TYPE_UNCACHABLE); | 1024 | goto second_try; |
1031 | } | 1025 | } |
1032 | } else { | 1026 | } |
1027 | |||
1028 | if (range0_sizek) { | ||
1029 | if (debug_print) | ||
1030 | printk(KERN_DEBUG "range0: %016lx - %016lx\n", | ||
1031 | range0_basek<<10, | ||
1032 | (range0_basek + range0_sizek)<<10); | ||
1033 | state->reg = range_to_mtrr(state->reg, range0_basek, | ||
1034 | range0_sizek, MTRR_TYPE_WRBACK); | ||
1035 | } | ||
1036 | |||
1037 | if (range0_sizek < state->range_sizek) { | ||
1033 | /* need to handle left over */ | 1038 | /* need to handle left over */ |
1034 | range_sizek = state->range_sizek - range0_sizek; | 1039 | range_sizek = state->range_sizek - range0_sizek; |
1035 | 1040 | ||
1036 | if (range_sizek) { | 1041 | if (debug_print) |
1037 | if (debug_print) | 1042 | printk(KERN_DEBUG "range: %016lx - %016lx\n", |
1038 | printk(KERN_DEBUG "range: %016lx - %016lx\n", | 1043 | range_basek<<10, |
1039 | range_basek<<10, | 1044 | (range_basek + range_sizek)<<10); |
1040 | (range_basek + range_sizek)<<10); | 1045 | state->reg = range_to_mtrr(state->reg, range_basek, |
1041 | state->reg = range_to_mtrr(state->reg, range_basek, | 1046 | range_sizek, MTRR_TYPE_WRBACK); |
1042 | range_sizek, | 1047 | } |
1043 | MTRR_TYPE_WRBACK); | 1048 | |
1044 | } | 1049 | if (hole_sizek) { |
1050 | hole_basek = range_basek - hole_sizek - second_sizek; | ||
1051 | if (debug_print) | ||
1052 | printk(KERN_DEBUG "hole: %016lx - %016lx\n", | ||
1053 | hole_basek<<10, | ||
1054 | (hole_basek + hole_sizek)<<10); | ||
1055 | state->reg = range_to_mtrr(state->reg, hole_basek, | ||
1056 | hole_sizek, MTRR_TYPE_UNCACHABLE); | ||
1045 | } | 1057 | } |
1046 | 1058 | ||
1047 | return second_sizek; | 1059 | return second_sizek; |