mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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

  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®