提交 6268b325 编写于 作者: L Linus Torvalds

Revert "ext4: don't release page refs in ext4_end_bio()"

This reverts commit b43d17f3.

Dave Jones reports that it causes lockups on his laptop, and his debug
output showed a lot of processes hung waiting for page_writeback (or
more commonly - processes hung waiting for a lock that was held during
that writeback wait).

The page_writeback hint made Ted suggest that Dave look at this commit,
and Dave verified that reverting it makes his problems go away.

Ted says:
 "That commit fixes a race which is seen when you write into fallocated
  (and hence uninitialized) disk blocks under *very* heavy memory
  pressure.  Furthermore, although theoretically it could trigger under
  normal direct I/O writes, it only seems to trigger if you are issuing
  a huge number of AIO writes, such that a just-written page can get
  evicted from memory, and then read back into memory, before the
  workqueue has a chance to update the extent tree.

  This race has been around for a little over a year, and no one noticed
  until two months ago; it only happens under fairly exotic conditions,
  and in fact even after trying very hard to create a simple repro under
  lab conditions, we could only reproduce the problem and confirm the
  fix on production servers running MySQL on very fast PCIe-attached
  flash devices.

  Given that Dave was able to hit this problem pretty quickly, if we
  confirm that this commit is at fault, the only reasonable thing to do
  is to revert it IMO."
Reported-and-tested-by: NDave Jones <davej@redhat.com>
Acked-by: NTheodore Ts'o <tytso@mit.edu>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 12679a2d
...@@ -60,6 +60,7 @@ void ext4_ioend_wait(struct inode *inode) ...@@ -60,6 +60,7 @@ void ext4_ioend_wait(struct inode *inode)
static void put_io_page(struct ext4_io_page *io_page) static void put_io_page(struct ext4_io_page *io_page)
{ {
if (atomic_dec_and_test(&io_page->p_count)) { if (atomic_dec_and_test(&io_page->p_count)) {
end_page_writeback(io_page->p_page);
put_page(io_page->p_page); put_page(io_page->p_page);
kmem_cache_free(io_page_cachep, io_page); kmem_cache_free(io_page_cachep, io_page);
} }
...@@ -233,9 +234,9 @@ static void ext4_end_bio(struct bio *bio, int error) ...@@ -233,9 +234,9 @@ static void ext4_end_bio(struct bio *bio, int error)
} while (bh != head); } while (bh != head);
} }
if (atomic_read(&io_end->pages[i]->p_count) == 1) put_io_page(io_end->pages[i]);
end_page_writeback(io_end->pages[i]->p_page);
} }
io_end->num_io_pages = 0;
inode = io_end->inode; inode = io_end->inode;
if (error) { if (error) {
...@@ -427,8 +428,6 @@ int ext4_bio_write_page(struct ext4_io_submit *io, ...@@ -427,8 +428,6 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
* PageWriteback bit from the page to prevent the system from * PageWriteback bit from the page to prevent the system from
* wedging later on. * wedging later on.
*/ */
if (atomic_read(&io_page->p_count) == 1)
end_page_writeback(page);
put_io_page(io_page); put_io_page(io_page);
return ret; return ret;
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册