Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 08 Oct 2010 12:39:52 -0500
From:      Alan Cox <alc@rice.edu>
To:        Kurt Alstrup <kalstrup@frontier.com>
Cc:        freebsd-stable@freebsd.org
Subject:   Re: Panic: attempted pmap_enter on 2MB page
Message-ID:  <4CAF5768.4020605@rice.edu>
In-Reply-To: <4CAF4D64.4050105@frontier.com>
References:  <4CAC14DA.7050409@verizon.net> <4CADFD60.9040005@rice.edu> <4CAF4D64.4050105@frontier.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Kurt Alstrup wrote:
> Apologies for late response, wanted to check the code again.
>
>
> On 10/07/2010 10:03 AM, Alan Cox wrote:
>   
>> Alan Cox wrote:
>> At a high-level, I agree with much of what you say.  In particular, if
>> pmap_enter() is applied to a virtual address that is already mapped by a large
>> page, the reported panic could result.  However, barring bugs, for example, in
>> memory allocation by the upper levels of the kernel, the panic inducing
>> situation shouldn't occur.
>>     
> Calls to malloc() of items larger than a page takes a turn through UMA and
> eventually ends up in kmem_malloc() via its page_alloc() routine.
> Kmem_malloc() in turn gets the pages from vm_page_alloc(), parks them in
> the kmem_object and maps them into the kernel_pmap in a loop callings
> pmap_enter() for each page. The assigned VA's are pulled from kmem_map.
> Pages acquired through vm_page_alloc() may be backed by a super page
> reservation and thus are eligible for auto-promotion.
>
> Calls to free() initially take a similar route, ending up on kmem_free()
> via UMAs page_free() routine. From there the call path is vm_map_remove(),
> vm_map_remove(), vm_map_delete() to pmap_remove().
>
> This logic indicate, that from the kernel/vm perspective the malloc/free()
> pair will map/unmap pages as needed. However, the pmapper never unmaps
> these pages as far as I can tell. The call path is pmap_remove(),
> pmap_remove_pte() to pmap_unuse_pt() who ignores the removal because the
> VA >= VM_MAXUSER_ADDRESS.
>
>   

No, consider:

static int
pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va,
    pd_entry_t ptepde, vm_page_t *free)
{
        pt_entry_t oldpte;
        vm_page_t m;

        PMAP_LOCK_ASSERT(pmap, MA_OWNED);
        oldpte = pte_load_clear(ptq);

pte_load_clear() zeroes the PTE, regardless of whether it is a kernel or 
user PTE.

I'm afraid that I need to catch an airplane.  I'll follow up to the rest 
of your message later.

Regards,
Alan





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4CAF5768.4020605>