RE: Where is memory handed out?

From: nathan.zook@amd.com
Date: Thu Mar 23 2000 - 11:19:30 EST


David,

I think I know how to make this work.
1) When we scan in an excluded region, we check to see if a mask is
included ie: (smap=16M-32M:X:0x06fffff), defaulting to a mask of 0. (Or
whatever it takes to exclude everything in the range.)

2) Exclusion regions are NOT stored with the SMAP region data, they go into
their own structure.
struct exclude_mem {
        int num_xmem;
        struct {
                _u64 base;
                _u64 top;
                _u64 mask;
        } regions[MAX_EXCLUDED_REGIONS];
};

num_xmem is the actual number of excluded regions recorded.

3) NVS and ACPI regions are scanned against the excluded regions.
Collisions are flagged for the ACPI driver. (This scan is accomplished at
the byte level since some ACPI regions are less than a full page.)

4) A function generates the working exclusion structure:
struct exclude_mem {
        int num_xmem;
        int low_badpage;
        struct {
                int basep;
                int topp;
                int maskp;
        } regions[MAX_EXCLUDED_REGIONS];
};

This is a translation of the above data into pages. What makes this scheme
work is the low_badpage. It points into the regions array at to the region
which excludes the lowest page. It is actually found by calling the
next_bad_page(0).

5) While initializing the first G, we read the bios-available pages off the
mempages resource tree. We compare are current page number against the
lowest bad page from the working structure.
If we are below, fine. If we are equal, we skip this page & call
next_bad_page(current_page_number+1).
If we are above, we call next_bad_page(current_page_number).
If we are then equal, we skip & call next_bad_page(current_page_number+1).

6) Once boot memory has been initialized, we copy the working structure
into boot memory. (WARNING: this data needs to be preserved until we
initialize big memory.)

7) When we initialize big memory, we continue to call next_bad_page as
necessary. When we are done, we free the working structure.

8) When the ACPI driver is ready to free the ACPI pages, it can set aside
memory for the working structure, call the function to set up the structure,
call next_bad_page(0) to initialize the working structure, and then step
through the ACPI pages, freeing them the same way we did initially.

unsigned int next_bad_page(unsigned int current_page):
if low_badpage == -1, return -1 (All exclusion regions exhausted)
if region[low_badpage].basep > current_page && current_page
        return region[low_badpage].basep

do
        if current_page
                first_bad_region_page[low_badpage, current_page];
        else
                for(i=0;i<num_xmem;i++)
                        first_bad_region_page[i, 0];
        for(i=0;i<num_xmem;i++)
                if region[i].basep < region[low_badpage].basep
                        low_badpage = i
while current_page >= region[lowbadpage].basep

if region[lowbadpage].basep == -1
        lowbadpage = -1;
        return -1;
return region[lowbadpage].basep

----
void first_bad_region_page[int index, int current_page]
if region[index].basep > region[index].topp || current_page >
region[index].topp
	region[index].basep = -1;
	return

get first bad page in region[index] >= current page set region[index].basep to this page return

=====

We end up with one comparison per page, and only make function calls when we have bad pages. The mempages tree (and its management) is much simplified by this, since there is no need to figure out how to shoehorn the excluded regions into the tree. It is not even necessary to worry about the user specifying overlapping regions and the like--we just find the next excluded page & keep going.

Obviously, I don't have the mempages tree working yet. If you would be willing to take this part off my hands, I can get it out much faster.

One part of this which is not clear to me is exactly how the mask should be specified.

We really do want base, top & mask, not just base & mask, as has been suggested, because you might get one chip out of eight, for instance, with the problem.

Note that there will be some failures if we try to support MAX_UNSIGNED_INT + 1 pages in the future.

Nathan

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Mar 23 2000 - 21:00:38 EST