Blame source/vdo/base/vdoPageCache.h

Packit Service d40955
/*
Packit Service d40955
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service d40955
 *
Packit Service d40955
 * This program is free software; you can redistribute it and/or
Packit Service d40955
 * modify it under the terms of the GNU General Public License
Packit Service d40955
 * as published by the Free Software Foundation; either version 2
Packit Service d40955
 * of the License, or (at your option) any later version.
Packit Service d40955
 * 
Packit Service d40955
 * This program is distributed in the hope that it will be useful,
Packit Service d40955
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d40955
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service d40955
 * GNU General Public License for more details.
Packit Service d40955
 * 
Packit Service d40955
 * You should have received a copy of the GNU General Public License
Packit Service d40955
 * along with this program; if not, write to the Free Software
Packit Service d40955
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service d40955
 * 02110-1301, USA. 
Packit Service d40955
 *
Packit Service d40955
 * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/vdoPageCache.h#7 $
Packit Service d40955
 */
Packit Service d40955
Packit Service d40955
#ifndef VDO_PAGE_CACHE_H
Packit Service d40955
#define VDO_PAGE_CACHE_H
Packit Service d40955
Packit Service d40955
#include "adminState.h"
Packit Service d40955
#include "atomic.h"
Packit Service d40955
#include "completion.h"
Packit Service d40955
#include "types.h"
Packit Service d40955
#include "waitQueue.h"
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Structure describing page meta data (defined internally).
Packit Service d40955
 **/
Packit Service d40955
typedef struct pageInfo PageInfo;
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Structure describing entire page cache.
Packit Service d40955
 * (Unfortunately the name "PageCache" is already taken by Albireo.)
Packit Service d40955
 **/
Packit Service d40955
typedef struct vdoPageCache VDOPageCache;
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Generation counter for page references.
Packit Service d40955
 **/
Packit Service d40955
typedef uint32_t VDOPageGeneration;
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Page-state count statistics sub-structure.
Packit Service d40955
 **/
Packit Service d40955
typedef struct {
Packit Service d40955
  /* free pages */
Packit Service d40955
  Atomic64 freePages;
Packit Service d40955
  /* clean (resident) pages */
Packit Service d40955
  Atomic64 cleanPages;
Packit Service d40955
  /* dirty pages per era */
Packit Service d40955
  Atomic64 dirtyPages;
Packit Service d40955
  /* pages incoming */
Packit Service d40955
  Atomic64 incomingPages;
Packit Service d40955
  /* pages outgoing */
Packit Service d40955
  Atomic64 outgoingPages;
Packit Service d40955
  /* pages in failed state */
Packit Service d40955
  Atomic64 failedPages;
Packit Service d40955
} AtomicPageStateCounts;
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Statistics and debugging fields for the page cache.
Packit Service d40955
 */
Packit Service d40955
typedef struct {
Packit Service d40955
  /* counts of how many pages are in each state */
Packit Service d40955
  AtomicPageStateCounts counts;
Packit Service d40955
  /* how many times free page not available */
Packit Service d40955
  Atomic64              cachePressure;
Packit Service d40955
  /* number of getVDOPageAsync() for read */
Packit Service d40955
  Atomic64              readCount;
Packit Service d40955
  /* number or getVDOPageAsync() for write */
Packit Service d40955
  Atomic64              writeCount;
Packit Service d40955
  /* number of times pages failed to read */
Packit Service d40955
  Atomic64              failedReads;
Packit Service d40955
  /* number of times pages failed to write */
Packit Service d40955
  Atomic64              failedWrites;
Packit Service d40955
  /* number of gets that are reclaimed */
Packit Service d40955
  Atomic64              reclaimed;
Packit Service d40955
  /* number of gets for outgoing pages */
Packit Service d40955
  Atomic64              readOutgoing;
Packit Service d40955
  /* number of gets that were already there */
Packit Service d40955
  Atomic64              foundInCache;
Packit Service d40955
  /* number of gets requiring discard */
Packit Service d40955
  Atomic64              discardRequired;
Packit Service d40955
  /* number of gets enqueued for their page */
Packit Service d40955
  Atomic64              waitForPage;
Packit Service d40955
  /* number of gets that have to fetch */
Packit Service d40955
  Atomic64              fetchRequired;
Packit Service d40955
  /* number of page fetches */
Packit Service d40955
  Atomic64              pagesLoaded;
Packit Service d40955
  /* number of page saves */
Packit Service d40955
  Atomic64              pagesSaved;
Packit Service d40955
  /* number of flushes initiated */
Packit Service d40955
  Atomic64              flushCount;
Packit Service d40955
} AtomicPageCacheStatistics;
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Signature for a function to call when a page is read into the cache.
Packit Service d40955
 *
