Re: page table fault, which should map kernel virtual address space
On Mon, Oct 4, 2010 at 2:03 AM, Alan Cox wrote: > On Thu, Sep 30, 2010 at 6:28 AM, Svatopluk Kraus wrote: >> >> On Tue, Sep 21, 2010 at 7:38 PM, Alan Cox wrote: >> > On Mon, Sep 20, 2010 at 9:32 AM, Svatopluk Kraus >> > 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 ___ 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"
Re: page table fault, which should map kernel virtual address space
On Thu, Sep 30, 2010 at 6:28 AM, Svatopluk Kraus wrote: > On Tue, Sep 21, 2010 at 7:38 PM, Alan Cox wrote: > > On Mon, Sep 20, 2010 at 9:32 AM, Svatopluk Kraus > 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 ___ 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"
Re: page table fault, which should map kernel virtual address space
On Tue, Sep 21, 2010 at 7:38 PM, Alan Cox wrote: > On Mon, Sep 20, 2010 at 9:32 AM, Svatopluk Kraus 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"
Re: page table fault, which should map kernel virtual address space
On Mon, Sep 20, 2010 at 9:32 AM, Svatopluk Kraus wrote: > > Hallo, > > this is about 'NKPT' definition, 'kernel_map' submaps, > and 'vm_map_findspace' function. > > Variable 'kernel_map' is used to manage kernel virtual address > space. When 'vm_map_findspace' function deals with 'kernel_map' > then 'pmap_growkernel' function is called. > > At least in 'i386' architecture, pmap implementation uses > 'pmap_growkernel' function to allocate missing page tables. > Missing page tables are problem, because no one checks > 'pte' pointer for validity after use of 'vtopte' macro. > > 'NKPT' definition defines a number of preallocated > page tables during system boot. > > 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. 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. Regards, Alan ___ 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"
page table fault, which should map kernel virtual address space
Hallo, this is about 'NKPT' definition, 'kernel_map' submaps, and 'vm_map_findspace' function. Variable 'kernel_map' is used to manage kernel virtual address space. When 'vm_map_findspace' function deals with 'kernel_map' then 'pmap_growkernel' function is called. At least in 'i386' architecture, pmap implementation uses 'pmap_growkernel' function to allocate missing page tables. Missing page tables are problem, because no one checks 'pte' pointer for validity after use of 'vtopte' macro. 'NKPT' definition defines a number of preallocated page tables during system boot. 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. I have met this scenario and solved it by increasing page tables preallocation count ('NKPT' definition). It's temporary solution which works for the present. Can someone more advanced and sacred in virtual memory module solve it (in 'vm_map_findspace' function for example)? Or tell me that the problem is elsewhere... Thanks, Svata -- View this message in context: http://old.nabble.com/page-table-fault%2C-which-should-map-kernel-virtual-address-space-tp29760054p29760054.html Sent from the freebsd-hackers mailing list archive at Nabble.com. ___ 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"