diff options
author | John Levon <john.levon@joyent.com> | 2019-04-25 02:39:05 -0700 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2019-04-30 08:09:06 -0700 |
commit | dddac438d5629d72879f2701924b62774cb4eaf0 (patch) | |
tree | eebd3b5baeb6927f0fa3515413ed2768c7cd08bf /usr/src | |
parent | 40320bdcdf7a073effbd3872d29e2bd595eae22c (diff) | |
download | illumos-joyent-dddac438d5629d72879f2701924b62774cb4eaf0.tar.gz |
10806 mnode_range_setup() makes assumptions about mnodes
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/i86pc/vm/vm_machdep.c | 115 |
1 files changed, 56 insertions, 59 deletions
diff --git a/usr/src/uts/i86pc/vm/vm_machdep.c b/usr/src/uts/i86pc/vm/vm_machdep.c index 8af60a1d15..28a5887d75 100644 --- a/usr/src/uts/i86pc/vm/vm_machdep.c +++ b/usr/src/uts/i86pc/vm/vm_machdep.c @@ -24,7 +24,7 @@ /* * Copyright (c) 2010, Intel Corporation. * All rights reserved. - * Copyright 2018 Joyent, Inc. + * Copyright 2019, Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -160,7 +160,7 @@ typedef struct { pgcnt_t mnr_mts_pgcnt; int mnr_mts_colors; pgcnt_t *mnr_mtsc_pgcnt; - } *mnr_mts; + } *mnr_mts; #endif } mnoderange_t; @@ -202,11 +202,11 @@ int nranges = NUM_MEM_RANGES; * This combines mem_node_config and memranges into one data * structure to be used for page list management. */ -mnoderange_t *mnoderanges; -int mnoderangecnt; -int mtype4g; -int mtype16m; -int mtypetop; /* index of highest pfn'ed mnoderange */ +static mnoderange_t *mnoderanges; +static int mnoderangecnt; +static int mtype4g; +static int mtype16m; +static int mtypetop; /* * 4g memory management variables for systems with more than 4g of memory: @@ -262,9 +262,9 @@ static int desfree4gshift = 4; /* maxmem4g shift to derive DESFREE4G */ #define FREEMEM16M MTYPE_FREEMEM(mtype16m) #define DESFREE16M desfree16m -#define RESTRICT16M_ALLOC(freemem, pgcnt, flags) \ - ((freemem != 0) && ((flags & PG_PANIC) == 0) && \ - ((freemem >= (FREEMEM16M)) || \ +#define RESTRICT16M_ALLOC(freemem, pgcnt, flags) \ + (mtype16m != -1 && (freemem != 0) && ((flags & PG_PANIC) == 0) && \ + ((freemem >= (FREEMEM16M)) || \ (FREEMEM16M < (DESFREE16M + pgcnt)))) static pgcnt_t desfree16m = 0x380; @@ -1389,39 +1389,46 @@ mnode_range_cnt(int mnode) #endif /* __xpv */ } -/* - * mnode_range_setup() initializes mnoderanges. - */ +static int +mnoderange_cmp(const void *v1, const void *v2) +{ + const mnoderange_t *m1 = v1; + const mnoderange_t *m2 = v2; + + if (m1->mnr_pfnlo < m2->mnr_pfnlo) + return (-1); + return (m1->mnr_pfnlo > m2->mnr_pfnlo); +} + void mnode_range_setup(mnoderange_t *mnoderanges) { - mnoderange_t *mp = mnoderanges; - int mnode, mri; - int mindex = 0; /* current index into mnoderanges array */ - int i, j; - pfn_t hipfn; - int last, hi; - - for (mnode = 0; mnode < max_mem_nodes; mnode++) { + mnoderange_t *mp; + size_t nr_ranges; + size_t mnode; + + for (mnode = 0, nr_ranges = 0, mp = mnoderanges; + mnode < max_mem_nodes; mnode++) { + size_t mri = nranges - 1; + if (mem_node_config[mnode].exists == 0) continue; - mri = nranges - 1; - while (MEMRANGEHI(mri) < mem_node_config[mnode].physbase) mri--; while (mri >= 0 && mem_node_config[mnode].physmax >= MEMRANGELO(mri)) { - mnoderanges->mnr_pfnlo = MAX(MEMRANGELO(mri), + mp->mnr_pfnlo = MAX(MEMRANGELO(mri), mem_node_config[mnode].physbase); - mnoderanges->mnr_pfnhi = MIN(MEMRANGEHI(mri), + mp->mnr_pfnhi = MIN(MEMRANGEHI(mri), mem_node_config[mnode].physmax); - mnoderanges->mnr_mnode = mnode; - mnoderanges->mnr_memrange = mri; - mnoderanges->mnr_exists = 1; - mnoderanges++; - mindex++; + mp->mnr_mnode = mnode; + mp->mnr_memrange = mri; + mp->mnr_next = -1; + mp->mnr_exists = 1; + mp++; + nr_ranges++; if (mem_node_config[mnode].physmax > MEMRANGEHI(mri)) mri--; else @@ -1430,33 +1437,26 @@ mnode_range_setup(mnoderange_t *mnoderanges) } /* - * For now do a simple sort of the mnoderanges array to fill in - * the mnr_next fields. Since mindex is expected to be relatively - * small, using a simple O(N^2) algorithm. + * mnoderangecnt can be larger than nr_ranges when memory DR is + * supposedly supported. */ - for (i = 0; i < mindex; i++) { - if (mp[i].mnr_pfnlo == 0) /* find lowest */ - break; - } - ASSERT(i < mindex); - last = i; - mtype16m = last; - mp[last].mnr_next = -1; - for (i = 0; i < mindex - 1; i++) { - hipfn = (pfn_t)(-1); - hi = -1; - /* find next highest mnode range */ - for (j = 0; j < mindex; j++) { - if (mp[j].mnr_pfnlo > mp[last].mnr_pfnlo && - mp[j].mnr_pfnlo < hipfn) { - hipfn = mp[j].mnr_pfnlo; - hi = j; - } - } - mp[hi].mnr_next = last; - last = hi; - } - mtypetop = last; + VERIFY3U(nr_ranges, <=, mnoderangecnt); + + qsort(mnoderanges, nr_ranges, sizeof (mnoderange_t), mnoderange_cmp); + + /* + * If some intrepid soul takes the axe to the memory DR code, we can + * remove ->mnr_next altogether, as we just sorted by ->mnr_pfnlo order. + * + * The VERIFY3U() above can be "==" then too. + */ + for (size_t i = 1; i < nr_ranges; i++) + mnoderanges[i].mnr_next = i - 1; + + mtypetop = nr_ranges - 1; + mtype16m = pfn_2_mtype(PFN_16MEG - 1); /* Can be -1 ... */ + if (physmax4g) + mtype4g = pfn_2_mtype(0xfffff); } #ifndef __xpv @@ -1978,9 +1978,6 @@ page_coloring_setup(caddr_t pcmemaddr) mnode_range_setup(mnoderanges); - if (physmax4g) - mtype4g = pfn_2_mtype(0xfffff); - for (k = 0; k < NPC_MUTEX; k++) { fpc_mutex[k] = (kmutex_t *)addr; addr += (max_mem_nodes * sizeof (kmutex_t)); |