summaryrefslogtreecommitdiffstats
path: root/cpukit/libblock/src
diff options
context:
space:
mode:
authorChristian Mauderer <christian.mauderer@embedded-brains.de>2021-01-19 15:33:35 +0100
committerChristian Mauderer <christian.mauderer@embedded-brains.de>2021-03-26 14:25:38 +0100
commit6ae79e6df6fbc89ffbd6badb3f84d6a2b513fe83 (patch)
tree370419dc3ec031519955f899069222fbd138b91b /cpukit/libblock/src
parentgen_uuid.c: Revert previous patch (597e4f476568a225d14dfaff02074cf269ad62ac) (diff)
downloadrtems-6ae79e6df6fbc89ffbd6badb3f84d6a2b513fe83.tar.bz2
libblock: Add rtems_bdbuf_peek()
Adds a peek function that allows (for example) a file system to suggest the next blocks that should be used for read ahead. This can increase the read speed of fragmented files. Update #3689
Diffstat (limited to 'cpukit/libblock/src')
-rw-r--r--cpukit/libblock/src/bdbuf.c84
-rw-r--r--cpukit/libblock/src/blkdev-print-stats.c2
2 files changed, 64 insertions, 22 deletions
diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
index a7d471507c..8aadf9c8ae 100644
--- a/cpukit/libblock/src/bdbuf.c
+++ b/cpukit/libblock/src/bdbuf.c
@@ -2019,6 +2019,23 @@ rtems_bdbuf_read_ahead_reset (rtems_disk_device *dd)
}
static void
+rtems_bdbuf_read_ahead_add_to_chain (rtems_disk_device *dd)
+{
+ rtems_status_code sc;
+ rtems_chain_control *chain = &bdbuf_cache.read_ahead_chain;
+
+ if (rtems_chain_is_empty (chain))
+ {
+ sc = rtems_event_send (bdbuf_cache.read_ahead_task,
+ RTEMS_BDBUF_READ_AHEAD_WAKE_UP);
+ if (sc != RTEMS_SUCCESSFUL)
+ rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_RA_WAKE_UP);
+ }
+
+ rtems_chain_append_unprotected (chain, &dd->read_ahead.node);
+}
+
+static void
rtems_bdbuf_check_read_ahead_trigger (rtems_disk_device *dd,
rtems_blkdev_bnum block)
{
@@ -2026,18 +2043,8 @@ rtems_bdbuf_check_read_ahead_trigger (rtems_disk_device *dd,
&& dd->read_ahead.trigger == block
&& !rtems_bdbuf_is_read_ahead_active (dd))
{
- rtems_status_code sc;
- rtems_chain_control *chain = &bdbuf_cache.read_ahead_chain;
-
- if (rtems_chain_is_empty (chain))
- {
- sc = rtems_event_send (bdbuf_cache.read_ahead_task,
- RTEMS_BDBUF_READ_AHEAD_WAKE_UP);
- if (sc != RTEMS_SUCCESSFUL)
- rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_RA_WAKE_UP);
- }
-
- rtems_chain_append_unprotected (chain, &dd->read_ahead.node);
+ dd->read_ahead.nr_blocks = RTEMS_DISK_READ_AHEAD_SIZE_AUTO;
+ rtems_bdbuf_read_ahead_add_to_chain(dd);
}
}
@@ -2112,6 +2119,24 @@ rtems_bdbuf_read (rtems_disk_device *dd,
return sc;
}
+void
+rtems_bdbuf_peek (rtems_disk_device *dd,
+ rtems_blkdev_bnum block,
+ uint32_t nr_blocks)
+{
+ rtems_bdbuf_lock_cache ();
+
+ if (bdbuf_cache.read_ahead_enabled && nr_blocks > 0)
+ {
+ rtems_bdbuf_read_ahead_reset(dd);
+ dd->read_ahead.next = block;
+ dd->read_ahead.nr_blocks = nr_blocks;
+ rtems_bdbuf_read_ahead_add_to_chain(dd);
+ }
+
+ rtems_bdbuf_unlock_cache ();
+}
+
static rtems_status_code
rtems_bdbuf_check_bd_and_lock_cache (rtems_bdbuf_buffer *bd, const char *kind)
{
@@ -2952,18 +2977,33 @@ rtems_bdbuf_read_ahead_task (rtems_task_argument arg)
if (bd != NULL)
{
- uint32_t transfer_count = dd->block_count - block;
+ uint32_t transfer_count = dd->read_ahead.nr_blocks;
+ uint32_t blocks_until_end_of_disk = dd->block_count - block;
uint32_t max_transfer_count = bdbuf_config.max_read_ahead_blocks;
- if (transfer_count >= max_transfer_count)
- {
- transfer_count = max_transfer_count;
- dd->read_ahead.trigger = block + transfer_count / 2;
- dd->read_ahead.next = block + transfer_count;
- }
- else
- {
- dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;
+ if (transfer_count == RTEMS_DISK_READ_AHEAD_SIZE_AUTO) {
+ transfer_count = blocks_until_end_of_disk;
+
+ if (transfer_count >= max_transfer_count)
+ {
+ transfer_count = max_transfer_count;
+ dd->read_ahead.trigger = block + transfer_count / 2;
+ dd->read_ahead.next = block + transfer_count;
+ }
+ else
+ {
+ dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;
+ }
+ } else {
+ if (transfer_count > blocks_until_end_of_disk) {
+ transfer_count = blocks_until_end_of_disk;
+ }
+
+ if (transfer_count > max_transfer_count) {
+ transfer_count = max_transfer_count;
+ }
+
+ ++dd->stats.read_ahead_peeks;
}
++dd->stats.read_ahead_transfers;
diff --git a/cpukit/libblock/src/blkdev-print-stats.c b/cpukit/libblock/src/blkdev-print-stats.c
index 8edf24fd8c..539ff08157 100644
--- a/cpukit/libblock/src/blkdev-print-stats.c
+++ b/cpukit/libblock/src/blkdev-print-stats.c
@@ -47,6 +47,7 @@ void rtems_blkdev_print_stats(
" READ HITS | %" PRIu32 "\n"
" READ MISSES | %" PRIu32 "\n"
" READ AHEAD TRANSFERS | %" PRIu32 "\n"
+ " READ AHEAD PEEKS | %" PRIu32 "\n"
" READ BLOCKS | %" PRIu32 "\n"
" READ ERRORS | %" PRIu32 "\n"
" WRITE TRANSFERS | %" PRIu32 "\n"
@@ -59,6 +60,7 @@ void rtems_blkdev_print_stats(
stats->read_hits,
stats->read_misses,
stats->read_ahead_transfers,
+ stats->read_ahead_peeks,
stats->read_blocks,
stats->read_errors,
stats->write_transfers,