kernel - 64-bit memory & ncpus work
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 7 Dec 2010 03:24:30 +0000 (19:24 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 7 Dec 2010 03:24:30 +0000 (19:24 -0800)
* Create a macro and bsr function for cpu masks in preparation for
  making cpumask_t 64 bits on 64-bit builds.  cpumask_t is still
  32 bits in this commit.

* Expand SMP_MAXCPUS to 31 for 64-bit builds in preparation for
  eventually expanding it to 63.

* Fix an array overflow when probing ncpus on 64-bit.

* Increase the boot-time kmap entries to accomodate large numbers of
  cpus.

* Clean up a few places where integer overflows could occur on
  64-bit machines with large amounts of ram.

  For the moment we are limited to 32G.  This will change in a
  followup commit.

12 files changed:
sys/cpu/i386/include/types.h
sys/cpu/x86_64/include/param.h
sys/cpu/x86_64/include/types.h
sys/platform/pc32/i386/pmap.c
sys/platform/pc64/x86_64/machdep.c
sys/platform/pc64/x86_64/mp_machdep.c
sys/platform/pc64/x86_64/pmap.c
sys/platform/vkernel/platform/pmap.c
sys/platform/vkernel64/platform/pmap.c
sys/vm/pmap.h
sys/vm/vm_map.c
sys/vm/vm_map.h

index 16fd412..1261a03 100644 (file)
@@ -66,6 +66,9 @@ typedef __uint32_t    pd_entry_t;
 typedef __uint32_t     pt_entry_t;
 typedef __uint32_t     cpumask_t;      /* mask representing a set of cpus */
 
+#define CPUMASK(cpu)           (1U << (cpu))
+#define BSRCPUMASK(mask)       bsrl(mask)
+
 #define PDESIZE         sizeof(pd_entry_t) /* for assembly files */
 #define PTESIZE         sizeof(pt_entry_t) /* for assembly files */
 
index 662c44e..de87df1 100644 (file)
@@ -88,7 +88,7 @@
  * Use SMP_MAXCPU instead of MAXCPU for structures that are intended to
  * remain compatible between UP and SMP builds.
  */
-#define SMP_MAXCPU     16
+#define SMP_MAXCPU     31
 #ifdef SMP
 #define MAXCPU         SMP_MAXCPU
 #else
index 0843757..c6ff8c8 100644 (file)
@@ -77,6 +77,9 @@ typedef __uint64_t    pt_entry_t;
 #endif
 typedef __uint32_t      cpumask_t;      /* mask representing a set of cpus */
 
+#define CPUMASK(cpu)   ((__uint32_t)1 << (cpu))
+#define BSRCPUMASK(mask)       bsrq(mask)
+
 #define PML4SIZE       sizeof(pml4_entry_t) /* for assembly files */
 #define PDPSIZE                sizeof(pdp_entry_t) /* for assembly files */
 #define PDESIZE         sizeof(pd_entry_t) /* for assembly files */
index fe4ad9f..84646f3 100644 (file)
@@ -2493,7 +2493,7 @@ pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m)
  * No requirements.
  */
 void *
