Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-05 Thread Kohji Okuno
Hi Konstantin,

I tested your patch. It was no problem.
Thank you for your kind correspondence.

Regards,
 Kohji Okuno

> On Sat, Oct 04, 2014 at 05:53:26PM +0900, Kohji Okuno wrote:
>> Hi, Konstantin,
>> 
>> > At the end of the mail is commit candidate.  I did not even compiled this.
>> > Can you test and report back, please ?
>> 
>> Could you check the following?
>> (1) should use kernel_pmap->pm_stats.resident_count
>>   ^^^
>> I'm sorry. My patch was wrong. 
> As well as mine.
> 
>> 
>> (2) should use pmap_resident_count_inc() in amd64.
> Correct.
> 
>> 
>> 
>> I will test, later.
>> 
>> In addtion, I have one question.
>> In current and 10-stable, is vm_map_delete() called by kva_free()?
> No, kva_free() only releases the vmem backing, leaving the page
> tables intact.  This is why I only did the stable/9 patch.
> 
>> If vm_map_delete() is called, this fix is needed in current and
>> 10-stable, I think.
> 
> Updated patch below.
> 
> Index: amd64/amd64/pmap.c
> ===
> --- amd64/amd64/pmap.c(revision 272506)
> +++ amd64/amd64/pmap.c(working copy)
> @@ -5040,6 +5040,9 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, in
>   pa = trunc_page(pa);
>   for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE)
>   pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode);
> + PMAP_LOCK(kernel_pmap);
> + pmap_resident_count_inc(kernel_pmap, OFF_TO_IDX(size));
> + PMAP_UNLOCK(kernel_pmap);
>   pmap_invalidate_range(kernel_pmap, va, va + tmpsize);
>   pmap_invalidate_cache_range(va, va + tmpsize);
>   return ((void *)(va + offset));
> Index: i386/i386/pmap.c
> ===
> --- i386/i386/pmap.c  (revision 272506)
> +++ i386/i386/pmap.c  (working copy)
> @@ -5066,10 +5066,14 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, in
>   size = roundup(offset + size, PAGE_SIZE);
>   pa = pa & PG_FRAME;
>  
> - if (pa < KERNLOAD && pa + size <= KERNLOAD)
> + if (pa < KERNLOAD && pa + size <= KERNLOAD) {
>   va = KERNBASE + pa;
> - else
> + } else {
>   va = kmem_alloc_nofault(kernel_map, size);
> + PMAP_LOCK(kernel_pmap);
> + kernel_pmap->pm_stats.resident_count += OFF_TO_IDX(size);
> + PMAP_UNLOCK(kernel_pmap);
> + }
>   if (!va)
>   panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
>  
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-05 Thread Kohji Okuno
Hi Konstantin,

Thank you very much for your detailed explanatin.
I understood the policy of vmem.

Many thanks,
 Kohji Okuno

