Messages in this thread Patch in this message | | | From | Nick Piggin <> | Subject | Re: 2.6.24-sha1: RIP [<ffffffff802596c8>] iov_iter_advance+0x38/0x70 | Date | Tue, 26 Feb 2008 14:46:56 +1100 |
| |
On Wednesday 20 February 2008 09:01, Alexey Dobriyan wrote: > On Tue, Feb 19, 2008 at 11:47:11PM +0300, wrote:
> > > Are you reproducing it simply by running the > > > ftest03 binary directly from the shell? How many times between oopses? > > > It is multi-process but no threads, so races should be minimal down > > > this path -- can you get an strace of the failing process? > > Speaking of multi-proceseness, changing MAXCHILD to 1, nchild to 1, > AFAICS, generates one child which oopses the very same way (in parallel > with generic LTP) But, lowering MAXIOVCNT to 8 generates no oops.
Thanks, I was able to reproduce quite easily with these settings. I think I have the correct patch now (at least it isn't triggerable any more here).
Thanks, Nick diff --git a/mm/filemap.c b/mm/filemap.c index 5c74b68..2650073 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1750,14 +1750,18 @@ static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes) } else { const struct iovec *iov = i->iov; size_t base = i->iov_offset; + size_t copied = 0; /* * The !iov->iov_len check ensures we skip over unlikely - * zero-length segments. + * zero-length segments (without overruning the iovec). */ - while (bytes || !iov->iov_len) { - int copy = min(bytes, iov->iov_len - base); + while (copied < bytes || + unlikely(!iov->iov_len && copied < i->count)) { + int copy; + copy = min(bytes, iov->iov_len - base); + copied += copy; bytes -= copy; base += copy; if (iov->iov_len == base) { | |