-pmap_kenter_temporary(vm_paddr_t pa, int i)
+pmap_kenter_temporary(vm_paddr_t pa, long i)
 {
        pmap_kenter((vm_offset_t)crashdumpmap + (i * PAGE_SIZE), pa);
        return ((void *)crashdumpmap);
index 608b2ed..d2a77a6 100644 (file)
@@ -1450,6 +1450,14 @@ getmemsize(caddr_t kmdp, u_int64_t first)
        if (Maxmem > atop(physmap[physmap_idx + 1]))
                Maxmem = atop(physmap[physmap_idx + 1]);
 
+       /*
+        *
+        */
+       if (Maxmem > atop(DMAP_MAX_ADDRESS - DMAP_MIN_ADDRESS)) {
+               kprintf("Limiting Maxmem due to DMAP size\n");
+               Maxmem = atop(DMAP_MAX_ADDRESS - DMAP_MIN_ADDRESS);
+       }
+
        if (atop(physmap[physmap_idx + 1]) != Maxmem &&
            (boothowto & RB_VERBOSE))
                kprintf("Physical memory use set to %ldK\n", Maxmem * 4);
index 76ef80a..8d4c0f8 100644 (file)
@@ -237,7 +237,7 @@ u_int32_t *io_apic_versions;
 #endif
 extern int nkpt;
 
-u_int32_t cpu_apic_versions[MAXCPU];
+u_int32_t cpu_apic_versions[NAPICID];  /* populated during mptable scan */
 int64_t tsc0_offset;
 extern int64_t tsc_offsets[];
 
@@ -564,6 +564,7 @@ mp_announce(void)
 if (apic_io_enable) {
        for (x = 0; x < mp_napics; ++x) {
                kprintf(" io%d (APIC): apic id: %2d", x, IO_TO_ID(x));
+               kprintf("napics %d versions %p address %p\n", mp_napics, io_apic_versions, io_apic_address);
                kprintf(", version: 0x%08x", io_apic_versions[x]);
                kprintf(", at 0x%08lx\n", io_apic_address[x]);
        }
@@ -996,6 +997,8 @@ mptable_pass2(struct mptable_pos *mpt)
        MALLOC(bus_data, bus_datum *, sizeof(bus_datum) * mp_nbusses,
            M_DEVBUF, M_WAITOK);
 
+       kprintf("xapics %d versions %p address %p\n", mp_napics, io_apic_versions, io_apic_address);
+
        for (x = 0; x < mp_napics; x++)
                ioapic[x] = permanent_io_mapping(io_apic_address[x]);
 
@@ -3087,6 +3090,7 @@ mptable_lapic_enumerate(struct lapic_enumerator *e)
        if (mp_naps > MAXCPU) {
                kprintf("Warning: only using %d of %d available CPUs!\n",
                        MAXCPU, mp_naps);
+               DELAY(1000000);
                mp_naps = MAXCPU;
        }
 
index ecf1967..6528097 100644 (file)
@@ -413,7 +413,7 @@ vtopde(vm_offset_t va)
 }
 
 static uint64_t
-allocpages(vm_paddr_t *firstaddr, int n)
+allocpages(vm_paddr_t *firstaddr, long n)
 {
        uint64_t ret;
 
@@ -427,7 +427,7 @@ static
 void
 create_pagetables(vm_paddr_t *firstaddr)
 {
-       int i;
+       long i;         /* must be 64 bits */
 
        /*
         * We are running (mostly) V=P at this point
@@ -443,6 +443,7 @@ create_pagetables(vm_paddr_t *firstaddr)
                ndmpdp = 4;
 
        nkpt = (Maxmem * sizeof(struct vm_page) + NBPDR - 1) / NBPDR;
+       nkpt += (Maxmem * sizeof(struct pv_entry) + NBPDR - 1) / NBPDR;
        nkpt += ((nkpt + nkpt + 1 + NKPML4E + NKPDPE + NDMPML4E + ndmpdp) +
                511) / 512;
        nkpt += 128;
@@ -520,7 +521,7 @@ create_pagetables(vm_paddr_t *firstaddr)
        /* Preset PG_M and PG_A because demotion expects it */
        if ((amd_feature & AMDID_PAGE1GB) == 0) {
                for (i = 0; i < NPDEPG * ndmpdp; i++) {
-                       ((pd_entry_t *)DMPDphys)[i] = (vm_paddr_t)i << PDRSHIFT;
+                       ((pd_entry_t *)DMPDphys)[i] = i << PDRSHIFT;
                        ((pd_entry_t *)DMPDphys)[i] |= PG_RW | PG_V | PG_PS |
                            PG_G | PG_M | PG_A;
                }
@@ -1051,6 +1052,8 @@ pmap_map(vm_offset_t *virtp, vm_paddr_t start, vm_paddr_t end, int prot)
        va = va_start;
 
        while (start < end) {
+               if ((start / PAGE_SIZE & 15) == 0)
+                       kprintf("%p %p\n", (void *)va, (void *)start);
                pmap_kenter_quick(va, start);
                va += PAGE_SIZE;
                start += PAGE_SIZE;
@@ -2846,7 +2849,7 @@ pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m)
  */
 /* JG Needed on x86_64? */
 void *
-pmap_kenter_temporary(vm_paddr_t pa, int i)
+pmap_kenter_temporary(vm_paddr_t pa, long i)
 {
        pmap_kenter((vm_offset_t)crashdumpmap + (i * PAGE_SIZE), pa);
        return ((void *)crashdumpmap);
index fba3d8b..a61cf7c 100644 (file)
@@ -748,7 +748,7 @@ pmap_kenter_quick(vm_offset_t va, vm_paddr_t pa)
  * to be used for panic dumps.
  */
 void *
-pmap_kenter_temporary(vm_paddr_t pa, int i)
+pmap_kenter_temporary(vm_paddr_t pa, long i)
 {
        pmap_kenter(crashdumpmap + (i * PAGE_SIZE), pa);
        return ((void *)crashdumpmap);
index 6b5e43a..a1e32ea 100644 (file)
@@ -2460,7 +2460,7 @@ pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m)
  * to be used for panic dumps.
  */
 void *
-pmap_kenter_temporary(vm_paddr_t pa, int i)
+pmap_kenter_temporary(vm_paddr_t pa, long i)
 {
        pmap_kenter(crashdumpmap + (i * PAGE_SIZE), pa);
        return ((void *)crashdumpmap);
index 682316e..e926e3d 100644 (file)
@@ -194,7 +194,7 @@ void                 pmap_replacevm (struct proc *, struct vmspace *, int);
 void            pmap_setlwpvm (struct lwp *, struct vmspace *);
 
 vm_offset_t     pmap_addr_hint (vm_object_t obj, vm_offset_t addr, vm_size_t size);
-void           *pmap_kenter_temporary (vm_paddr_t pa, int i);
+void           *pmap_kenter_temporary (vm_paddr_t pa, long i);
 void            pmap_init2 (void);
 struct vm_page *pmap_kvtom(vm_offset_t va);
 
index 79c1a02..e86920c 100644 (file)
@@ -142,7 +142,11 @@ struct sysref_class vmspace_sysref_class = {
        }
 };
 
-#define VMEPERCPU      2
+/*
+ * per-cpu page table cross mappings are initialized in early boot
+ * and might require a considerable number of vm_map_entry structures.
+ */
+#define VMEPERCPU      (MAXCPU+1)
 
 static struct vm_zone mapentzone_store, mapzone_store;
 static vm_zone_t mapentzone, mapzone;
index 3b67c66..9001339 100644 (file)
@@ -451,7 +451,7 @@ vmspace_president_count(struct vmspace *vmspace)
  * during boot to bootstrap the VM system.
  */
 #define MAX_KMAP       10
-#define        MAX_MAPENT      256
+#define        MAX_MAPENT      2048    /* required to support up to 64 cpus */
 
 /*
  * Copy-on-write flags for vm_map operations