* two small bio cleanups
@ 2018-07-24 12:04 Christoph Hellwig
2018-07-24 12:04 ` [PATCH 1/2] block: simplify bio_check_pages_dirty Christoph Hellwig
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Christoph Hellwig @ 2018-07-24 12:04 UTC (permalink / raw)
To: axboe; +Cc: linux-block
To remove invariants that are odd and in the way of multipage biovecs.
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] block: simplify bio_check_pages_dirty
2018-07-24 12:04 two small bio cleanups Christoph Hellwig
@ 2018-07-24 12:04 ` Christoph Hellwig
2018-07-24 12:04 ` [PATCH 2/2] block: bio_set_pages_dirty can't see NULL bv_page in a valid bio_vec Christoph Hellwig
2018-07-24 20:41 ` two small bio cleanups Jens Axboe
2 siblings, 0 replies; 4+ messages in thread
From: Christoph Hellwig @ 2018-07-24 12:04 UTC (permalink / raw)
To: axboe; +Cc: linux-block
bio_check_pages_dirty currently inviolates the invariant that bv_page of
a bio_vec inside bi_vcnt shouldn't be zero, and that is going to become
really annoying with multpath biovecs. Fortunately there isn't any
all that good reason for it - once we decide to defer freeing the bio
to a workqueue holding onto a few additional pages isn't really an
issue anymore. So just check if there is a clean page that needs
dirtying in the first path, and do a second pass to free them if there
was none, while the cache is still hot.
Also use the chance to micro-optimize bio_dirty_fn a bit by not saving
irq state - we know we are called from a workqueue.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
---
block/bio.c | 56 ++++++++++++++++++++---------------------------------
1 file changed, 21 insertions(+), 35 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 8ecc95615941..504b42278099 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1649,19 +1649,15 @@ static void bio_release_pages(struct bio *bio)
struct bio_vec *bvec;
int i;
- bio_for_each_segment_all(bvec, bio, i) {
- struct page *page = bvec->bv_page;
-
- if (page)
- put_page(page);
- }
+ bio_for_each_segment_all(bvec, bio, i)
+ put_page(bvec->bv_page);
}
/*
* bio_check_pages_dirty() will check that all the BIO's pages are still dirty.
* If they are, then fine. If, however, some pages are clean then they must
* have been written out during the direct-IO read. So we take another ref on
- * the BIO and the offending pages and re-dirty the pages in process context.
+ * the BIO and re-dirty the pages in process context.
*
* It is expected that bio_check_pages_dirty() will wholly own the BIO from
* here on. It will run one put_page() against each page and will run one
@@ -1679,52 +1675,42 @@ static struct bio *bio_dirty_list;
*/
static void bio_dirty_fn(struct work_struct *work)
{
- unsigned long flags;
- struct bio *bio;
+ struct bio *bio, *next;
- spin_lock_irqsave(&bio_dirty_lock, flags);
- bio = bio_dirty_list;
+ spin_lock_irq(&bio_dirty_lock);
+ next = bio_dirty_list;
bio_dirty_list = NULL;
- spin_unlock_irqrestore(&bio_dirty_lock, flags);
+ spin_unlock_irq(&bio_dirty_lock);
- while (bio) {
- struct bio *next = bio->bi_private;
+ while ((bio = next) != NULL) {
+ next = bio->bi_private;
bio_set_pages_dirty(bio);
bio_release_pages(bio);
bio_put(bio);
- bio = next;
}
}
void bio_check_pages_dirty(struct bio *bio)
{
struct bio_vec *bvec;
- int nr_clean_pages = 0;
+ unsigned long flags;
int i;
bio_for_each_segment_all(bvec, bio, i) {
- struct page *page = bvec->bv_page;
-
- if (PageDirty(page) || PageCompound(page)) {
- put_page(page);
- bvec->bv_page = NULL;
- } else {
- nr_clean_pages++;
- }
+ if (!PageDirty(bvec->bv_page) && !PageCompound(bvec->bv_page))
+ goto defer;
}
- if (nr_clean_pages) {
- unsigned long flags;
-
- spin_lock_irqsave(&bio_dirty_lock, flags);
- bio->bi_private = bio_dirty_list;
- bio_dirty_list = bio;
- spin_unlock_irqrestore(&bio_dirty_lock, flags);
- schedule_work(&bio_dirty_work);
- } else {
- bio_put(bio);
- }
+ bio_release_pages(bio);
+ bio_put(bio);
+ return;
+defer:
+ spin_lock_irqsave(&bio_dirty_lock, flags);
+ bio->bi_private = bio_dirty_list;
+ bio_dirty_list = bio;
+ spin_unlock_irqrestore(&bio_dirty_lock, flags);
+ schedule_work(&bio_dirty_work);
}
EXPORT_SYMBOL_GPL(bio_check_pages_dirty);
--
2.18.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] block: bio_set_pages_dirty can't see NULL bv_page in a valid bio_vec
2018-07-24 12:04 two small bio cleanups Christoph Hellwig
2018-07-24 12:04 ` [PATCH 1/2] block: simplify bio_check_pages_dirty Christoph Hellwig
@ 2018-07-24 12:04 ` Christoph Hellwig
2018-07-24 20:41 ` two small bio cleanups Jens Axboe
2 siblings, 0 replies; 4+ messages in thread
From: Christoph Hellwig @ 2018-07-24 12:04 UTC (permalink / raw)
To: axboe; +Cc: linux-block
So don't bother handling it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
---
block/bio.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 504b42278099..07d3ffd95989 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1636,10 +1636,8 @@ void bio_set_pages_dirty(struct bio *bio)
int i;
bio_for_each_segment_all(bvec, bio, i) {
- struct page *page = bvec->bv_page;
-
- if (page && !PageCompound(page))
- set_page_dirty_lock(page);
+ if (!PageCompound(bvec->bv_page))
+ set_page_dirty_lock(bvec->bv_page);
}
}
EXPORT_SYMBOL_GPL(bio_set_pages_dirty);
--
2.18.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: two small bio cleanups
2018-07-24 12:04 two small bio cleanups Christoph Hellwig
2018-07-24 12:04 ` [PATCH 1/2] block: simplify bio_check_pages_dirty Christoph Hellwig
2018-07-24 12:04 ` [PATCH 2/2] block: bio_set_pages_dirty can't see NULL bv_page in a valid bio_vec Christoph Hellwig
@ 2018-07-24 20:41 ` Jens Axboe
2 siblings, 0 replies; 4+ messages in thread
From: Jens Axboe @ 2018-07-24 20:41 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-block
On 7/24/18 5:04 AM, Christoph Hellwig wrote:
> To remove invariants that are odd and in the way of multipage biovecs.
Applied for 4.19, thanks.
--
Jens Axboe
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-07-24 20:41 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-24 12:04 two small bio cleanups Christoph Hellwig
2018-07-24 12:04 ` [PATCH 1/2] block: simplify bio_check_pages_dirty Christoph Hellwig
2018-07-24 12:04 ` [PATCH 2/2] block: bio_set_pages_dirty can't see NULL bv_page in a valid bio_vec Christoph Hellwig
2018-07-24 20:41 ` two small bio cleanups Jens Axboe
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.