svn commit: r224516 - in head/sys: amd64/amd64 i386/i386
pc98/pc98
Bruce Evans
brde at optusnet.com.au
Sat Jul 30 23:21:53 UTC 2011
On Sun, 31 Jul 2011, Bruce Evans wrote:
> ... In the
> whole kernel, 155 lines match TUNABLE.*FETCH and 14 of these match 'if ('.
> Some of the 14 are not wrong. About 1/3 of them are for dubious use in
> memory sizing. E.g., in amd64/machdep.c:
>
> % realmem = Maxmem;
>
> The unprobed Maxmem remains in realmem for printing a confusing value later
> in sysctls.
Oops. This is actually the final (probed) value of Maxmem. I got confused
by the file order being different from the dynamic order.
>
> % % /*
> % * Display physical memory if SMBIOS reports reasonable amount.
> % */
> % memsize = 0;
> % sysenv = getenv("smbios.memory.enabled");
> % if (sysenv != NULL) {
> % memsize = (uintmax_t)strtoul(sysenv, (char **)NULL, 10) <<
> 10;
> % freeenv(sysenv);
> % }
>
> First override for `memsize'.
>
> % if (memsize < ptoa((uintmax_t)cnt.v_free_count))
> % memsize = ptoa((uintmax_t)Maxmem);
>
> `memsize' is normally (?) `Maxmem' in bytes, but not if SMBIOS set it.
>
> % printf("real memory = %ju (%ju MB)\n", memsize, memsize >> 20);
>
> Code doesn't match comment. The display is unconditional, but the comment
> set that it is only done if SMBIOS reports a reasonable amount.
>
> `memsize' is not used after this point, so the only effect of the SMBIOS
> check is to possibly print a value that is different from all of the
> following:
> - the initial Maxmem in bytes
> - the final realmem in bytes (this equals the initial Maxmem in bytes)
> - the final Maxmem in bytes.
> The comment is also wrong in saying that SMBIOS is used. Only an
> environment string is used. Users can easily confuse themselves by putting
> garbage in this string.
>
> The above logic is also confused by the memory size being in cnt.v_free_cnt.
> If SMBIOS does't change memsize from 0, then we use Maxmem even if it is
> larger than cnt.v_free_cnt.
So realmem is the correct final value unless the SMBIOS non-call gives a
different value; in the latter case, we print this different value above
but the realmem sysctl can't recover it.
> % /*
> % * Maxmem isn't the "maximum memory", it's one larger than the
> % * highest page of the physical address space. It should be
> % * called something like "Maxphyspage". We may adjust this
> % * based on ``hw.physmem'' and the results of the memory test.
> % */
> % Maxmem = atop(physmap[physmap_idx + 1]);
>
> Here we change Maxmem to another unprobed value. I think this value is
> more closely related to cnt.v_free_cnt.
>
> % % #ifdef MAXMEM
> % Maxmem = MAXMEM / 4;
> % #endif
>
> Then we optionally change MaxMem to a hard-configured value.
>
> % % if (TUNABLE_ULONG_FETCH("hw.physmem", &physmem_tunable))
> % Maxmem = atop(physmem_tunable);
>
> Then we use a temporary variable, since the primary variable has
> units of pages while the tunable has units of bytes. But this can
> be reorganized to:
>
> /*
> * memsize was Maxmem in bytes, but was not maintained when Maxmem
> * was changed about. Maintain it now.
> */
> memsize = ptoa(Maxmem).
> *
> * XXX we also have a physmem variable, but this can't be used to
> * hole the result of the tunable any more than Maxmem can, since
> * it is in pages. memsize is not quite right either, since it
> * is a uintmax_t while the following assumes that it is u_long.
> * The u_long is too small for PAE on i386, but works for amd64.
> * The uintmax_t is needed on i386, but is not needed for amd64.
> */
> TUNABLE_ULONG_FETCH("hw.physmem", &memsize); /* XXX sic */
> Maxmem = atop(memsize);
>
> % /*
> % * Don't allow MAXMEM or hw.physmem to extend the amount of memory
> % * in the system.
> % */
> % if (Maxmem > atop(physmap[physmap_idx + 1]))
> % Maxmem = atop(physmap[physmap_idx + 1]);
Now we're in the getmemsize() function, which doesn't have a memsize
variable. It should have one instead of the physmem_tunable variable,
if only because the physmem tunable is actually for memsize in bytes
and not for physmem in pages.
Bruce
More information about the svn-src-head
mailing list