> On Sun, Oct 05, 2014 at 01:15:12PM +0900, Kohji Okuno wrote:
>> Hi,
>> 
>> > On Sat, Oct 04, 2014 at 08:53:35PM +0900, Kohji Okuno wrote:
>> >> Hi Konstantin,
>> >> 
>> >> Thank you for your prompt response.
>> >> I will test and report from next monday.
>> >> 
>> >> >> In addtion, I have one question.
>> >> >> In current and 10-stable, is vm_map_delete() called by kva_free()?
>> >> > No, kva_free() only releases the vmem backing, leaving the page
>> >> > tables intact.  This is why I only did the stable/9 patch.
>> >> 
>> >> Where are PTEs allocated by pmap_mapdev() freed in current and 10-stable?
>> >> Could you please explain me?
>> > They are not freed. The removal of the vmem which covers the address
>> > space managed by corresponding ptes, allows the reuse of both KVA region
>> > and corresponding PTEs in the tables. The only concern with the resident
>> > page tables is to avoid two kva_alloc() to step over each other, and
>> > this is ensured by vmem.
>> 
>> I agree that normal pages are reusable. But, since the pages mapped by
>> pmap_mapdev() are concerned with the physicall address of device (For
>> example: video memory), these PTEs aren't reusable, I think.
>> So, should we free these PTEs by pmap_unmapdev()?
> There is no hold on any physical pages which were referenced by the ptes.
> The only thing which is left out are the records in the page tables
> which map the KVA to said device memory.  It is harmless.
> 
> When the KVA is reused, the ptes in page tables are overwritten.
> 
> It might be argued that clearing PTEs, or at least removing the PG_V
> bit catches erronous unintended accesses to the freed range, but by the
> cost of the overhead of re-polluting the caches. And since clearing is
> not effective without doing TLB flush, which requires broadcast IPI,
> it is more trouble than advantage.
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-05 Thread Konstantin Belousov
On Sun, Oct 05, 2014 at 01:15:12PM +0900, Kohji Okuno wrote:
> Hi,
> 
> > On Sat, Oct 04, 2014 at 08:53:35PM +0900, Kohji Okuno wrote:
> >> Hi Konstantin,
> >> 
> >> Thank you for your prompt response.
> >> I will test and report from next monday.
> >> 
> >> >> In addtion, I have one question.
> >> >> In current and 10-stable, is vm_map_delete() called by kva_free()?
> >> > No, kva_free() only releases the vmem backing, leaving the page
> >> > tables intact.  This is why I only did the stable/9 patch.
> >> 
> >> Where are PTEs allocated by pmap_mapdev() freed in current and 10-stable?
> >> Could you please explain me?
> > They are not freed. The removal of the vmem which covers the address
> > space managed by corresponding ptes, allows the reuse of both KVA region
> > and corresponding PTEs in the tables. The only concern with the resident
> > page tables is to avoid two kva_alloc() to step over each other, and
> > this is ensured by vmem.
> 
> I agree that normal pages are reusable. But, since the pages mapped by
> pmap_mapdev() are concerned with the physicall address of device (For
> example: video memory), these PTEs aren't reusable, I think.
> So, should we free these PTEs by pmap_unmapdev()?
There is no hold on any physical pages which were referenced by the ptes.
The only thing which is left out are the records in the page tables
which map the KVA to said device memory.  It is harmless.

When the KVA is reused, the ptes in page tables are overwritten.

It might be argued that clearing PTEs, or at least removing the PG_V
bit catches erronous unintended accesses to the freed range, but by the
cost of the overhead of re-polluting the caches. And since clearing is
not effective without doing TLB flush, which requires broadcast IPI,
it is more trouble than advantage.
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-04 Thread Kohji Okuno
Hi,

> On Sat, Oct 04, 2014 at 08:53:35PM +0900, Kohji Okuno wrote:
>> Hi Konstantin,
>> 
>> Thank you for your prompt response.
>> I will test and report from next monday.
>> 
>> >> In addtion, I have one question.
>> >> In current and 10-stable, is vm_map_delete() called by kva_free()?
>> > No, kva_free() only releases the vmem backing, leaving the page
>> > tables intact.  This is why I only did the stable/9 patch.
>> 
>> Where are PTEs allocated by pmap_mapdev() freed in current and 10-stable?
>> Could you please explain me?
> They are not freed. The removal of the vmem which covers the address
> space managed by corresponding ptes, allows the reuse of both KVA region
> and corresponding PTEs in the tables. The only concern with the resident
> page tables is to avoid two kva_alloc() to step over each other, and
> this is ensured by vmem.

I agree that normal pages are reusable. But, since the pages mapped by
pmap_mapdev() are concerned with the physicall address of device (For
example: video memory), these PTEs aren't reusable, I think.
So, should we free these PTEs by pmap_unmapdev()?

Best regards,
 Kohji Okuno

___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-04 Thread Konstantin Belousov
On Sat, Oct 04, 2014 at 08:53:35PM +0900, Kohji Okuno wrote:
> Hi Konstantin,
> 
> Thank you for your prompt response.
> I will test and report from next monday.
> 
> >> In addtion, I have one question.
> >> In current and 10-stable, is vm_map_delete() called by kva_free()?
> > No, kva_free() only releases the vmem backing, leaving the page
> > tables intact.  This is why I only did the stable/9 patch.
> 
> Where are PTEs allocated by pmap_mapdev() freed in current and 10-stable?
> Could you please explain me?
They are not freed. The removal of the vmem which covers the address
space managed by corresponding ptes, allows the reuse of both KVA region
and corresponding PTEs in the tables. The only concern with the resident
page tables is to avoid two kva_alloc() to step over each other, and
this is ensured by vmem.
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-04 Thread Kohji Okuno
Hi Konstantin,

