From: Chuck Lever <cel@kernel.org> To: unlisted-recipients:; (no To-header on input) Cc: Jens Axboe <axboe@kernel.dk>, Christoph Hellwig <hch@lst.de>, David Howells <dhowells@redhat.com>, iommu@lists.linux.dev, linux-rdma@vger.kernel.org, Chuck Lever <chuck.lever@oracle.com> Subject: [PATCH RFC 2/9] bvec: Add bio_vec fields to manage DMA mapping Date: Thu, 19 Oct 2023 11:25:45 -0400 [thread overview] Message-ID: <169772914548.5232.12015170784207638561.stgit@klimt.1015granger.net> (raw) In-Reply-To: <169772852492.5232.17148564580779995849.stgit@klimt.1015granger.net> From: Chuck Lever <chuck.lever@oracle.com> These are roughly equivalent to the fields used for managing scatterlist DMA mapping. Cc: Jens Axboe <axboe@kernel.dk> Cc: Christoph Hellwig <hch@lst.de> Cc: David Howells <dhowells@redhat.com> Cc: iommu@lists.linux.dev Cc: linux-rdma@vger.kernel.org Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- include/linux/bvec.h | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/include/linux/bvec.h b/include/linux/bvec.h index 555aae5448ae..1074f34a4e8f 100644 --- a/include/linux/bvec.h +++ b/include/linux/bvec.h @@ -13,6 +13,7 @@ #include <linux/limits.h> #include <linux/minmax.h> #include <linux/types.h> +#include <asm/io.h> struct page; @@ -32,6 +33,13 @@ struct bio_vec { struct page *bv_page; unsigned int bv_len; unsigned int bv_offset; + dma_addr_t bv_dma_address; +#ifdef CONFIG_NEED_SG_DMA_LENGTH + unsigned int bv_dma_length; +#endif +#ifdef CONFIG_NEED_SG_DMA_FLAGS + unsigned int bv_dma_flags; +#endif }; /** @@ -74,6 +82,24 @@ static inline void bvec_set_virt(struct bio_vec *bv, void *vaddr, bvec_set_page(bv, virt_to_page(vaddr), len, offset_in_page(vaddr)); } +/** + * bv_phys - return physical address of a bio_vec + * @bv: bio_vec + */ +static inline dma_addr_t bv_phys(struct bio_vec *bv) +{ + return page_to_phys(bv->bv_page) + bv->bv_offset; +} + +/** + * bv_virt - return virtual address of a bio_vec + * @bv: bio_vec + */ +static inline void *bv_virt(struct bio_vec *bv) +{ + return page_address(bv->bv_page) + bv->bv_offset; +} + struct bvec_iter { sector_t bi_sector; /* device address in 512 byte sectors */ @@ -280,4 +306,121 @@ static inline void *bvec_virt(struct bio_vec *bvec) return page_address(bvec->bv_page) + bvec->bv_offset; } +/* + * These macros should be used after a dma_map_bvecs call has been done + * to get bus addresses of each of the bio_vec array entries and their + * lengths. You should work only with the number of bio_vec array entries + * dma_map_bvecs returns, or alternatively stop on the first bv_dma_len(bv) + * which is 0. + */ +#define bv_dma_address(bv) ((bv)->bv_dma_address) + +#ifdef CONFIG_NEED_SG_DMA_LENGTH +#define bv_dma_len(bv) ((bv)->bv_dma_length) +#else +#define bv_dma_len(bv) ((bv)->bv_len) +#endif + +/* + * On 64-bit architectures there is a 4-byte padding in struct scatterlist + * (assuming also CONFIG_NEED_SG_DMA_LENGTH is set). Use this padding for DMA + * flags bits to indicate when a specific dma address is a bus address or the + * buffer may have been bounced via SWIOTLB. + */ +#ifdef CONFIG_NEED_SG_DMA_FLAGS + +#define BV_DMA_BUS_ADDRESS BIT(0) +#define BV_DMA_SWIOTLB BIT(1) + +/** + * bv_dma_is_bus_address - Return whether a given segment was marked + * as a bus address + * @bv: bio_vec array entry + * + * Description: + * Returns true if bv_dma_mark_bus_address() has been called on + * this bio_vec. + **/ +static inline bool bv_dma_is_bus_address(struct bio_vec *bv) +{ + return bv->bv_dma_flags & BV_DMA_BUS_ADDRESS; +} + +/** + * bv_dma_mark_bus_address - Mark the bio_vec entry as a bus address + * @bv: bio_vec array entry + * + * Description: + * Marks the passed-in bv entry to indicate that the dma_address is + * a bus address and doesn't need to be unmapped. This should only be + * used by dma_map_bvecs() implementations to mark bus addresses + * so they can be properly cleaned up in dma_unmap_bvecs(). + **/ +static inline void bv_dma_mark_bus_address(struct bio_vec *bv) +{ + bv->bv_dma_flags |= BV_DMA_BUS_ADDRESS; +} + +/** + * bv_unmark_bus_address - Unmark the bio_vec entry as a bus address + * @bv: bio_vec array entry + * + * Description: + * Clears the bus address mark. + **/ +static inline void bv_dma_unmark_bus_address(struct bio_vec *bv) +{ + bv->bv_dma_flags &= ~BV_DMA_BUS_ADDRESS; +} + +/** + * bv_dma_is_swiotlb - Return whether the bio_vec was marked for SWIOTLB + * bouncing + * @bv: bio_vec array entry + * + * Description: + * Returns true if the bio_vec was marked for SWIOTLB bouncing. Not all + * elements may have been bounced, so the caller would have to check + * individual BV entries with is_swiotlb_buffer(). + */ +static inline bool bv_dma_is_swiotlb(struct bio_vec *bv) +{ + return bv->bv_dma_flags & BV_DMA_SWIOTLB; +} + +/** + * bv_dma_mark_swiotlb - Mark the bio_vec for SWIOTLB bouncing + * @bv: bio_vec array entry + * + * Description: + * Marks a a bio_vec for SWIOTLB bounce. Not all bio_vec entries may + * be bounced. + */ +static inline void bv_dma_mark_swiotlb(struct bio_vec *bv) +{ + bv->bv_dma_flags |= BV_DMA_SWIOTLB; +} + +#else + +static inline bool bv_dma_is_bus_address(struct bio_vec *bv) +{ + return false; +} +static inline void bv_dma_mark_bus_address(struct bio_vec *bv) +{ +} +static inline void bv_dma_unmark_bus_address(struct bio_vec *bv) +{ +} +static inline bool bv_dma_is_swiotlb(struct bio_vec *bv) +{ + return false; +} +static inline void bv_dma_mark_swiotlb(struct bio_vec *bv) +{ +} + +#endif /* CONFIG_NEED_SG_DMA_FLAGS */ + #endif /* __LINUX_BVEC_H */
WARNING: multiple messages have this Message-ID (diff)
From: Chuck Lever <cel@kernel.org> Cc: Jens Axboe <axboe@kernel.dk>, Christoph Hellwig <hch@lst.de>, David Howells <dhowells@redhat.com>, iommu@lists.linux.dev, linux-rdma@vger.kernel.org, Chuck Lever <chuck.lever@oracle.com> Subject: [PATCH RFC 2/9] bvec: Add bio_vec fields to manage DMA mapping Date: Thu, 19 Oct 2023 11:25:45 -0400 [thread overview] Message-ID: <169772914548.5232.12015170784207638561.stgit@klimt.1015granger.net> (raw) In-Reply-To: <169772852492.5232.17148564580779995849.stgit@klimt.1015granger.net> From: Chuck Lever <chuck.lever@oracle.com> These are roughly equivalent to the fields used for managing scatterlist DMA mapping. Cc: Jens Axboe <axboe@kernel.dk> Cc: Christoph Hellwig <hch@lst.de> Cc: David Howells <dhowells@redhat.com> Cc: iommu@lists.linux.dev Cc: linux-rdma@vger.kernel.org Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- include/linux/bvec.h | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/include/linux/bvec.h b/include/linux/bvec.h index 555aae5448ae..1074f34a4e8f 100644 --- a/include/linux/bvec.h +++ b/include/linux/bvec.h @@ -13,6 +13,7 @@ #include <linux/limits.h> #include <linux/minmax.h> #include <linux/types.h> +#include <asm/io.h> struct page; @@ -32,6 +33,13 @@ struct bio_vec { struct page *bv_page; unsigned int bv_len; unsigned int bv_offset; + dma_addr_t bv_dma_address; +#ifdef CONFIG_NEED_SG_DMA_LENGTH + unsigned int bv_dma_length; +#endif +#ifdef CONFIG_NEED_SG_DMA_FLAGS + unsigned int bv_dma_flags; +#endif }; /** @@ -74,6 +82,24 @@ static inline void bvec_set_virt(struct bio_vec *bv, void *vaddr, bvec_set_page(bv, virt_to_page(vaddr), len, offset_in_page(vaddr)); } +/** + * bv_phys - return physical address of a bio_vec + * @bv: bio_vec + */ +static inline dma_addr_t bv_phys(struct bio_vec *bv) +{ + return page_to_phys(bv->bv_page) + bv->bv_offset; +} + +/** + * bv_virt - return virtual address of a bio_vec + * @bv: bio_vec + */ +static inline void *bv_virt(struct bio_vec *bv) +{ + return page_address(bv->bv_page) + bv->bv_offset; +} + struct bvec_iter { sector_t bi_sector; /* device address in 512 byte sectors */ @@ -280,4 +306,121 @@ static inline void *bvec_virt(struct bio_vec *bvec) return page_address(bvec->bv_page) + bvec->bv_offset; } +/* + * These macros should be used after a dma_map_bvecs call has been done + * to get bus addresses of each of the bio_vec array entries and their + * lengths. You should work only with the number of bio_vec array entries + * dma_map_bvecs returns, or alternatively stop on the first bv_dma_len(bv) + * which is 0. + */ +#define bv_dma_address(bv) ((bv)->bv_dma_address) + +#ifdef CONFIG_NEED_SG_DMA_LENGTH +#define bv_dma_len(bv) ((bv)->bv_dma_length) +#else +#define bv_dma_len(bv) ((bv)->bv_len) +#endif + +/* + * On 64-bit architectures there is a 4-byte padding in struct scatterlist + * (assuming also CONFIG_NEED_SG_DMA_LENGTH is set). Use this padding for DMA + * flags bits to indicate when a specific dma address is a bus address or the + * buffer may have been bounced via SWIOTLB. + */ +#ifdef CONFIG_NEED_SG_DMA_FLAGS + +#define BV_DMA_BUS_ADDRESS BIT(0) +#define BV_DMA_SWIOTLB BIT(1) + +/** + * bv_dma_is_bus_address - Return whether a given segment was marked + * as a bus address + * @bv: bio_vec array entry + * + * Description: + * Returns true if bv_dma_mark_bus_address() has been called on + * this bio_vec. + **/ +static inline bool bv_dma_is_bus_address(struct bio_vec *bv) +{ + return bv->bv_dma_flags & BV_DMA_BUS_ADDRESS; +} + +/** + * bv_dma_mark_bus_address - Mark the bio_vec entry as a bus address + * @bv: bio_vec array entry + * + * Description: + * Marks the passed-in bv entry to indicate that the dma_address is + * a bus address and doesn't need to be unmapped. This should only be + * used by dma_map_bvecs() implementations to mark bus addresses + * so they can be properly cleaned up in dma_unmap_bvecs(). + **/ +static inline void bv_dma_mark_bus_address(struct bio_vec *bv) +{ + bv->bv_dma_flags |= BV_DMA_BUS_ADDRESS; +} + +/** + * bv_unmark_bus_address - Unmark the bio_vec entry as a bus address + * @bv: bio_vec array entry + * + * Description: + * Clears the bus address mark. + **/ +static inline void bv_dma_unmark_bus_address(struct bio_vec *bv) +{ + bv->bv_dma_flags &= ~BV_DMA_BUS_ADDRESS; +} + +/** + * bv_dma_is_swiotlb - Return whether the bio_vec was marked for SWIOTLB + * bouncing + * @bv: bio_vec array entry + * + * Description: + * Returns true if the bio_vec was marked for SWIOTLB bouncing. Not all + * elements may have been bounced, so the caller would have to check + * individual BV entries with is_swiotlb_buffer(). + */ +static inline bool bv_dma_is_swiotlb(struct bio_vec *bv) +{ + return bv->bv_dma_flags & BV_DMA_SWIOTLB; +} + +/** + * bv_dma_mark_swiotlb - Mark the bio_vec for SWIOTLB bouncing + * @bv: bio_vec array entry + * + * Description: + * Marks a a bio_vec for SWIOTLB bounce. Not all bio_vec entries may + * be bounced. + */ +static inline void bv_dma_mark_swiotlb(struct bio_vec *bv) +{ + bv->bv_dma_flags |= BV_DMA_SWIOTLB; +} + +#else + +static inline bool bv_dma_is_bus_address(struct bio_vec *bv) +{ + return false; +} +static inline void bv_dma_mark_bus_address(struct bio_vec *bv) +{ +} +static inline void bv_dma_unmark_bus_address(struct bio_vec *bv) +{ +} +static inline bool bv_dma_is_swiotlb(struct bio_vec *bv) +{ + return false; +} +static inline void bv_dma_mark_swiotlb(struct bio_vec *bv) +{ +} + +#endif /* CONFIG_NEED_SG_DMA_FLAGS */ + #endif /* __LINUX_BVEC_H */
next prev parent reply other threads:[~2023-10-19 15:25 UTC|newest] Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-10-19 15:25 [PATCH RFC 0/9] Exploring biovec support in (R)DMA API Chuck Lever 2023-10-19 15:25 ` Chuck Lever 2023-10-19 15:25 ` [PATCH RFC 1/9] dma-debug: Fix a typo in a debugging eye-catcher Chuck Lever 2023-10-20 4:49 ` Christoph Hellwig 2023-10-20 13:38 ` Chuck Lever III 2023-10-23 5:56 ` Christoph Hellwig 2023-10-19 15:25 ` Chuck Lever [this message] 2023-10-19 15:25 ` [PATCH RFC 2/9] bvec: Add bio_vec fields to manage DMA mapping Chuck Lever 2023-10-19 15:25 ` [PATCH RFC 3/9] dma-debug: Add dma_debug_ helpers for mapping bio_vec arrays Chuck Lever 2023-10-19 15:25 ` Chuck Lever 2023-10-19 21:38 ` kernel test robot 2023-10-19 23:21 ` Chuck Lever III 2023-10-23 2:43 ` Liu, Yujie 2023-10-23 14:27 ` Chuck Lever III 2023-10-19 21:49 ` kernel test robot 2023-10-19 15:25 ` [PATCH RFC 4/9] mm: kmsan: Add support for DMA " Chuck Lever 2023-10-19 15:25 ` Chuck Lever 2023-10-19 15:26 ` [PATCH RFC 5/9] dma-direct: Support direct " Chuck Lever 2023-10-19 15:26 ` Chuck Lever 2023-10-19 15:26 ` [PATCH RFC 6/9] DMA-API: Add dma_sync_bvecs_for_cpu() and dma_sync_bvecs_for_device() Chuck Lever 2023-10-19 15:26 ` Chuck Lever 2023-10-19 15:26 ` [PATCH RFC 7/9] DMA: Add dma_map_bvecs_attrs() Chuck Lever 2023-10-19 15:26 ` Chuck Lever 2023-10-19 22:10 ` kernel test robot 2023-10-19 15:26 ` [PATCH RFC 8/9] iommu/dma: Support DMA-mapping a bio_vec array Chuck Lever 2023-10-19 15:26 ` Chuck Lever 2023-10-19 15:26 ` [PATCH RFC 9/9] RDMA: Add helpers for DMA-mapping an array of bio_vecs Chuck Lever 2023-10-19 15:26 ` Chuck Lever 2023-10-19 15:53 ` [PATCH RFC 0/9] Exploring biovec support in (R)DMA API Matthew Wilcox 2023-10-19 17:48 ` Chuck Lever 2023-10-20 4:58 ` Christoph Hellwig 2023-10-20 10:30 ` Robin Murphy 2023-10-23 5:59 ` Christoph Hellwig 2023-10-19 16:43 ` Robin Murphy 2023-10-19 17:53 ` Jason Gunthorpe
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=169772914548.5232.12015170784207638561.stgit@klimt.1015granger.net \ --to=cel@kernel.org \ --cc=axboe@kernel.dk \ --cc=chuck.lever@oracle.com \ --cc=dhowells@redhat.com \ --cc=hch@lst.de \ --cc=iommu@lists.linux.dev \ --cc=linux-rdma@vger.kernel.org \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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.