Packit Service d40955
 * 

If specified, this function is called when a page is fetched from disk.

Packit Service d40955
 *
Packit Service d40955
 * @param rawPage      The raw memory of the freshly-fetched page
Packit Service d40955
 * @param pbn          The absolute physical block number of the page
Packit Service d40955
 * @param zone         The block map zone to which the cache belongs
Packit Service d40955
 * @param pageContext  A pointer to client-specific data for the new page
Packit Service d40955
 *
Packit Service d40955
 * @return VDO_SUCCESS on success or VDO_BAD_PAGE if the page is incorrectly
Packit Service d40955
 *         formatted
Packit Service d40955
 **/
Packit Service d40955
typedef int VDOPageReadFunction(void                *rawPage,
Packit Service d40955
                                PhysicalBlockNumber  pbn,
Packit Service d40955
                                BlockMapZone        *zone,
Packit Service d40955
                                void                *pageContext);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Signature for a function to call when a page is written from the cache.
Packit Service d40955
 *
Packit Service d40955
 * 

If specified, this function is called when a page is written to disk.

Packit Service d40955
 *
Packit Service d40955
 * @param rawPage      The raw memory of the freshly-written page
Packit Service d40955
 * @param zone         The block map zone to which the cache belongs
Packit Service d40955
 * @param pageContext  A pointer to client-specific data for the new page
Packit Service d40955
 *
Packit Service d40955
 * @return whether the page needs to be rewritten
Packit Service d40955
 **/
Packit Service d40955
typedef bool VDOPageWriteFunction(void         *rawPage,
Packit Service d40955
                                  BlockMapZone *zone,
Packit Service d40955
                                  void         *pageContext);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Construct a PageCache.
Packit Service d40955
 *
Packit Service d40955
 * @param [in]  layer             The physical layer to read and write
Packit Service d40955
 * @param [in]  pageCount         The number of cache pages to hold
Packit Service d40955
 * @param [in]  readHook          The function to be called when a page is read
Packit Service d40955
 *                                into the cache
Packit Service d40955
 * @param [in]  writeHook         The function to be called after a page is
Packit Service d40955
 *                                written from the cache
Packit Service d40955
 * @param [in]  pageContextSize   The size of the per-page context that will be
Packit Service d40955
 *                                passed to the read and write hooks
Packit Service d40955
 * @param [in]  maximumAge        The number of journal blocks before a dirtied
Packit Service d40955
 *                                page is considered old and must be written
Packit Service d40955
 *                                out
Packit Service d40955
 * @param [in]  zone              The block map zone which owns this cache
Packit Service d40955
 * @param [out] cachePtr          A pointer to hold the cache
Packit Service d40955
 *
Packit Service d40955
 * @return a success or error code
Packit Service d40955
 **/
Packit Service d40955
int makeVDOPageCache(PhysicalLayer         *layer,
Packit Service d40955
                     PageCount              pageCount,
Packit Service d40955
                     VDOPageReadFunction   *readHook,
Packit Service d40955
                     VDOPageWriteFunction  *writeHook,
Packit Service d40955
                     size_t                 pageContextSize,
Packit Service d40955
                     BlockCount             maximumAge,
Packit Service d40955
                     BlockMapZone          *zone,
Packit Service d40955
                     VDOPageCache         **cachePtr)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Free the page cache structure and null out the reference to it.
Packit Service d40955
 *
Packit Service d40955
 * @param cachePtr a pointer to the cache to free
Packit Service d40955
 **/
Packit Service d40955
void freeVDOPageCache(VDOPageCache **cachePtr);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Set the initial dirty period for a page cache.
Packit Service d40955
 *
Packit Service d40955
 * @param cache  The cache
Packit Service d40955
 * @param period The initial dirty period to set
Packit Service d40955
 **/
Packit Service d40955
void setVDOPageCacheInitialPeriod(VDOPageCache *cache, SequenceNumber period);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Switch the page cache into or out of read-only rebuild mode.
Packit Service d40955
 *
Packit Service d40955
 * @param cache       The cache
Packit Service d40955
 * @param rebuilding  true if the cache should be put into
Packit Service d40955
 *                    read-only rebuild mode, false otherwise
Packit Service d40955
 **/
Packit Service d40955
void setVDOPageCacheRebuildMode(VDOPageCache *cache, bool rebuilding);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Check whether a page cache is active (i.e. has any active lookups,
Packit Service d40955
 * outstanding I/O, or pending I/O).
