From owner-svn-src-all@freebsd.org Thu May 16 17:41:20 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E298A15A1822; Thu, 16 May 2019 17:41:19 +0000 (UTC) (envelope-from tychon@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 8F2D86A647; Thu, 16 May 2019 17:41:19 +0000 (UTC) (envelope-from tychon@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7AD2F241B0; Thu, 16 May 2019 17:41:19 +0000 (UTC) (envelope-from tychon@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x4GHfJNm015187; Thu, 16 May 2019 17:41:19 GMT (envelope-from tychon@FreeBSD.org) Received: (from tychon@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4GHfHQp013193; Thu, 16 May 2019 17:41:17 GMT (envelope-from tychon@FreeBSD.org) Message-Id: <201905161741.x4GHfHQp013193@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tychon set sender to tychon@FreeBSD.org using -f From: Tycho Nightingale Date: Thu, 16 May 2019 17:41:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r347836 - in head: sys/arm64/arm64 sys/arm64/include sys/compat/linuxkpi/common/src sys/sys sys/x86/include sys/x86/iommu sys/x86/x86 usr.sbin/camdd X-SVN-Group: head X-SVN-Commit-Author: tychon X-SVN-Commit-Paths: in head: sys/arm64/arm64 sys/arm64/include sys/compat/linuxkpi/common/src sys/sys sys/x86/include sys/x86/iommu sys/x86/x86 usr.sbin/camdd X-SVN-Commit-Revision: 347836 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 8F2D86A647 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.99 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.99)[-0.987,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 May 2019 17:41:20 -0000 Author: tychon Date: Thu May 16 17:41:16 2019 New Revision: 347836 URL: https://svnweb.freebsd.org/changeset/base/347836 Log: Allow loading the same DMA address multiple times without any prior unload for the LinuxKPI. Reviewed by: kib, zeising Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D20181 Modified: head/sys/arm64/arm64/busdma_bounce.c head/sys/arm64/include/bus_dma.h head/sys/arm64/include/bus_dma_impl.h head/sys/compat/linuxkpi/common/src/linux_pci.c head/sys/sys/bus_dma.h head/sys/x86/include/bus_dma.h head/sys/x86/include/busdma_impl.h head/sys/x86/iommu/busdma_dmar.c head/sys/x86/x86/busdma_bounce.c head/usr.sbin/camdd/camdd.c Modified: head/sys/arm64/arm64/busdma_bounce.c ============================================================================== --- head/sys/arm64/arm64/busdma_bounce.c Thu May 16 17:38:59 2019 (r347835) +++ head/sys/arm64/arm64/busdma_bounce.c Thu May 16 17:41:16 2019 (r347836) @@ -152,6 +152,8 @@ static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, vm_offset_t vaddr, bus_addr_t addr, bus_size_t size); static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage); int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr); +static bool _bus_dmamap_pagesneeded(bus_dma_tag_t dmat, vm_paddr_t buf, + bus_size_t buflen, int *pagesneeded); static void _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap, void *buf, bus_size_t buflen, int flags); static void _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, @@ -271,6 +273,15 @@ out: return (error); } +static bool +bounce_bus_dma_id_mapped(bus_dma_tag_t dmat, vm_paddr_t buf, bus_size_t buflen) +{ + + if ((dmat->bounce_flags & BF_COULD_BOUNCE) == 0) + return (true); + return (!_bus_dmamap_pagesneeded(dmat, buf, buflen, NULL)); +} + static bus_dmamap_t alloc_dmamap(bus_dma_tag_t dmat, int flags) { @@ -539,29 +550,45 @@ bounce_bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr dmat->bounce_flags); } +static bool +_bus_dmamap_pagesneeded(bus_dma_tag_t dmat, vm_paddr_t buf, bus_size_t buflen, + int *pagesneeded) +{ + bus_addr_t curaddr; + bus_size_t sgsize; + int count; + + /* + * Count the number of bounce pages needed in order to + * complete this transfer + */ + count = 0; + curaddr = buf; + while (buflen != 0) { + sgsize = MIN(buflen, dmat->common.maxsegsz); + if (bus_dma_run_filter(&dmat->common, curaddr)) { + sgsize = MIN(sgsize, + PAGE_SIZE - (curaddr & PAGE_MASK)); + if (pagesneeded == NULL) + return (true); + count++; + } + curaddr += sgsize; + buflen -= sgsize; + } + + if (pagesneeded != NULL) + *pagesneeded = count; + return (count != 0); +} + static void _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf, bus_size_t buflen, int flags) { - bus_addr_t curaddr; - bus_size_t sgsize; if ((map->flags & DMAMAP_COULD_BOUNCE) != 0 && map->pagesneeded == 0) { - /* - * Count the number of bounce pages - * needed in order to complete this transfer - */ - curaddr = buf; - while (buflen != 0) { - sgsize = MIN(buflen, dmat->common.maxsegsz); - if (bus_dma_run_filter(&dmat->common, curaddr)) { - sgsize = MIN(sgsize, - PAGE_SIZE - (curaddr & PAGE_MASK)); - map->pagesneeded++; - } - curaddr += sgsize; - buflen -= sgsize; - } + _bus_dmamap_pagesneeded(dmat, buf, buflen, &map->pagesneeded); CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded); } } @@ -1316,6 +1343,7 @@ busdma_swi(void) struct bus_dma_impl bus_dma_bounce_impl = { .tag_create = bounce_bus_dma_tag_create, .tag_destroy = bounce_bus_dma_tag_destroy, + .id_mapped = bounce_bus_dma_id_mapped, .map_create = bounce_bus_dmamap_create, .map_destroy = bounce_bus_dmamap_destroy, .mem_alloc = bounce_bus_dmamem_alloc, Modified: head/sys/arm64/include/bus_dma.h ============================================================================== --- head/sys/arm64/include/bus_dma.h Thu May 16 17:38:59 2019 (r347835) +++ head/sys/arm64/include/bus_dma.h Thu May 16 17:41:16 2019 (r347836) @@ -9,6 +9,18 @@ #include /* + * Is DMA address 1:1 mapping of physical address + */ +static inline bool +bus_dma_id_mapped(bus_dma_tag_t dmat, vm_paddr_t buf, bus_size_t buflen) +{ + struct bus_dma_tag_common *tc; + + tc = (struct bus_dma_tag_common *)dmat; + return (tc->impl->id_mapped(dmat, buf, buflen)); +} + +/* * Allocate a handle for mapping from kva/uva/physical * address space into bus device space. */ Modified: head/sys/arm64/include/bus_dma_impl.h ============================================================================== --- head/sys/arm64/include/bus_dma_impl.h Thu May 16 17:38:59 2019 (r347835) +++ head/sys/arm64/include/bus_dma_impl.h Thu May 16 17:41:16 2019 (r347836) @@ -58,6 +58,7 @@ struct bus_dma_impl { bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, void *lockfuncarg, bus_dma_tag_t *dmat); int (*tag_destroy)(bus_dma_tag_t dmat); + bool (*id_mapped)(bus_dma_tag_t, vm_paddr_t, bus_size_t); int (*map_create)(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp); int (*map_destroy)(bus_dma_tag_t dmat, bus_dmamap_t map); int (*mem_alloc)(bus_dma_tag_t dmat, void** vaddr, int flags, Modified: head/sys/compat/linuxkpi/common/src/linux_pci.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_pci.c Thu May 16 17:38:59 2019 (r347835) +++ head/sys/compat/linuxkpi/common/src/linux_pci.c Thu May 16 17:41:16 2019 (r347836) @@ -520,6 +520,7 @@ linux_dma_alloc_coherent(struct device *dev, size_t si return (mem); } +#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__) dma_addr_t linux_dma_map_phys(struct device *dev, vm_paddr_t phys, size_t len) { @@ -530,6 +531,15 @@ linux_dma_map_phys(struct device *dev, vm_paddr_t phys priv = dev->dma_priv; + /* + * If the resultant mapping will be entirely 1:1 with the + * physical address, short-circuit the remainder of the + * bus_dma API. This avoids tracking collisions in the pctrie + * with the additional benefit of reducing overhead. + */ + if (bus_dma_id_mapped(priv->dmat, phys, len)) + return (phys); + obj = uma_zalloc(linux_dma_obj_zone, 0); DMA_PRIV_LOCK(priv); @@ -562,7 +572,15 @@ linux_dma_map_phys(struct device *dev, vm_paddr_t phys DMA_PRIV_UNLOCK(priv); return (obj->dma_addr); } +#else +dma_addr_t +linux_dma_map_phys(struct device *dev, vm_paddr_t phys, size_t len) +{ + return (phys); +} +#endif +#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__) void linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t len) { @@ -571,6 +589,9 @@ linux_dma_unmap(struct device *dev, dma_addr_t dma_add priv = dev->dma_priv; + if (pctrie_is_empty(&priv->ptree)) + return; + DMA_PRIV_LOCK(priv); obj = LINUX_DMA_PCTRIE_LOOKUP(&priv->ptree, dma_addr); if (obj == NULL) { @@ -584,6 +605,12 @@ linux_dma_unmap(struct device *dev, dma_addr_t dma_add uma_zfree(linux_dma_obj_zone, obj); } +#else +void +linux_dma_unmap(struct device *dev, dma_addr_t dma_addr, size_t len) +{ +} +#endif int linux_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, int nents, Modified: head/sys/sys/bus_dma.h ============================================================================== --- head/sys/sys/bus_dma.h Thu May 16 17:38:59 2019 (r347835) +++ head/sys/sys/bus_dma.h Thu May 16 17:41:16 2019 (r347836) @@ -67,7 +67,9 @@ #ifndef _BUS_DMA_H_ #define _BUS_DMA_H_ +#ifdef _KERNEL #include +#endif /* * Machine independent interface for mapping physical addresses to peripheral @@ -133,6 +135,7 @@ typedef struct bus_dma_segment { bus_size_t ds_len; /* length of transfer */ } bus_dma_segment_t; +#ifdef _KERNEL /* * A function that returns 1 if the address cannot be accessed by * a device and 0 if it can be. @@ -302,5 +305,6 @@ BUS_DMAMAP_OP void bus_dmamap_sync(bus_dma_tag_t dmat, BUS_DMAMAP_OP void bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t dmamap); #undef BUS_DMAMAP_OP +#endif /* _KERNEL */ #endif /* _BUS_DMA_H_ */ Modified: head/sys/x86/include/bus_dma.h ============================================================================== --- head/sys/x86/include/bus_dma.h Thu May 16 17:38:59 2019 (r347835) +++ head/sys/x86/include/bus_dma.h Thu May 16 17:41:16 2019 (r347836) @@ -36,6 +36,18 @@ #include /* + * Is DMA address 1:1 mapping of physical address + */ +static inline bool +bus_dma_id_mapped(bus_dma_tag_t dmat, vm_paddr_t buf, bus_size_t buflen) +{ + struct bus_dma_tag_common *tc; + + tc = (struct bus_dma_tag_common *)dmat; + return (tc->impl->id_mapped(dmat, buf, buflen)); +} + +/* * Allocate a handle for mapping from kva/uva/physical * address space into bus device space. */ Modified: head/sys/x86/include/busdma_impl.h ============================================================================== --- head/sys/x86/include/busdma_impl.h Thu May 16 17:38:59 2019 (r347835) +++ head/sys/x86/include/busdma_impl.h Thu May 16 17:41:16 2019 (r347836) @@ -62,6 +62,7 @@ struct bus_dma_impl { void *lockfuncarg, bus_dma_tag_t *dmat); int (*tag_destroy)(bus_dma_tag_t dmat); int (*tag_set_domain)(bus_dma_tag_t); + bool (*id_mapped)(bus_dma_tag_t, vm_paddr_t, bus_size_t); int (*map_create)(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp); int (*map_destroy)(bus_dma_tag_t dmat, bus_dmamap_t map); int (*mem_alloc)(bus_dma_tag_t dmat, void** vaddr, int flags, Modified: head/sys/x86/iommu/busdma_dmar.c ============================================================================== --- head/sys/x86/iommu/busdma_dmar.c Thu May 16 17:38:59 2019 (r347835) +++ head/sys/x86/iommu/busdma_dmar.c Thu May 16 17:41:16 2019 (r347836) @@ -365,6 +365,13 @@ out: return (error); } +static bool +dmar_bus_dma_id_mapped(bus_dma_tag_t dmat, vm_paddr_t buf, bus_size_t buflen) +{ + + return (false); +} + static int dmar_bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) { @@ -857,6 +864,7 @@ struct bus_dma_impl bus_dma_dmar_impl = { .tag_create = dmar_bus_dma_tag_create, .tag_destroy = dmar_bus_dma_tag_destroy, .tag_set_domain = dmar_bus_dma_tag_set_domain, + .id_mapped = dmar_bus_dma_id_mapped, .map_create = dmar_bus_dmamap_create, .map_destroy = dmar_bus_dmamap_destroy, .mem_alloc = dmar_bus_dmamem_alloc, Modified: head/sys/x86/x86/busdma_bounce.c ============================================================================== --- head/sys/x86/x86/busdma_bounce.c Thu May 16 17:38:59 2019 (r347835) +++ head/sys/x86/x86/busdma_bounce.c Thu May 16 17:41:16 2019 (r347836) @@ -141,6 +141,8 @@ static int reserve_bounce_pages(bus_dma_tag_t dmat, bu static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr, vm_paddr_t addr1, vm_paddr_t addr2, bus_size_t size); static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage); +static bool _bus_dmamap_pagesneeded(bus_dma_tag_t dmat, vm_paddr_t buf, + bus_size_t buflen, int *pagesneeded); static void _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap, void *buf, bus_size_t buflen, int flags); static void _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, @@ -223,6 +225,15 @@ bounce_bus_dma_tag_create(bus_dma_tag_t parent, bus_si return (error); } +static bool +bounce_bus_dma_id_mapped(bus_dma_tag_t dmat, vm_paddr_t buf, bus_size_t buflen) +{ + + if ((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) == 0) + return (true); + return (!_bus_dmamap_pagesneeded(dmat, buf, buflen, NULL)); +} + /* * Update the domain for the tag. We may need to reallocate the zone and * bounce pages. @@ -501,29 +512,45 @@ bounce_bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr dmat->bounce_flags); } +static bool +_bus_dmamap_pagesneeded(bus_dma_tag_t dmat, vm_paddr_t buf, bus_size_t buflen, + int *pagesneeded) +{ + vm_paddr_t curaddr; + bus_size_t sgsize; + int count; + + /* + * Count the number of bounce pages needed in order to + * complete this transfer + */ + count = 0; + curaddr = buf; + while (buflen != 0) { + sgsize = MIN(buflen, dmat->common.maxsegsz); + if (bus_dma_run_filter(&dmat->common, curaddr)) { + sgsize = MIN(sgsize, + PAGE_SIZE - (curaddr & PAGE_MASK)); + if (pagesneeded == NULL) + return (true); + count++; + } + curaddr += sgsize; + buflen -= sgsize; + } + + if (pagesneeded != NULL) + *pagesneeded = count; + return (count != 0); +} + static void _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf, bus_size_t buflen, int flags) { - vm_paddr_t curaddr; - bus_size_t sgsize; if (map != &nobounce_dmamap && map->pagesneeded == 0) { - /* - * Count the number of bounce pages - * needed in order to complete this transfer - */ - curaddr = buf; - while (buflen != 0) { - sgsize = MIN(buflen, dmat->common.maxsegsz); - if (bus_dma_run_filter(&dmat->common, curaddr)) { - sgsize = MIN(sgsize, - PAGE_SIZE - (curaddr & PAGE_MASK)); - map->pagesneeded++; - } - curaddr += sgsize; - buflen -= sgsize; - } + _bus_dmamap_pagesneeded(dmat, buf, buflen, &map->pagesneeded); CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded); } } @@ -1305,6 +1332,7 @@ struct bus_dma_impl bus_dma_bounce_impl = { .tag_create = bounce_bus_dma_tag_create, .tag_destroy = bounce_bus_dma_tag_destroy, .tag_set_domain = bounce_bus_dma_tag_set_domain, + .id_mapped = bounce_bus_dma_id_mapped, .map_create = bounce_bus_dmamap_create, .map_destroy = bounce_bus_dmamap_destroy, .mem_alloc = bounce_bus_dmamem_alloc, Modified: head/usr.sbin/camdd/camdd.c ============================================================================== --- head/usr.sbin/camdd/camdd.c Thu May 16 17:38:59 2019 (r347835) +++ head/usr.sbin/camdd/camdd.c Thu May 16 17:41:16 2019 (r347836) @@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include