2001-12-01 22:03:45

by Maciej Zenczykowski

[permalink] [raw]
Subject: [OT] Wrapping memory.

Hi All,

I have a pseudo-on-topic question:

I would like to have a 64 KBarray (of char), that's trivial, however what
I would like is for the last 4 KB [yes thankfully this is exactly one
page... (assume i386)] to reference the same physical memory as the first
four.

I.e. 16 4KB pages referencing physical 4 KB pages number 0..14, 0.

Is this at all possible? If so, how would I do this in user space (and
could it be done without root priv?)?

Thanks a lot,

Maciej Zenczykowski.

P.S. Yes, this is necessary, otherwise I have to give up on 32-bit access
(switch to 8-bit) and include mod 60KB in every memory access (very random
and I don't think I could predict when no to do this...]


2001-12-01 22:16:56

by Alan

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.

> I would like to have a 64 KBarray (of char), that's trivial, however what
> I would like is for the last 4 KB [yes thankfully this is exactly one
> page... (assume i386)] to reference the same physical memory as the first
> four.

Yep you can do that.

> Is this at all possible? If so, how would I do this in user space (and
> could it be done without root priv?)?

mmap will do what you need. Create a 60K object on disk and mmap it
at the base address and then 60K further on for 4K.

2001-12-02 01:53:05

by Benjamin LaHaise

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.

On Sat, Dec 01, 2001 at 10:24:58PM +0000, Alan Cox wrote:
> > Is this at all possible? If so, how would I do this in user space (and
> > could it be done without root priv?)?
>
> mmap will do what you need. Create a 60K object on disk and mmap it
> at the base address and then 60K further on for 4K.

And try to use /dev/shm/ first...

-ben

2001-12-02 10:31:08

by Christoph Rohland

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.

Hi Benjamin,

On Sat, 1 Dec 2001, Benjamin LaHaise wrote:
>> mmap will do what you need. Create a 60K object on disk and mmap it
>> at the base address and then 60K further on for 4K.
>
> And try to use /dev/shm/ first...

If you can live with glibc >= 2.2 and kernel 2.4 you should use
shm_open, shm_unlink for object creation and deletion.

Greetings
Christoph


2001-12-02 17:54:16

by David Woodhouse

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.


[email protected] said:
> > I would like to have a 64 KBarray (of char), that's trivial, however
> > what I would like is for the last 4 KB [yes thankfully this is exactly
> > one page... (assume i386)] to reference the same physical memory as the
> > first four.

> mmap will do what you need. Create a 60K object on disk and mmap it at
> the base address and then 60K further on for 4K.

You said 'assume i386', but just to make it clear - this is likely to break
horribly on some non-i386 platforms, due to dcache aliasing. You may find
that the second mmap(MAP_FIXED) fails, or if it succeeds then changes made
with one virtual address won't be instantly visible through the other
mapping. About the best case on such hardware is that Linux will just map
the offending page uncached.

--
dwmw2


2001-12-03 08:51:35

by Christoph Rohland

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.

Hi David,

On Sun, 02 Dec 2001, David Woodhouse wrote:
> You said 'assume i386', but just to make it clear - this is likely
> to break horribly on some non-i386 platforms, due to dcache
> aliasing.

Which platforms are affected by this?

Greetings
Christoph


2001-12-03 23:46:25

by David Woodhouse

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.


[email protected] said:
> On Sun, 02 Dec 2001, David Woodhouse wrote:
> > You said 'assume i386', but just to make it clear - this is likely
> > to break horribly on some non-i386 platforms, due to dcache
> > aliasing.
> Which platforms are affected by this?

Anything with a virtually-indexed cache and a data capacity per way that's
more than your page size - basically anything where it's possible for two
different _virtual_ addresses for the same physical address to end up on
different cache lines.

On SH3 you'll get away with it because the range of address space covered by
the cache is only 2KiB anyway - it's a 8KiB cache but 4-way associative, so
only the bottom 11 bits of the address affect the cache line used - and in
fact it doesn't matter that it's virtually indexed because unless you start
using 1KiB pages, those bits aren't changed by the MMU - only the offset
within the page defined the cache line you look in, and it doesn't matter
about the translation.

On SH4, the data capacity per way of the cache is 8KiB, and because we use
4KiB pages we have two colours. See arch_get_unmapped_area() in
arch/sh/kernel/sys_sh.c, and its usage in sys_mmap() and sys_mremap().
Basically we refuse to allow a mmap of a page to the 'wrong' colour, to
avoid getting aliases.

ARM used to just break, but I pointed it out to Russell a while ago and I
believe he fixed it. I don't remember what his fix was - it may have been
just to map the offending page uncached, which is also a fairly effective
was of avoiding cache aliasing :)

