Merge branch 'stable/for-linus-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb
Pull swiotlb fixes from Konrad Rzeszutek Wilk: "This has one fix to make i915 work when using Xen SWIOTLB, and a feature from Geert to aid in debugging of devices that can't do DMA outside the 32-bit address space. The feature from Geert is on top of v4.10 merge window commit (specifically you pulling my previous branch), as his changes were dependent on the Documentation/ movement patches. I figured it would just easier than me trying than to cherry-pick the Documentation patches to satisfy git. The patches have been soaking since 12/20, albeit I updated the last patch due to linux-next catching an compiler error and adding an Tested-and-Reported-by tag" * 'stable/for-linus-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb: swiotlb: Export swiotlb_max_segment to users swiotlb: Add swiotlb=noforce debug option swiotlb: Convert swiotlb_force from int to enum x86, swiotlb: Simplify pci_swiotlb_detect_override()
This commit is contained in:
@@ -53,7 +53,7 @@
|
||||
*/
|
||||
#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)
|
||||
|
||||
int swiotlb_force;
|
||||
enum swiotlb_force swiotlb_force;
|
||||
|
||||
/*
|
||||
* Used to do a quick range check in swiotlb_tbl_unmap_single and
|
||||
@@ -82,6 +82,12 @@ static phys_addr_t io_tlb_overflow_buffer;
|
||||
static unsigned int *io_tlb_list;
|
||||
static unsigned int io_tlb_index;
|
||||
|
||||
/*
|
||||
* Max segment that we can provide which (if pages are contingous) will
|
||||
* not be bounced (unless SWIOTLB_FORCE is set).
|
||||
*/
|
||||
unsigned int max_segment;
|
||||
|
||||
/*
|
||||
* We need to save away the original address corresponding to a mapped entry
|
||||
* for the sync operations.
|
||||
@@ -106,8 +112,12 @@ setup_io_tlb_npages(char *str)
|
||||
}
|
||||
if (*str == ',')
|
||||
++str;
|
||||
if (!strcmp(str, "force"))
|
||||
swiotlb_force = 1;
|
||||
if (!strcmp(str, "force")) {
|
||||
swiotlb_force = SWIOTLB_FORCE;
|
||||
} else if (!strcmp(str, "noforce")) {
|
||||
swiotlb_force = SWIOTLB_NO_FORCE;
|
||||
io_tlb_nslabs = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -120,6 +130,20 @@ unsigned long swiotlb_nr_tbl(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(swiotlb_nr_tbl);
|
||||
|
||||
unsigned int swiotlb_max_segment(void)
|
||||
{
|
||||
return max_segment;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(swiotlb_max_segment);
|
||||
|
||||
void swiotlb_set_max_segment(unsigned int val)
|
||||
{
|
||||
if (swiotlb_force == SWIOTLB_FORCE)
|
||||
max_segment = 1;
|
||||
else
|
||||
max_segment = rounddown(val, PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* default to 64MB */
|
||||
#define IO_TLB_DEFAULT_SIZE (64UL<<20)
|
||||
unsigned long swiotlb_size_or_default(void)
|
||||
@@ -201,6 +225,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
|
||||
if (verbose)
|
||||
swiotlb_print_info();
|
||||
|
||||
swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -279,6 +304,7 @@ swiotlb_late_init_with_default_size(size_t default_size)
|
||||
rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs);
|
||||
if (rc)
|
||||
free_pages((unsigned long)vstart, order);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -333,6 +359,8 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
|
||||
|
||||
late_alloc = 1;
|
||||
|
||||
swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT);
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup4:
|
||||
@@ -347,6 +375,7 @@ cleanup2:
|
||||
io_tlb_end = 0;
|
||||
io_tlb_start = 0;
|
||||
io_tlb_nslabs = 0;
|
||||
max_segment = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -375,6 +404,7 @@ void __init swiotlb_free(void)
|
||||
PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT));
|
||||
}
|
||||
io_tlb_nslabs = 0;
|
||||
max_segment = 0;
|
||||
}
|
||||
|
||||
int is_swiotlb_buffer(phys_addr_t paddr)
|
||||
@@ -543,8 +573,15 @@ static phys_addr_t
|
||||
map_single(struct device *hwdev, phys_addr_t phys, size_t size,
|
||||
enum dma_data_direction dir, unsigned long attrs)
|
||||
{
|
||||
dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start);
|
||||
dma_addr_t start_dma_addr;
|
||||
|
||||
if (swiotlb_force == SWIOTLB_NO_FORCE) {
|
||||
dev_warn_ratelimited(hwdev, "Cannot do DMA to address %pa\n",
|
||||
&phys);
|
||||
return SWIOTLB_MAP_ERROR;
|
||||
}
|
||||
|
||||
start_dma_addr = phys_to_dma(hwdev, io_tlb_start);
|
||||
return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size,
|
||||
dir, attrs);
|
||||
}
|
||||
@@ -721,6 +758,9 @@ static void
|
||||
swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
|
||||
int do_panic)
|
||||
{
|
||||
if (swiotlb_force == SWIOTLB_NO_FORCE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Ran out of IOMMU space for this operation. This is very bad.
|
||||
* Unfortunately the drivers cannot handle this operation properly.
|
||||
@@ -763,7 +803,7 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
|
||||
* we can safely return the device addr and not worry about bounce
|
||||
* buffering it.
|
||||
*/
|
||||
if (dma_capable(dev, dev_addr, size) && !swiotlb_force)
|
||||
if (dma_capable(dev, dev_addr, size) && swiotlb_force != SWIOTLB_FORCE)
|
||||
return dev_addr;
|
||||
|
||||
trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force);
|
||||
@@ -904,7 +944,7 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
|
||||
phys_addr_t paddr = sg_phys(sg);
|
||||
dma_addr_t dev_addr = phys_to_dma(hwdev, paddr);
|
||||
|
||||
if (swiotlb_force ||
|
||||
if (swiotlb_force == SWIOTLB_FORCE ||
|
||||
!dma_capable(hwdev, dev_addr, sg->length)) {
|
||||
phys_addr_t map = map_single(hwdev, sg_phys(sg),
|
||||
sg->length, dir, attrs);
|
||||
|
Reference in New Issue
Block a user