Print this page
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>

*** 22,32 **** * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 2010, Intel Corporation. * All rights reserved. ! * Copyright 2018 Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ --- 22,32 ---- * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 2010, Intel Corporation. * All rights reserved. ! * Copyright 2019, Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */
*** 200,214 **** /* * 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 */ /* * 4g memory management variables for systems with more than 4g of memory: * * physical memory below 4g is required for 32bit dma devices and, currently, --- 200,214 ---- /* * This combines mem_node_config and memranges into one data * structure to be used for page list management. */ ! 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: * * physical memory below 4g is required for 32bit dma devices and, currently,
*** 261,271 **** */ #define FREEMEM16M MTYPE_FREEMEM(mtype16m) #define DESFREE16M desfree16m #define RESTRICT16M_ALLOC(freemem, pgcnt, flags) \ ! ((freemem != 0) && ((flags & PG_PANIC) == 0) && \ ((freemem >= (FREEMEM16M)) || \ (FREEMEM16M < (DESFREE16M + pgcnt)))) static pgcnt_t desfree16m = 0x380; --- 261,271 ---- */ #define FREEMEM16M MTYPE_FREEMEM(mtype16m) #define DESFREE16M desfree16m #define RESTRICT16M_ALLOC(freemem, pgcnt, flags) \ ! (mtype16m != -1 && (freemem != 0) && ((flags & PG_PANIC) == 0) && \ ((freemem >= (FREEMEM16M)) || \ (FREEMEM16M < (DESFREE16M + pgcnt)))) static pgcnt_t desfree16m = 0x380;
*** 1387,1464 **** ASSERT(mnrcnt <= MAX_MNODE_MRANGES); return (mnrcnt); #endif /* __xpv */ } ! /* ! * mnode_range_setup() initializes mnoderanges. ! */ 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++) { 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), mem_node_config[mnode].physbase); ! mnoderanges->mnr_pfnhi = MIN(MEMRANGEHI(mri), mem_node_config[mnode].physmax); ! mnoderanges->mnr_mnode = mnode; ! mnoderanges->mnr_memrange = mri; ! mnoderanges->mnr_exists = 1; ! mnoderanges++; ! mindex++; if (mem_node_config[mnode].physmax > MEMRANGEHI(mri)) mri--; else break; } } /* ! * 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. */ ! 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; } #ifndef __xpv /* * Update mnoderanges for memory hot-add DR operations. --- 1387,1464 ---- ASSERT(mnrcnt <= MAX_MNODE_MRANGES); return (mnrcnt); #endif /* __xpv */ } ! 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; ! 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; while (MEMRANGEHI(mri) < mem_node_config[mnode].physbase) mri--; while (mri >= 0 && mem_node_config[mnode].physmax >= MEMRANGELO(mri)) { ! mp->mnr_pfnlo = MAX(MEMRANGELO(mri), mem_node_config[mnode].physbase); ! mp->mnr_pfnhi = MIN(MEMRANGEHI(mri), mem_node_config[mnode].physmax); ! 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 break; } } /* ! * mnoderangecnt can be larger than nr_ranges when memory DR is ! * supposedly supported. */ ! 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 /* * Update mnoderanges for memory hot-add DR operations.
*** 1976,1988 **** mnoderanges = (mnoderange_t *)addr; addr += (mnoderangecnt * sizeof (mnoderange_t)); 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)); } for (k = 0; k < NPC_MUTEX; k++) { --- 1976,1985 ----