Thank you for your prompt response.
I will test and report from next monday.

>> In addtion, I have one question.
>> In current and 10-stable, is vm_map_delete() called by kva_free()?
> No, kva_free() only releases the vmem backing, leaving the page
> tables intact.  This is why I only did the stable/9 patch.

Where are PTEs allocated by pmap_mapdev() freed in current and 10-stable?
Could you please explain me?

Regards,
 Kohji Okuno

> On Sat, Oct 04, 2014 at 05:53:26PM +0900, Kohji Okuno wrote:
>> Hi, Konstantin,
>> 
>> > At the end of the mail is commit candidate.  I did not even compiled this.
>> > Can you test and report back, please ?
>> 
>> Could you check the following?
>> (1) should use kernel_pmap->pm_stats.resident_count
>>   ^^^
>> I'm sorry. My patch was wrong. 
> As well as mine.
> 
>> 
>> (2) should use pmap_resident_count_inc() in amd64.
> Correct.
> 
>> 
>> 
>> I will test, later.
>> 
>> In addtion, I have one question.
>> In current and 10-stable, is vm_map_delete() called by kva_free()?
> No, kva_free() only releases the vmem backing, leaving the page
> tables intact.  This is why I only did the stable/9 patch.
> 
>> If vm_map_delete() is called, this fix is needed in current and
>> 10-stable, I think.
> 
> Updated patch below.
> 
> Index: amd64/amd64/pmap.c
> ===
> --- amd64/amd64/pmap.c(revision 272506)
> +++ amd64/amd64/pmap.c(working copy)
> @@ -5040,6 +5040,9 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, in
>   pa = trunc_page(pa);
>   for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE)
>   pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode);
> + PMAP_LOCK(kernel_pmap);
> + pmap_resident_count_inc(kernel_pmap, OFF_TO_IDX(size));
> + PMAP_UNLOCK(kernel_pmap);
>   pmap_invalidate_range(kernel_pmap, va, va + tmpsize);
>   pmap_invalidate_cache_range(va, va + tmpsize);
>   return ((void *)(va + offset));
> Index: i386/i386/pmap.c
> ===
> --- i386/i386/pmap.c  (revision 272506)
> +++ i386/i386/pmap.c  (working copy)
> @@ -5066,10 +5066,14 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, in
>   size = roundup(offset + size, PAGE_SIZE);
>   pa = pa & PG_FRAME;
>  
> - if (pa < KERNLOAD && pa + size <= KERNLOAD)
> + if (pa < KERNLOAD && pa + size <= KERNLOAD) {
>   va = KERNBASE + pa;
> - else
> + } else {
>   va = kmem_alloc_nofault(kernel_map, size);
> + PMAP_LOCK(kernel_pmap);
> + kernel_pmap->pm_stats.resident_count += OFF_TO_IDX(size);
> + PMAP_UNLOCK(kernel_pmap);
> + }
>   if (!va)
>   panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
>  
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-04 Thread Konstantin Belousov
On Sat, Oct 04, 2014 at 05:53:26PM +0900, Kohji Okuno wrote:
> Hi, Konstantin,
> 
> > At the end of the mail is commit candidate.  I did not even compiled this.
> > Can you test and report back, please ?
> 
> Could you check the following?
> (1) should use kernel_pmap->pm_stats.resident_count
>   ^^^
> I'm sorry. My patch was wrong. 
As well as mine.

> 
> (2) should use pmap_resident_count_inc() in amd64.
Correct.

> 
> 
> I will test, later.
> 
> In addtion, I have one question.
> In current and 10-stable, is vm_map_delete() called by kva_free()?
No, kva_free() only releases the vmem backing, leaving the page
tables intact.  This is why I only did the stable/9 patch.

> If vm_map_delete() is called, this fix is needed in current and
> 10-stable, I think.

Updated patch below.

