On Fri, Oct 03, 2014 at 05:25:33PM +0900, Kohji Okuno
wrote:> Hi,
>
> At least in i386 && 9-stable, when we call pmap_mapdev() and
> pmap_unmapdev(), kernel_pmap.pm_stats.resident_count is decreased
> incorrectly.
>
> pmap_mapdev_attr()->pmap_kenter_attr():
> In this path, kernel_pmap.pm_stats.resident_count is not increlmented.
>
>
pmap_unmapdev()->kmem_free(kernel_map)->vm_map_remove()->pmap_remove():
> But, in this path, kernel_pmap.pm_stats.resident_count is decreased in
> pmap_remove_pte().
>
> While I called pmap_mapdev() and pmap_unmapdev() repeatedly and
> kernel_pmap.pm_stats.resident_count became `0', since pmap_remove()
> returned without removing ptes, I encountered various kernel panics.
I think you are right.
The problem seems to be fixed in HEAD and 10, since mapdev was switched
to use kva_alloc/kva_free. I added stable@ to Cc:.
>
> And, when I enabled INVARIANTS, I looked the following panic message.
> panic: vm_page_free_toq: freeing mapped page 0xXXXXXXXX.
Do you mean that this panic is related to missed pmap_remove() ?
I doubt it, since pmap_mapdev() does not establish managed mappings.
>
> I think, I should change the following.
> What do you think about this?
>
>
> diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
> index 2adc6f8..a0998e8 100644
> --- a/sys/i386/i386/pmap.c
> +++ b/sys/i386/i386/pmap.c
> @@ -5061,6 +5061,7 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int
mode)
> {
> vm_offset_t va, offset;
> vm_size_t tmpsize;
> + int kmem_allocated = 0;
>
> offset = pa & PAGE_MASK;
> size = roundup(offset + size, PAGE_SIZE);
> @@ -5068,13 +5069,18 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int
mode)
>
> if (pa < KERNLOAD && pa + size <= KERNLOAD)
> va = KERNBASE + pa;
> - else
> + else {
> va = kmem_alloc_nofault(kernel_map, size);
> + kmem_allocated = 1;
You could just do
PMAP_LOCK(kernel_pmap);
kernel_pmap.pm_stats.resident_count += OFF_TO_IDX(size);
PMAP_UNLOCK(kernel_pmap);
there. And, the same fix is needed for amd64.
> + }
> if (!va)
> panic("pmap_mapdev: Couldn't alloc kernel virtual
memory");
>
> - for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE)
> + for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE) {
> pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode);
> + if (kmem_allocated)
> + kernel_pmap.pm_stats.resident_count++;
> + }
> pmap_invalidate_range(kernel_pmap, va, va + tmpsize);
> pmap_invalidate_cache_range(va, va + size);
> return ((void *)(va + offset));
> _______________________________________________
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to
"freebsd-current-unsubscribe@freebsd.org"
_______________________________________________
freebsd-stable@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to
"freebsd-stable-unsubscribe@freebsd.org"