mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-11-09 08:37:58 +08:00
libblock: Add read-ahead task
Read-ahead requests were previously executed in the context of the reading task. This blocks the reading task until the complete read with read-ahead transfer is finished. A read-ahead task is introduced to off-load the read-ahead transfer. This allows the reading task to work with the requested block more quickly. The read-ahead is triggered after two misses of ascending consecutive blocks or a read hit of a block read by the most-recent read-ahead transfer. The read-ahead feature is configurable and can be disabled.
This commit is contained in:
1 parent
6273201b14
commit
39ee704e75
11 files changed
+568
-130
No files matched your search
@@ -46,7 +46,7 @@ extern "C" {
|
||||
* @ingroup rtems_libblock
|
||||
*
|
||||
* The Block Device Buffer Management implements a cache between the disk
|
||||
* devices and file systems. The code provides read ahead and write queuing to
|
||||
* 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 block size used by a file system can be set at runtime and must be a
|
||||
@@ -152,10 +152,13 @@ extern "C" {
|
||||
* written. This would be a performance problem.
|
||||
*
|
||||
* The code performs multiple block reads and writes. Multiple block reads or
|
||||
* read ahead increases performance with hardware that supports it. It also
|
||||
* read-ahead increases performance with hardware that supports it. It also
|
||||
* helps with a large cache as the disk head movement is reduced. It however
|
||||
* is a speculative operation so excessive use can remove valuable and needed
|
||||
* blocks from the cache.
|
||||
* blocks from the cache. The read-ahead is triggered after two misses of
|
||||
* ascending consecutive blocks or a read hit of a block read by the
|
||||
* most-resent read-ahead transfer. The read-ahead works per disk, but all
|
||||
* transfers are issued by the read-ahead task.
|
||||
*
|
||||
* The cache has the following lists of buffers:
|
||||
* - LRU: Accessed or transfered buffers released in least recently used
|
||||
@@ -379,6 +382,8 @@ typedef struct rtems_bdbuf_config {
|
||||
uint32_t buffer_max; /**< Maximum buffer size
|
||||
* supported. It is also the
|
||||
* allocation size. */
|
||||
rtems_task_priority read_ahead_priority; /**< Priority of the read-ahead
|
||||
* task. */
|
||||
} rtems_bdbuf_config;
|
||||
|
||||
/**
|
||||
@@ -389,8 +394,8 @@ typedef struct rtems_bdbuf_config {
|
||||
extern const rtems_bdbuf_config rtems_bdbuf_configuration;
|
||||
|
||||
/**
|
||||
* The max_read_ahead_blocks value is altered if there are fewer buffers
|
||||
* than this defined max. This stops thrashing in the cache.
|
||||
* The default value for the maximum read-ahead blocks disables the read-ahead
|
||||
* feature.
|
||||
*/
|
||||
#define RTEMS_BDBUF_MAX_READ_AHEAD_BLOCKS_DEFAULT 0
|
||||
|
||||
@@ -425,6 +430,12 @@ extern const rtems_bdbuf_config rtems_bdbuf_configuration;
|
||||
#define RTEMS_BDBUF_SWAPOUT_WORKER_TASK_PRIORITY_DEFAULT \
|
||||
RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT
|
||||
|
||||
/**
|
||||
* Default read-ahead task priority. The same as the swap-out task.
|
||||
*/
|
||||
#define RTEMS_BDBUF_READ_AHEAD_TASK_PRIORITY_DEFAULT \
|
||||
RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT
|
||||
|
||||
/**
|
||||
* Default task stack size for swap-out and worker tasks.
|
||||
*/
|
||||
@@ -621,7 +632,7 @@ rtems_bdbuf_syncdev (rtems_disk_device *dd);
|
||||
/**
|
||||
* @brief Purges all buffers corresponding to the disk device @a dd.
|
||||
*
|
||||
* This may result in loss of data.
|
||||
* This may result in loss of data. The read-ahead state of this device is reset.
|
||||
*
|
||||
* Before you can use this function, the rtems_bdbuf_init() routine must be
|
||||
* called at least once to initialize the cache, otherwise a fatal error will
|
||||
@@ -635,7 +646,8 @@ rtems_bdbuf_purge_dev (rtems_disk_device *dd);
|
||||
/**
|
||||
* @brief Sets the block size of a disk device.
|
||||
*
|
||||
* This will set the block size derived fields of the disk device.
|
||||
* This will set the block size derived fields of the disk device. The
|
||||
* read-ahead state of this device is reset.
|
||||
*
|
||||
* Before you can use this function, the rtems_bdbuf_init() routine must be
|
||||
* called at least once to initialize the cache, otherwise a fatal error will
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/chain.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -54,6 +55,37 @@ typedef int (*rtems_block_device_ioctl)(
|
||||
void *argp
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Trigger value to disable further read-ahead requests.
|
||||
*/
|
||||
#define RTEMS_DISK_READ_AHEAD_NO_TRIGGER ((rtems_blkdev_bnum) -1)
|
||||
|
||||
/**
|
||||
* @brief Read-ahead control.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Chain node for the read-ahead request queue of the read-ahead task.
|
||||
*/
|
||||
rtems_chain_node node;
|
||||
|
||||
/**
|
||||
* @brief Block value to trigger the read-ahead request.
|
||||
*
|
||||
* A value of @ref RTEMS_DISK_READ_AHEAD_NO_TRIGGER will disable further
|
||||
* read-ahead requests since no valid block can have this value.
|
||||
*/
|
||||
rtems_blkdev_bnum trigger;
|
||||
|
||||
/**
|
||||
* @brief Start block for the next read-ahead request.
|
||||
*
|
||||
* In case the trigger value is out of range of valid blocks, this value my
|
||||
* be arbitrary.
|
||||
*/
|
||||
rtems_blkdev_bnum next;
|
||||
} rtems_disk_read_ahread;
|
||||
|
||||
/**
|
||||
* @brief Description of a disk device (logical and physical disks).
|
||||
*
|
||||
@@ -168,6 +200,11 @@ struct rtems_disk_device {
|
||||
* releases this disk.
|
||||
*/
|
||||
bool deleted;
|
||||
|
||||
/**
|
||||
* @brief Read-ahead control for this disk.
|
||||
*/
|
||||
rtems_disk_read_ahread read_ahead;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+226
-121
File diff suppressed because it is too large.
Load diff
@@ -36,6 +36,7 @@ rtems_status_code rtems_disk_init_phys(
|
||||
dd->media_block_size = block_size;
|
||||
dd->ioctl = handler;
|
||||
dd->driver_data = driver_data;
|
||||
dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;
|
||||
|
||||
if (block_count > 0) {
|
||||
if ((*handler)(dd, RTEMS_BLKIO_CAPABILITIES, &dd->capabilities) != 0) {
|
||||
@@ -67,6 +68,7 @@ rtems_status_code rtems_disk_init_log(
|
||||
dd->media_block_size = phys_dd->media_block_size;
|
||||
dd->ioctl = phys_dd->ioctl;
|
||||
dd->driver_data = phys_dd->driver_data;
|
||||
dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;
|
||||
|
||||
if (phys_dd->phys_dev == phys_dd) {
|
||||
rtems_blkdev_bnum phys_block_count = phys_dd->size;
|
||||
|
||||
@@ -1241,6 +1241,10 @@ rtems_fs_init_functions_t rtems_fs_init_helper =
|
||||
#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE \
|
||||
RTEMS_BDBUF_BUFFER_MAX_SIZE_DEFAULT
|
||||
#endif
|
||||
#ifndef CONFIGURE_BDBUF_READ_AHEAD_TASK_PRIORITY
|
||||
#define CONFIGURE_BDBUF_READ_AHEAD_TASK_PRIORITY \
|
||||
RTEMS_BDBUF_READ_AHEAD_TASK_PRIORITY_DEFAULT
|
||||
#endif
|
||||
#ifdef CONFIGURE_INIT
|
||||
const rtems_bdbuf_config rtems_bdbuf_configuration = {
|
||||
CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS,
|
||||
@@ -1253,11 +1257,14 @@ rtems_fs_init_functions_t rtems_fs_init_helper =
|
||||
CONFIGURE_BDBUF_TASK_STACK_SIZE,
|
||||
CONFIGURE_BDBUF_CACHE_MEMORY_SIZE,
|
||||
CONFIGURE_BDBUF_BUFFER_MIN_SIZE,
|
||||
CONFIGURE_BDBUF_BUFFER_MAX_SIZE
|
||||
CONFIGURE_BDBUF_BUFFER_MAX_SIZE,
|
||||
CONFIGURE_BDBUF_READ_AHEAD_TASK_PRIORITY
|
||||
};
|
||||
#endif
|
||||
|
||||
#define CONFIGURE_LIBBLOCK_TASKS (1 + CONFIGURE_SWAPOUT_WORKER_TASKS)
|
||||
#define CONFIGURE_LIBBLOCK_TASKS \
|
||||
(1 + CONFIGURE_SWAPOUT_WORKER_TASKS + \
|
||||
(CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS != 0))
|
||||
|
||||
#define CONFIGURE_LIBBLOCK_TASK_EXTRA_STACKS \
|
||||
(CONFIGURE_LIBBLOCK_TASKS * \
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
ACLOCAL_AMFLAGS = -I ../aclocal
|
||||
|
||||
SUBDIRS = POSIX
|
||||
SUBDIRS += block13
|
||||
SUBDIRS += rbheap01
|
||||
SUBDIRS += flashdisk01
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
rtems_tests_PROGRAMS = block13
|
||||
block13_SOURCES = init.c
|
||||
|
||||
dist_rtems_tests_DATA = block13.scn block13.doc
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(top_srcdir)/../automake/compile.am
|
||||
include $(top_srcdir)/../automake/leaf.am
|
||||
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
|
||||
|
||||
LINK_OBJS = $(block13_OBJECTS)
|
||||
LINK_LIBS = $(block13_LDLIBS)
|
||||
|
||||
block13$(EXEEXT): $(block13_OBJECTS) $(block13_DEPENDENCIES)
|
||||
@rm -f block13$(EXEEXT)
|
||||
$(make-exe)
|
||||
|
||||
include $(top_srcdir)/../automake/local.am
|
||||
@@ -0,0 +1,11 @@
|
||||
This file describes the directives and concepts tested by this test set.
|
||||
|
||||
test set name: block13
|
||||
|
||||
directives:
|
||||
|
||||
TBD
|
||||
|
||||
concepts:
|
||||
|
||||
Tests the read-ahead feature of bdbuf.
|
||||
@@ -0,0 +1,11 @@
|
||||
*** TEST BLOCK 13 ***
|
||||
0 2 3 4 5 6 7 8
|
||||
reset
|
||||
8
|
||||
reset
|
||||
7
|
||||
reset
|
||||
6 7
|
||||
reset
|
||||
5 6 8
|
||||
*** END OF TEST BLOCK 13 ***
|
||||
File diff suppressed because it is too large.
Load diff
@@ -41,6 +41,7 @@ AM_CONDITIONAL(NETTESTS,test "$rtems_cv_RTEMS_NETWORKING" = "yes")
|
||||
|
||||
# Explicitly list all Makefiles here
|
||||
AC_CONFIG_FILES([Makefile
|
||||
block13/Makefile
|
||||
rbheap01/Makefile
|
||||
syscall01/Makefile
|
||||
flashdisk01/Makefile
|
||||
|
||||
Reference in new issue
Block a user