Re: [PATCH rtems 1/2] libblock: Add rtems_bdbuf_peek()

2021-01-22 Thread Gedare Bloom
On Fri, Jan 22, 2021 at 7:08 AM Christian MAUDERER <
christian.maude...@embedded-brains.de> wrote:

> Am 22.01.21 um 14:59 schrieb Gedare Bloom:
> >
> >
> > On Fri, Jan 22, 2021 at 6:24 AM Christian Mauderer
> >  > > wrote:
> >
> > 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.
> > ---
> >   cpukit/include/rtems/bdbuf.h |  21 
> >   cpukit/include/rtems/diskdevs.h  |  27 -
> >   cpukit/libblock/src/bdbuf.c  |  80 +++
> >   cpukit/libblock/src/blkdev-print-stats.c |  28 ++---
> >   testsuites/fstests/fsdosfswrite01/init.c |  51 +-
> >   testsuites/libtests/block14/block14.scn  |  37 ---
> >   testsuites/libtests/block14/init.c   | 124
> +--
> >   7 files changed, 264 insertions(+), 104 deletions(-)
> >
> > diff --git a/cpukit/include/rtems/bdbuf.h
> b/cpukit/include/rtems/bdbuf.h
> > index fbb4fc05e9..0cde571816 100644
> > --- a/cpukit/include/rtems/bdbuf.h
> > +++ b/cpukit/include/rtems/bdbuf.h
> > @@ -539,6 +539,27 @@ rtems_bdbuf_read (
> > rtems_bdbuf_buffer** bd
> >   );
> >
> > +/**
> > + * Provide a hint to the read ahead mechanism which blocks should
> > be cached
> > + * next. This overwrites the default linear pattern. You should use
> > it in (for
> > + * example) a file system to tell bdbuf where the next part of a
> > fragmented file
> > + * is. If you know the length of the file, you can provide that too.
> > + *
> > + * Before you can use this function, the rtems_bdbuf_init() routine
> > must be
> > + * called at least once to initialize everything. Otherwise you
> > might get
> > + * unexpected results.
> > + *
> > + * @param dd [in] The disk device.
> > + * @param block [in] Linear media block number.
> > + * @param nr_blocks [in] Number of consecutive blocks that can be
> > pre-fetched.
> > + */
> > +void
> > +rtems_bdbuf_peek (
> > +  rtems_disk_device *dd,
> > +  rtems_blkdev_bnum block,
> > +  uint32_t nr_blocks
> > +);
> > +
> >   /**
> >* Release the buffer obtained by a read call back to the cache.
> > If the buffer
> >* was obtained by a get call and was not already in the cache the
> > release
> > diff --git a/cpukit/include/rtems/diskdevs.h
> > b/cpukit/include/rtems/diskdevs.h
> > index 85d157dcd5..d7529cbe89 100644
> > --- a/cpukit/include/rtems/diskdevs.h
> > +++ b/cpukit/include/rtems/diskdevs.h
> > @@ -58,6 +58,11 @@ typedef int (*rtems_block_device_ioctl)(
> >*/
> >   #define RTEMS_DISK_READ_AHEAD_NO_TRIGGER ((rtems_blkdev_bnum) -1)
> >
> > +/**
> > + * @brief Size value to set number of blocks based on config and
> > disk size.
> > + */
> > +#define RTEMS_DISK_READ_AHEAD_SIZE_AUTO (0)
> > +
> >   /**
> >* @brief Block device read-ahead control.
> >*/
> > @@ -71,7 +76,8 @@ typedef struct {
> >  * @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.
> > +   * read-ahead requests (except the ones triggered by @a
> > rtems_bdbuf_peek)
> > +   * since no valid block can have this value.
> >  */
> > rtems_blkdev_bnum trigger;
> >
> > @@ -82,6 +88,14 @@ typedef struct {
> >  * be arbitrary.
> >  */
> > rtems_blkdev_bnum next;
> > +
> > +  /**
> > +   * @brief Size of the next read-ahead request in blocks.
> > +   *
> > +   * A value of @ref RTEMS_DISK_READ_AHEAD_SIZE_AUTO will try to
> > read the rest
> > +   * of the disk but at most the configured max_read_ahead_blocks.
> > +   */
> > +  uint32_t nr_blocks;
> >   } rtems_blkdev_read_ahead;
> >
> >   /**
> > @@ -110,10 +124,19 @@ typedef struct {
> > /**
> >  * @brief Read-ahead transfer count.
> >  *
> > -   * Each read-ahead transfer may read multiple blocks.
> > +   * Each read-ahead transfer may read multiple blocks. This counts
> all
> > +   * transfers (with and without size).
> >  */
> > uint32_t read_ahead_transfers;
> >
> > +  /**
> > +   * @brief Read-ahead transfers with given size.
> > +   *
> > +   * Number of times a read ahead transfer has been given a size.
> > This is the
> > +   * case for read ahead transfers that are caused by a peek.
> > +   */
> > +  uint32_t read_ahead_transfers_with_size;
> >
> >
> > A little bit wordy. Maybe you just want to count the number of peeks?

Re: [PATCH rtems 1/2] libblock: Add rtems_bdbuf_peek()

2021-01-22 Thread Christian MAUDERER

Am 22.01.21 um 14:59 schrieb Gedare Bloom:



On Fri, Jan 22, 2021 at 6:24 AM Christian Mauderer 
> wrote:


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.
---
  cpukit/include/rtems/bdbuf.h             |  21 
  cpukit/include/rtems/diskdevs.h          |  27 -
  cpukit/libblock/src/bdbuf.c              |  80 +++
  cpukit/libblock/src/blkdev-print-stats.c |  28 ++---
  testsuites/fstests/fsdosfswrite01/init.c |  51 +-
  testsuites/libtests/block14/block14.scn  |  37 ---
  testsuites/libtests/block14/init.c       | 124 +--
  7 files changed, 264 insertions(+), 104 deletions(-)

diff --git a/cpukit/include/rtems/bdbuf.h b/cpukit/include/rtems/bdbuf.h
index fbb4fc05e9..0cde571816 100644
--- a/cpukit/include/rtems/bdbuf.h
+++ b/cpukit/include/rtems/bdbuf.h
@@ -539,6 +539,27 @@ rtems_bdbuf_read (
    rtems_bdbuf_buffer** bd
  );

+/**
+ * Provide a hint to the read ahead mechanism which blocks should
be cached
+ * next. This overwrites the default linear pattern. You should use
it in (for
+ * example) a file system to tell bdbuf where the next part of a
fragmented file
+ * is. If you know the length of the file, you can provide that too.
+ *
+ * Before you can use this function, the rtems_bdbuf_init() routine
must be
+ * called at least once to initialize everything. Otherwise you
might get
+ * unexpected results.
+ *
+ * @param dd [in] The disk device.
+ * @param block [in] Linear media block number.
+ * @param nr_blocks [in] Number of consecutive blocks that can be
pre-fetched.
+ */
+void
+rtems_bdbuf_peek (
+  rtems_disk_device *dd,
+  rtems_blkdev_bnum block,
+  uint32_t nr_blocks
+);
+
  /**
   * Release the buffer obtained by a read call back to the cache.
If the buffer
   * was obtained by a get call and was not already in the cache the
release
diff --git a/cpukit/include/rtems/diskdevs.h
b/cpukit/include/rtems/diskdevs.h
index 85d157dcd5..d7529cbe89 100644
--- a/cpukit/include/rtems/diskdevs.h
+++ b/cpukit/include/rtems/diskdevs.h
@@ -58,6 +58,11 @@ typedef int (*rtems_block_device_ioctl)(
   */
  #define RTEMS_DISK_READ_AHEAD_NO_TRIGGER ((rtems_blkdev_bnum) -1)

+/**
+ * @brief Size value to set number of blocks based on config and
disk size.
+ */
+#define RTEMS_DISK_READ_AHEAD_SIZE_AUTO (0)
+
  /**
   * @brief Block device read-ahead control.
   */
@@ -71,7 +76,8 @@ typedef struct {
     * @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.
+   * read-ahead requests (except the ones triggered by @a
rtems_bdbuf_peek)
+   * since no valid block can have this value.
     */
    rtems_blkdev_bnum trigger;

@@ -82,6 +88,14 @@ typedef struct {
     * be arbitrary.
     */
    rtems_blkdev_bnum next;
+
+  /**
+   * @brief Size of the next read-ahead request in blocks.
+   *
+   * A value of @ref RTEMS_DISK_READ_AHEAD_SIZE_AUTO will try to
read the rest
+   * of the disk but at most the configured max_read_ahead_blocks.
+   */
+  uint32_t nr_blocks;
  } rtems_blkdev_read_ahead;

  /**
@@ -110,10 +124,19 @@ typedef struct {
    /**
     * @brief Read-ahead transfer count.
     *
-   * Each read-ahead transfer may read multiple blocks.
+   * Each read-ahead transfer may read multiple blocks. This counts all
+   * transfers (with and without size).
     */
    uint32_t read_ahead_transfers;

+  /**
+   * @brief Read-ahead transfers with given size.
+   *
+   * Number of times a read ahead transfer has been given a size.
This is the
+   * case for read ahead transfers that are caused by a peek.
+   */
+  uint32_t read_ahead_transfers_with_size;


A little bit wordy. Maybe you just want to count the number of peeks?


I thought about that too. But in theory, someone could add another 
mechanism that uses the size. For example it would be possible to do the 
normal read ahead with that too.


But if you prefer, I can rename it to "read_ahead_peeks". I would avoid 
removing the read_ahead altogether because it belongs to this mechanism.




+
    /**
     * @brief Count of blocks transfered from the device.
     */
diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
index a7d471507c..02acf11f54 100644
--- a/cpukit/libblock/src/bdbuf.c
+++ 

Re: [PATCH rtems 1/2] libblock: Add rtems_bdbuf_peek()

2021-01-22 Thread Gedare Bloom
On Fri, Jan 22, 2021 at 6:24 AM Christian Mauderer <
christian.maude...@embedded-brains.de> wrote:

> 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.
> ---
>  cpukit/include/rtems/bdbuf.h |  21 
>  cpukit/include/rtems/diskdevs.h  |  27 -
>  cpukit/libblock/src/bdbuf.c  |  80 +++
>  cpukit/libblock/src/blkdev-print-stats.c |  28 ++---
>  testsuites/fstests/fsdosfswrite01/init.c |  51 +-
>  testsuites/libtests/block14/block14.scn  |  37 ---
>  testsuites/libtests/block14/init.c   | 124 +--
>  7 files changed, 264 insertions(+), 104 deletions(-)
>
> diff --git a/cpukit/include/rtems/bdbuf.h b/cpukit/include/rtems/bdbuf.h
> index fbb4fc05e9..0cde571816 100644
> --- a/cpukit/include/rtems/bdbuf.h
> +++ b/cpukit/include/rtems/bdbuf.h
> @@ -539,6 +539,27 @@ rtems_bdbuf_read (
>rtems_bdbuf_buffer** bd
>  );
>
> +/**
> + * Provide a hint to the read ahead mechanism which blocks should be
> cached
> + * next. This overwrites the default linear pattern. You should use it in
> (for
> + * example) a file system to tell bdbuf where the next part of a
> fragmented file
> + * is. If you know the length of the file, you can provide that too.
> + *
> + * Before you can use this function, the rtems_bdbuf_init() routine must
> be
> + * called at least once to initialize everything. Otherwise you might get
> + * unexpected results.
> + *
> + * @param dd [in] The disk device.
> + * @param block [in] Linear media block number.
> + * @param nr_blocks [in] Number of consecutive blocks that can be
> pre-fetched.
> + */
> +void
> +rtems_bdbuf_peek (
> +  rtems_disk_device *dd,
> +  rtems_blkdev_bnum block,
> +  uint32_t nr_blocks
> +);
> +
>  /**
>   * Release the buffer obtained by a read call back to the cache. If the
> buffer
>   * was obtained by a get call and was not already in the cache the release
> diff --git a/cpukit/include/rtems/diskdevs.h
> b/cpukit/include/rtems/diskdevs.h
> index 85d157dcd5..d7529cbe89 100644
> --- a/cpukit/include/rtems/diskdevs.h
> +++ b/cpukit/include/rtems/diskdevs.h
> @@ -58,6 +58,11 @@ typedef int (*rtems_block_device_ioctl)(
>   */
>  #define RTEMS_DISK_READ_AHEAD_NO_TRIGGER ((rtems_blkdev_bnum) -1)
>
> +/**
> + * @brief Size value to set number of blocks based on config and disk
> size.
> + */
> +#define RTEMS_DISK_READ_AHEAD_SIZE_AUTO (0)
> +
>  /**
>   * @brief Block device read-ahead control.
>   */
> @@ -71,7 +76,8 @@ typedef struct {
> * @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.
> +   * read-ahead requests (except the ones triggered by @a
> rtems_bdbuf_peek)
> +   * since no valid block can have this value.
> */
>rtems_blkdev_bnum trigger;
>
> @@ -82,6 +88,14 @@ typedef struct {
> * be arbitrary.
> */
>rtems_blkdev_bnum next;
> +
> +  /**
> +   * @brief Size of the next read-ahead request in blocks.
> +   *
> +   * A value of @ref RTEMS_DISK_READ_AHEAD_SIZE_AUTO will try to read the
> rest
> +   * of the disk but at most the configured max_read_ahead_blocks.
> +   */
> +  uint32_t nr_blocks;
>  } rtems_blkdev_read_ahead;
>
>  /**
> @@ -110,10 +124,19 @@ typedef struct {
>/**
> * @brief Read-ahead transfer count.
> *
> -   * Each read-ahead transfer may read multiple blocks.
> +   * Each read-ahead transfer may read multiple blocks. This counts all
> +   * transfers (with and without size).
> */
>uint32_t read_ahead_transfers;
>
> +  /**
> +   * @brief Read-ahead transfers with given size.
> +   *
> +   * Number of times a read ahead transfer has been given a size. This is
> the
> +   * case for read ahead transfers that are caused by a peek.
> +   */
> +  uint32_t read_ahead_transfers_with_size;


A little bit wordy. Maybe you just want to count the number of peeks?


>

+
>/**
> * @brief Count of blocks transfered from the device.
> */
> diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
> index a7d471507c..02acf11f54 100644
> --- a/cpukit/libblock/src/bdbuf.c
> +++ b/cpukit/libblock/src/bdbuf.c
> @@ -2018,6 +2018,23 @@ rtems_bdbuf_read_ahead_reset (rtems_disk_device *dd)
>dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;
>  }
>
> +static void
> +rtems_bdbuf_read_ahead_add_to_chain (rtems_disk_device *dd)
> +{
> +  rtems_status_code sc;
> +  rtems_chain_control *chain = _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, 

[PATCH rtems 1/2] libblock: Add rtems_bdbuf_peek()

2021-01-22 Thread Christian Mauderer
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.
---
 cpukit/include/rtems/bdbuf.h |  21 
 cpukit/include/rtems/diskdevs.h  |  27 -
 cpukit/libblock/src/bdbuf.c  |  80 +++
 cpukit/libblock/src/blkdev-print-stats.c |  28 ++---
 testsuites/fstests/fsdosfswrite01/init.c |  51 +-
 testsuites/libtests/block14/block14.scn  |  37 ---
 testsuites/libtests/block14/init.c   | 124 +--
 7 files changed, 264 insertions(+), 104 deletions(-)

diff --git a/cpukit/include/rtems/bdbuf.h b/cpukit/include/rtems/bdbuf.h
index fbb4fc05e9..0cde571816 100644
--- a/cpukit/include/rtems/bdbuf.h
+++ b/cpukit/include/rtems/bdbuf.h
@@ -539,6 +539,27 @@ rtems_bdbuf_read (
   rtems_bdbuf_buffer** bd
 );
 
+/**
+ * Provide a hint to the read ahead mechanism which blocks should be cached
+ * next. This overwrites the default linear pattern. You should use it in (for
+ * example) a file system to tell bdbuf where the next part of a fragmented 
file
+ * is. If you know the length of the file, you can provide that too.
+ *
+ * Before you can use this function, the rtems_bdbuf_init() routine must be
+ * called at least once to initialize everything. Otherwise you might get
+ * unexpected results.
+ *
+ * @param dd [in] The disk device.
+ * @param block [in] Linear media block number.
+ * @param nr_blocks [in] Number of consecutive blocks that can be pre-fetched.
+ */
+void
+rtems_bdbuf_peek (
+  rtems_disk_device *dd,
+  rtems_blkdev_bnum block,
+  uint32_t nr_blocks
+);
+
 /**
  * Release the buffer obtained by a read call back to the cache. If the buffer
  * was obtained by a get call and was not already in the cache the release
diff --git a/cpukit/include/rtems/diskdevs.h b/cpukit/include/rtems/diskdevs.h
index 85d157dcd5..d7529cbe89 100644
--- a/cpukit/include/rtems/diskdevs.h
+++ b/cpukit/include/rtems/diskdevs.h
@@ -58,6 +58,11 @@ typedef int (*rtems_block_device_ioctl)(
  */
 #define RTEMS_DISK_READ_AHEAD_NO_TRIGGER ((rtems_blkdev_bnum) -1)
 
+/**
+ * @brief Size value to set number of blocks based on config and disk size.
+ */
+#define RTEMS_DISK_READ_AHEAD_SIZE_AUTO (0)
+
 /**
  * @brief Block device read-ahead control.
  */
@@ -71,7 +76,8 @@ typedef struct {
* @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.
+   * read-ahead requests (except the ones triggered by @a rtems_bdbuf_peek)
+   * since no valid block can have this value.
*/
   rtems_blkdev_bnum trigger;
 
@@ -82,6 +88,14 @@ typedef struct {
* be arbitrary.
*/
   rtems_blkdev_bnum next;
+
+  /**
+   * @brief Size of the next read-ahead request in blocks.
+   *
+   * A value of @ref RTEMS_DISK_READ_AHEAD_SIZE_AUTO will try to read the rest
+   * of the disk but at most the configured max_read_ahead_blocks.
+   */
+  uint32_t nr_blocks;
 } rtems_blkdev_read_ahead;
 
 /**
@@ -110,10 +124,19 @@ typedef struct {
   /**
* @brief Read-ahead transfer count.
*
-   * Each read-ahead transfer may read multiple blocks.
+   * Each read-ahead transfer may read multiple blocks. This counts all
+   * transfers (with and without size).
*/
   uint32_t read_ahead_transfers;
 
+  /**
+   * @brief Read-ahead transfers with given size.
+   *
+   * Number of times a read ahead transfer has been given a size. This is the
+   * case for read ahead transfers that are caused by a peek.
+   */
+  uint32_t read_ahead_transfers_with_size;
+
   /**
* @brief Count of blocks transfered from the device.
*/
diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
index a7d471507c..02acf11f54 100644
--- a/cpukit/libblock/src/bdbuf.c
+++ b/cpukit/libblock/src/bdbuf.c
@@ -2018,6 +2018,23 @@ rtems_bdbuf_read_ahead_reset (rtems_disk_device *dd)
   dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER;
 }
 
+static void
+rtems_bdbuf_read_ahead_add_to_chain (rtems_disk_device *dd)
+{
+  rtems_status_code sc;
+  rtems_chain_control *chain = _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, >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 = _cache.read_ahead_chain;
-
-if