From: Wu Fengguang <wfg@mail.ustc.edu.cn>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org, Michael Tokarev <mjt@tls.msk.ru>,
Jens Axboe <axboe@suse.de>
Subject: [PATCH 4/5] readahead: backoff on I/O error
Date: Fri, 09 Jun 2006 16:08:05 +0800 [thread overview]
Message-ID: <349840680.03819@ustc.edu.cn> (raw)
Message-ID: <20060609081120.531013274@localhost.localdomain> (raw)
In-Reply-To: 20060609080801.741901069@localhost.localdomain
[-- Attachment #1: readahead-eio-case.patch --]
[-- Type: text/plain, Size: 3496 bytes --]
Backoff readahead size exponentially on I/O error.
------
Michael Tokarev <mjt@tls.msk.ru> described the problem as:
[QUOTE]
Suppose there's a CD-rom with a scratch/etc, one sector is unreadable.
In order to "fix" it, one have to read it and write to another CD-rom,
or something.. or just ignore the error (if it's just a skip in a video
stream). Let's assume the unreadable block is number U.
But current behavior is just insane. An application requests block
number N, which is before U. Kernel tries to read-ahead blocks N..U.
Cdrom drive tries to read it, re-read it.. for some time. Finally,
when all the N..U-1 blocks are read, kernel returns block number N
(as requested) to an application, successefully.
Now an app requests block number N+1, and kernel tries to read
blocks N+1..U+1. Retrying again as in previous step.
And so on, up to when an app requests block number U-1. And when,
finally, it requests block U, it receives read error.
So, kernel currentry tries to re-read the same failing block as
many times as the current readahead value (256 (times?) by default).
This whole process already killed my cdrom drive (I posted about it
to LKML several months ago) - literally, the drive has fried, and
does not work anymore. Ofcourse that problem was a bug in firmware
(or whatever) of the drive *too*, but.. main problem with that is
current readahead logic as described above.
[/QUOTE]
Which was confirmed by Jens Axboe <axboe@suse.de>:
[QUOTE]
For ide-cd, it tends do only end the first part of the request on a
medium error. So you may see a lot of repeats :/
[/QUOTE]
With this patch, retries are expected to be reduced from, say, 256, to 5.
Signed-off-by: Wu Fengguang <wfg@mail.ustc.edu.cn>
---
--- linux-2.6.17-rc4-mm3.orig/mm/filemap.c
+++ linux-2.6.17-rc4-mm3/mm/filemap.c
@@ -809,6 +809,33 @@ grab_cache_page_nowait(struct address_sp
EXPORT_SYMBOL(grab_cache_page_nowait);
/*
+ * CD/DVDs are error prone. When a medium error occurs, the driver may fail
+ * a _large_ part of the i/o request. Imagine the worst scenario:
+ *
+ * ---R__________________________________________B__________
+ * ^ reading here ^ bad block(assume 4k)
+ *
+ * read(R) => miss => readahead(R...B) => media error => frustrating retries
+ * => failing the whole request => read(R) => read(R+1) =>
+ * readahead(R+1...B+1) => bang => read(R+2) => read(R+3) =>
+ * readahead(R+3...B+2) => bang => read(R+3) => read(R+4) =>
+ * readahead(R+4...B+3) => bang => read(R+4) => read(R+5) => ......
+ *
+ * It is going insane. Fix it by quickly scaling down the readahead size.
+ */
+static void shrink_readahead_size_eio(struct file *filp,
+ struct file_ra_state *ra)
+{
+ if (!ra->ra_pages)
+ return;
+
+ ra->ra_pages /= 4;
+ printk(KERN_WARNING "Retracting readahead size of %s to %luK\n",
+ filp->f_dentry->d_iname,
+ ra->ra_pages << (PAGE_CACHE_SHIFT - 10));
+}
+
+/*
* This is a generic file read routine, and uses the
* mapping->a_ops->readpage() function for the actual low-level
* stuff.
@@ -983,6 +1010,7 @@ readpage:
}
unlock_page(page);
error = -EIO;
+ shrink_readahead_size_eio(filp, &ra);
goto readpage_error;
}
unlock_page(page);
@@ -1535,6 +1563,7 @@ page_not_uptodate:
* Things didn't work out. Return zero to tell the
* mm layer so, possibly freeing the page cache page first.
*/
+ shrink_readahead_size_eio(file, ra);
page_cache_release(page);
return NULL;
}
--
next prev parent reply other threads:[~2006-06-09 8:11 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20060609080801.741901069@localhost.localdomain>
2006-06-09 8:08 ` [PATCH 0/5] Adaptive readahead updates 2 Wu Fengguang
[not found] ` <20060609081119.231751179@localhost.localdomain>
2006-06-09 8:08 ` [PATCH 1/5] readahead: no RA_FLAG_EOF on single page file Wu Fengguang
[not found] ` <20060609081120.054527393@localhost.localdomain>
2006-06-09 8:08 ` [PATCH 3/5] readahead: call scheme - no fastcall for readahead_cache_hit() Wu Fengguang
[not found] ` <20060609081120.531013274@localhost.localdomain>
2006-06-09 8:08 ` Wu Fengguang [this message]
2006-06-10 18:33 ` [PATCH 4/5] readahead: backoff on I/O error Ingo Oeser
2006-06-10 19:48 ` Michael Tokarev
[not found] ` <20060612011245.GA5214@mail.ustc.edu.cn>
2006-06-12 1:12 ` Wu Fengguang
2006-06-12 3:43 ` Andrew Morton
2006-06-12 11:06 ` Michael Tokarev
2006-06-17 6:38 ` Michael Tokarev
2006-06-17 7:00 ` Michael Tokarev
[not found] ` <20060609081121.002572642@localhost.localdomain>
2006-06-09 8:08 ` [PATCH 5/5] readahead: remove size limit on read_ahead_kb Wu Fengguang
2006-06-11 5:34 [PATCH 4/5] readahead: backoff on I/O error Just Marc
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=349840680.03819@ustc.edu.cn \
--to=wfg@mail.ustc.edu.cn \
--cc=akpm@osdl.org \
--cc=axboe@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=mjt@tls.msk.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox