Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F165293986
D20181.id57130.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D20181.id57130.diff
View Options
Index: sys/compat/linuxkpi/common/src/linux_pci.c
===================================================================
--- sys/compat/linuxkpi/common/src/linux_pci.c
+++ sys/compat/linuxkpi/common/src/linux_pci.c
@@ -502,6 +502,15 @@
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);
Index: sys/x86/include/bus_dma.h
===================================================================
--- sys/x86/include/bus_dma.h
+++ sys/x86/include/bus_dma.h
@@ -35,6 +35,18 @@
#include <x86/busdma_impl.h>
+/*
+ * 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.
Index: sys/x86/include/busdma_impl.h
===================================================================
--- sys/x86/include/busdma_impl.h
+++ sys/x86/include/busdma_impl.h
@@ -62,6 +62,7 @@
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,
Index: sys/x86/iommu/busdma_dmar.c
===================================================================
--- sys/x86/iommu/busdma_dmar.c
+++ sys/x86/iommu/busdma_dmar.c
@@ -365,6 +365,13 @@
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 @@
.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,
Index: sys/x86/x86/busdma_bounce.c
===================================================================
--- sys/x86/x86/busdma_bounce.c
+++ sys/x86/x86/busdma_bounce.c
@@ -141,6 +141,8 @@
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 int _bus_dmamap_pagesneeded(bus_dma_tag_t dmat, vm_paddr_t buf,
+ bus_size_t buflen);
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,19 @@
return (error);
}
+static bool
+bounce_bus_dma_id_mapped(bus_dma_tag_t dmat, vm_paddr_t buf, bus_size_t buflen)
+{
+ int pagesneeded;
+
+ if ((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) == 0)
+ return (true);
+
+ pagesneeded = _bus_dmamap_pagesneeded(dmat, buf, buflen);
+
+ return (pagesneeded == 0);
+}
+
/*
* Update the domain for the tag. We may need to reallocate the zone and
* bounce pages.
@@ -501,29 +516,38 @@
dmat->bounce_flags);
}
-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)
+static int
+_bus_dmamap_pagesneeded(bus_dma_tag_t dmat, vm_paddr_t buf, bus_size_t buflen)
{
vm_paddr_t curaddr;
bus_size_t sgsize;
+ int pagesneeded = 0;
- 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;
+ /*
+ * 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));
+ pagesneeded++;
}
+ curaddr += sgsize;
+ buflen -= sgsize;
+ }
+
+ return (pagesneeded);
+}
+
+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)
+{
+ if (map != &nobounce_dmamap && map->pagesneeded == 0) {
+ map->pagesneeded = _bus_dmamap_pagesneeded(dmat, buf, buflen);
CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
}
}
@@ -1305,6 +1329,7 @@
.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,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Aug 8, 11:35 AM (3 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36226673
Default Alt Text
D20181.id57130.diff (5 KB)
Attached To
Mode
D20181: For the LinuxKPI allow loading the same DMA address multiple times without any prior unload
Attached
Detach File
Event Timeline
Log In to Comment