The MIPS kernel doesn't deal with this at all. Ralf tells me that the RM7000
and R[236]000 processors should be fine for the same reason as the SH3, but
R[45]000 are likely to break.

I don't know about other architectures.

A third possible approach other than just refusing the wrong-colour mapping
or disabling the cache entirely is to use the MMU to make sure only one
colour is accessible at a time - when you get a fault on the virtual address
of another colour, you flush the caches and swap over. You're not going to
do that without a physical->virtual lookup though, so it's basically not an
option for Linux atm.

--
dwmw2


Attachments:
aliastest.c (1.67 kB)
aliastest.c

2001-12-04 10:46:02

by David Woodhouse

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.


[email protected] said:
> We actually still map the pages as cached, but when update_mmu_cache
> detects that a page has been mmapped more than once, we ensure that
> the other mappings in the current mm will fault when accessed.

Oooh. Can you do that without having phys->virt lookup? And what about
mappings in other mms? Or are the ARM caches so broken that you have to
flush the whole damn thing on mm switch anyway?

VIVT. Urgh.

--
dwmw2


2001-12-04 10:47:22

by Russell King

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.

On Mon, Dec 03, 2001 at 09:11:18AM +0000, David Woodhouse wrote:
> ARM used to just break, but I pointed it out to Russell a while ago and I
> believe he fixed it. I don't remember what his fix was - it may have been
> just to map the offending page uncached, which is also a fairly effective
> was of avoiding cache aliasing :)

We actually still map the pages as cached, but when update_mmu_cache
detects that a page has been mmapped more than once, we ensure that
the other mappings in the current mm will fault when accessed.

--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html

2001-12-04 11:01:46

by Russell King

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.

On Tue, Dec 04, 2001 at 10:45:04AM +0000, David Woodhouse wrote:
> Oooh. Can you do that without having phys->virt lookup?

Yep. But only because we have page->mapping->i_mmap_shared.

> And what about mappings in other mms? Or are the ARM caches so broken
> that you have to flush the whole damn thing on mm switch anyway?
> VIVT. Urgh.

Correct. ;(

--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html

2001-12-04 16:47:44

by Jamie Lokier

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.

Russell King wrote:
> On Mon, Dec 03, 2001 at 09:11:18AM +0000, David Woodhouse wrote:
> > ARM used to just break, but I pointed it out to Russell a while ago and I
> > believe he fixed it. I don't remember what his fix was - it may have been
> > just to map the offending page uncached, which is also a fairly effective
> > was of avoiding cache aliasing :)
>
> We actually still map the pages as cached, but when update_mmu_cache
> detects that a page has been mmapped more than once, we ensure that
> the other mappings in the current mm will fault when accessed.

It should be possible, in a "portable" program, to map the two pages you
want and then test to see whether they are aliasing correctly.

Write to one and read from the other page, and vice versa. Repeat a few
thousand times just in case you were interrupted in the middle.

That is my approach to creating circular buffers (which is the question
which started this thread).

Unfortunately, the update_mmu_cache makes aliasing work properly while
ruining performence, so then it's better to not to use the mapping trick
at all in that case. To check for this, I have to call gettimeofday()
between pairs of accesses, to check whether they are slow. I don't know
for sure if this works because I don't have an ARM to try it on.

-- Jamie

2001-12-04 21:06:00

by Russell King

[permalink] [raw]
Subject: Re: [OT] Wrapping memory.

On Tue, Dec 04, 2001 at 04:39:50PM +0000, Jamie Lokier wrote:
> Unfortunately, the update_mmu_cache makes aliasing work properly while
> ruining performence, so then it's better to not to use the mapping trick
> at all in that case. To check for this, I have to call gettimeofday()
> between pairs of accesses, to check whether they are slow. I don't know
> for sure if this works because I don't have an ARM to try it on.

Why not create a program and email it to someone with an ARM machine?

--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html