Re: designing fast, streaming disk i/o with mmap: help wanted

From: Paul Barton-Davis (pbd@Op.Net)
Date: Sat Apr 01 2000 - 00:37:19 EST

  • Next message: Brian Macy: "pc_keyb.c handle_kbd_event..."

    OK, so forget most of my previous message on this topic. As usually
    happens, the task of writing out an explanation of my current scheme
    leads to a deeper insight into how to do it right.

    I got rid of the whole intermediate ringbuffer idea. The current
    scheme now uses mmap(2) exclusively. An excellent prod, since this
    removes one entire layer of copying. We now move data from the
    soundcard (which is itself using system RAM as a PCI busmaster) direct
    to the buffer cache with 1 copy. Very nice.

    However, there is still a problem to solve. The audio thread (the one
    thats copying data from the soundcard hardware) is absolutely *not*
    allowed to block for anything except the soundcard. That includes page
    faults. As a result, it must be guaranteed that the region it maps are
    in physical memory before it tries to read/write from them. This is
    where the butler thread comes in. Its primary job is to keep touching
    pages some distance ahead of the current playback and record positions
    to try to ensure that the pages are faulted in before the audio thread
    tries to use them. If the VM system let us specify this behaviour, we
    could do without the butler for this function, but as far as I know,
    read-ahead is not configurable, and neither is
    "fault-in-and-keep-resident-till-i-say-so" behaviour.

    The butler thread has a secondary function: it munmaps() regions that
    were used for recording, so that the contents are flushed back to
    disk. In the current context, this is less significant.

    For the most part, this scheme works well. Typical mmap(2) times are
    on the order of 10-30usec; typical data copying time to/from the
    mmapped regions by the audio thread on the order of 0.5msec for
    32K. This is all just fine.

    But every so often, it fails, with either an mmap(2) call that takes
    10's of msecs or a copy that takes the same, or both. This leads to
    missed deadlines reading from the soundcard.

    My guess is that the VM system decided to throw out some of the pages
    that the butler thread faulted in, and when the audio thread finally
    comes to use them, it has to refault them back into RAM. Right now, I
    am typically using 64K * 24 tracks = 1MB of RAM for the read-ahead,
    and at any point in time, 32K for each track currently playing back
    (i map and unmap the 32K immediately). I would not have expected such
    small amounts of RAM to have been the subject of page "ejection".

    I know about mlock(2), but I am not clear how to use it here, since
    the mapping used by the butler thread is distinct from the mapping
    used by the audio thread. All I want to ensure is that once the butler
    thread has faulted in data from a file, it won't be lost until the
    audio thread unmaps it.

    Comments, ideas ?

    --p

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/



    This archive was generated by hypermail 2b29 : Sat Apr 01 2000 - 00:40:25 EST