user_to_phys() without mmap? - Linux

This is a discussion on user_to_phys() without mmap? - Linux ; I'm trying to use a framebuffer from user space (think plain video ram, not some PCI or AGP video card), but mmap'ing from kernel space into user space is causing large latencies and unsightly artifacts. It appears that anything written ...

+ Reply to Thread
Results 1 to 11 of 11

Thread: user_to_phys() without mmap?

  1. user_to_phys() without mmap?

    I'm trying to use a framebuffer from user space (think plain video ram,
    not some PCI or AGP video card), but mmap'ing from kernel space into
    user space is causing large latencies and unsightly artifacts. It
    appears that anything written into the mmap'ed user memory is in fact
    being copied into kernel space.

    What I was actually hoping was that the memory manager would simply map
    the underlying physical pages directly into the user's address space. I
    think that's simple enough to do in theory, but there is much that I
    don't know about Linux kernel internals, so in practice who knows?

    Has anybody else made physical memory directly accessible from user
    space, without resorting to copying data back and forth continually?

  2. Re: user_to_phys() without mmap?

    Neil Steiner writes:
    > I'm trying to use a framebuffer from user space (think plain video
    > ram, not some PCI or AGP video card), but mmap'ing from kernel space
    > into user space is causing large latencies and unsightly artifacts.
    > It appears that anything written into the mmap'ed user memory is in
    > fact being copied into kernel space.


    Theoretically, this could probably be implemented with help of the
    MMU and some 'weird' fault handling, but I don't think someone would
    take the trouble, because it seems pretty useless. The /dev/mem driver
    certainly doesn't do this. Only the MMU will interfere accesses to
    virtual memory locations from user space, except for faults caused by
    this accesses.

    > What I was actually hoping was that the memory manager would simply
    > map the underlying physical pages directly into the user's address
    > space. I think that's simple enough to do in theory, but there is
    > much that I don't know about Linux kernel internals, so in practice
    > who knows?


    I do :-). But the code isn't really that complicated. What it
    basically does is set up page table entries for the range you
    requested. Assuming you are using /dev/mem, could it be possible
    that you are accessing cached memory?

    static int mmap_mem(struct file * file, struct vm_area_struct * vma)
    {
    unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;

    /*
    * Accessing memory above the top the kernel knows about or
    * through a file pointer that was marked O_SYNC will be
    * done non-cached.
    */
    if (noncached_address(offset) || (file->f_flags & O_SYNC))
    vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
    (../linux/drivers/char/mem.c)


  3. Re: user_to_phys() without mmap?

    Neil Steiner wrote:
    > I'm trying to use a framebuffer from user space (think plain video ram,
    > not some PCI or AGP video card), but mmap'ing from kernel space into
    > user space is causing large latencies and unsightly artifacts.


    Maybe you should map it uncached?

    > It appears that anything written into the mmap'ed user memory is in
    > fact being copied into kernel space.


    You mean that every access causes a page fault and the performs the access
    from inside the kernel? That would basically mean that the memory-mapping
    was incomplete/incorrect. Hard to tell without knowing what is going on...


    > What I was actually hoping was that the memory manager would simply map
    > the underlying physical pages directly into the user's address space.


    I did something similar with Linux 2.2 and 2.4, though it was less than one
    page for some buffers and registers. I copied the code from some other
    driver in the kernel though, I think it was from some TV receiver card.
    Maybe the driver is still there and by reading a bit you could do the same.

    Just one thing though: why not use the Linux framebuffer interface?

    Uli


  4. Re: user_to_phys() without mmap?

    Ulrich Eckhardt writes:
    > Neil Steiner wrote:


    [...]

    >> It appears that anything written into the mmap'ed user memory is in
    >> fact being copied into kernel space.

    >
    > You mean that every access causes a page fault and the performs the access
    > from inside the kernel? That would basically mean that the memory-mapping
    > was incomplete/incorrect. Hard to tell without knowing what is going
    > on...


    Modify the kernel such that it prints the page table flags after setup
    and maybe also printks whenever a fault occurs for a particular page
    that is part of the area being accessed. Then access it. That should
    be fairly noisy, but would easily throw light on this issue.

    [...]

    > Just one thing though: why not use the Linux framebuffer interface?


    'The Linux framebuffer interface' is nothing more than a char driver
    providing mmap'ed access to some hadrware framebuffer and some
    additional ioctl for mode switching.

  5. Re: user_to_phys() without mmap?

    On Sun, 15 Jul 2007 00:20:45 +0200 Rainer Weikusat wrote:
    | Neil Steiner writes:
    |> I'm trying to use a framebuffer from user space (think plain video
    |> ram, not some PCI or AGP video card), but mmap'ing from kernel space
    |> into user space is causing large latencies and unsightly artifacts.
    |> It appears that anything written into the mmap'ed user memory is in
    |> fact being copied into kernel space.
    |
    | Theoretically, this could probably be implemented with help of the
    | MMU and some 'weird' fault handling, but I don't think someone would
    | take the trouble, because it seems pretty useless. The /dev/mem driver
    | certainly doesn't do this. Only the MMU will interfere accesses to
    | virtual memory locations from user space, except for faults caused by
    | this accesses.

    I tried to map the video buffer into user space some time ago and I did
    find that what was mapped was not the actual physical memory of the video
    card, but just some memory apparently allocated by a driver in the kernel
    which was then periodically copied from that memory into the real physical
    memory.

    I speculated that the above was taking place because it was an attempt
    to port an old graphical program I had originally developed on DOS so it
    it would run on Linux. It was a cellular life game program (simulation
    of cell growth and death activity). Under Linux 2.4 on a 400 MHz P-II
    it was getting speeds of not more than one generation every 2-3 seconds.
    Under DOS 3.3 on a 25 MHz i386, it was getting 16 generations per second.
    That's 32 to 48 times slower on a machine that could have been as much
    as 16 times faster. There was _more_ than _just_ copying data between
    buffers going on.

    Directly mapping physical memory to a process _can_, of course, be very
    hazardous. Said program needs to be able to give up that mapping when
    needed, such as during virtual console switch. Presumably X windows is
    fully mapped to physical memory (it seems to be reasonably fast), but it
    is trusted to give up any such mappings when leaving X.

    Still, it would be nice to have BOTH a way to easily get a direct mmap
    to physical video buffer memory, as well as an indirect mmap to a logical
    buffer that can be kernel switched as needed. This could and should be
    done by having the user space virtual memory mapping go to the real
    device memory when that console is the currently selected one, and be
    mapped to a memory copy of the device memory at other times. That way,
    every virtual console can have a mapping from virtual memory, and the
    one that is active be mapped directly.

    Unfortunately, this also means graphical console actions would likely be
    limited due to the need for the kernel to manage it. Advanced features
    of a video card cannot be used. So it would still be necessary for other
    direct video access (e.g. what X uses) to be retained for some means for
    full control. But multi-VC simple access should be possible.

    --
    |---------------------------------------/----------------------------------|
    | Phil Howard KA9WGN (ka9wgn.ham.org) / Do not send to the address below |
    | first name lower case at ipal.net / spamtrap-2007-07-15-0906@ipal.net |
    |------------------------------------/-------------------------------------|

  6. Re: user_to_phys() without mmap?

    phil-news-nospam@ipal.net writes:
    > On Sun, 15 Jul 2007 00:20:45 +0200 Rainer Weikusat wrote:
    > | Neil Steiner writes:
    > |> I'm trying to use a framebuffer from user space (think plain video
    > |> ram, not some PCI or AGP video card), but mmap'ing from kernel space
    > |> into user space is causing large latencies and unsightly artifacts.
    > |> It appears that anything written into the mmap'ed user memory is in
    > |> fact being copied into kernel space.
    > |
    > | Theoretically, this could probably be implemented with help of the
    > | MMU and some 'weird' fault handling, but I don't think someone would
    > | take the trouble, because it seems pretty useless. The /dev/mem driver
    > | certainly doesn't do this. Only the MMU will interfere accesses to
    > | virtual memory locations from user space, except for faults caused by
    > | this accesses.
    >
    > I tried to map the video buffer into user space some time ago and I did
    > find that what was mapped was not the actual physical memory of the video
    > card, but just some memory apparently allocated by a driver in the kernel
    > which was then periodically copied from that memory into the real physical
    > memory.


    Which driver? That should be easy to determine.

  7. Re: user_to_phys() without mmap?

    On Mon, 16 Jul 2007 14:46:24 +0200 Rainer Weikusat wrote:
    | phil-news-nospam@ipal.net writes:
    |> On Sun, 15 Jul 2007 00:20:45 +0200 Rainer Weikusat wrote:
    |> | Neil Steiner writes:
    |> |> I'm trying to use a framebuffer from user space (think plain video
    |> |> ram, not some PCI or AGP video card), but mmap'ing from kernel space
    |> |> into user space is causing large latencies and unsightly artifacts.
    |> |> It appears that anything written into the mmap'ed user memory is in
    |> |> fact being copied into kernel space.
    |> |
    |> | Theoretically, this could probably be implemented with help of the
    |> | MMU and some 'weird' fault handling, but I don't think someone would
    |> | take the trouble, because it seems pretty useless. The /dev/mem driver
    |> | certainly doesn't do this. Only the MMU will interfere accesses to
    |> | virtual memory locations from user space, except for faults caused by
    |> | this accesses.
    |>
    |> I tried to map the video buffer into user space some time ago and I did
    |> find that what was mapped was not the actual physical memory of the video
    |> card, but just some memory apparently allocated by a driver in the kernel
    |> which was then periodically copied from that memory into the real physical
    |> memory.
    |
    | Which driver? That should be easy to determine.

    The basic console driver used for text and framebuffer modes. Those are
    standard common modes across all video cards that support legacy VGA, so
    there is just one driver. I don't know that it has a particular name.

    --
    |---------------------------------------/----------------------------------|
    | Phil Howard KA9WGN (ka9wgn.ham.org) / Do not send to the address below |
    | first name lower case at ipal.net / spamtrap-2007-07-16-0805@ipal.net |
    |------------------------------------/-------------------------------------|

  8. Re: user_to_phys() without mmap?

    > Assuming you are using /dev/mem, could it be possible that you are
    > accessing cached memory?


    It turns out that the memory was indeed being cached. I was already
    using ioremap_nocache(), so I didn't realize that I had to specify
    anything additional when using remap_page_range().

    In any case, once I added the following, my speeds and latencies from
    user and kernel spaces evened out:

    pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;

    Thanks for the comments Rainer, and each of the rest of you as well.
    It's nice to have this problem squared away.

  9. Re: user_to_phys() without mmap?

    >> I'm trying to use a framebuffer from user space (think plain video ram,
    >> not some PCI or AGP video card), but mmap'ing from kernel space into
    >> user space is causing large latencies and unsightly artifacts.

    >
    > Maybe you should map it uncached?


    You're right. I was already using ioremap_nocache(), so I didn't
    realize that I had to specify anything additional when using
    remap_page_range(). But I added this, and everything started working as
    desired.

    pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;

    > Just one thing though: why not use the Linux framebuffer interface?


    I'm using this for a special purpose proof-of-concept, and although I
    need this to work, it really is not a central part of my work.
    Honestly, the framebuffer interface looked like it would be more
    complicated to use in my case. I usually opt for the Right Way, but
    this time I took the shortcut.

    Thanks for your comments. They helped me get this worked out.

  10. Re: user_to_phys() without mmap?

    phil-news-nospam@ipal.net writes:
    > On Mon, 16 Jul 2007 14:46:24 +0200 Rainer Weikusat wrote:
    > | phil-news-nospam@ipal.net writes:
    > |> On Sun, 15 Jul 2007 00:20:45 +0200 Rainer Weikusat wrote:
    > |> | Neil Steiner writes:
    > |> |> I'm trying to use a framebuffer from user space (think plain video
    > |> |> ram, not some PCI or AGP video card), but mmap'ing from kernel space
    > |> |> into user space is causing large latencies and unsightly artifacts.
    > |> |> It appears that anything written into the mmap'ed user memory is in
    > |> |> fact being copied into kernel space.
    > |> |
    > |> | Theoretically, this could probably be implemented with help of the
    > |> | MMU and some 'weird' fault handling, but I don't think someone would
    > |> | take the trouble, because it seems pretty useless. The /dev/mem driver
    > |> | certainly doesn't do this. Only the MMU will interfere accesses to
    > |> | virtual memory locations from user space, except for faults caused by
    > |> | this accesses.
    > |>
    > |> I tried to map the video buffer into user space some time ago and I did
    > |> find that what was mapped was not the actual physical memory of the video
    > |> card, but just some memory apparently allocated by a driver in the kernel
    > |> which was then periodically copied from that memory into the real physical
    > |> memory.
    > |
    > | Which driver? That should be easy to determine.
    >
    > The basic console driver used for text and framebuffer modes.


    So you weren't mmaping some hardware framebuffer to begin with but the
    virtual framebuffer associated with one of the virtual consoles,
    right?

  11. Re: user_to_phys() without mmap?

    On Mon, 16 Jul 2007 17:50:29 +0200 Rainer Weikusat wrote:
    | phil-news-nospam@ipal.net writes:
    |> On Mon, 16 Jul 2007 14:46:24 +0200 Rainer Weikusat wrote:
    |> | phil-news-nospam@ipal.net writes:
    |> |> On Sun, 15 Jul 2007 00:20:45 +0200 Rainer Weikusat wrote:
    |> |> | Neil Steiner writes:
    |> |> |> I'm trying to use a framebuffer from user space (think plain video
    |> |> |> ram, not some PCI or AGP video card), but mmap'ing from kernel space
    |> |> |> into user space is causing large latencies and unsightly artifacts.
    |> |> |> It appears that anything written into the mmap'ed user memory is in
    |> |> |> fact being copied into kernel space.
    |> |> |
    |> |> | Theoretically, this could probably be implemented with help of the
    |> |> | MMU and some 'weird' fault handling, but I don't think someone would
    |> |> | take the trouble, because it seems pretty useless. The /dev/mem driver
    |> |> | certainly doesn't do this. Only the MMU will interfere accesses to
    |> |> | virtual memory locations from user space, except for faults caused by
    |> |> | this accesses.
    |> |>
    |> |> I tried to map the video buffer into user space some time ago and I did
    |> |> find that what was mapped was not the actual physical memory of the video
    |> |> card, but just some memory apparently allocated by a driver in the kernel
    |> |> which was then periodically copied from that memory into the real physical
    |> |> memory.
    |> |
    |> | Which driver? That should be easy to determine.
    |>
    |> The basic console driver used for text and framebuffer modes.
    |
    | So you weren't mmaping some hardware framebuffer to begin with but the
    | virtual framebuffer associated with one of the virtual consoles,
    | right?

    Both. I was hoping the kernel would switch translations so that what was
    mapped in VM for the framebuffer would be changed over to literally access
    the hardware when that console was switched to be the one displayed.

    This isn't a hard concept to understand. I just don't know if there any
    big showstoppers in the kernel or hardware (like the segment tables). It
    would be similar to activating and de-activating pages (part of swapping).

    When the virtual console to be displayed is changed by whatever means is
    changing it, then something like these steps would happen:

    1. Remove segment table entries for the mappings of the old console
    to a state similar to "swapped out". If a process tries to access
    that data during the copying, it gets blocked like it would be for
    a page to swap in.

    2. Copy data from the hardware buffer to memory allocated to save the
    old virtual console.

    3. Set up the segment table entries for the mappings of the old console
    to point to the memory location where the contents was saved.

    4. If any processes were blocked on these mappings, unblock them.

    5. Remove segment table entries for the mappings of the new console
    to a state similar to "swapped out". If a process tries to access
    that data during the copying, it gets blocked like it would be for
    a page to swap in.

    6. Copy data from the memory allocated to save the new virtual console
    into the hardware buffer.

    7. Set up the segment table entries for the mappings of the new console
    to point to the hardware buffer memory locations.

    8. If any processes were blocked on these mappings, unblock them.

    This is just a memory mappable variation of what virtual text consoles are
    doing now, anyway. It just extends to graphical content (more content)
    and provides for mappability (via a raw virtual console device node).
    Appropriate locks will be needed, especially on MP systems.

    --
    |---------------------------------------/----------------------------------|
    | Phil Howard KA9WGN (ka9wgn.ham.org) / Do not send to the address below |
    | first name lower case at ipal.net / spamtrap-2007-07-16-1546@ipal.net |
    |------------------------------------/-------------------------------------|

+ Reply to Thread