All of lore.kernel.org
 help / color / mirror / Atom feed
* avoiding duplicate icache flushing of shared maps on nommu
@ 2009-11-28 15:40 Mike Frysinger
  2009-11-28 18:53 ` Mike Frysinger
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Mike Frysinger @ 2009-11-28 15:40 UTC (permalink / raw)
  To: David Howells, Paul Mundt, Bernd Schmidt, Jie Zhang
  Cc: Linux kernel mailing list, uclinux-dist-devel

when working with FDPIC, there are many shared maps of read only text
regions (the C library, applet packages like busybox, ...) between
applications.  but the current mm/nommu.c:do_mmap_pgoff() function
will issue an icache flush whenever a vma is added to a mm instead of
only doing it when the map is initially created.  am i missing
something obvious here, or would a change like below be OK ?  this
easily cuts the number of icache flushes during boot by 50% if not
more.

(yes, this now does the icache flush while holding the
nommu_region_sem, but i'm interested if the _idea_ is OK)

--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1409,14 +1409,14 @@ unsigned long do_mmap_pgoff(struct file *file,

    current->mm->total_vm += len >> PAGE_SHIFT;

+   if (prot & PROT_EXEC)
+       flush_icache_range(result, result + len);
+
 share:
    add_vma_to_mm(current->mm, vma);

    up_write(&nommu_region_sem);

-   if (prot & PROT_EXEC)
-       flush_icache_range(result, result + len);
-
    kleave(" = %lx", result);
    return result;

-mike

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: avoiding duplicate icache flushing of shared maps on nommu
  2009-11-28 15:40 avoiding duplicate icache flushing of shared maps on nommu Mike Frysinger
@ 2009-11-28 18:53 ` Mike Frysinger
  2009-11-30  3:18 ` Jie Zhang
  2009-12-02 14:15 ` David Howells
  2 siblings, 0 replies; 8+ messages in thread
From: Mike Frysinger @ 2009-11-28 18:53 UTC (permalink / raw)
  To: David Howells, Paul Mundt, Bernd Schmidt, Jie Zhang
  Cc: Linux kernel mailing list, uclinux-dist-devel

On Sat, Nov 28, 2009 at 10:40, Mike Frysinger wrote:
> when working with FDPIC, there are many shared maps of read only text
> regions (the C library, applet packages like busybox, ...) between
> applications.  but the current mm/nommu.c:do_mmap_pgoff() function
> will issue an icache flush whenever a vma is added to a mm instead of
> only doing it when the map is initially created.  am i missing
> something obvious here, or would a change like below be OK ?  this
> easily cuts the number of icache flushes during boot by 50% if not
> more.

for some actual numbers, my default boot iflushes 18,562,124 bytes.
with this fix, it's down to 4,528,580 bytes (a 75% shrink).  with the
stack fix, it's down to 989,636 bytes (a 95% shrink).
-mike

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: avoiding duplicate icache flushing of shared maps on nommu
  2009-11-28 15:40 avoiding duplicate icache flushing of shared maps on nommu Mike Frysinger
  2009-11-28 18:53 ` Mike Frysinger
@ 2009-11-30  3:18 ` Jie Zhang
  2009-12-02 14:15 ` David Howells
  2 siblings, 0 replies; 8+ messages in thread
From: Jie Zhang @ 2009-11-30  3:18 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: David Howells, Paul Mundt, Bernd Schmidt,
	Linux kernel mailing list, uclinux-dist-devel

On 11/28/2009 11:40 PM, Mike Frysinger wrote:
> when working with FDPIC, there are many shared maps of read only text
> regions (the C library, applet packages like busybox, ...) between
> applications.  but the current mm/nommu.c:do_mmap_pgoff() function
> will issue an icache flush whenever a vma is added to a mm instead of
> only doing it when the map is initially created.  am i missing
> something obvious here, or would a change like below be OK ?  this
> easily cuts the number of icache flushes during boot by 50% if not
> more.
>
> (yes, this now does the icache flush while holding the
> nommu_region_sem, but i'm interested if the _idea_ is OK)
>
I don't see any problem. But I'm not a kernel expert. I tried to take a 
look at the source code history. But I cannot find code older than 
2.6.12. In the CVS repository of uClinux, there is no similar code in 
kernel sub-directory. :-(


Jie


> --- a/mm/nommu.c
> +++ b/mm/nommu.c
> @@ -1409,14 +1409,14 @@ unsigned long do_mmap_pgoff(struct file *file,
>
>      current->mm->total_vm += len>>  PAGE_SHIFT;
>
> +   if (prot&  PROT_EXEC)
> +       flush_icache_range(result, result + len);
> +
>   share:
>      add_vma_to_mm(current->mm, vma);
>
>      up_write(&nommu_region_sem);
>
> -   if (prot&  PROT_EXEC)
> -       flush_icache_range(result, result + len);
> -
>      kleave(" = %lx", result);
>      return result;
>
> -mike


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: avoiding duplicate icache flushing of shared maps on nommu
  2009-11-28 15:40 avoiding duplicate icache flushing of shared maps on nommu Mike Frysinger
  2009-11-28 18:53 ` Mike Frysinger
  2009-11-30  3:18 ` Jie Zhang
@ 2009-12-02 14:15 ` David Howells
  2009-12-02 21:40   ` Mike Frysinger
  2009-12-02 22:41   ` Mike Frysinger
  2 siblings, 2 replies; 8+ messages in thread