Packit Service d40955
 *
Packit Service d40955
 * @param cache  The cache to check
Packit Service d40955
 *
Packit Service d40955
 * @return true if the cache is active
Packit Service d40955
 **/
Packit Service d40955
bool isPageCacheActive(VDOPageCache *cache)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Advance the dirty period for a page cache.
Packit Service d40955
 *
Packit Service d40955
 * @param cache   The cache to advance
Packit Service d40955
 * @param period  The new dirty period
Packit Service d40955
 **/
Packit Service d40955
void advanceVDOPageCachePeriod(VDOPageCache *cache, SequenceNumber period);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Write one or more batches of dirty pages.
Packit Service d40955
 *
Packit Service d40955
 * All writable pages in the ancient era and some number in the old era
Packit Service d40955
 * are scheduled for writing.
Packit Service d40955
 *
Packit Service d40955
 * @param cache    the VDO page cache
Packit Service d40955
 * @param batches  how many batches to write now
Packit Service d40955
 * @param total    how many batches (including those being written now) remain
Packit Service d40955
 *                   in this era
Packit Service d40955
 **/
Packit Service d40955
void writeVDOPageCachePages(VDOPageCache *cache,
Packit Service d40955
                            size_t        batches,
Packit Service d40955
                            size_t        total);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Rotate the dirty page eras.
Packit Service d40955
 *
Packit Service d40955
 * Move all pages in the old era to the ancient era and then move
Packit Service d40955
 * the current era bin into the old era.
Packit Service d40955
 *
Packit Service d40955
 * @param cache   the VDO page cache
Packit Service d40955
 **/
Packit Service d40955
void rotateVDOPageCacheEras(VDOPageCache *cache);
Packit Service d40955
Packit Service d40955
// ASYNC
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * A completion awaiting a specific page.  Also a live reference into the
Packit Service d40955
 * page once completed, until freed.
Packit Service d40955
 **/
Packit Service d40955
typedef struct {
Packit Service d40955
  /** The generic completion */
Packit Service d40955
  VDOCompletion        completion;
Packit Service d40955
  /** The cache involved */
Packit Service d40955
  VDOPageCache        *cache;
Packit Service d40955
  /** The waiter for the pending list */
Packit Service d40955
  Waiter               waiter;
Packit Service d40955
  /** The absolute physical block number of the page on disk */
Packit Service d40955
  PhysicalBlockNumber  pbn;
Packit Service d40955
  /** Whether the page may be modified */
Packit Service d40955
  bool                 writable;
Packit Service d40955
  /** Whether the page is available */
Packit Service d40955
  bool                 ready;
Packit Service d40955
  /** The info structure for the page, only valid when ready */
Packit Service d40955
  PageInfo            *info;
Packit Service d40955
} VDOPageCompletion;
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Initialize a VDO Page Completion, requesting a particular page from the
Packit Service d40955
 * cache.
Packit Service d40955
 *
Packit Service d40955
 * @param pageCompletion  The VDOPageCompletion to initialize
Packit Service d40955
 * @param cache           The VDO page cache
Packit Service d40955
 * @param pbn             The absolute physical block of the desired page
Packit Service d40955
 * @param writable        Whether the page can be modified
Packit Service d40955
 * @param parent          The parent object
Packit Service d40955
 * @param callback        The completion callback
Packit Service d40955
 * @param errorHandler    The handler for page errors
Packit Service d40955
 *
Packit Service d40955
 * @note Once a completion has occurred for the getVDOPageAsync operation,
Packit Service d40955
 *       the underlying page shall be busy (stuck in memory) until the
Packit Service d40955
 *       VDOCompletion returned by this operation has been released.
Packit Service d40955
 **/
Packit Service d40955
void initVDOPageCompletion(VDOPageCompletion   *pageCompletion,
Packit Service d40955
                           VDOPageCache        *cache,
Packit Service d40955
                           PhysicalBlockNumber  pbn,
Packit Service d40955
                           bool                 writable,
Packit Service d40955
                           void                *parent,
Packit Service d40955
                           VDOAction           *callback,
Packit Service d40955
                           VDOAction           *errorHandler);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Release a VDO Page Completion.
Packit Service d40955
 *
Packit Service d40955
 * The page referenced by this completion (if any) will no longer be
Packit Service d40955
 * held busy by this completion. If a page becomes discardable and
Packit Service d40955
 * there are completions awaiting free pages then a new round of
Packit Service d40955
 * page discarding is started.
Packit Service d40955
 *
Packit Service d40955
 * @param completion The completion to release
Packit Service d40955
 **/
