ia64/xen-unstable

changeset 2095:b6006dac0b1a

bitkeeper revision 1.1155 (411350f1WPGKHyDE_nv5WX9LJBbaWg)

Add support for marking bad pages using the 'badpage=xxx'
cmdline option when booting Xen.
author kaf24@scramble.cl.cam.ac.uk
date Fri Aug 06 09:35:45 2004 +0000 (2004-08-06)
parents 8e0d9e45c5f7
children ff029926ccf1 7d826896e90c
files README.CD docs/HOWTOs/Xen-HOWTO docs/user.tex xen/common/kernel.c xen/common/page_alloc.c xen/include/xen/lib.h
line diff
     1.1 --- a/README.CD	Thu Aug 05 22:27:41 2004 +0000
     1.2 +++ b/README.CD	Fri Aug 06 09:35:45 2004 +0000
     1.3 @@ -277,6 +277,13 @@ that may be able to help diagnose proble
     1.4  
     1.5   noht		  Disable Hyperthreading.
     1.6  
     1.7 + badpage=<page number>[,<page number>]*
     1.8 +                  Specify a list of pages not to be allocated for use 
     1.9 +                  because they contain bad bytes. For example, if your
    1.10 +                  memory tester says that byte 0x12345678 is bad, you would
    1.11 +                  place 'badpage=0x12345' on Xen's command line (i.e., the
    1.12 +                  last three digits of the byte address are not included!).
    1.13 +
    1.14   com1=<baud>,DPS[,<io_base>,<irq>]
    1.15   com2=<baud>,DPS[,<io_base>,<irq>]
    1.16                    Xen supports up to two 16550-compatible serial ports.
     2.1 --- a/docs/HOWTOs/Xen-HOWTO	Thu Aug 05 22:27:41 2004 +0000
     2.2 +++ b/docs/HOWTOs/Xen-HOWTO	Fri Aug 06 09:35:45 2004 +0000
     2.3 @@ -223,6 +223,13 @@ The following is a list of command line 
     2.4  
     2.5   noht             Disable Hyperthreading.
     2.6  
     2.7 + badpage=<page number>[,<page number>]*
     2.8 +                  Specify a list of pages not to be allocated for use 
     2.9 +                  because they contain bad bytes. For example, if your
    2.10 +                  memory tester says that byte 0x12345678 is bad, you would
    2.11 +                  place 'badpage=0x12345' on Xen's command line (i.e., the
    2.12 +                  last three digits of the byte address are not included!).
    2.13 +
    2.14   com1=<baud>,DPS[,<io_base>,<irq>]
    2.15   com2=<baud>,DPS[,<io_base>,<irq>]
    2.16                    Xen supports up to two 16550-compatible serial ports.
     3.1 --- a/docs/user.tex	Thu Aug 05 22:27:41 2004 +0000
     3.2 +++ b/docs/user.tex	Fri Aug 06 09:35:45 2004 +0000
     3.3 @@ -1140,6 +1140,14 @@ editting \path{grub.conf}.
     3.4  {\bf noht } \\
     3.5   Disable Hyperthreading. \\
     3.6  
     3.7 +{\bf badpage=$<$page number$>$[,$<$page number$>$] } \\
     3.8 +                  Specify a list of pages not to be allocated for use 
     3.9 +                  because they contain bad bytes. For example, if your
    3.10 +                  memory tester says that byte 0x12345678 is bad, you would
    3.11 +                  place 'badpage=0x12345' on Xen's command line (i.e., the
    3.12 +                  last three digits of the byte address are not
    3.13 +                  included!). \\
    3.14 +
    3.15  {\bf com1=$<$baud$>$,DPS[,$<$io\_base$>$,$<$irq$>$] \\
    3.16   com2=$<$baud$>$,DPS[,$<$io\_base$>$,$<$irq$>$] } \\
    3.17   Xen supports up to two 16550-compatible serial ports.
     4.1 --- a/xen/common/kernel.c	Thu Aug 05 22:27:41 2004 +0000
     4.2 +++ b/xen/common/kernel.c	Fri Aug 06 09:35:45 2004 +0000
     4.3 @@ -91,32 +91,40 @@ char opt_nmi[10] = "dom0";
     4.4  #else
     4.5  char opt_nmi[10] = "fatal";
     4.6  #endif
     4.7 +/*
     4.8 + * Comma-separated list of hexadecimal page numbers containing bad bytes.
     4.9 + * e.g. 'badpage=0x3f45,0x8a321'.
    4.10 + */
    4.11 +char opt_badpage[100] = "";
    4.12  
    4.13  static struct {
    4.14      unsigned char *name;
    4.15      enum { OPT_STR, OPT_UINT, OPT_BOOL } type;
    4.16      void *var;
    4.17 +    unsigned int len;
    4.18  } opts[] = {
    4.19 -    { "console",           OPT_STR,  &opt_console },
    4.20 -    { "conswitch",         OPT_STR,  &opt_conswitch },
    4.21 -    { "com1",              OPT_STR,  &opt_com1 },
    4.22 -    { "com2",              OPT_STR,  &opt_com2 },
    4.23 -    { "dom0_mem",          OPT_UINT, &opt_dom0_mem }, 
    4.24 -    { "noht",              OPT_BOOL, &opt_noht },
    4.25 -    { "noacpi",            OPT_BOOL, &opt_noacpi },
    4.26 -    { "nosmp",             OPT_BOOL, &opt_nosmp },
    4.27 -    { "noreboot",          OPT_BOOL, &opt_noreboot },
    4.28 -    { "ignorebiostables",  OPT_BOOL, &opt_ignorebiostables },
    4.29 -    { "watchdog",          OPT_BOOL, &opt_watchdog },
    4.30 -    { "pdb",               OPT_STR,  &opt_pdb },
    4.31 -    { "tbuf_size",         OPT_UINT, &opt_tbuf_size },
    4.32 -    { "sched",             OPT_STR,  &opt_sched },
    4.33 -    { "physdev_dom0_hide", OPT_STR,  &opt_physdev_dom0_hide },
    4.34 -    { "leveltrigger",      OPT_STR,  &opt_leveltrigger },
    4.35 -    { "edgetrigger",       OPT_STR,  &opt_edgetrigger },
    4.36 -    { "xenheap_megabytes", OPT_UINT, &opt_xenheap_megabytes },
    4.37 -    { "nmi",               OPT_STR,  &opt_nmi },
    4.38 -    { NULL,               0,        NULL     }
    4.39 +#define V(_x) &_x, sizeof(_x)
    4.40 +    { "console",           OPT_STR,  V(opt_console) },
    4.41 +    { "conswitch",         OPT_STR,  V(opt_conswitch) },
    4.42 +    { "com1",              OPT_STR,  V(opt_com1) },
    4.43 +    { "com2",              OPT_STR,  V(opt_com2) },
    4.44 +    { "dom0_mem",          OPT_UINT, V(opt_dom0_mem) },
    4.45 +    { "noht",              OPT_BOOL, V(opt_noht) },
    4.46 +    { "noacpi",            OPT_BOOL, V(opt_noacpi) },
    4.47 +    { "nosmp",             OPT_BOOL, V(opt_nosmp) },
    4.48 +    { "noreboot",          OPT_BOOL, V(opt_noreboot) },
    4.49 +    { "ignorebiostables",  OPT_BOOL, V(opt_ignorebiostables) },
    4.50 +    { "watchdog",          OPT_BOOL, V(opt_watchdog) },
    4.51 +    { "pdb",               OPT_STR,  V(opt_pdb) },
    4.52 +    { "tbuf_size",         OPT_UINT, V(opt_tbuf_size) },
    4.53 +    { "sched",             OPT_STR,  V(opt_sched) },
    4.54 +    { "physdev_dom0_hide", OPT_STR,  V(opt_physdev_dom0_hide) },
    4.55 +    { "leveltrigger",      OPT_STR,  V(opt_leveltrigger) },
    4.56 +    { "edgetrigger",       OPT_STR,  V(opt_edgetrigger) },
    4.57 +    { "xenheap_megabytes", OPT_UINT, V(opt_xenheap_megabytes) },
    4.58 +    { "nmi",               OPT_STR,  V(opt_nmi) },
    4.59 +    { "badpage",           OPT_STR,  V(opt_badpage) },
    4.60 +    { NULL,                0,        NULL, 0 }
    4.61  };
    4.62  
    4.63  
    4.64 @@ -154,7 +162,10 @@ void cmain(multiboot_info_t *mbi)
    4.65                  {
    4.66                  case OPT_STR:
    4.67                      if ( opt != NULL )
    4.68 -                        strcpy(opts[i].var, opt);
    4.69 +                    {
    4.70 +                        strncpy(opts[i].var, opt, opts[i].len);
    4.71 +                        ((char *)opts[i].var)[opts[i].len-1] = '\0';
    4.72 +                    }
    4.73                      break;
    4.74                  case OPT_UINT:
    4.75                      if ( opt != NULL )
     5.1 --- a/xen/common/page_alloc.c	Thu Aug 05 22:27:41 2004 +0000
     5.2 +++ b/xen/common/page_alloc.c	Fri Aug 06 09:35:45 2004 +0000
     5.3 @@ -29,6 +29,7 @@
     5.4  #include <xen/slab.h>
     5.5  #include <xen/irq.h>
     5.6  
     5.7 +extern char opt_badpage[];
     5.8  
     5.9  /*********************
    5.10   * ALLOCATION BITMAP
    5.11 @@ -137,7 +138,8 @@ unsigned long init_heap_allocator(
    5.12      unsigned long bitmap_start, unsigned long max_pages)
    5.13  {
    5.14      int i, j;
    5.15 -    unsigned long bitmap_size;
    5.16 +    unsigned long bitmap_size, bad_pfn;
    5.17 +    char *p;
    5.18  
    5.19      memset(avail, 0, sizeof(avail));
    5.20  
    5.21 @@ -155,40 +157,42 @@ unsigned long init_heap_allocator(
    5.22      /* All allocated by default. */
    5.23      memset(alloc_bitmap, ~0, bitmap_size);
    5.24  
    5.25 +    /*
    5.26 +     * Process the bad-page list. Marking the page free in the bitmap will
    5.27 +     * indicate to init_heap_pages() that it should not be placed on the 
    5.28 +     * buddy lists.
    5.29 +     */
    5.30 +    p = opt_badpage;
    5.31 +    while ( *p != '\0' )
    5.32 +    {
    5.33 +        bad_pfn = simple_strtoul(p, &p, 0);
    5.34 +
    5.35 +        if ( *p == ',' )
    5.36 +            p++;
    5.37 +        else if ( *p != '\0' )
    5.38 +            break;
    5.39 +
    5.40 +        if ( (bad_pfn < max_pages) && allocated_in_map(bad_pfn) )
    5.41 +        {
    5.42 +            printk("Marking page %08lx as bad\n", bad_pfn);
    5.43 +            map_free(bad_pfn, 1);
    5.44 +        }
    5.45 +    }
    5.46 +
    5.47      return bitmap_start + bitmap_size;
    5.48  }
    5.49  
    5.50  /* Hand the specified arbitrary page range to the specified heap zone. */
    5.51  void init_heap_pages(int zone, struct pfn_info *pg, unsigned long nr_pages)
    5.52  {
    5.53 -    int i;
    5.54 -    unsigned long flags;
    5.55 -
    5.56 -    spin_lock_irqsave(&heap_lock, flags);
    5.57 +    unsigned long i, pfn = page_to_pfn(pg);
    5.58  
    5.59 -    /* Free up the memory we've been given to play with. */
    5.60 -    map_free(page_to_pfn(pg), nr_pages);
    5.61 -    avail[zone] += nr_pages;
    5.62 -    
    5.63 -    while ( nr_pages != 0 )
    5.64 +    /* Process each page in turn, skipping bad pages. */
    5.65 +    for ( i = 0; i < nr_pages; i++ )
    5.66      {
    5.67 -        /*
    5.68 -         * Next chunk is limited by alignment of pg, but also must not be
    5.69 -         * bigger than remaining bytes.
    5.70 -         */
    5.71 -        for ( i = 0; i < MAX_ORDER; i++ )
    5.72 -            if ( ((page_to_pfn(pg) & (1 << i)) != 0) ||
    5.73 -                 ((1 << (i + 1)) > nr_pages) )
    5.74 -                break;
    5.75 -
    5.76 -        PFN_ORDER(pg) = i;
    5.77 -        list_add_tail(&pg->list, &heap[zone][i]);
    5.78 -
    5.79 -        pg       += 1 << i;
    5.80 -        nr_pages -= 1 << i;
    5.81 +        if ( likely(allocated_in_map(pfn+i)) ) /* bad page? */
    5.82 +            free_heap_pages(zone, pg+i, 0);
    5.83      }
    5.84 -
    5.85 -    spin_unlock_irqrestore(&heap_lock, flags);
    5.86  }
    5.87  
    5.88  
     6.1 --- a/xen/include/xen/lib.h	Thu Aug 05 22:27:41 2004 +0000
     6.2 +++ b/xen/include/xen/lib.h	Fri Aug 06 09:35:45 2004 +0000
     6.3 @@ -6,7 +6,7 @@
     6.4  #include <xen/string.h>
     6.5  
     6.6  #ifndef NDEBUG
     6.7 -#define ASSERT(_p) if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , __LINE__, __FILE__); *(int*)0=0; }
     6.8 +#define ASSERT(_p) if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s\n", #_p , __LINE__, __FILE__); *(int*)0=0; }
     6.9  #else
    6.10  #define ASSERT(_p) ((void)0)
    6.11  #endif