Commit 5ce1110b92b31d079aa443e967f43a2294e01194
Committed by
Linus Torvalds
1 parent
f615bfca46
Exists in
master
and in
4 other branches
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
include/linux/fs.h
... | ... | @@ -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 | /* |
mm/readahead.c
... | ... | @@ -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); |