🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: gmane.linux.kernel
3 messages
3 total messages Started by "Linh Dang" Sat, 17 Sep 2005 12:10
mmap (2) vs read (2)
#307702
Author: "Linh Dang"
Date: Sat, 17 Sep 2005 12:10
78 lines
1874 bytes
Hi, how come reading memory from /dev/mem using pread(2) or mmap(2)
will give diffent results?

I run the little prog below 10 times and it always give the following
results

# for i in `seq 1 10`; do ./bar 0x4000000 ; done
04000000: 00000000
pread(04000000): 00cc7d83
04000000: 00000000
pread(04000000): 00cc7d83
04000000: 00000000
pread(04000000): 00cc7d83
04000000: 00000000
pread(04000000): 00cc7d83
04000000: 00000000
pread(04000000): 00cc7d83
04000000: 00000000
pread(04000000): 00cc7d83
04000000: 00000000
pread(04000000): 00cc7d83
04000000: 00000000
pread(04000000): 00cc7d83
04000000: 00000000
pread(04000000): 00cc7d83
04000000: 00000000
pread(04000000): 00cc7d83

thanx


----------------------------------- bar.c ---------------------------------
#include <unistd.h>
#include <stdio.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>


int
main(int argc, char** argv)
{
        uint32_t *addr, item;
        uint32_t offset, val;
        int fd, update = 0;
        if (argc < 2)
                return 1;

        offset  = strtoul(argv[1], NULL, 0);
        if (argc > 2) {
                val = strtoul(argv[2], NULL, 0);
                update = 1;
        }

        fd   = open("/dev/mem", O_RDWR, 0666);
        addr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, 0x8080|MAP_SHARED, fd, offset);

        if (addr)
        {
                printf("%8.8x: %8.8x", offset, *addr);
                if (update) {
                        *addr = val;
                        msync(addr, 4096, MS_SYNC);
                        printf("-> %8.8x\n", *addr);
                } else
                        printf("\n");

                pread(fd, &item, sizeof(item), offset);
                printf("pread(%8.8x): %8.8x\n", offset, item);

                munmap(addr, 4096);
        }

        close(fd);

}
Re: mmap (2) vs read (2)
#307713
Author: Arjan van de Ven
Date: Sat, 17 Sep 2005 14:26
31 lines
900 bytes
--=-x1k5kpWfz8zl0a5MVQLh
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

On Sat, 2005-09-17 at 12:10 -0400, Linh Dang wrote:
> Hi, how come reading memory from /dev/mem using pread(2) or mmap(2)
> will give diffent results?

because you're being evil ;)

mmap of /dev/mem for *ram* is special. To avoid cache aliases and other
evils, you can only mmap non-ram realistically on /dev/mem.

Why are you using /dev/mem in the first place, it's a sure sign that
you're doing something really wrong in your design...


--=-x1k5kpWfz8zl0a5MVQLh
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQBDLF/apv2rCoFn+CIRAs4jAJsFzGUMn8LX0rUzk9zXVYf5rfrjPQCeLUiH
D0yFXEeMcNQaCmBHtb5dZG0=RE/6
-----END PGP SIGNATURE-----

--=-x1k5kpWfz8zl0a5MVQLh--
Re: mmap (2) vs read (2)
#307832
Author: "Linh Dang"
Date: Sun, 18 Sep 2005 12:47
32 lines
1211 bytes
Arjan van de Ven <arjanv@redhat.com> wrote:

> On Sat, 2005-09-17 at 12:10 -0400, Linh Dang wrote:
>> Hi, how come reading memory from /dev/mem using pread(2) or mmap(2)
>> will give diffent results?
>
> because you're being evil ;)
>
> mmap of /dev/mem for *ram* is special. To avoid cache aliases and
> other evils, you can only mmap non-ram realistically on /dev/mem.
>
> Why are you using /dev/mem in the first place, it's a sure sign that
> you're doing something really wrong in your design...

Thanx for the reply, what I'm doing is writing a driver (based on
mem.c) to export a block of ram to (other masters on) the PCI bus. The
driver does:

        1. get a contiguous block of ram using alloc_pages()
        2. export (via host-bridge hw setting) the block to the pci
           bus
        3. provide the .mmap() method in the driver to let userspace
           to mmap the device

In doing so, I encountered the inconsistencies of mmap(2) vs
read(2)/write(2). The work around I found is to SetPageReserved() on
all the pages got from alloc_pages(). But unfortunately I have no
clues why it's so. The vm code is not the easiest one to read
(compared to let's say the network code.)

--
Linh Dang
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads