* add a bvec_phys helper v2
@ 2024-07-05 12:32 Christoph Hellwig
2024-07-05 12:32 ` [PATCH 1/2] block: add a bvec_phys helper Christoph Hellwig
2024-07-05 12:32 ` [PATCH 2/2] block: pass a phys_addr_t to get_max_segment_size Christoph Hellwig
0 siblings, 2 replies; 8+ messages in thread
From: Christoph Hellwig @ 2024-07-05 12:32 UTC (permalink / raw)
To: Jens Axboe; +Cc: Geert Uytterhoeven, linux-m68k, linux-block
Hi Jens,
this series adds a bvec_phys helper to get the physical address
of a bio_vec so that callers don't have to poke into bvec internals.
There aren't a whole lot of user of it yet, but with the new proposed
DMA mapping API we might grow a lot more soon.
Changes since v1:
- reorder the two patches as suggested by Geert
- fix a comment typo
- use PFN_PHYS instead of open coding it
- also pass a len argument to get_max_segment_size instead of open
coding a min in both callers
Diffstat:
arch/m68k/emu/nfblock.c | 2 +-
block/bio.c | 2 +-
block/blk-merge.c | 27 ++++++++++++---------------
block/blk.h | 4 ++--
include/linux/bvec.h | 14 ++++++++++++++
5 files changed, 30 insertions(+), 19 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] block: add a bvec_phys helper
2024-07-05 12:32 add a bvec_phys helper v2 Christoph Hellwig
@ 2024-07-05 12:32 ` Christoph Hellwig
2024-07-05 12:32 ` [PATCH 2/2] block: pass a phys_addr_t to get_max_segment_size Christoph Hellwig
1 sibling, 0 replies; 8+ messages in thread
From: Christoph Hellwig @ 2024-07-05 12:32 UTC (permalink / raw)
To: Jens Axboe; +Cc: Geert Uytterhoeven, linux-m68k, linux-block
Get callers out of poking into bvec internals a bit more. Not a huge win
right now, but with the proposed new DMA mapping API we might end up with
a lot more of this otherwise.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/m68k/emu/nfblock.c | 2 +-
block/bio.c | 2 +-
block/blk.h | 4 ++--
include/linux/bvec.h | 14 ++++++++++++++
4 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index 8eea7ef9115146..874fe958877388 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -71,7 +71,7 @@ static void nfhd_submit_bio(struct bio *bio)
len = bvec.bv_len;
len >>= 9;
nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift,
- page_to_phys(bvec.bv_page) + bvec.bv_offset);
+ bvec_phys(&bvec));
sec += len;
}
bio_endio(bio);
diff --git a/block/bio.c b/block/bio.c
index e9e809a63c5975..a3b1b2266c50be 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -953,7 +953,7 @@ bool bvec_try_merge_hw_page(struct request_queue *q, struct bio_vec *bv,
bool *same_page)
{
unsigned long mask = queue_segment_boundary(q);
- phys_addr_t addr1 = page_to_phys(bv->bv_page) + bv->bv_offset;
+ phys_addr_t addr1 = bvec_phys(bv);
phys_addr_t addr2 = page_to_phys(page) + offset + len - 1;
if ((addr1 | mask) != (addr2 | mask))
diff --git a/block/blk.h b/block/blk.h
index 47dadd2439b1ca..8e8936e97307c6 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -98,8 +98,8 @@ static inline bool biovec_phys_mergeable(struct request_queue *q,
struct bio_vec *vec1, struct bio_vec *vec2)
{
unsigned long mask = queue_segment_boundary(q);
- phys_addr_t addr1 = page_to_phys(vec1->bv_page) + vec1->bv_offset;
- phys_addr_t addr2 = page_to_phys(vec2->bv_page) + vec2->bv_offset;
+ phys_addr_t addr1 = bvec_phys(vec1);
+ phys_addr_t addr2 = bvec_phys(vec2);
/*
* Merging adjacent physical pages may not work correctly under KMSAN
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index bd1e361b351c5a..f41c7f0ef91ed5 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -280,4 +280,18 @@ static inline void *bvec_virt(struct bio_vec *bvec)
return page_address(bvec->bv_page) + bvec->bv_offset;
}
+/**
+ * bvec_phys - return the physical address for a bvec
+ * @bvec: bvec to return the physical address for
+ */
+static inline phys_addr_t bvec_phys(const struct bio_vec *bvec)
+{
+ /*
+ * Note this open codes page_to_phys because page_to_phys is defined in
+ * <asm/io.h>, which we don't want to pull in here. If it ever moves to
+ * a sensible place we should start using it.
+ */
+ return PFN_PHYS(page_to_pfn(bvec->bv_page)) + bvec->bv_offset;
+}
+
#endif /* __LINUX_BVEC_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 2/2] block: pass a phys_addr_t to get_max_segment_size
2024-07-05 12:32 add a bvec_phys helper v2 Christoph Hellwig
2024-07-05 12:32 ` [PATCH 1/2] block: add a bvec_phys helper Christoph Hellwig
@ 2024-07-05 12:32 ` Christoph Hellwig
2024-07-06 6:21 ` Jens Axboe
1 sibling, 1 reply; 8+ messages in thread
From: Christoph Hellwig @ 2024-07-05 12:32 UTC (permalink / raw)
To: Jens Axboe; +Cc: Geert Uytterhoeven, linux-m68k, linux-block
Work on a single address to simplify the logic, and prepare the callers
from using better helpers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/blk-merge.c | 27 ++++++++++++---------------
1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/block/blk-merge.c b/block/blk-merge.c
index cff20bcc0252a7..b1e1b7a6933511 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -207,25 +207,24 @@ static inline unsigned get_max_io_size(struct bio *bio,
}
/**
- * get_max_segment_size() - maximum number of bytes to add as a single segment
+ * get_max_segment_size() - maximum number of bytes to add to a single segment
* @lim: Request queue limits.
- * @start_page: See below.
- * @offset: Offset from @start_page where to add a segment.
+ * @paddr: address of the range to add
+ * @max_len: maximum length available to add at @paddr
*
- * Returns the maximum number of bytes that can be added as a single segment.
+ * Returns the maximum number of bytes of the range starting at @paddr that can
+ * be added to a single segment.
*/
static inline unsigned get_max_segment_size(const struct queue_limits *lim,
- struct page *start_page, unsigned long offset)
+ phys_addr_t paddr, unsigned int len)
{
- unsigned long mask = lim->seg_boundary_mask;
-
- offset = mask & (page_to_phys(start_page) + offset);
-
/*
* Prevent an overflow if mask = ULONG_MAX and offset = 0 by adding 1
* after having calculated the minimum.
*/
- return min(mask - offset, (unsigned long)lim->max_segment_size - 1) + 1;
+ return min_t(unsigned long, len,
+ min(lim->seg_boundary_mask - (lim->seg_boundary_mask & paddr),
+ (unsigned long)lim->max_segment_size - 1) + 1);
}
/**
@@ -258,9 +257,7 @@ static bool bvec_split_segs(const struct queue_limits *lim,
unsigned seg_size = 0;
while (len && *nsegs < max_segs) {
- seg_size = get_max_segment_size(lim, bv->bv_page,
- bv->bv_offset + total_len);
- seg_size = min(seg_size, len);
+ seg_size = get_max_segment_size(lim, bvec_phys(bv) + total_len, len);
(*nsegs)++;
total_len += seg_size;
@@ -494,8 +491,8 @@ static unsigned blk_bvec_map_sg(struct request_queue *q,
while (nbytes > 0) {
unsigned offset = bvec->bv_offset + total;
- unsigned len = min(get_max_segment_size(&q->limits,
- bvec->bv_page, offset), nbytes);
+ unsigned len = get_max_segment_size(&q->limits, bvec_phys(bvec),
+ nbytes);
struct page *page = bvec->bv_page;
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 2/2] block: pass a phys_addr_t to get_max_segment_size
2024-07-05 12:32 ` [PATCH 2/2] block: pass a phys_addr_t to get_max_segment_size Christoph Hellwig
@ 2024-07-06 6:21 ` Jens Axboe
2024-07-06 6:22 ` Christoph Hellwig
0 siblings, 1 reply; 8+ messages in thread
From: Jens Axboe @ 2024-07-06 6:21 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Geert Uytterhoeven, linux-m68k, linux-block
On 7/5/24 6:32 AM, Christoph Hellwig wrote:
> Work on a single address to simplify the logic, and prepare the callers
> from using better helpers.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> block/blk-merge.c | 27 ++++++++++++---------------
> 1 file changed, 12 insertions(+), 15 deletions(-)
>
> diff --git a/block/blk-merge.c b/block/blk-merge.c
> index cff20bcc0252a7..b1e1b7a6933511 100644
> --- a/block/blk-merge.c
> +++ b/block/blk-merge.c
> @@ -207,25 +207,24 @@ static inline unsigned get_max_io_size(struct bio *bio,
> }
>
> /**
> - * get_max_segment_size() - maximum number of bytes to add as a single segment
> + * get_max_segment_size() - maximum number of bytes to add to a single segment
v1 had this change too, not sure why? The previous description seems
better than the changed one.
--
Jens Axboe
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] block: pass a phys_addr_t to get_max_segment_size
2024-07-06 6:21 ` Jens Axboe
@ 2024-07-06 6:22 ` Christoph Hellwig
2024-07-06 6:24 ` Jens Axboe
0 siblings, 1 reply; 8+ messages in thread
From: Christoph Hellwig @ 2024-07-06 6:22 UTC (permalink / raw)
To: Jens Axboe; +Cc: Christoph Hellwig, Geert Uytterhoeven, linux-m68k, linux-block
On Sat, Jul 06, 2024 at 12:21:06AM -0600, Jens Axboe wrote:
> > /**
> > - * get_max_segment_size() - maximum number of bytes to add as a single segment
> > + * get_max_segment_size() - maximum number of bytes to add to a single segment
>
> v1 had this change too, not sure why? The previous description seems
> better than the changed one.
Because it is used to also append data from another bio_vec to a
pre-existing SG segment, not just to create new ones.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] block: pass a phys_addr_t to get_max_segment_size
2024-07-06 6:22 ` Christoph Hellwig
@ 2024-07-06 6:24 ` Jens Axboe
0 siblings, 0 replies; 8+ messages in thread
From: Jens Axboe @ 2024-07-06 6:24 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Geert Uytterhoeven, linux-m68k, linux-block
On 7/6/24 12:22 AM, Christoph Hellwig wrote:
> On Sat, Jul 06, 2024 at 12:21:06AM -0600, Jens Axboe wrote:
>>> /**
>>> - * get_max_segment_size() - maximum number of bytes to add as a single segment
>>> + * get_max_segment_size() - maximum number of bytes to add to a single segment
>>
>> v1 had this change too, not sure why? The previous description seems
>> better than the changed one.
>
> Because it is used to also append data from another bio_vec to a
> pre-existing SG segment, not just to create new ones.
Sure, but then let's make it something that makes more sense at least.
Maximum size to consider as a single segment, or something like that.
--
Jens Axboe
^ permalink raw reply [flat|nested] 8+ messages in thread
* add a bvec_phys helper v3
@ 2024-07-06 7:52 Christoph Hellwig
2024-07-06 7:52 ` [PATCH 1/2] block: add a bvec_phys helper Christoph Hellwig
0 siblings, 1 reply; 8+ messages in thread
From: Christoph Hellwig @ 2024-07-06 7:52 UTC (permalink / raw)
To: Jens Axboe; +Cc: Geert Uytterhoeven, linux-m68k, linux-block
Hi Jens,
this series adds a bvec_phys helper to get the physical address
of a bio_vec so that callers don't have to poke into bvec internals.
There aren't a whole lot of user of it yet, but with the new proposed
DMA mapping API we might grow a lot more soon.
Changes since v2:
- keep the existing (somewhat weird) description of get_max_segment_size
Changes since v1:
- reorder the two patches as suggested by Geert
- fix a comment typo
- use PFN_PHYS instead of open coding it
- also pass a len argument to get_max_segment_size instead of open
coding a min in both callers
Diffstat:
arch/m68k/emu/nfblock.c | 2 +-
block/bio.c | 2 +-
block/blk-merge.c | 25 +++++++++++--------------
block/blk.h | 4 ++--
include/linux/bvec.h | 14 ++++++++++++++
5 files changed, 29 insertions(+), 18 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] block: add a bvec_phys helper
2024-07-06 7:52 add a bvec_phys helper v3 Christoph Hellwig
@ 2024-07-06 7:52 ` Christoph Hellwig
2024-07-06 9:57 ` Chaitanya Kulkarni
0 siblings, 1 reply; 8+ messages in thread
From: Christoph Hellwig @ 2024-07-06 7:52 UTC (permalink / raw)
To: Jens Axboe; +Cc: Geert Uytterhoeven, linux-m68k, linux-block
Get callers out of poking into bvec internals a bit more. Not a huge win
right now, but with the proposed new DMA mapping API we might end up with
a lot more of this otherwise.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/m68k/emu/nfblock.c | 2 +-
block/bio.c | 2 +-
block/blk.h | 4 ++--
include/linux/bvec.h | 14 ++++++++++++++
4 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index 8eea7ef9115146..874fe958877388 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -71,7 +71,7 @@ static void nfhd_submit_bio(struct bio *bio)
len = bvec.bv_len;
len >>= 9;
nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift,
- page_to_phys(bvec.bv_page) + bvec.bv_offset);
+ bvec_phys(&bvec));
sec += len;
}
bio_endio(bio);
diff --git a/block/bio.c b/block/bio.c
index e9e809a63c5975..a3b1b2266c50be 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -953,7 +953,7 @@ bool bvec_try_merge_hw_page(struct request_queue *q, struct bio_vec *bv,
bool *same_page)
{
unsigned long mask = queue_segment_boundary(q);
- phys_addr_t addr1 = page_to_phys(bv->bv_page) + bv->bv_offset;
+ phys_addr_t addr1 = bvec_phys(bv);
phys_addr_t addr2 = page_to_phys(page) + offset + len - 1;
if ((addr1 | mask) != (addr2 | mask))
diff --git a/block/blk.h b/block/blk.h
index 8c27d524303aa7..d099ef1df5f64a 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -109,8 +109,8 @@ static inline bool biovec_phys_mergeable(struct request_queue *q,
struct bio_vec *vec1, struct bio_vec *vec2)
{
unsigned long mask = queue_segment_boundary(q);
- phys_addr_t addr1 = page_to_phys(vec1->bv_page) + vec1->bv_offset;
- phys_addr_t addr2 = page_to_phys(vec2->bv_page) + vec2->bv_offset;
+ phys_addr_t addr1 = bvec_phys(vec1);
+ phys_addr_t addr2 = bvec_phys(vec2);
/*
* Merging adjacent physical pages may not work correctly under KMSAN
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index bd1e361b351c5a..f41c7f0ef91ed5 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -280,4 +280,18 @@ static inline void *bvec_virt(struct bio_vec *bvec)
return page_address(bvec->bv_page) + bvec->bv_offset;
}
+/**
+ * bvec_phys - return the physical address for a bvec
+ * @bvec: bvec to return the physical address for
+ */
+static inline phys_addr_t bvec_phys(const struct bio_vec *bvec)
+{
+ /*
+ * Note this open codes page_to_phys because page_to_phys is defined in
+ * <asm/io.h>, which we don't want to pull in here. If it ever moves to
+ * a sensible place we should start using it.
+ */
+ return PFN_PHYS(page_to_pfn(bvec->bv_page)) + bvec->bv_offset;
+}
+
#endif /* __LINUX_BVEC_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 1/2] block: add a bvec_phys helper
2024-07-06 7:52 ` [PATCH 1/2] block: add a bvec_phys helper Christoph Hellwig
@ 2024-07-06 9:57 ` Chaitanya Kulkarni
0 siblings, 0 replies; 8+ messages in thread
From: Chaitanya Kulkarni @ 2024-07-06 9:57 UTC (permalink / raw)
To: Christoph Hellwig, Jens Axboe
Cc: Geert Uytterhoeven, linux-m68k@lists.linux-m68k.org,
linux-block@vger.kernel.org
On 7/6/2024 12:52 AM, Christoph Hellwig wrote:
> Get callers out of poking into bvec internals a bit more. Not a huge win
> right now, but with the proposed new DMA mapping API we might end up with
> a lot more of this otherwise.
>
> Signed-off-by: Christoph Hellwig<hch@lst.de>
thanks for the adding open code comment, looks good.
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
-ck
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-07-06 9:57 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-05 12:32 add a bvec_phys helper v2 Christoph Hellwig
2024-07-05 12:32 ` [PATCH 1/2] block: add a bvec_phys helper Christoph Hellwig
2024-07-05 12:32 ` [PATCH 2/2] block: pass a phys_addr_t to get_max_segment_size Christoph Hellwig
2024-07-06 6:21 ` Jens Axboe
2024-07-06 6:22 ` Christoph Hellwig
2024-07-06 6:24 ` Jens Axboe
-- strict thread matches above, loose matches on Subject: below --
2024-07-06 7:52 add a bvec_phys helper v3 Christoph Hellwig
2024-07-06 7:52 ` [PATCH 1/2] block: add a bvec_phys helper Christoph Hellwig
2024-07-06 9:57 ` Chaitanya Kulkarni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox