Skip to contentSkip to conversation

readahead: context based method: remove readahead_ratio

PATCH New Fengguang Wu 1 participant 6 messages Jan 6, 2007 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH 1/6 readahead: sysctl parameters: set readahead_hit_rate=1

Set default readahead_hit_rate to 1 for the majority users.

---
 Documentation/sysctl/vm.txt |    2 +-
 mm/readahead.c              |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
Documentation/sysctl/vm.txt +1 -1
@@ -261,4 +261,4 @@ Possible values can be:
 
 The larger value, the more capabilities, with more possible overheads.
 
-The default value is 0.
+The default value is 1.
mm/readahead.c +1 -1
@@ -42,7 +42,7 @@ int readahead_ratio = 50;
 EXPORT_SYMBOL_GPL(readahead_ratio);
 
 /* Readahead as long as cache hit ratio keeps above 1/##. */
-int readahead_hit_rate = 0;
+int readahead_hit_rate = 1;
 #endif /* CONFIG_ADAPTIVE_READAHEAD */
 
 /*

--

#2 lore raw

PATCH 2/6 readahead: min/max sizes: remove get_readahead_bounds()

In reply to a message not in the archive

Remove get_readahead_bounds():
- ra_max: we already have get_max_readahead() for it
- ra_min: is only used by context based readahead, and will be moved there and set to a more reasonable value

---
 mm/readahead.c |   24 ------------------------
 1 file changed, 24 deletions(-)
mm/readahead.c +0 -24
@@ -780,30 +780,6 @@ out:
 	return nr_pages;
 }
 
-/*
- * ra_min is mainly determined by the size of cache memory. Reasonable?
- *
- * Table of concrete numbers for 4KB page size:
- *   inactive + free (MB):    4   8   16   32   64  128  256  512 1024
- *            ra_min (KB):   16  16   16   16   20   24   32   48   64
- */
-static inline void get_readahead_bounds(struct file_ra_state *ra,
-					unsigned long *ra_min,
-					unsigned long *ra_max)
-{
-	unsigned long active;
-	unsigned long inactive;
-	unsigned long free;
-
-	__get_zone_counts(&active, &inactive, &free, NODE_DATA(numa_node_id()));
-
-	free += inactive;
-	*ra_max = min(min(ra->ra_pages, 0xFFFFUL), free / 2);
-	*ra_min = min(min(MIN_RA_PAGES + (free >> 14),
-			  DIV_ROUND_UP(64*1024, PAGE_CACHE_SIZE)),
-			  *ra_max / 8);
-}
-
 #endif /* CONFIG_ADAPTIVE_READAHEAD */
 
 /*

--

#3 lore raw

PATCH 3/6 readahead: context based method: update ra_min

In reply to a message not in the archive

Classify the 4 cases into 2 classes, and assign proper ra_min for them. Also update comments correspondly.

---
 mm/readahead.c |   49 +++++++++++++++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 16 deletions(-)
mm/readahead.c +33 -16
@@ -1285,17 +1285,26 @@ static int
 try_context_based_readahead(struct address_space *mapping,
 			struct file_ra_state *ra,
 			struct page *page, pgoff_t offset,
-			unsigned long ra_min, unsigned long ra_max)
+			unsigned long req_size, unsigned long ra_max)
 {
 	pgoff_t start;
+	unsigned long ra_min;
 	unsigned long ra_size;
 	unsigned long la_size;
 
-	/* Check if there is a segment of history pages, and its end index.
+	/*
+	 * Check if there is a segment of history pages, and its end index.
 	 * Based on which we decide whether and where to start read-ahead.
-	 *
-	 * Case 1: we have a current page.
-	 * 	   Search forward for a nearby hole.
+	 */
+
+	/*
+	 * Select a reasonable large initial size for sequential reads.
+	 */
+	ra_min = min(req_size * 4, mapping->backing_dev_info->ra_pages0);
+
+	/*
+	 * Case s1: we have a current page.
+	 * =======> Search forward for a nearby hole.
 	 */
 	read_lock_irq(&mapping->tree_lock);
 	if (page) {
@@ -1308,8 +1317,9 @@ try_context_based_readahead(struct addre
 		return -1;
 	}
 
-	/* Case 2: current page is missing; previous page is present.
-	 *         Just do read-ahead from the current index on.
+	/*
+	 * Case s2: current page is missing; previous page is present.
+	 * =======> Just do read-ahead from the current index on.
 	 * There's clear sign of sequential reading. It can be
 	 * 	a) seek => read => this read
 	 * 	b) cache hit read(s) => this read
@@ -1321,26 +1331,33 @@ try_context_based_readahead(struct addre
 		goto has_history_pages;
 	}
 
-	/* Case 2x: the same context info as 2.
-	 * It can be the early stage of semi-sequential reads(interleaved/nfsd),
-	 * or an ugly random one.  So be conservative.
+	/*
+	 * Not an obvious sequential read:
+	 * select a conservative initial size, plus user prefered agressiveness.
+	 */
+	ra_min = min(req_size, MIN_RA_PAGES) +
+		 readahead_hit_rate * 8192 / PAGE_CACHE_SIZE;
+
+	/*
+	 * Case r1: the same context info as s2, but not that obvious.
+	 * =======> The same action as s2, but be conservative.
+	 * It can be the early stage of intermixed sequential reads,
+	 * or an ugly random one.
 	 */
 	if (readahead_hit_rate && __probe_page(mapping, offset - 1)) {
 		start = offset;
-		if (ra_min > 2 * readahead_hit_rate)
-		    ra_min = 2 * readahead_hit_rate;
 		goto has_history_pages;
 	}
 
-	/* Case 3: no current/previous pages;
-	 *         sparse read-ahead is enabled: ok, be aggressive.
-	 *         Check if there's any adjecent history pages.
+	/*
+	 * Case r2: no current/previous pages; sparse read-ahead is enabled.
+	 * =======> Do sparse read-ahead if there are adjecent history pages.
 	 */
 	if (readahead_hit_rate > 1) {
 		start = radix_tree_scan_data_backward(&mapping->page_tree,
 							       offset, ra_min);
 		if (start != ULONG_MAX && offset - start < ra_min) {
-			ra_min += offset - start;
+			ra_min *= 2;
 			offset = ++start; /* pretend the request starts here */
 			goto has_history_pages;
 		}

--

#4 lore raw

PATCH 4/6 readahead: context based method: remove readahead_ratio

In reply to a message not in the archive

The context based readahead is pretty conservative by nature, so do not apply readahead_ratio here.

---
 mm/readahead.c |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
mm/readahead.c +3 -4
@@ -1236,9 +1236,7 @@ static unsigned long count_history_pages
 	 * Check the far pages coarsely.
 	 * The enlarged count will contribute to the look-ahead size.
 	 */
-	lookback = ra_max * (LOOKAHEAD_RATIO + 1) *
-						100 / (readahead_ratio | 1);
-
+	lookback = ra_max * LOOKAHEAD_RATIO;
 	for (count += ra_max; count < lookback; count += ra_max)
 		if (!__probe_page(mapping, offset - count))
 			break;
@@ -1384,7 +1382,8 @@ has_history_pages:
 		adjust_rala_aggressive(ra_max, &ra_size, &la_size);
 		ra_set_class(ra, RA_CLASS_CONTEXT_AGGRESSIVE);
 	} else {
-		ra_size = max(ra_min, ra_size * readahead_ratio / 100);
+		if (ra_size < ra_min)
+		    ra_size = ra_min;
 		if (!adjust_rala(ra_max, &ra_size, &la_size))
 			return -1;
 		ra_set_class(ra, RA_CLASS_CONTEXT);

--

#5 lore raw

PATCH 5/6 readahead: call scheme: remove get_readahead_bounds()

In reply to a message not in the archive

Remove the one and only get_readahead_bounds() call.

---
 mm/readahead.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
mm/readahead.c +2 -3
@@ -1572,7 +1572,6 @@ page_cache_readahead_adaptive(struct add
 				pgoff_t offset, unsigned long req_size)
 {
 	unsigned long ra_size;
-	unsigned long ra_min;
 	unsigned long ra_max;
 	int ret;
 
@@ -1593,7 +1592,7 @@ page_cache_readahead_adaptive(struct add
 	else if (offset)
 		ra_account(ra, RA_EVENT_CACHE_MISS, req_size);
 
-	get_readahead_bounds(ra, &ra_min, &ra_max);
+	ra_max = get_max_readahead(ra);
 
 	/* read-ahead disabled? */
 	if (unlikely(!ra_max || !readahead_ratio)) {
@@ -1633,7 +1632,7 @@ page_cache_readahead_adaptive(struct add
 	 * Context based sequential read-ahead.
 	 */
 	ret = try_context_based_readahead(mapping, ra, page,
-							offset, ra_min, ra_max);
+						offset, req_size, ra_max);
 	if (ret > 0)
 		return ra_submit(ra, mapping, filp);
 	if (ret < 0)

--

#6 lore raw

PATCH 6/6 readahead: nfsd case: remove ra_min

In reply to a message not in the archive

ra_min => req_size.
Now it is for try_context_based_readahead() to compute ra_min from req_size.

Please fold it into readahead-nfsd-case.patch to avoid a compiling error.

---
 mm/readahead.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/readahead.c +1 -1
@@ -1673,7 +1673,7 @@ readit:
 		   !probe_page(mapping, ra_index)) {
 			ra->prev_page = ra_index - 1;
 			ret = try_context_based_readahead(mapping, ra, NULL,
-						 ra_index, ra_min, ra_max);
+						 ra_index, req_size, ra_max);
 			if (ret > 0)
 				ra_size += ra_submit(ra, mapping, filp);
 		}

--