[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <464322BC.50101@panasas.com>
Date: Thu, 10 May 2007 16:48:44 +0300
From: Benny Halevy <bhalevy@...asas.com>
To: Jens Axboe <jens.axboe@...cle.com>
CC: linux-kernel@...r.kernel.org
Subject: Re: [PATCH 8/12] x86-64: update iommu/dma mapping functions to sg
helpers
Jens Axboe wrote:
<snip>
> @@ -323,13 +324,17 @@ static int __dma_map_cont(struct scatterlist *sg, int start, int stopat,
> {
> unsigned long iommu_start = alloc_iommu(pages);
> unsigned long iommu_page = iommu_start;
> - int i;
> + struct scatterlist *s;
> + int i, nelems;
>
> if (iommu_start == -1)
> return -1;
> +
> + nelems = stopat - start;
> + while (start--)
> + sg = sg_next(sg);
Ouch. This will suck if we merge many times in a long list.
How about keeping and passing start as a struct scatterlist * rather
than an index? (see attached example, (compiles, bu untested though)
>
> - for (i = start; i < stopat; i++) {
> - struct scatterlist *s = &sg[i];
> + for_each_sg(sg, s, nelems, i) {
> unsigned long pages, addr;
> unsigned long phys_addr = s->dma_address;
There seems to be a bug hiding here as now i is in [0, nelems) now,
not [start, stopat) so "if (i == start)" below should turn into "if (i == 0)"
this is fixed by comparing pointers instead way in the attached example.
>
> @@ -360,12 +365,14 @@ static inline int dma_map_cont(struct scatterlist *sg, int start, int stopat,
> struct scatterlist *sout,
> unsigned long pages, int need)
> {
> - if (!need) {
> + if (!need) {
> BUG_ON(stopat - start != 1);
> - *sout = sg[start];
> - sout->dma_length = sg[start].length;
> + while (--start)
> + sg = sg_next(sg);
same efficiency issue as above.
> + *sout = *sg;
> + sout->dma_length = sg->length;
> return 0;
> - }
> + }
> return __dma_map_cont(sg, start, stopat, sout, pages);
> }
>
<snip>
View attachment "pci-gart-sg_chain.patch" of type "text/plain" (3264 bytes)
Powered by blists - more mailing lists