Extend struct file_ra_state to support the adaptive read-ahead logic.
Signed-off-by: Wu Fengguang <[email protected]>
---
include/linux/fs.h | 57 +++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 47 insertions(+), 10 deletions(-)
--- linux-2.6.17-rc4-mm3.orig/include/linux/fs.h
+++ linux-2.6.17-rc4-mm3/include/linux/fs.h
@@ -613,21 +613,58 @@ struct fown_struct {
/*
* Track a single file's readahead state
+ *
+ * Diagram for the adaptive readahead logic:
+ *
+ * |--------- old chunk ------->|-------------- new chunk -------------->|
+ * +----------------------------+----------------------------------------+
+ * | # | # |
+ * +----------------------------+----------------------------------------+
+ * ^ ^ ^ ^
+ * file_ra_state.la_index .ra_index .lookahead_index .readahead_index
+ *
+ * Deduced sizes:
+ * |----------- readahead size ------------>|
+ * +----------------------------+----------------------------------------+
+ * | # | # |
+ * +----------------------------+----------------------------------------+
+ * |------- invoke interval ------>|-- lookahead size -->|
*/
struct file_ra_state {
- unsigned long start; /* Current window */
- unsigned long size;
- unsigned long flags; /* ra flags RA_FLAG_xxx*/
- unsigned long cache_hit; /* cache hit count*/
- unsigned long prev_page; /* Cache last read() position */
- unsigned long ahead_start; /* Ahead window */
- unsigned long ahead_size;
- unsigned long ra_pages; /* Maximum readahead window */
- unsigned long mmap_hit; /* Cache hit stat for mmap accesses */
- unsigned long mmap_miss; /* Cache miss stat for mmap accesses */
+ union {
+ struct { /* conventional read-ahead */
+ unsigned long start; /* Current window */
+ unsigned long size;
+ unsigned long ahead_start; /* Ahead window */
+ unsigned long ahead_size;
+ unsigned long cache_hit; /* cache hit count */
+ };
+#ifdef CONFIG_ADAPTIVE_READAHEAD
+ struct { /* adaptive read-ahead */
+ pgoff_t la_index;
+ pgoff_t ra_index;
+ pgoff_t lookahead_index;
+ pgoff_t readahead_index;
+ unsigned long age;
+ uint64_t cache_hits;
+ };
+#endif
+ };
+
+ /* mmap read-around */
+ unsigned long mmap_hit; /* Cache hit stat for mmap accesses */
+ unsigned long mmap_miss; /* Cache miss stat for mmap accesses */
+
+ /* common ones */
+ unsigned long flags; /* ra flags RA_FLAG_xxx*/
+ unsigned long prev_page; /* Cache last read() position */
+ unsigned long ra_pages; /* Maximum readahead window */
};
#define RA_FLAG_MISS 0x01 /* a cache miss occured against this file */
#define RA_FLAG_INCACHE 0x02 /* file is already in cache */
+#define RA_FLAG_MMAP (1UL<<31) /* mmaped page access */
+#define RA_FLAG_NO_LOOKAHEAD (1UL<<30) /* disable look-ahead */
+#define RA_FLAG_EOF (1UL<<29) /* readahead hits EOF */
struct file {
/*
--
Wu Fengguang wrote:
>Extend struct file_ra_state to support the adaptive read-ahead logic.
>
Another nitpick: It is usually OK to do these things in the same patch
that actually uses the new data (or functions -- eg. patch 15).
If the addition is complex or in a completely different subsystem
(eg. your rescue_pages function), _that_ can justify it being split
into its own patch. Then you might also prepend the subject with mm:
and cc linux-mm to get better reviews.
--
Send instant messages to your online friends http://au.messenger.yahoo.com
On Thu, May 25, 2006 at 04:03:31PM +1000, Nick Piggin wrote:
> Wu Fengguang wrote:
>
> >Extend struct file_ra_state to support the adaptive read-ahead logic.
> >
>
> Another nitpick: It is usually OK to do these things in the same patch
> that actually uses the new data (or functions -- eg. patch 15).
>
> If the addition is complex or in a completely different subsystem
> (eg. your rescue_pages function), _that_ can justify it being split
> into its own patch. Then you might also prepend the subject with mm:
> and cc linux-mm to get better reviews.
Ok, thanks for the advice.
Regards,
Wu
Wu Fengguang <[email protected]> wrote:
>
> #define RA_FLAG_MISS 0x01 /* a cache miss occured against this file */
> #define RA_FLAG_INCACHE 0x02 /* file is already in cache */
> +#define RA_FLAG_MMAP (1UL<<31) /* mmaped page access */
> +#define RA_FLAG_NO_LOOKAHEAD (1UL<<30) /* disable look-ahead */
> +#define RA_FLAG_EOF (1UL<<29) /* readahead hits EOF */
Odd. Why not use 4, 8, 16?
On Fri, May 26, 2006 at 10:05:52AM -0700, Andrew Morton wrote:
> Wu Fengguang <[email protected]> wrote:
> >
> > #define RA_FLAG_MISS 0x01 /* a cache miss occured against this file */
> > #define RA_FLAG_INCACHE 0x02 /* file is already in cache */
> > +#define RA_FLAG_MMAP (1UL<<31) /* mmaped page access */
> > +#define RA_FLAG_NO_LOOKAHEAD (1UL<<30) /* disable look-ahead */
> > +#define RA_FLAG_EOF (1UL<<29) /* readahead hits EOF */
>
> Odd. Why not use 4, 8, 16?
Sorry, the lower 8 bits are for ra_class values in the new code. It can
cause data corruption when dynamic switching between the two logics :(
I'd like to change the flags member to explicit ones like
struct {
unsigned miss :1;
unsigned incache :1;
unsigned mmap :1;
unsigned no_lookahead :1;
unsigned eof :1;
} flags;
unsigned class_new :4;
unsigned class_old :4;
Reasonable?
On Fri, May 26, 2006 at 10:05:52AM -0700, Andrew Morton wrote:
> Wu Fengguang <[email protected]> wrote:
> >
> > #define RA_FLAG_MISS 0x01 /* a cache miss occured against this file */
> > #define RA_FLAG_INCACHE 0x02 /* file is already in cache */
> > +#define RA_FLAG_MMAP (1UL<<31) /* mmaped page access */
> > +#define RA_FLAG_NO_LOOKAHEAD (1UL<<30) /* disable look-ahead */
> > +#define RA_FLAG_EOF (1UL<<29) /* readahead hits EOF */
>
> Odd. Why not use 4, 8, 16?
I'm now settled with:
-#define RA_FLAG_MISS 0x01 /* a cache miss occured against this file */
-#define RA_FLAG_INCACHE 0x02 /* file is already in cache */
+#define RA_FLAG_MISS (1UL<<31) /* a cache miss occured against this file */
+#define RA_FLAG_INCACHE (1UL<<30) /* file is already in cache */
+#define RA_FLAG_MMAP (1UL<<29) /* mmaped page access */
+#define RA_FLAG_NO_LOOKAHEAD (1UL<<28) /* disable look-ahead */
+#define RA_FLAG_EOF (1UL<<27) /* readahead hits EOF */
And still let the low bits hold ra_class values.