On Tue, Sep 21, 2010 at 7:38 PM, Alan Cox <alan.l....@gmail.com> wrote:
> On Mon, Sep 20, 2010 at 9:32 AM, Svatopluk Kraus <onw...@gmail.com> wrote:
>> Beyond 'kernel_map', some submaps of 'kernel_map' (buffer_map,
>> pager_map,...) exist as result of 'kmem_suballoc' function call.
>> When this submaps are used (for example 'kmem_alloc_nofault'
>> function) and its virtual address subspace is at the end of
>> used kernel virtual address space at the moment (and above 'NKPT'
>> preallocation), then missing page tables are not allocated
>> and double fault can happen.
>>
>
> No, the page tables are allocated.  If you create a submap X of the kernel
> map using kmem_suballoc(), then a vm_map_findspace() is performed by
> vm_map_find() on the kernel map to find space for the submap X.  As you note
> above, the call to vm_map_findspace() on the kernel map will call
> pmap_growkernel() if needed to extend the kernel page table.
>
> If you create another submap X' of X, then that submap X' can only map
> addresses that fall within the range for X.  So, any necessary page table
> pages were allocated when X was created.

You are right. Mea culpa. I was focused on a solution and made
too quick conclusion. The page table fault hitted in 'pager_map',
which is submap of 'clean_map' and when I debugged the problem
I didn't see a submap stuff as a whole.

> That said, there may actually be a problem with the implementation of the
> superpage_align parameter to kmem_suballoc().  If a submap is created with
> superpage_align equal to TRUE, but the submap's size is not a multiple of
> the superpage size, then vm_map_find() may not allocate a page table page
> for the last megabyte or so of the submap.
>
> There are only a few places where kmem_suballoc() is called with
> superpage_align set to TRUE.  If you changed them to FALSE, that is an easy
> way to test this hypothesis.

Yes, it helps.

My story is that the problem started up when I updated a project
('coldfire' port)
based on FreeBSD 8.0. to FreeBSD current version. In the current version
the 'clean_map' submap is created with superpage_align set to TRUE.

I have looked at vm_map_find() and debugged the page table fault once again.
IMO, it looks that a do-while loop does not work in the function as intended.
A vm_map_findspace() finds a space and calls pmap_growkernel() if needed.
A pmap_align_superpage() arrange the space but never call pmap_growkernel().
A vm_map_insert() inserts the aligned space into a map without error
and never call pmap_growkernel() and does not invoke loop iteration.

I don't know too much about an idea how a virtual memory model is implemented
and used in other modules. But it seems that it could be more reasonable to
align address space in vm_map_findspace() internally and not to loop externally.

I have tried to add a check in vm_map_insert() that checks the 'end' parameter
against 'kernel_vm_end' variable and returns KERN_NO_SPACE error if needed.
In this case the loop in vm_map_find() works and I have no problem with
the page table fault. But 'kernel_vm_end' variable must be initializated
properly before first use of vm_map_insert(). The 'kernel_vm_end' variable
can be self-initializated in pmap_growkernel() in FreeBSD 8.0 (it is too late),
but it was changed in current version ('i386' port).

Thanks for your answer, but I'm still looking for permanent
and approved solution.

 Regards, Svata
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to