Packit Service d40955
void releaseVDOPageCompletion(VDOCompletion *completion);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Asynchronous operation to get a VDO page.
Packit Service d40955
 *
Packit Service d40955
 * May cause another page to be discarded (potentially writing a dirty page)
Packit Service d40955
 * and the one nominated by the completion to be loaded from disk.
Packit Service d40955
 *
Packit Service d40955
 * When the page becomes available the callback registered in the completion
Packit Service d40955
 * provided is triggered. Once triggered the page is marked busy until
Packit Service d40955
 * the completion is destroyed.
Packit Service d40955
 *
Packit Service d40955
 * @param completion    the completion initialized my initVDOPageCompletion().
Packit Service d40955
 **/
Packit Service d40955
void getVDOPageAsync(VDOCompletion *completion);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Mark a VDO page referenced by a completed VDOPageCompletion as dirty.
Packit Service d40955
 *
Packit Service d40955
 * @param completion      a VDO Page Completion whose callback has been called
Packit Service d40955
 * @param oldDirtyPeriod  the period in which the page was already dirty (0 if
Packit Service d40955
 *                        it wasn't)
Packit Service d40955
 * @param newDirtyPeriod  the period in which the page is now dirty
Packit Service d40955
 **/
Packit Service d40955
void markCompletedVDOPageDirty(VDOCompletion  *completion,
Packit Service d40955
                               SequenceNumber  oldDirtyPeriod,
Packit Service d40955
                               SequenceNumber  newDirtyPeriod);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Request that a VDO page be written out as soon as it is not busy.
Packit Service d40955
 *
Packit Service d40955
 * @param completion  the VDOPageCompletion containing the page
Packit Service d40955
 **/
Packit Service d40955
void requestVDOPageWrite(VDOCompletion *completion);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Access the raw memory for a read-only page of a completed VDOPageCompletion.
Packit Service d40955
 *
Packit Service d40955
 * @param completion    a vdo page completion whose callback has been called
Packit Service d40955
 *
Packit Service d40955
 * @return a pointer to the raw memory at the beginning of the page, or
Packit Service d40955
 *         NULL if the page is not available.
Packit Service d40955
 **/
Packit Service d40955
const void *dereferenceReadableVDOPage(VDOCompletion *completion);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Access the raw memory for a writable page of a completed VDOPageCompletion.
Packit Service d40955
 *
Packit Service d40955
 * @param completion    a vdo page completion whose callback has been called
Packit Service d40955
 *
Packit Service d40955
 * @return a pointer to the raw memory at the beginning of the page, or
Packit Service d40955
 *         NULL if the page is not available, or if the page is read-only
Packit Service d40955
 **/
Packit Service d40955
void *dereferenceWritableVDOPage(VDOCompletion *completion);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Get the per-page client context for the page in a page completion whose
Packit Service d40955
 * callback has been invoked. Should only be called after dereferencing the
Packit Service d40955
 * page completion to validate the page.
Packit Service d40955
 *
Packit Service d40955
 * @param completion    a vdo page completion whose callback has been invoked
Packit Service d40955
 *
Packit Service d40955
 * @return a pointer to the per-page client context, or NULL if
Packit Service d40955
 *         the page is not available
Packit Service d40955
 **/
Packit Service d40955
void *getVDOPageCompletionContext(VDOCompletion *completion);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Drain I/O for a page cache.
Packit Service d40955
 *
Packit Service d40955
 * @param cache  The cache to drain
Packit Service d40955
 **/
Packit Service d40955
void drainVDOPageCache(VDOPageCache *cache);
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Invalidate all entries in the VDO page cache. There must not be any
Packit Service d40955
 * dirty pages in the cache.
Packit Service d40955
 *
Packit Service d40955
 * @param cache  the cache to invalidate
Packit Service d40955
 *
Packit Service d40955
 * @return a success or error code
Packit Service d40955
 **/
Packit Service d40955
int invalidateVDOPageCache(VDOPageCache *cache)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
// STATISTICS & TESTING
Packit Service d40955
Packit Service d40955
/**
Packit Service d40955
 * Get current cache statistics.
Packit Service d40955
 *
Packit Service d40955
 * @param cache  the page cache
Packit Service d40955
 *
Packit Service d40955
 * @return the statistics
Packit Service d40955
 **/
Packit Service d40955
AtomicPageCacheStatistics *getVDOPageCacheStatistics(VDOPageCache *cache)
Packit Service d40955
  __attribute__((warn_unused_result));
Packit Service d40955
Packit Service d40955
#endif // VDO_PAGE_CACHE_H