From: ebiederm@xmission.com (Eric W. Biederman)
To: Jesse Barnes <jesse.barnes@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>,
linux-kernel@vger.kernel.org,
Justin Piszcz <jpiszcz@lucidpixels.com>
Subject: Re: [PATCH] trim memory not covered by WB MTRRs
Date: Thu, 07 Jun 2007 01:45:32 -0600 [thread overview]
Message-ID: <m1wsygryw3.fsf@ebiederm.dsl.xmission.com> (raw)
In-Reply-To: <200706061229.24486.jesse.barnes@intel.com> (Jesse Barnes's message of "Wed, 6 Jun 2007 12:29:23 -0700")
Jesse Barnes <jesse.barnes@intel.com> writes:
> On some machines, buggy BIOSes don't properly setup WB MTRRs to
> cover all available RAM, meaning the last few megs (or even gigs)
> of memory will be marked uncached. Since Linux tends to allocate
> from high memory addresses first, this causes the machine to be
> unusably slow as soon as the kernel starts really using memory
> (i.e. right around init time).
>
> This patch works around the problem by scanning the MTRRs at
> boot and figuring out whether the current end_pfn value (setup
> by early e820 code) goes beyond the highest WB MTRR range, and
> if so, trimming it to match. A fairly obnoxious KERN_WARNING
> is printed too, letting the user know that not all of their
> memory is available due to a likely BIOS bug.
>
> Something similar could be done on i386 if needed, but the boot
> ordering would be slightly different, since the MTRR code on i386
> depends on the boot_cpu_data structure being setup.
>
> Justin, can you please test and make sure this patch works for
> you too? It'll only work around the problem, but it's better
> than having to do mem= by hand or waiting for a fix from your
> BIOS vendor.
Ok. Overall this feels good but a few nits below.
Would it make sense to split this into two patches.
The first to just do the cleanup that removes the allocations
for holding the mttr ranges?
> Thanks,
> Jesse
>
> Signed-off-by: Jesse Barnes <jesse.barnes@intel.com>
>
> diff --git a/arch/i386/kernel/cpu/mtrr/generic.c
> b/arch/i386/kernel/cpu/mtrr/generic.c
> index c4ebb51..71fc768 100644
> --- a/arch/i386/kernel/cpu/mtrr/generic.c
> +++ b/arch/i386/kernel/cpu/mtrr/generic.c
> @@ -13,7 +13,7 @@
> #include "mtrr.h"
>
>
> struct mtrr_state {
> - struct mtrr_var_range *var_ranges;
> + struct mtrr_var_range var_ranges[NUM_VAR_RANGES];
Could we name it MAX_VAR_RANGES and not NUM_VAR_RANGES.
In practices this is going to be 8 for every cpu I know of,
so calling this NUM_VAR_RANGES may be a little confusing.
> mtrr_type fixed_ranges[NUM_FIXED_RANGES];
> unsigned char enabled;
> unsigned char have_fixed;
> @@ -84,12 +84,6 @@ void get_mtrr_state(void)
> struct mtrr_var_range *vrs;
> unsigned lo, dummy;
>
> - if (!mtrr_state.var_ranges) {
> - mtrr_state.var_ranges = kmalloc(num_var_ranges * sizeof (struct
> mtrr_var_range),
> - GFP_KERNEL);
> - if (!mtrr_state.var_ranges)
> - return;
> - }
> vrs = mtrr_state.var_ranges;
>
> rdmsr(MTRRcap_MSR, lo, dummy);
> diff --git a/arch/i386/kernel/cpu/mtrr/if.c b/arch/i386/kernel/cpu/mtrr/if.c
> index c7d8f17..d7922ce 100644
> --- a/arch/i386/kernel/cpu/mtrr/if.c
> +++ b/arch/i386/kernel/cpu/mtrr/if.c
> @@ -12,7 +12,7 @@
> #include "mtrr.h"
>
> /* RED-PEN: this is accessed without any locking */
> -extern unsigned int *usage_table;
> +extern unsigned int usage_table[];
I think that should be:
> +extern unsigned int usage_table[NUM_VAR_RANGES];
Or even better yet the declaration moved to a header file.
>
> +/**
> + * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs
> + *
> + * Some buggy BIOSes don't setup the MTRRs properly for systems with certain
> + * memory configurations. This routine checks to make sure the MTRRs having
> + * a write back type cover all of the memory the kernel is intending to use.
> + * If not, it'll trim any memory off the end by adjusting end_pfn, removing
> + * it from the kernel's allocation pools, warning the user with an obnoxious
> + * message.
> + */
> +void __init mtrr_trim_uncached_memory(void)
> +{
> + unsigned long i, base, size, highest_addr = 0;
> + mtrr_type type;
> +
> + /* Find highest cached pfn */
> + for (i = 0; i < num_var_ranges; i++) {
> + mtrr_if->get(i, &base, &size, &type);
> + if (type != MTRR_TYPE_WRBACK)
> + continue;
> + base <<= PAGE_SHIFT;
> + size <<= PAGE_SHIFT;
> + if (highest_addr < base + size)
> + highest_addr = base + size;
> + }
This looks like it will handle the common case, so I have no major objections
to this code.
At least in theory and possibly in practice there are a couple of corner
cases we have missed her.
- Overlapping MTRRs.
- What happens if we have uncached memory lower down?
Except for performance problems I guess that case is relatively harmless.
- Is it possible and worth it to amend the e820 map, so it shows the
problem area as Reserved or otherwise not usable RAM?
> +
> + if ((highest_addr >> PAGE_SHIFT) != end_pfn) {
> + printk(KERN_WARNING "***************\n");
> + printk(KERN_WARNING "**** WARNING: likely BIOS bug\n");
> + printk(KERN_WARNING "**** MTRRs don't cover all of "
> + "memory, trimmed %ld pages\n", end_pfn -
> + (highest_addr >> PAGE_SHIFT));
> + printk(KERN_WARNING "***************\n");
> + end_pfn = highest_addr >> PAGE_SHIFT;
> + }
> +}
>
> /**
> * mtrr_bp_init - initialize mtrrs on the boot CPU
> diff --git a/arch/i386/kernel/cpu/mtrr/mtrr.h b/arch/i386/kernel/cpu/mtrr/mtrr.h
> index 289dfe6..a29dcba 100644
> --- a/arch/i386/kernel/cpu/mtrr/mtrr.h
> +++ b/arch/i386/kernel/cpu/mtrr/mtrr.h
> @@ -14,6 +14,7 @@
> #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
>
> #define NUM_FIXED_RANGES 88
> +#define NUM_VAR_RANGES 256
MAX_VAR_RANGES?
> #define MTRRfix64K_00000_MSR 0x250
> #define MTRRfix16K_80000_MSR 0x258
> #define MTRRfix16K_A0000_MSR 0x259
Eric
next prev parent reply other threads:[~2007-06-07 7:47 UTC|newest]
Thread overview: 118+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-06 19:29 Jesse Barnes
2007-06-06 20:26 ` Justin Piszcz
2007-06-06 20:28 ` Jesse Barnes
2007-06-06 20:31 ` Jesse Barnes
2007-06-06 20:37 ` Justin Piszcz
2007-06-06 20:50 ` Jesse Barnes
2007-06-06 21:26 ` Justin Piszcz
2007-06-06 21:53 ` Justin Piszcz
2007-06-06 22:03 ` Justin Piszcz
2007-06-06 22:05 ` Jesse Barnes
2007-06-06 22:07 ` Justin Piszcz
2007-06-06 22:13 ` Justin Piszcz
2007-06-06 22:24 ` Jesse Barnes
2007-06-06 22:26 ` Justin Piszcz
2007-06-06 22:28 ` Jesse Barnes
2007-06-06 22:31 ` Justin Piszcz
2007-06-06 22:35 ` Justin Piszcz
2007-06-06 22:37 ` Randy Dunlap
2007-06-06 22:46 ` Justin Piszcz
2007-06-06 22:54 ` Justin Piszcz
2007-06-06 23:11 ` Randy Dunlap
2007-06-06 23:15 ` Justin Piszcz
2007-06-06 23:34 ` Jesse Barnes
2007-06-07 8:10 ` Justin Piszcz
2007-06-06 22:39 ` Justin Piszcz
2007-06-06 22:57 ` Justin Piszcz
2007-06-06 23:20 ` Jesse Barnes
2007-06-06 23:24 ` Justin Piszcz
2007-06-06 23:27 ` Jesse Barnes
2007-06-07 8:51 ` Andi Kleen
2007-06-07 8:53 ` Justin Piszcz
2007-06-07 9:55 ` Satyam Sharma
2007-06-07 17:33 ` Jesse Barnes
2007-06-07 7:45 ` Eric W. Biederman [this message]
2007-06-07 17:30 ` Jesse Barnes
2007-06-08 23:13 ` Eric W. Biederman
2007-06-12 15:39 ` Jesse Barnes
2007-06-07 8:16 ` Andi Kleen
2007-06-07 17:35 ` Jesse Barnes
2007-06-07 17:40 ` Justin Piszcz
2007-06-07 14:41 ` Pavel Machek
2007-06-08 0:20 ` Andrew Morton
2007-06-08 1:33 ` Jesse Barnes
2007-06-08 21:15 ` Andrew Morton
2007-06-08 21:28 ` Jesse Barnes
2007-06-13 1:11 ` Eric W. Biederman
2007-06-13 2:29 ` Jesse Barnes
2007-06-13 22:19 ` Eric W. Biederman
2007-06-20 11:22 ` Helge Hafting
2007-06-20 14:37 ` Andi Kleen
2007-06-07 22:30 Jesse Barnes
2007-06-07 22:50 ` Justin Piszcz
2007-06-07 22:53 ` Justin Piszcz
2007-06-07 23:00 ` Justin Piszcz
2007-06-08 8:20 ` Justin Piszcz
2007-06-12 14:50 ` Pavel Machek
2007-06-12 15:29 ` Jesse Barnes
2007-06-12 15:48 ` Andi Kleen
2007-06-12 21:30 ` Pavel Machek
2007-06-12 21:31 ` Justin Piszcz
2007-06-12 21:38 ` Ray Lee
2007-06-12 21:55 ` Pavel Machek
2007-06-13 0:25 ` Ray Lee
2007-06-13 8:22 ` Pavel Machek
2007-06-14 19:38 ` Pim Zandbergen
2007-06-14 20:26 ` Justin Piszcz
2007-06-14 21:18 ` Jesse Barnes
2007-06-14 21:21 ` Justin Piszcz
2007-06-14 21:26 ` Jesse Barnes
2007-06-15 10:21 ` Pim Zandbergen
2007-06-15 16:20 ` Jesse Barnes
2007-06-21 14:24 ` Pim Zandbergen
2007-06-21 14:28 ` Justin Piszcz
2007-06-25 16:31 ` Pim Zandbergen
2007-06-25 16:34 ` Justin Piszcz
2007-06-15 10:17 ` Pim Zandbergen
2007-06-15 10:34 ` Justin Piszcz
2007-06-15 17:28 ` Jesse Barnes
2007-06-20 13:55 ` Pim Zandbergen
2007-06-21 19:40 ` Yinghai Lu
2007-06-21 19:56 ` Jesse Barnes
[not found] <fa.i7vJP3lxWAlyOLjcsqOWPKlixD8@ifi.uio.no>
[not found] ` <fa.3ijVoClbWNHWrMhDABWjNPxp+wo@ifi.uio.no>
[not found] ` <fa.ZqgSvRGj/scOmd0AwnU6e21Gcwc@ifi.uio.no>
[not found] ` <fa.oNsjw768fkDpx3oef91fjAQs1Iw@ifi.uio.no>
[not found] ` <fa.x8ZCt4n0yXI1llhRq4wfjNfqK4w@ifi.uio.no>
2007-06-08 1:57 ` Robert Hancock
[not found] <8tyOc-8f0-17@gated-at.bofh.it>
2007-06-13 6:52 ` Bodo Eggert
2007-06-13 16:19 ` Dave Jones
2007-06-25 21:34 Jesse Barnes
2007-06-25 21:45 ` Justin Piszcz
2007-06-25 22:01 ` Andrew Morton
2007-06-25 22:05 ` Jesse Barnes
2007-06-25 22:29 ` Justin Piszcz
2007-06-25 23:34 ` Andi Kleen
2007-06-25 23:36 ` Jesse Barnes
2007-06-26 0:54 ` Eric W. Biederman
2007-06-26 3:29 ` Jesse Barnes
2007-06-26 3:30 ` Jesse Barnes
2007-06-26 15:03 ` Andi Kleen
2007-06-26 15:07 ` Jesse Barnes
2007-06-26 15:18 ` Jesse Barnes
2007-06-26 15:39 ` Andi Kleen
2007-06-26 15:54 ` Yinghai Lu
2007-06-26 16:06 ` Eric W. Biederman
2007-06-26 17:38 ` Andi Kleen
2007-06-26 18:55 ` Yinghai Lu
2007-06-26 15:02 ` Andi Kleen
2007-06-26 15:38 ` Jesse Barnes
2007-06-27 10:44 ` Pim Zandbergen
2007-06-27 11:22 ` Andi Kleen
2007-06-27 11:40 ` Pim Zandbergen
2007-06-27 11:44 ` Justin Piszcz
2007-06-27 14:22 ` Mauro Giachero
2007-06-27 15:04 ` Jesse Barnes
2007-06-27 16:00 ` Pim Zandbergen
2007-06-27 16:07 ` Jesse Barnes
2007-06-27 16:22 ` Jesse Barnes
2007-06-27 17:02 ` Pim Zandbergen
2007-06-27 17:06 ` Jesse Barnes
2007-06-27 17:17 ` Pim Zandbergen
2007-07-05 12:12 ` Pavel Machek
2007-07-05 12:16 ` Justin Piszcz
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=m1wsygryw3.fsf@ebiederm.dsl.xmission.com \
--to=ebiederm@xmission.com \
--cc=andi@firstfloor.org \
--cc=jesse.barnes@intel.com \
--cc=jpiszcz@lucidpixels.com \
--cc=linux-kernel@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®