summaryrefslogtreecommitdiffstats
path: root/cpukit/libblock/include/rtems/bdbuf.h
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2009-08-05 00:00:54 +0000
committerChris Johns <chrisj@rtems.org>2009-08-05 00:00:54 +0000
commit0d15414ed6c144f7f7e4ce63476b3eb9b94acceb (patch)
treed403db6ba0eae020e8613bb81a0427ca1ab85867 /cpukit/libblock/include/rtems/bdbuf.h
parent2009-08-04 Joel Sherrill <joel.sherrill@OARcorp.com> (diff)
downloadrtems-0d15414ed6c144f7f7e4ce63476b3eb9b94acceb.tar.bz2
009-08-05 Chris Johns <chrisj@rtems.org>
* libmisc/dummy/dummy-networking.c: New. * libmisc/dummy/dummy.c, libmisc/Makefile.am: Move trhe networking configuration into a separate file so configuration varations do not cause conflicts. * score/inline/rtems/score/object.inl, score/include/rtems/score/object.h: Remove warnings. * score/inline/rtems/score/object.inl: Add _Chain_First, _Chain_Last, _Chain_Mext, and _Chain_Previous. * sapi/inline/rtems/chain.inl: Add rtems_chain_first, rtems_chain_last, rtems_chain_mext, and rtems_chain_previous. * libblock/include/rtems/diskdevs.h: Remove the bdbuf pool id and block_size_log2. Add media_block_size. * libblock/src/diskdevs.c: Remove size restrictions on block size. Add media block size initialisation. Remove comment to clean up the bdbuf cache. * libblock/src/blkdev.c: Remove references to block_size_log2. Allow any block size. * libblock/include/rtems/bdbuf.h, libblock/src/bdbuf.c: Remove all references to pools and make the cache handle demand driver variable buffer size allocation. Added worker threads support the swapout task. * sapi/include/confdefs.h: Updated the bdbuf configutation.
Diffstat (limited to 'cpukit/libblock/include/rtems/bdbuf.h')
-rw-r--r--cpukit/libblock/include/rtems/bdbuf.h261
1 files changed, 125 insertions, 136 deletions
diff --git a/cpukit/libblock/include/rtems/bdbuf.h b/cpukit/libblock/include/rtems/bdbuf.h
index 1f79f89d0d..16f86fcdd3 100644
--- a/cpukit/libblock/include/rtems/bdbuf.h
+++ b/cpukit/libblock/include/rtems/bdbuf.h
@@ -10,9 +10,10 @@
* Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
* Author: Victor V. Vengerov <vvv@oktet.ru>
*
- * Copyright (C) 2008 Chris Johns <chrisj@rtems.org>
+ * Copyright (C) 2008,2009 Chris Johns <chrisj@rtems.org>
* Rewritten to remove score mutex access. Fixes many performance
* issues.
+ Change to support demand driven variable buffer sizes.
*
* @(#) bdbuf.h,v 1.9 2005/02/02 00:06:18 joel Exp
*/
@@ -44,8 +45,33 @@ extern "C" {
* devices and file systems. The code provides read ahead and write queuing to
* the drivers and fast cache look up using an AVL tree.
*
- * The buffers are held in pools based on size. Each pool has buffers and the
- * buffers follow this state machine:
+ * The block size used by a file system can be set at runtime and must be a
+ * multiple of the disk device block size. The disk device's physical block
+ * size is called the media block size. The file system can set the block size
+ * it uses to a larger multiple of the media block size. The driver must be
+ * able to handle buffers sizes larger than one media block.
+ *
+ * The user configures the amount of memory to be used as buffers in the cache,
+ * and the minimum and maximum buffer size. The cache will allocate additional
+ * memory for the buffer descriptors and groups. There are enough buffer
+ * descriptors allocated so all the buffer memory can be used as minimum sized
+ * buffers.
+ *
+ * The cache is a single pool of buffers. The buffer memory is divided into
+ * groups where the size of buffer memory allocated to a group is the maximum
+ * buffer size. A group's memory can be divided down into small buffer sizes
+ * that are a multiple of 2 of the minimum buffer size. A group is the minumum
+ * allocation unit for buffers of a specific size. If a buffer of maximum size
+ * is request the group will have a single buffer. If a buffer of minium size
+ * is requested the group is divided into minimum sized buffers and the
+ * remaining buffers are held ready for use. A group keeps track of which
+ * buffers are with a file system or driver and groups who have buffer in use
+ * cannot be realloced. Groups with no buffers in use can be taken and
+ * realloced to a new size. This is how buffers of different sizes move around
+ * the cache.
+
+ * The buffers are held in various lists in the cache. All buffers follow this
+ * state machine:
*
* @dot
* digraph g {
@@ -82,14 +108,14 @@ extern "C" {
* to another requester until released back to the cache. The same goes to a
* buffer in the transfer state. The transfer state means being read or
* written. If the file system has modifed the block and releases it as
- * modified it placed on the pool's modified list and a hold timer
+ * modified it placed on the cache's modified list and a hold timer
* initialised. The buffer is held for the hold time before being written to
* disk. Buffers are held for a configurable period of time on the modified
* list as a write sets the state to transfer and this locks the buffer out
- * from the file system until the write complete. Buffers are often repeatable
- * accessed and modified in a series of small updates so if sent to the disk
- * when released as modified the user would have to block waiting until it had
- * been written. This would be a performance problem.
+ * from the file system until the write completes. Buffers are often accessed
+ * and modified in a series of small updates so if sent to the disk when
+ * released as modified the user would have to block waiting until it had been
+ * written. This would be a performance problem.
*
* The code performs mulitple block reads and writes. Multiple block reads or
* read ahead increases performance with hardware that supports it. It also
@@ -103,12 +129,22 @@ extern "C" {
* than the LRU list. This means these buffers are used before buffers used by
* the file system.
*
- * The pool has the following lists of buffers:
+ * The cache has the following lists of buffers:
* - @c ready: Empty buffers created when the pool is initialised.
* - @c modified: Buffers waiting to be written to disk.
* - @c sync: Buffers to be synced to disk.
* - @c lru: Accessed buffers released in least recently used order.
*
+ * The cache scans the ready list then the LRU list for a suitable buffer in
+ * this order. A suitable buffer is one that matches the same allocation size
+ * as the device the buffer is for. The a buffer's group has no buffers in use
+ * with the file system or driver the group is reallocated. This means the
+ * buffers in the group are invalidated, resized and placed on the ready queue.
+ * There is a performance issue with this design. The reallocation of a group
+ * may forced recently accessed buffers out of the cache when they should
+ * not. The design should be change to have groups on a LRU list if they have
+ * no buffers in use.
+ *
* @{
*/
@@ -128,14 +164,20 @@ typedef enum
} rtems_bdbuf_buf_state;
/**
+ * Forward reference to the block.
+ */
+struct rtems_bdbuf_group;
+typedef struct rtems_bdbuf_group rtems_bdbuf_group;
+
+/**
* To manage buffers we using buffer descriptors (BD). A BD holds a buffer plus
* a range of other information related to managing the buffer in the cache. To
- * speed-up buffer lookup descriptors are organized in AVL-Tree. The fields
+ * speed-up buffer lookup descriptors are organized in AVL-Tree. The fields
* 'dev' and 'block' are search keys.
*/
typedef struct rtems_bdbuf_buffer
{
- rtems_chain_node link; /* Link in the BD onto a number of lists. */
+ rtems_chain_node link; /**< Link the BD onto a number of lists. */
struct rtems_bdbuf_avl_node
{
@@ -154,94 +196,57 @@ typedef struct rtems_bdbuf_buffer
volatile rtems_bdbuf_buf_state state; /**< State of the buffer. */
- volatile uint32_t waiters; /**< The number of threads waiting on this
- * buffer. */
- rtems_bdpool_id pool; /**< Identifier of buffer pool to which this buffer
- belongs */
-
- volatile uint32_t hold_timer; /**< Timer to indicate how long a buffer
- * has been held in the cache modified. */
+ volatile uint32_t waiters; /**< The number of threads waiting on this
+ * buffer. */
+ rtems_bdbuf_group* group; /**< Pointer to the group of BDs this BD is
+ * part of. */
+ volatile uint32_t hold_timer; /**< Timer to indicate how long a buffer
+ * has been held in the cache modified. */
} rtems_bdbuf_buffer;
/**
- * The groups of the blocks with the same size are collected in a pool. Note
- * that a several of the buffer's groups with the same size can exists.
+ * A group is a continuous block of buffer descriptors. A group covers the
+ * maximum configured buffer size and is the allocation size for the buffers to
+ * a specific buffer size. If you allocate a buffer to be a specific size, all
+ * buffers in the group, if there are more than 1 will also be that size. The
+ * number of buffers in a group is a multiple of 2, ie 1, 2, 4, 8, etc.
*/
-typedef struct rtems_bdbuf_pool
+struct rtems_bdbuf_group
{
- uint32_t blksize; /**< The size of the blocks (in bytes) */
- uint32_t nblks; /**< Number of blocks in this pool */
-
- uint32_t flags; /**< Configuration flags */
-
- rtems_id lock; /**< The pool lock. Lock this data and
- * all BDs. */
- rtems_id sync_lock; /**< Sync calls lock writes. */
- bool sync_active; /**< True if a sync is active. */
- rtems_id sync_requester; /**< The sync requester. */
- dev_t sync_device; /**< The device to sync */
-
- rtems_bdbuf_buffer* tree; /**< Buffer descriptor lookup AVL tree
- * root */
- rtems_chain_control ready; /**< Free buffers list (or read-ahead) */
- rtems_chain_control lru; /**< Last recently used list */
- rtems_chain_control modified; /**< Modified buffers list */
- rtems_chain_control sync; /**< Buffers to sync list */
-
- rtems_id access; /**< Obtain if waiting for a buffer in the
- * ACCESS state. */
- volatile uint32_t access_waiters; /**< Count of access blockers. */
- rtems_id transfer; /**< Obtain if waiting for a buffer in the
- * TRANSFER state. */
- volatile uint32_t transfer_waiters; /**< Count of transfer blockers. */
- rtems_id waiting; /**< Obtain if waiting for a buffer and the
- * none are available. */
- volatile uint32_t wait_waiters; /**< Count of waiting blockers. */
-
- rtems_bdbuf_buffer* bds; /**< Pointer to table of buffer descriptors
- * allocated for this buffer pool. */
- void* buffers; /**< The buffer's memory. */
-} rtems_bdbuf_pool;
-
-/**
- * Configuration structure describes block configuration (size, amount, memory
- * location) for buffering layer pool.
- */
-typedef struct rtems_bdbuf_pool_config {
- int size; /**< Size of block */
- int num; /**< Number of blocks of appropriate size */
- unsigned char* mem_area; /**< Pointer to the blocks location or NULL, in this
- * case memory for blocks will be allocated by
- * Buffering Layer with the help of RTEMS partition
- * manager */
-} rtems_bdbuf_pool_config;
-
-/**
- * External reference to the pool configuration table describing each pool in
- * the system.
- *
- * The configuration table is provided by the application.
- */
-extern rtems_bdbuf_pool_config rtems_bdbuf_pool_configuration[];
-
-/**
- * External reference the size of the pool configuration table
- * @ref rtems_bdbuf_pool_configuration.
- *
- * The configuration table size is provided by the application.
- */
-extern size_t rtems_bdbuf_pool_configuration_size;
+ rtems_chain_node link; /**< Link the groups on a LRU list if they
+ * have no buffers in use. */
+ size_t bds_per_group; /**< The number of BD allocated to this
+ * group. This value must be a multiple of
+ * 2. */
+ uint32_t users; /**< How many users the block has. */
+ rtems_bdbuf_buffer* bdbuf; /**< First BD this block covers. */
+};
/**
* Buffering configuration definition. See confdefs.h for support on using this
* structure.
*/
typedef struct rtems_bdbuf_config {
- uint32_t max_read_ahead_blocks; /**< Number of blocks to read ahead. */
- uint32_t max_write_blocks; /**< Number of blocks to write at once. */
- rtems_task_priority swapout_priority; /**< Priority of the swap out task. */
- uint32_t swapout_period; /**< Period swapout checks buf timers. */
- uint32_t swap_block_hold; /**< Period a buffer is held. */
+ uint32_t max_read_ahead_blocks; /**< Number of blocks to read
+ * ahead. */
+ uint32_t max_write_blocks; /**< Number of blocks to write
+ * at once. */
+ rtems_task_priority swapout_priority; /**< Priority of the swap out
+ * task. */
+ uint32_t swapout_period; /**< Period swapout checks buf
+ * timers. */
+ uint32_t swap_block_hold; /**< Period a buffer is held. */
+ uint32_t swapout_workers; /**< The number of worker
+ * threads for the swapout
+ * task. */
+ rtems_task_priority swapout_worker_priority; /**< Priority of the swap out
+ * task. */
+ size_t size; /**< Size of memory in the
+ * cache */
+ uint32_t buffer_min; /**< Minimum buffer size. */
+ uint32_t buffer_max; /**< Maximum buffer size
+ * supported. It is also the
+ * allocation size. */
} rtems_bdbuf_config;
/**
@@ -249,7 +254,7 @@ typedef struct rtems_bdbuf_config {
*
* The configuration is provided by the application.
*/
-extern rtems_bdbuf_config rtems_bdbuf_configuration;
+extern const rtems_bdbuf_config rtems_bdbuf_configuration;
/**
* The max_read_ahead_blocks value is altered if there are fewer buffers
@@ -278,11 +283,35 @@ extern rtems_bdbuf_config rtems_bdbuf_configuration;
#define RTEMS_BDBUF_SWAPOUT_TASK_BLOCK_HOLD_DEFAULT 1000
/**
+ * Default swap-out worker tasks. Currently disabled.
+ */
+#define RTEMS_BDBUF_SWAPOUT_WORKER_TASKS_DEFAULT 0
+
+/**
+ * Default swap-out worker task priority. The same as the swapout task.
+ */
+#define RTEMS_BDBUF_SWAPOUT_WORKER_TASK_PRIORITY_DEFAULT \
+ RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT
+
+/**
+ * Default size of memory allocated to the cache.
+ */
+#define RTEMS_BDBUF_CACHE_MEMORY_SIZE_DEFAULT (64 * 512)
+
+/**
+ * Default minimum size of buffers.
+ */
+#define RTEMS_BDBUF_BUFFER_MIN_SIZE_DEFAULT (512)
+
+/**
+ * Default maximum size of buffers.
+ */
+#define RTEMS_BDBUF_BUFFER_MAX_SIZE_DEFAULT (4096)
+
+/**
* Prepare buffering layer to work - initialize buffer descritors and (if it is
- * neccessary) buffers. Buffers will be allocated accoriding to the
- * configuration table, each entry describes the size of block and the size of
- * the pool. After initialization all blocks is placed into the ready state.
- * lists.
+ * neccessary) buffers. After initialization all blocks is placed into the
+ * ready state.
*
* @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed
* successfully or error code if error is occured)
@@ -395,13 +424,12 @@ rtems_bdbuf_sync (rtems_bdbuf_buffer* bd);
/**
* Synchronize all modified buffers for this device with the disk and wait
- * until the transfers have completed. The sync mutex for the pool is locked
+ * until the transfers have completed. The sync mutex for the cache is locked
* stopping the addition of any further modifed buffers. It is only the
* currently modified buffers that are written.
*
- * @note Nesting calls to sync multiple devices attached to a single pool will
- * be handled sequentially. A nested call will be blocked until the first sync
- * request has complete. This is only true for device using the same pool.
+ * @note Nesting calls to sync multiple devices will be handled sequentially. A
+ * nested call will be blocked until the first sync request has complete.
*
* @param dev Block device number
*
@@ -411,45 +439,6 @@ rtems_bdbuf_sync (rtems_bdbuf_buffer* bd);
rtems_status_code
rtems_bdbuf_syncdev (dev_t dev);
-/**
- * Find first appropriate buffer pool. This primitive returns the index of
- * first buffer pool which block size is greater than or equal to specified
- * size.
- *
- * @param block_size Requested block size
- * @param pool The pool to use for the requested pool size.
- *
- * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed
- * successfully or error code if error is occured)
- * @retval RTEMS_INVALID_SIZE The specified block size is invalid (not a power
- * of 2)
- * @retval RTEMS_NOT_DEFINED The buffer pool for this or greater block size
- * is not configured.
- */
-rtems_status_code
-rtems_bdbuf_find_pool (uint32_t block_size, rtems_bdpool_id *pool);
-
-/**
- * Obtain characteristics of buffer pool with specified number.
- *
- * @param pool Buffer pool number
- * @param block_size Block size for which buffer pool is configured returned
- * there
- * @param blocks Number of buffers in buffer pool.
- *
- * RETURNS:
- * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed
- * successfully or error code if error is occured)
- * @retval RTEMS_INVALID_SIZE The appropriate buffer pool is not configured.
- *
- * @note Buffer pools enumerated continuously starting from 0.
- */
-rtems_status_code rtems_bdbuf_get_pool_info(
- rtems_bdpool_id pool,
- uint32_t *block_size,
- uint32_t *blocks
-);
-
/** @} */
#ifdef __cplusplus