Ticket #9150: 9150-v1.patch

File 9150-v1.patch, 7.7 KB (added by danielk, 9 years ago)

Initial patch

  • libs/libmythtv/ThreadedFileWriter.cpp

     
    2525#define HAVE_FDATASYNC 0
    2626#endif
    2727
     28#if HAVE_POSIX_FADVISE < 1
     29static int posix_fadvise(int, off_t, off_t, int) { return 0; }
     30#endif
     31
    2832#define LOC QString("TFW(%1): ").arg(fd)
    2933#define LOC_ERR QString("TFW(%1), Error: ").arg(fd)
    3034
     
    365369    flush = false;
    366370}
    367371
    368 /** \fn ThreadedFileWriter::Sync(void)
    369  *  \brief flush data written to the file descriptor to disk.
     372/** \brief Flush data written to the file descriptor to disk.
    370373 *
    371  *   NOTE: This doesn't even try flush our queue of data.
    372  *   This only ensures that data which has already been sent
    373  *   to the kernel for this file is written to disk. This
    374  *   means that if this backend is writing the data over a
    375  *   network filesystem like NFS, then the data will be visible
    376  *   to the NFS server after this is called. It is also useful
    377  *   in preventing the kernel from buffering up so many writes
    378  *   that they steal the CPU for a long time when the write
    379  *   to disk actually occurs.
     374 *  This prevents freezing up Linux disk access on a running
     375 *  CFQ, AS, or Deadline as the disk write schedulers. It does
     376 *  this via two mechanism. One is a data sync using the best
     377 *  mechanism available (fdatasync then fsync). The second is
     378 *  by telling the kernel we do not intend to use the data just
     379 *  written anytime soon so other processes time-slices will
     380 *  not be used to deal with our excess dirty pages.
     381 *
     382 *  \note We used to also use sync_file_range on Linux, however
     383 *  this is incompatible with newer filesystems such as BRTFS and
     384 *  does not actually sync any blocks that have not been allocated
     385 *  yet.
     386 *
     387 *  \note We use standard posix calls for this, so any operating
     388 *  system supporting the calls will benefit, but this has been
     389 *  designed with Linux in mind. Other OS's may benefit from
     390 *  revisiting this function.
    380391 */
    381392void ThreadedFileWriter::Sync(void)
    382393{
    383394    if (fd >= 0)
    384395    {
    385 #if HAVE_SYNC_FILE_RANGE
    386             uint64_t write_position;
     396        /// Toss any data the kernel wrote to disk on it's own from
     397        /// the cache, so we don't get penalized for preserving it
     398        /// during the sync.
     399        int ret = posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
     400        if (ret)
     401        {
     402            VERBOSE(VB_IMPORTANT, LOC + "fadvise error" + ENO);
     403        }
    387404
    388             buflock.lock();
    389             write_position = m_file_wpos;
    390             buflock.unlock();
    391 
    392             if ((write_position - m_file_sync) > TFW_MAX_WRITE_SIZE ||
    393                 (write_position && m_file_sync < (uint64_t)tfw_min_write_size))
    394             {
    395                 sync_file_range(fd, m_file_sync, write_position - m_file_sync,
    396                                 SYNC_FILE_RANGE_WRITE);
    397                 m_file_sync = write_position;
    398             }
    399 #elif HAVE_FDATASYNC
    400             fdatasync(fd);
     405#if HAVE_FDATASYNC
     406        // fdatasync tries to avoid updating metadata, but will in
     407        // practice update metadata as the file will usually have
     408        // grown since the last sync.
     409        fdatasync(fd);
    401410#else
    402             fsync(fd);
     411        fsync(fd);
    403412#endif
     413
     414        // Toss any data we just synced from cache, so we don't
     415        // get penalized for it between now and the next sync.
     416        (void) posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
    404417    }
    405418}
    406419
  • libs/libmythtv/RingBuffer.cpp

     
    4343#define O_BINARY 0
    4444#endif
    4545
     46#if HAVE_POSIX_FADVISE < 1
     47static int posix_fadvise(int, off_t, off_t, int) { return 0; }
     48#endif
     49
    4650// about one second at 35mbit
    4751const uint RingBuffer::kBufferSize = 4 * 1024 * 1024;
    4852const int  RingBuffer::kDefaultOpenTimeout = 2000; // ms
     
    423427                {
    424428                    if (0 == lseek(fd2, 0, SEEK_SET))
    425429                    {
    426 #if HAVE_POSIX_FADVISE
    427430                        posix_fadvise(fd2, 0, 0, POSIX_FADV_SEQUENTIAL);
    428 #endif
     431                        posix_fadvise(fd2, 0, 1*1024*1024, POSIX_FADV_WILLNEED);
    429432                        lasterror = 0;
    430433                        break;
    431434                    }
     
    12591262            poslock.lockForWrite();
    12601263            rbwlock.lockForWrite();
    12611264            internalreadpos += read_return;
     1265            off_t donotneed = internalreadpos;
    12621266            rbwpos = (rbwpos + read_return) % kBufferSize;
    12631267            VERBOSE(VB_FILE|VB_EXTRA,
    12641268                    LOC + QString("rbwpos += %1K requested %2K in read")
    12651269                    .arg(read_return/1024,3).arg(totfree/1024,3));
    12661270            rbwlock.unlock();
    12671271            poslock.unlock();
     1272
     1273            if (fd2 >=0 && donotneed > 0)
     1274                posix_fadvise(fd2, 0, donotneed, POSIX_FADV_DONTNEED);
    12681275        }
    12691276
    12701277        int used = kBufferSize - ReadBufFree();
     
    13441351    reallyrunning = false;
    13451352    readsallowed = false;
    13461353    delete [] readAheadBuffer;
     1354    readAheadBuffer = NULL;
    13471355
    1348     readAheadBuffer = NULL;
    13491356    rbwlock.unlock();
    13501357    rbrlock.unlock();
    13511358    rwlock.unlock();
     
    15011508            if (remotefile)
    15021509                remotefile->Seek(old_pos, SEEK_SET);
    15031510            else
     1511            {
    15041512                lseek64(fd2, old_pos, SEEK_SET);
     1513                posix_fadvise(fd2, old_pos, 1*1024*1024, POSIX_FADV_WILLNEED);
     1514            }
    15051515        }
    15061516        else
    15071517        {
     
    18691879                if (remotefile)
    18701880                    ret = remotefile->Seek(internalreadpos, SEEK_SET);
    18711881                else
     1882                {
    18721883                    ret = lseek64(fd2, internalreadpos, SEEK_SET);
     1884                    posix_fadvise(fd2, 0,
     1885                                  internalreadpos, POSIX_FADV_DONTNEED);
     1886                    posix_fadvise(fd2, internalreadpos,
     1887                                  1*1024*1024, POSIX_FADV_WILLNEED);
     1888                }
    18731889                VERBOSE(VB_FILE, LOC +
    18741890                        QString("Seek to %1 from ignore pos %2 returned %3")
    18751891                        .arg(internalreadpos).arg(ignorereadpos).arg(ret));
     
    19181934                new_pos = fi.size() - off_end;
    19191935            }
    19201936        }
     1937/*
    19211938#ifdef __FreeBSD__
    19221939        else if (llabs(new_pos-readpos) > 100000000LL)
    19231940#else
    19241941        else if (abs(new_pos-readpos) > 100000000LL)
    19251942#endif
     1943*/
     1944        else
    19261945        {
    19271946            if (remotefile)
    19281947            {
     
    19341953                off_end = fi.size() - new_pos;
    19351954            }
    19361955        }
    1937         if (off_end == 250000)
     1956
     1957        if (off_end != 0xDEADBEEF)
    19381958        {
    19391959            VERBOSE(VB_FILE, LOC +
     1960                    QString("Seek(): Offset from end: %1").arg(off_end));
     1961        }
     1962
     1963        if (off_end <= 250000)
     1964        {
     1965            VERBOSE(VB_FILE, LOC +
    19401966                    QString("Seek(): offset from end: %1").arg(off_end) +
    19411967                    "\n\t\t\t -- ignoring read ahead thread until next seek.");
    19421968
     
    19461972            if (remotefile)
    19471973                ret = remotefile->Seek(ignorereadpos, SEEK_SET);
    19481974            else
     1975            {
    19491976                ret = lseek64(fd2, ignorereadpos, SEEK_SET);
     1977                posix_fadvise(fd2, ignorereadpos, 250000, POSIX_FADV_WILLNEED);
     1978            }
    19501979
    19511980            if (ret < 0)
    19521981            {
     
    20292058    else
    20302059    {
    20312060        ret = lseek64(fd2, pos, whence);
     2061        if (ret >= 0)
     2062        {
     2063            posix_fadvise(fd2, 0,   ret,         POSIX_FADV_DONTNEED);
     2064            posix_fadvise(fd2, ret, 1*1024*1024, POSIX_FADV_WILLNEED);
     2065        }
    20322066    }
    20332067
    20342068    if (ret >= 0)