From: David Howells @ 2009-12-02 14:15 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: dhowells, Paul Mundt, Bernd Schmidt, Jie Zhang,
	Linux kernel mailing list, uclinux-dist-devel

Mike Frysinger <vapier.adi@gmail.com> wrote:

> (yes, this now does the icache flush while holding the
> nommu_region_sem, but i'm interested if the _idea_ is OK)

Yes...  But it's not quite as simple as you think.  The first mapping made of
a file could be PROT_READ only, in which case a second, executable mapping
made that shares it would not get flushed from the icache.

How about the attached patch?

David
---
From: Mike Frysinger <vapier.adi@gmail.com>
Subject: [PATCH] NOMMU: Avoiding duplicate icache flushes of shared maps

When working with FDPIC, there are many shared mappings of read-only code
regions between applications (the C library, applet packages like busybox,
etc.), but the current do_mmap_pgoff() function will issue an icache flush
whenever a VMA is added to an MM instead of only doing it when the map is
initially created.

The flush can instead be done when a region is first mmapped PROT_EXEC.  Note
that we may not rely on the first mapping of a region being executable - it's
possible for it to be PROT_READ only, so we have to remember whether we've
flushed the region or not, and then flush the entire region when a bit of it is
made executable.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 include/linux/mm_types.h |    2 ++
 mm/nommu.c               |   11 ++++++++---
 2 files changed, 10 insertions(+), 3 deletions(-)


diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 84a524a..84d020b 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -123,6 +123,8 @@ struct vm_region {
 	struct file	*vm_file;	/* the backing file or NULL */
 
 	atomic_t	vm_usage;	/* region usage count */
+	bool		vm_icache_flushed : 1; /* true if the icache has been flushed for
+						* this region */
 };
 
 /*
diff --git a/mm/nommu.c b/mm/nommu.c
index 969392c..95159a1 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1353,10 +1353,15 @@ unsigned long do_mmap_pgoff(struct file *file,
 share:
 	add_vma_to_mm(current->mm, vma);
 
-	up_write(&nommu_region_sem);
+	/* we flush the region from the icache only when the first executable
+	 * mapping of it is made  */
+	if (vma->vm_flags & VM_EXEC && !region->vm_icache_flushed) {
+		flush_icache_range(region->vm_start,
+				   region->vm_end - region->vm_start);
+		region->vm_icache_flushed = true;
+	}
 
-	if (prot & PROT_EXEC)
-		flush_icache_range(result, result + len);
+	up_write(&nommu_region_sem);
 
 	kleave(" = %lx", result);
 	return result;


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: avoiding duplicate icache flushing of shared maps on nommu
  2009-12-02 14:15 ` David Howells
@ 2009-12-02 21:40   ` Mike Frysinger
  2009-12-02 23:51     ` David Howells
  2009-12-02 22:41   ` Mike Frysinger
  1 sibling, 1 reply; 8+ messages in thread
From: Mike Frysinger @ 2009-12-02 21:40 UTC (permalink / raw)
  To: David Howells
  Cc: Paul Mundt, Bernd Schmidt, Jie Zhang, Linux kernel mailing list,
	uclinux-dist-devel

On Wed, Dec 2, 2009 at 09:15, David Howells wrote:
> Mike Frysinger wrote:
>> (yes, this now does the icache flush while holding the
>> nommu_region_sem, but i'm interested if the _idea_ is OK)
>
> Yes...  But it's not quite as simple as you think.  The first mapping made of
> a file could be PROT_READ only, in which case a second, executable mapping
> made that shares it would not get flushed from the icache.

that is a tricky edge case ;)

> How about the attached patch?

it works, but i think we want to put the vm_icache_flushed in
linux/mm_types.h behind NOMMU so we dont bloat the MMU guys ?
-mike

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: avoiding duplicate icache flushing of shared maps on nommu
  2009-12-02 14:15 ` David Howells
  2009-12-02 21:40   ` Mike Frysinger
@ 2009-12-02 22:41   ` Mike Frysinger
  2009-12-03 16:14     ` David Howells
  1 sibling, 1 reply; 8+ messages in thread
From: Mike Frysinger @ 2009-12-02 22:41 UTC (permalink / raw)
  To: David Howells
  Cc: Paul Mundt, Bernd Schmidt, Jie Zhang, Linux kernel mailing list,
	uclinux-dist-devel

On Wed, Dec 2, 2009 at 09:15, David Howells wrote:
> Mike Frysinger wrote:
> +               flush_icache_range(region->vm_start,
> +                                  region->vm_end - region->vm_start);
> -               flush_icache_range(result, result + len);

actually, there's one typo here.  you want:
flush_icache_range(region->vm_start, region->vm_end);

it doesnt crash on blackfin systems as addresses not in icache get
nopped, but it was causing large delays on exec mappings.  i thought
this was due to the nic on the board i was using as it's hitting some
weird pauses by itself.
-mike

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: avoiding duplicate icache flushing of shared maps on nommu
  2009-12-02 21:40   ` Mike Frysinger
@ 2009-12-02 23:51     ` David Howells
  0 siblings, 0 replies; 8+ messages in thread
From: David Howells @ 2009-12-02 23:51 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: dhowells, Paul Mundt, Bernd Schmidt, Jie Zhang,
	Linux kernel mailing list, uclinux-dist-devel

Mike Frysinger <vapier.adi@gmail.com> wrote:

> it works, but i think we want to put the vm_icache_flushed in
> linux/mm_types.h behind NOMMU so we dont bloat the MMU guys ?

No.  The vm_region struct just isn't used in MMU-mode.

David

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: avoiding duplicate icache flushing of shared maps on nommu
  2009-12-02 22:41   ` Mike Frysinger
@ 2009-12-03 16:14     ` David Howells
  0 siblings, 0 replies; 8+ messages in thread
From: David Howells @ 2009-12-03 16:14 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: dhowells, Paul Mundt, Bernd Schmidt, Jie Zhang,
	Linux kernel mailing list, uclinux-dist-devel

Mike Frysinger <vapier.adi@gmail.com> wrote:

> actually, there's one typo here.  you want:
> flush_icache_range(region->vm_start, region->vm_end);

Good catch, thanks.

David

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-12-03 16:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-28 15:40 avoiding duplicate icache flushing of shared maps on nommu Mike Frysinger
2009-11-28 18:53 ` Mike Frysinger
2009-11-30  3:18 ` Jie Zhang
2009-12-02 14:15 ` David Howells
2009-12-02 21:40   ` Mike Frysinger
2009-12-02 23:51     ` David Howells
2009-12-02 22:41   ` Mike Frysinger
2009-12-03 16:14     ` David Howells

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.