Index: amd64/amd64/pmap.c
===
--- amd64/amd64/pmap.c  (revision 272506)
+++ amd64/amd64/pmap.c  (working copy)
@@ -5040,6 +5040,9 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, in
pa = trunc_page(pa);
for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE)
pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode);
+   PMAP_LOCK(kernel_pmap);
+   pmap_resident_count_inc(kernel_pmap, OFF_TO_IDX(size));
+   PMAP_UNLOCK(kernel_pmap);
pmap_invalidate_range(kernel_pmap, va, va + tmpsize);
pmap_invalidate_cache_range(va, va + tmpsize);
return ((void *)(va + offset));
Index: i386/i386/pmap.c
===
--- i386/i386/pmap.c(revision 272506)
+++ i386/i386/pmap.c(working copy)
@@ -5066,10 +5066,14 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, in
size = roundup(offset + size, PAGE_SIZE);
pa = pa & PG_FRAME;
 
-   if (pa < KERNLOAD && pa + size <= KERNLOAD)
+   if (pa < KERNLOAD && pa + size <= KERNLOAD) {
va = KERNBASE + pa;
-   else
+   } else {
va = kmem_alloc_nofault(kernel_map, size);
+   PMAP_LOCK(kernel_pmap);
+   kernel_pmap->pm_stats.resident_count += OFF_TO_IDX(size);
+   PMAP_UNLOCK(kernel_pmap);
+   }
if (!va)
panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
 
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-04 Thread Kohji Okuno
Hi, Konstantin,

> At the end of the mail is commit candidate.  I did not even compiled this.
> Can you test and report back, please ?

Could you check the following?
(1) should use kernel_pmap->pm_stats.resident_count
  ^^^
I'm sorry. My patch was wrong. 

(2) should use pmap_resident_count_inc() in amd64.


I will test, later.

In addtion, I have one question.
In current and 10-stable, is vm_map_delete() called by kva_free()?
If vm_map_delete() is called, this fix is needed in current and
10-stable, I think.

Regards,
 Kohji Okuno

> On Sat, Oct 04, 2014 at 05:00:36PM +0900, Kohji Okuno wrote:
>> Hi, Konstantin,
>> 
>> Thank you for your comment.
>> And, your change is better than mine.
> At the end of the mail is commit candidate.  I did not even compiled this.
> Can you test and report back, please ?
> 
>> 
>> > Do you mean that this panic is related to missed pmap_remove() ?
>> > I doubt it, since pmap_mapdev() does not establish managed mappings.
>> 
>> Yes, pmap_mapdev() does not establish managed mappings. But, if
>> kernel_pmap.pm_stats.resident_count is zero, then any managed pages
>> (for example pipe_map, exec_map, or etc.) are not able to change
>> unmanaged status, because pmap_remove() returns without calling
>> pmap_remove_pte().
>> 
>> In this result, I encounterd the panic. Could you refer the following?
> Yes, kmem_back() indeed uses managed mapping.
> 
> Index: amd64/amd64/pmap.c
> ===
> --- amd64/amd64/pmap.c(revision 272506)
> +++ amd64/amd64/pmap.c(working copy)
> @@ -5040,6 +5040,9 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, in
>   pa = trunc_page(pa);
>   for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE)
>   pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode);
> + PMAP_LOCK(kernel_pmap);
> + kernel_pmap.pm_stats.resident_count += OFF_TO_IDX(size);
> + PMAP_UNLOCK(kernel_pmap);
>   pmap_invalidate_range(kernel_pmap, va, va + tmpsize);
>   pmap_invalidate_cache_range(va, va + tmpsize);
>   return ((void *)(va + offset));
> Index: i386/i386/pmap.c
> ===
> --- i386/i386/pmap.c  (revision 272506)
> +++ i386/i386/pmap.c  (working copy)
> @@ -5066,10 +5066,14 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, in
>   size = roundup(offset + size, PAGE_SIZE);
>   pa = pa & PG_FRAME;
>  
> - if (pa < KERNLOAD && pa + size <= KERNLOAD)
> + if (pa < KERNLOAD && pa + size <= KERNLOAD) {
>   va = KERNBASE + pa;
> - else
> + } else {
>   va = kmem_alloc_nofault(kernel_map, size);
> + PMAP_LOCK(kernel_pmap);
> + kernel_pmap.pm_stats.resident_count += OFF_TO_IDX(size);
> + PMAP_UNLOCK(kernel_pmap);
> + }
>   if (!va)
>   panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
>  
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-04 Thread Konstantin Belousov
On Sat, Oct 04, 2014 at 05:00:36PM +0900, Kohji Okuno wrote:
> Hi, Konstantin,
> 
> Thank you for your comment.
> And, your change is better than mine.
At the end of the mail is commit candidate.  I did not even compiled this.
Can you test and report back, please ?

