Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42d00284 authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by Linus Torvalds
Browse files

iommu sg merging: x86: make pci-gart iommu respect the segment size limits



This patch makes pci-gart iommu respect segment size limits when
merging sg lists.

Signed-off-by: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Jeff Garzik <jeff@garzik.org>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Acked-by: default avatarJens Axboe <jens.axboe@oracle.com>
Cc: Dave Airlie <airlied@linux.ie>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4d57cdfa
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -416,6 +416,8 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
	struct scatterlist *s, *ps, *start_sg, *sgmap;
	int need = 0, nextneed, i, out, start;
	unsigned long pages = 0;
	unsigned int seg_size;
	unsigned int max_seg_size;

	if (nents == 0)
		return 0;
@@ -426,6 +428,8 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
	out = 0;
	start = 0;
	start_sg = sgmap = sg;
	seg_size = 0;
	max_seg_size = dma_get_max_seg_size(dev);
	ps = NULL; /* shut up gcc */
	for_each_sg(sg, s, nents, i) {
		dma_addr_t addr = sg_phys(s);
@@ -443,11 +447,13 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
			 * offset.
			 */
			if (!iommu_merge || !nextneed || !need || s->offset ||
			    (s->length + seg_size > max_seg_size) ||
			    (ps->offset + ps->length) % PAGE_SIZE) {
				if (dma_map_cont(start_sg, i - start, sgmap,
						  pages, need) < 0)
					goto error;
				out++;
				seg_size = 0;
				sgmap = sg_next(sgmap);
				pages = 0;
				start = i;
@@ -455,6 +461,7 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
			}
		}

		seg_size += s->length;
		need = nextneed;
		pages += to_pages(s->offset, s->length);
		ps = s;