Re: mlockall and mmap of IO devices don't mix

Martin J. Bligh
2003-10-04T14:34:49Z

>> > pfn_valid is useless, it doesn't handle all IO holes on x86 for examples.
>>
>> Sounds like pfn_valid() is buggy on x86. It's supposed to definitively
>> indicate whether the PFN is a valid page of ram (and has a valid struct
>> page entry.) If it doesn't do that, the architecture implementation is
>> wrong.
>
> Looks like it. But it also has to be fast (see include/asm-i386/mmzone.h)
> and doesn't even hide the holes in NUMA machines.

There are no holes between nodes for any i386 NUMA machines at the moment,
and we don't free back the struct pages for internal holes yet. So we have
pfn_valid set up for i386 such that there's a valid struct page if pfn_valid
is true.

> We had a page_is_ram() for this somewhere. I don't know, why this is
> gone. It would be useful in other places as well.
>
> If the page_is_ram() test could be done using the vma only now, this
> would be even better and should be called vma_is_ram() to generalize
> these corner cases (today and in the future) and make more
> clear what these kind of tests want to do.

page_is_ram is defined in arch/i386/mm/init.c:

static inline int page_is_ram(unsigned long pagenr)
{
int i;

for (i = 0; i < e820.nr_map; i++) {
unsigned long addr, end;

if (e820.map[i].type != E820_RAM) /* not usable memory */
continue;
/*
* !!!FIXME!!! Some BIOSen report areas as RAM that
* are not. Notably the 640->1Mb area. We need a sanity
* check here.
*/
addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
if ((pagenr >= addr) && (pagenr < end))
return 1;
}
return 0;
}

However, we probably want a runtime one that checks some aspect of
the struct page itself to see whether it's a valid memory page or not.

I believe it's useful to have the faster and slower tests still.
Most things using pfn_valid seem to be doing it before a pfn_to_page
translation to check it's safe, and we still seem to have that correct.
pfn_has_struct_page or something might be a better name, but still.

M.