Commit 5ce1110b92b31d079aa443e967f43a2294e01194

Authored by Fengguang Wu
Committed by Linus Torvalds
1 parent f615bfca46

readahead: data structure and routines

Extend struct file_ra_state to support the on-demand readahead logic.  Also
define some helpers for it.

Signed-off-by: Fengguang Wu <wfg@mail.ustc.edu.cn>
Cc: Steven Pratt <slpratt@austin.ibm.com>
Cc: Ram Pai <linuxram@us.ibm.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 83 additions and 0 deletions Side-by-side Diff

... ... @@ -695,6 +695,10 @@
695 695  
696 696 /*
697 697 * Track a single file's readahead state
  698 + *
  699 + * ================#============|==================#==================|
  700 + * ^ ^ ^ ^
  701 + * file_ra_state.la_index .ra_index .lookahead_index .readahead_index
698 702 */
699 703 struct file_ra_state {
700 704 unsigned long start; /* Current window */
... ... @@ -704,6 +708,12 @@
704 708 unsigned long prev_index; /* Cache last read() position */
705 709 unsigned long ahead_start; /* Ahead window */
706 710 unsigned long ahead_size;
  711 +
  712 + pgoff_t la_index; /* enqueue time */
  713 + pgoff_t ra_index; /* begin offset */
  714 + pgoff_t lookahead_index; /* time to do next readahead */
  715 + pgoff_t readahead_index; /* end offset */
  716 +
707 717 unsigned long ra_pages; /* Maximum readahead window */
708 718 unsigned long mmap_hit; /* Cache hit stat for mmap accesses */
709 719 unsigned long mmap_miss; /* Cache miss stat for mmap accesses */
... ... @@ -711,6 +721,60 @@
711 721 };
712 722 #define RA_FLAG_MISS 0x01 /* a cache miss occured against this file */
713 723 #define RA_FLAG_INCACHE 0x02 /* file is already in cache */
  724 +
  725 +/*
  726 + * Measuring read-ahead sizes.
  727 + *
  728 + * |----------- readahead size ------------>|
  729 + * ===#============|==================#=====================|
  730 + * |------- invoke interval ------>|-- lookahead size -->|
  731 + */
  732 +static inline unsigned long ra_readahead_size(struct file_ra_state *ra)
  733 +{
  734 + return ra->readahead_index - ra->ra_index;
  735 +}
  736 +
  737 +static inline unsigned long ra_lookahead_size(struct file_ra_state *ra)
  738 +{
  739 + return ra->readahead_index - ra->lookahead_index;
  740 +}
  741 +
  742 +static inline unsigned long ra_invoke_interval(struct file_ra_state *ra)
  743 +{
  744 + return ra->lookahead_index - ra->la_index;
  745 +}
  746 +
  747 +/*
  748 + * Check if @index falls in the readahead windows.
  749 + */
  750 +static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index)
  751 +{
  752 + return (index >= ra->la_index &&
  753 + index < ra->readahead_index);
  754 +}
  755 +
  756 +/*
  757 + * Where is the old read-ahead and look-ahead?
  758 + */
  759 +static inline void ra_set_index(struct file_ra_state *ra,
  760 + pgoff_t la_index, pgoff_t ra_index)
  761 +{
  762 + ra->la_index = la_index;
  763 + ra->ra_index = ra_index;
  764 +}
  765 +
  766 +/*
  767 + * Where is the new read-ahead and look-ahead?
  768 + */
  769 +static inline void ra_set_size(struct file_ra_state *ra,
  770 + unsigned long ra_size, unsigned long la_size)
  771 +{
  772 + ra->readahead_index = ra->ra_index + ra_size;
  773 + ra->lookahead_index = ra->ra_index + ra_size - la_size;
  774 +}
  775 +
  776 +unsigned long ra_submit(struct file_ra_state *ra,
  777 + struct address_space *mapping, struct file *filp);
714 778  
715 779 struct file {
716 780 /*
... ... @@ -592,4 +592,23 @@
592 592 return min(nr, (node_page_state(numa_node_id(), NR_INACTIVE)
593 593 + node_page_state(numa_node_id(), NR_FREE_PAGES)) / 2);
594 594 }
  595 +
  596 +/*
  597 + * Submit IO for the read-ahead request in file_ra_state.
  598 + */
  599 +unsigned long ra_submit(struct file_ra_state *ra,
  600 + struct address_space *mapping, struct file *filp)
  601 +{
  602 + unsigned long ra_size;
  603 + unsigned long la_size;
  604 + int actual;
  605 +
  606 + ra_size = ra_readahead_size(ra);
  607 + la_size = ra_lookahead_size(ra);
  608 + actual = __do_page_cache_readahead(mapping, filp,
  609 + ra->ra_index, ra_size, la_size);
  610 +
  611 + return actual;
  612 +}
  613 +EXPORT_SYMBOL_GPL(ra_submit);