From: Yinghai Lu <yhlu.kernel.send@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>,
Ingo Molnar <mingo@elte.hu>, "H. Peter Anvin" <hpa@zytor.com>,
Thomas Gleixner <tglx@linutronix.de>,
Gabriel C <nix.or.die@googlemail.com>,
Mika Fischer <mika.fischer@zoopnet.de>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v8 - fix
Date: Tue, 29 Apr 2008 20:25:58 -0700 [thread overview]
Message-ID: <200804292025.58268.yhlu.kernel@gmail.com> (raw)
In-Reply-To: <200804290352.33543.yhlu.kernel@gmail.com>
v9: address format change requests by Ingo
more case handling in range_to_var_with_hole
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Index: linux-2.6/arch/x86/Kconfig
===================================================================
--- linux-2.6.orig/arch/x86/Kconfig
+++ linux-2.6/arch/x86/Kconfig
@@ -1092,13 +1092,12 @@ config MTRR_SANITIZER
If unsure, say Y.
config MTRR_SANITIZER_ENABLE_DEFAULT
- def_bool y
- prompt "Enable MTRR cleanup by default"
+ int "MTRR cleanup enable value (0-1)"
+ range 0 1
+ default "0"
depends on MTRR_SANITIZER
help
- Enable mtrr cleanup by default
-
- If unsure, say Y.
+ Enable mtrr cleanup default value
config X86_PAT
bool
Index: linux-2.6/arch/x86/kernel/cpu/mtrr/main.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/mtrr/main.c
+++ linux-2.6/arch/x86/kernel/cpu/mtrr/main.c
@@ -611,17 +611,9 @@ static struct sysdev_driver mtrr_sysdev_
};
#ifdef CONFIG_MTRR_SANITIZER
-
-#ifdef CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT
-static int enable_mtrr_cleanup __initdata = 1;
-#else
-static int enable_mtrr_cleanup __initdata;
-#endif
-
+static int enable_mtrr_cleanup __initdata = CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT;
#else
-
static int enable_mtrr_cleanup __initdata = -1;
-
#endif
static int __init disable_mtrr_cleanup_setup(char *str)
@@ -640,6 +632,7 @@ static int __init enable_mtrr_cleanup_se
}
early_param("enble_mtrr_cleanup", enable_mtrr_cleanup_setup);
+/* should be related to MTRR_VAR_RANGES nums */
#define RANGE_NUM 256
struct res_range {
@@ -647,13 +640,27 @@ struct res_range {
unsigned long end;
};
-static int __init add_range(struct res_range *range, int nr_range, unsigned long start,
- unsigned long end, int merge)
+static int __init
+add_range(struct res_range *range, int nr_range, unsigned long start,
+ unsigned long end)
{
- int i;
+ /* out of slots */
+ if (nr_range >= RANGE_NUM)
+ return nr_range;
- if (!merge)
- goto addit;
+ range[nr_range].start = start;
+ range[nr_range].end = end;
+
+ nr_range++;
+
+ return nr_range;
+}
+
+static int __init
+add_range_with_merge(struct res_range *range, int nr_range, unsigned long start,
+ unsigned long end)
+{
+ int i;
/* try to merge it with old one */
for (i = 0; i < nr_range; i++) {
@@ -676,24 +683,14 @@ static int __init add_range(struct res_r
return nr_range;
}
-addit:
/* need to add that */
- if (nr_range >= RANGE_NUM)
- return nr_range;
-
- range[nr_range].start = start;
- range[nr_range].end = end;
-
- nr_range++;
-
- return nr_range;
-
+ return add_range(range, nr_range, start, end);
}
-static void __init subtract_range(struct res_range *range, unsigned long start,
- unsigned long end)
+
+static void __init
+subtract_range(struct res_range *range, unsigned long start, unsigned long end)
{
- int i;
- int j;
+ int i, j;
for (j = 0; j < RANGE_NUM; j++) {
if (!range[j].end)
@@ -747,46 +744,47 @@ static int __init cmp_range(const void *
}
struct var_mtrr_state {
- unsigned long range_startk, range_sizek;
- unsigned long chunk_sizek;
- unsigned long gran_sizek;
- unsigned int reg;
- unsigned address_bits;
+ unsigned long range_startk;
+ unsigned long range_sizek;
+ unsigned long chunk_sizek;
+ unsigned long gran_sizek;
+ unsigned int reg;
+ unsigned int address_bits;
};
-static void __init set_var_mtrr(
- unsigned int reg, unsigned long basek, unsigned long sizek,
- unsigned char type, unsigned address_bits)
+static void __init
+set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
+ unsigned char type, unsigned address_bits)
{
u32 base_lo, base_hi, mask_lo, mask_hi;
- unsigned address_mask_high;
+ u64 base, mask;
if (!sizek) {
fill_mtrr_var_range(reg, 0, 0, 0, 0);
return;
}
- address_mask_high = ((1u << (address_bits - 32u)) - 1u);
+ mask = (1ULL << address_bits) - 1;
+ mask &= ~((((u64)sizek) << 10) - 1);
- base_hi = basek >> 22;
- base_lo = basek << 10;
+ base = ((u64)basek) << 10;
- if (sizek < 4*1024*1024) {
- mask_hi = address_mask_high;
- mask_lo = ~((sizek << 10) - 1);
- } else {
- mask_hi = address_mask_high & (~((sizek >> 22) - 1));
- mask_lo = 0;
- }
+ base |= type;
+ mask |= 0x800;
+
+ base_lo = base & ((1ULL<<32) - 1);
+ base_hi = base >> 32;
+
+ mask_lo = mask & ((1ULL<<32) - 1);
+ mask_hi = mask >> 32;
- base_lo |= type;
- mask_lo |= 0x800;
fill_mtrr_var_range(reg, base_lo, base_hi, mask_lo, mask_hi);
}
-static unsigned int __init range_to_mtrr(unsigned int reg,
- unsigned long range_startk, unsigned long range_sizek,
- unsigned char type, unsigned address_bits)
+static unsigned int __init
+range_to_mtrr(unsigned int reg, unsigned long range_startk,
+ unsigned long range_sizek, unsigned char type,
+ unsigned address_bits)
{
if (!range_sizek || (reg >= num_var_ranges))
return reg;
@@ -794,6 +792,7 @@ static unsigned int __init range_to_mtrr
while (range_sizek) {
unsigned long max_align, align;
unsigned long sizek;
+
/* Compute the maximum size I can make a range */
if (range_startk)
max_align = ffs(range_startk) - 1;
@@ -818,7 +817,8 @@ static unsigned int __init range_to_mtrr
return reg;
}
-static void __init range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek)
+static void __init
+range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek)
{
unsigned long hole_basek, hole_sizek;
unsigned long range0_basek, range0_sizek;
@@ -848,23 +848,31 @@ static void __init range_to_mtrr_with_ho
/* try to append some small hole */
range0_basek = state->range_startk;
range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
- if ((range0_sizek == state->range_sizek) ||
- ((range0_basek + range0_sizek - chunk_sizek > basek) && basek)) {
+ if (range0_sizek == state->range_sizek) {
printk(KERN_INFO "rangeX: %016lx - %016lx\n", range0_basek<<10, (range0_basek + state->range_sizek)<<10);
state->reg = range_to_mtrr(state->reg, range0_basek,
state->range_sizek, MTRR_TYPE_WRBACK, state->address_bits);
return;
+ } else if (basek) {
+ while (range0_basek + range0_sizek - chunk_sizek > basek) {
+ range0_sizek -= chunk_sizek;
+ if (!range0_sizek)
+ break;
+ }
}
- range0_sizek -= chunk_sizek;
+ if (range0_sizek > chunk_sizek)
+ range0_sizek -= chunk_sizek;
printk(KERN_INFO "range0: %016lx - %016lx\n", range0_basek<<10, (range0_basek + range0_sizek)<<10);
state->reg = range_to_mtrr(state->reg, range0_basek,
range0_sizek, MTRR_TYPE_WRBACK, state->address_bits);
range_basek = range0_basek + range0_sizek;
range_sizek = chunk_sizek;
- if (range_sizek - (state->range_sizek - range0_sizek) < (chunk_sizek >> 1)) {
+
+ if ((range_sizek - (state->range_sizek - range0_sizek) < (chunk_sizek >> 1)) &&
+ (range_basek + range_sizek <= basek)) {
hole_sizek = range_sizek - (state->range_sizek - range0_sizek);
hole_basek = range_basek + range_sizek - hole_sizek;
} else
@@ -880,7 +888,9 @@ static void __init range_to_mtrr_with_ho
}
}
-static void __init set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn, unsigned long size_pfn)
+static void __init
+set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn,
+ unsigned long size_pfn)
{
unsigned long basek, sizek;
@@ -921,7 +931,7 @@ static int __init parse_mtrr_chunk_size_
early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt);
/* granity of mtrr of block */
-static u64 mtrr_gran_size __initdata = (64ULL<<20);
+static u64 mtrr_gran_size __initdata = (1ULL<<20);
static int __init parse_mtrr_gran_size_opt(char *p)
{
@@ -932,17 +942,19 @@ static int __init parse_mtrr_gran_size_o
}
early_param("mtrr_gran_size", parse_mtrr_gran_size_opt);
-static void __init x86_setup_var_mtrrs(struct res_range *range, int nr_range, unsigned address_bits)
+static void __init
+x86_setup_var_mtrrs(struct res_range *range, int nr_range,
+ unsigned address_bits)
{
struct var_mtrr_state var_state;
int i;
- var_state.range_startk = 0;
- var_state.range_sizek = 0;
- var_state.reg = 0;
- var_state.address_bits = address_bits;
- var_state.chunk_sizek = mtrr_chunk_size >> 10;
- var_state.gran_sizek = mtrr_gran_size >> 10;
+ var_state.range_startk = 0;
+ var_state.range_sizek = 0;
+ var_state.reg = 0;
+ var_state.address_bits = address_bits;
+ var_state.chunk_sizek = mtrr_chunk_size >> 10;
+ var_state.gran_sizek = mtrr_gran_size >> 10;
/* Write the range etc */
for (i = 0; i < nr_range; i++)
@@ -952,11 +964,16 @@ static void __init x86_setup_var_mtrrs(s
range_to_mtrr_with_hole(&var_state, 0);
printk(KERN_INFO "DONE variable MTRRs\n");
/* Clear out the extra MTRR's */
- while (var_state.reg < num_var_ranges)
- set_var_mtrr(var_state.reg++, 0, 0, 0, var_state.address_bits);
+ while (var_state.reg < num_var_ranges) {
+ set_var_mtrr(var_state.reg, 0, 0, 0, var_state.address_bits);
+ var_state.reg++;
+ }
}
-static int __init x86_get_mtrr_mem_range(struct res_range *range, int nr_range, unsigned long extra_remove_base, unsigned long extra_remove_size)
+static int __init
+x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
+ unsigned long extra_remove_base,
+ unsigned long extra_remove_size)
{
unsigned long i, base, size;
mtrr_type type;
@@ -965,7 +982,7 @@ static int __init x86_get_mtrr_mem_range
mtrr_if->get(i, &base, &size, &type);
if (type != MTRR_TYPE_WRBACK)
continue;
- nr_range = add_range(range, nr_range, base, base + size - 1, 1);
+ nr_range = add_range_with_merge(range, nr_range, base, base + size - 1);
}
printk(KERN_INFO "After WB checking\n");
for (i = 0; i < nr_range; i++)
@@ -1005,11 +1022,11 @@ static int __init x86_get_mtrr_mem_range
static int __init mtrr_cleanup(unsigned address_bits)
{
+ unsigned long extra_remove_base, extra_remove_size;
unsigned long i, base, size, def, dummy;
- mtrr_type type;
struct res_range range[RANGE_NUM];
+ mtrr_type type;
int nr_range;
- unsigned long extra_remove_base, extra_remove_size;
/* extra one for all 0 */
int num[MTRR_NUM_TYPES + 1];
@@ -1053,7 +1070,6 @@ static int __init mtrr_cleanup(unsigned
x86_setup_var_mtrrs(range, nr_range, address_bits);
return 1;
-
}
static int disable_mtrr_trim;
next prev parent reply other threads:[~2008-04-30 3:26 UTC|newest]
Thread overview: 89+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-28 6:37 [PATCH] x86: mtrr cleanup for converting continuous to discrete layout Yinghai Lu
2008-04-28 9:06 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v2 Yinghai Lu
2008-04-28 13:08 ` Ingo Molnar
2008-04-28 13:49 ` Arjan van de Ven
2008-04-28 15:28 ` Mika Fischer
2008-04-28 5:50 ` Arjan van de Ven
2008-04-28 16:01 ` Gabriel C
2008-04-28 16:28 ` Mika Fischer
2008-04-28 19:44 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v3 Yinghai Lu
2008-04-28 20:15 ` Ingo Molnar
2008-04-28 20:18 ` Yinghai Lu
2008-04-28 20:29 ` Ingo Molnar
2008-04-28 20:16 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v4 Yinghai Lu
2008-04-28 22:05 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v5 Yinghai Lu
2008-04-28 22:36 ` Randy Dunlap
2008-04-28 22:47 ` Yinghai Lu
2008-04-29 2:42 ` Andrew Morton
2008-04-29 3:01 ` Yinghai Lu
[not found] ` <200804290157.30651.yhlu.kernel@gmail.com>
2008-04-29 8:59 ` [PATCH 2/2] x86: fix trimming e820 with MTRR holes Yinghai Lu
2008-04-29 11:35 ` Ingo Molnar
2008-04-29 17:18 ` Yinghai Lu
2008-04-29 17:20 ` Yinghai Lu
2008-04-30 3:25 ` [PATCH] x86: fix trimming e820 with MTRR holes. - fix Yinghai Lu
2008-04-30 12:09 ` Ingo Molnar
2008-04-29 9:00 ` [PATCH 1/2] x86: mtrr cleanup for converting continuous to discrete layout v7 Yinghai Lu
2008-04-29 9:47 ` Gabriel C
2008-04-29 10:30 ` Yinghai Lu
2008-04-29 10:56 ` Yinghai Lu
2008-04-29 11:26 ` Ingo Molnar
2008-04-29 11:51 ` Gabriel C
2008-04-29 17:11 ` Yinghai Lu
2008-04-29 20:25 ` Gabriel C
2008-04-29 21:49 ` Yinghai Lu
2008-04-29 23:56 ` Gabriel C
2008-04-30 0:06 ` Gabriel C
2008-04-30 0:38 ` Yinghai Lu
2008-04-30 1:02 ` Gabriel C
2008-04-30 3:00 ` Yinghai Lu
2008-04-30 3:29 ` Yinghai Lu
2008-04-30 4:12 ` Gabriel C
2008-04-30 4:25 ` Yinghai Lu
2008-04-30 12:04 ` Gabriel C
2008-04-30 16:26 ` Yinghai Lu
2008-04-30 0:13 ` Yinghai Lu
2008-04-29 10:52 ` [PATCH 1/2] x86: mtrr cleanup for converting continuous to discrete layout v8 Yinghai Lu
2008-04-29 13:07 ` Ingo Molnar
2008-04-29 17:25 ` Yinghai Lu
2008-04-29 20:46 ` Randy Dunlap
2008-04-29 21:54 ` Yinghai Lu
2008-04-30 3:25 ` Yinghai Lu [this message]
2008-04-30 12:09 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v8 - fix Ingo Molnar
2008-05-01 8:00 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete - auto detect Yinghai Lu
2008-05-01 11:45 ` Gabriel C
2008-05-02 0:06 ` Yinghai Lu
2008-05-02 0:29 ` Gabriel C
2008-05-02 0:35 ` Yinghai Lu
2008-05-02 1:18 ` Gabriel C
2008-05-02 1:55 ` Yinghai Lu
2008-05-01 12:09 ` Mika Fischer
2008-05-01 16:35 ` Yinghai Lu
2008-05-01 16:59 ` Mika Fischer
2008-05-01 17:40 ` Yinghai Lu
2008-05-01 15:09 ` Randy Dunlap
2008-05-01 16:38 ` Yinghai Lu
2008-05-01 18:57 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete - auto detect v2 Yinghai Lu
2008-05-01 19:42 ` H. Peter Anvin
2008-05-01 21:02 ` Yinghai Lu
2008-05-01 21:10 ` H. Peter Anvin
2008-05-01 21:20 ` Yinghai Lu
2008-05-01 21:26 ` H. Peter Anvin
2008-05-01 21:31 ` Yinghai Lu
2008-05-01 21:33 ` H. Peter Anvin
2008-05-01 21:44 ` Yinghai Lu
2008-05-01 21:49 ` H. Peter Anvin
2008-05-01 22:52 ` Yinghai Lu
2008-05-01 22:57 ` H. Peter Anvin
2008-05-01 23:10 ` Yinghai Lu
2008-05-02 0:52 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete - auto detect v3 Yinghai Lu
2008-05-02 9:40 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete - auto detect v4 Yinghai Lu
2008-04-29 19:00 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v5 Eric W. Biederman
2008-04-29 20:04 ` Yinghai Lu
2008-04-29 20:29 ` Eric W. Biederman
2008-04-29 21:57 ` Yinghai Lu
2008-04-29 22:09 ` Ingo Molnar
2008-04-29 22:18 ` Yinghai Lu
2008-04-29 22:14 ` Eric W. Biederman
2008-04-29 22:54 ` Thomas Gleixner
2008-04-30 1:16 ` Eric W. Biederman
2008-04-30 9:57 ` Alan Cox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200804292025.58268.yhlu.kernel@gmail.com \
--to=yhlu.kernel.send@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mika.fischer@zoopnet.de \
--cc=mingo@elte.hu \
--cc=nix.or.die@googlemail.com \
--cc=tglx@linutronix.de \
--cc=yhlu.kernel@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.