> 
> > Do you mean that this panic is related to missed pmap_remove() ?
> > I doubt it, since pmap_mapdev() does not establish managed mappings.
> 
> Yes, pmap_mapdev() does not establish managed mappings. But, if
> kernel_pmap.pm_stats.resident_count is zero, then any managed pages
> (for example pipe_map, exec_map, or etc.) are not able to change
> unmanaged status, because pmap_remove() returns without calling
> pmap_remove_pte().
> 
> In this result, I encounterd the panic. Could you refer the following?
Yes, kmem_back() indeed uses managed mapping.

Index: amd64/amd64/pmap.c
===
--- amd64/amd64/pmap.c  (revision 272506)
+++ amd64/amd64/pmap.c  (working copy)
@@ -5040,6 +5040,9 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, in
pa = trunc_page(pa);
for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE)
pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode);
+   PMAP_LOCK(kernel_pmap);
+   kernel_pmap.pm_stats.resident_count += OFF_TO_IDX(size);
+   PMAP_UNLOCK(kernel_pmap);
pmap_invalidate_range(kernel_pmap, va, va + tmpsize);
pmap_invalidate_cache_range(va, va + tmpsize);
return ((void *)(va + offset));
Index: i386/i386/pmap.c
===
--- i386/i386/pmap.c(revision 272506)
+++ i386/i386/pmap.c(working copy)
@@ -5066,10 +5066,14 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, in
size = roundup(offset + size, PAGE_SIZE);
pa = pa & PG_FRAME;
 
-   if (pa < KERNLOAD && pa + size <= KERNLOAD)
+   if (pa < KERNLOAD && pa + size <= KERNLOAD) {
va = KERNBASE + pa;
-   else
+   } else {
va = kmem_alloc_nofault(kernel_map, size);
+   PMAP_LOCK(kernel_pmap);
+   kernel_pmap.pm_stats.resident_count += OFF_TO_IDX(size);
+   PMAP_UNLOCK(kernel_pmap);
+   }
if (!va)
panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
 
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-04 Thread Kohji Okuno
Hi, Konstantin,

Thank you for your comment.
And, your change is better than mine.

> Do you mean that this panic is related to missed pmap_remove() ?
> I doubt it, since pmap_mapdev() does not establish managed mappings.

Yes, pmap_mapdev() does not establish managed mappings. But, if
kernel_pmap.pm_stats.resident_count is zero, then any managed pages
(for example pipe_map, exec_map, or etc.) are not able to change
unmanaged status, because pmap_remove() returns without calling
pmap_remove_pte().

In this result, I encounterd the panic. Could you refer the following?

Regards,
 Kohji Okuno

int
vm_map_delete(vm_map_t map, vm_offset_t start, vm_offset_t end)
{
 >> SNIP <<
   /** this pmap_remove() does not change for mappings! **/
   pmap_remove(map->pmap, entry->start, entry->end);

/*
 * Delete the entry only after removing all pmap
 * entries pointing to its pages.  (Otherwise, its
 * page frames may be reallocated, and any modify bits
 * will be set in the wrong object!)
 */

/** this calls vm_page_free_toq() and causes panic! **/
vm_map_entry_delete(map, entry);
entry = next;
}
return (KERN_SUCCESS);
}

> 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 0x.
> 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-unsubscr...@freebsd.org"
> ___
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


Re: About pmap_mapdev() & pmap_unmapdev()

2014-10-03 Thread Konstantin Belousov
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 0x.
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-unsubscr...@freebsd.org"
___
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"


About pmap_mapdev() & pmap_unmapdev()

2014-10-03 Thread Kohji Okuno
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.

And, when I enabled INVARIANTS, I looked the following panic message.
panic: vm_page_free_toq: freeing mapped page 0x.

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;
+   }
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-unsubscr...@freebsd.org"