page table fault, which should map kernel virtual address space

Svatopluk Kraus onwahe at gmail.com
Tue Oct 5 12:16:52 UTC 2010


On Mon, Oct 4, 2010 at 2:03 AM, Alan Cox <alan.l.cox at gmail.com> wrote:
> On Thu, Sep 30, 2010 at 6:28 AM, Svatopluk Kraus <onwahe at gmail.com> wrote:
>>
>> On Tue, Sep 21, 2010 at 7:38 PM, Alan Cox <alan.l.cox at gmail.com> wrote:
>> > On Mon, Sep 20, 2010 at 9:32 AM, Svatopluk Kraus <onwahe at 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.
>
> I have a patch that implements one possible fix for this problem.  I'll
> probably commit that patch in the next day or two.
>
> Regards,
> Alan

I tried your patch and it works. Many thanks.

Regards, Svata


More information about the freebsd-hackers mailing list