Re: [PATCH v4 2/2] videobuf2-dma-sg: Replace vb2_dma_sg_desc with sg_table

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Hans

Thank you very much for your mail.

For what I understand sg_alloc_table_from_pages does not allocate any
page or bounce buffer, it just take a set of N pages and makes a
sg_table from it, on the process it finds out if page A and A+1are on
the same pfn and if it is true they will share the sg. So it is a
later function that produces the error.  As I see it, before this
patch we were reimplementing sg_alloc_table_from_pages.

Which function is returning -ENOMEM?


Regards!



On Fri, Jan 3, 2014 at 3:52 PM, Hans Verkuil <hverkuil@xxxxxxxxx> wrote:
> Hi Ricardo,
>
> I've run into a problem that is caused by this patch:
>
> On 08/02/2013 04:20 PM, Ricardo Ribalda Delgado wrote:
>> Replace the private struct vb2_dma_sg_desc with the struct sg_table so
>> we can benefit from all the helping functions in lib/scatterlist.c for
>> things like allocating the sg or compacting the descriptor
>>
>> marvel-ccic and solo6x10 drivers, that uses this api has been updated
>>
>> Acked-by: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx>
>> Reviewed-by: Andre Heider <a.heider@xxxxxxxxx>
>> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@xxxxxxxxx>
>> ---
>>  drivers/media/platform/marvell-ccic/mcam-core.c    |   14 +--
>>  drivers/media/v4l2-core/videobuf2-dma-sg.c         |  103 ++++++++------------
>>  drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c |   20 ++--
>>  include/media/videobuf2-dma-sg.h                   |   10 +-
>>  4 files changed, 63 insertions(+), 84 deletions(-)
>>
>
> <snip>
>
>> diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c
>> index 4999c48..2f86054 100644
>> --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
>> +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
>
> <snip>
>
>> @@ -99,17 +98,11 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_fla
>>       buf->vaddr = NULL;
>>       buf->write = 0;
>>       buf->offset = 0;
>> -     buf->sg_desc.size = size;
>> +     buf->size = size;
>>       /* size is already page aligned */
>> -     buf->sg_desc.num_pages = size >> PAGE_SHIFT;
>> -
>> -     buf->sg_desc.sglist = vzalloc(buf->sg_desc.num_pages *
>> -                                   sizeof(*buf->sg_desc.sglist));
>> -     if (!buf->sg_desc.sglist)
>> -             goto fail_sglist_alloc;
>> -     sg_init_table(buf->sg_desc.sglist, buf->sg_desc.num_pages);
>> +     buf->num_pages = size >> PAGE_SHIFT;
>>
>> -     buf->pages = kzalloc(buf->sg_desc.num_pages * sizeof(struct page *),
>> +     buf->pages = kzalloc(buf->num_pages * sizeof(struct page *),
>>                            GFP_KERNEL);
>>       if (!buf->pages)
>>               goto fail_pages_array_alloc;
>> @@ -118,6 +111,11 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size, gfp_t gfp_fla
>>       if (ret)
>>               goto fail_pages_alloc;
>>
>> +     ret = sg_alloc_table_from_pages(&buf->sg_table, buf->pages,
>> +                     buf->num_pages, 0, size, gfp_flags);
>> +     if (ret)
>> +             goto fail_table_alloc;
>> +
>>       buf->handler.refcount = &buf->refcount;
>>       buf->handler.put = vb2_dma_sg_put;
>>       buf->handler.arg = buf;
>
> The problem here is the switch from sg_init_table to sg_alloc_table_from_pages. If
> the PCI hardware only accepts 32-bit DMA transfers, but it is used on a 64-bit OS
> with > 4GB physical memory, then the kernel will allocate DMA bounce buffers for you.
>
> With sg_init_table that works fine since each page in the scatterlist maps to a
> bounce buffer that is also just one page, but with sg_alloc_table_from_pages the DMA
> bounce buffers can be multiple pages. This is in turn rounded up to the next power of
> 2 and allocated in the 32-bit address space. Unfortunately, due to memory fragmentation
> this very quickly fails with -ENOMEM.
>
> I discovered this while converting saa7134 to vb2. I think that when DMA bounce
> buffers are needed, then it should revert to sg_init_table.
>
> I don't know whether this bug also affects non-v4l drivers.
>
> For now at least I won't try to fix this myself as I have discovered that dma-sg
> doesn't work anyway for saa7134 due to a hardware limitation so I will switch to
> dma-contig for that driver.
>
> But at the very least I thought I should write this down so others know about this
> subtle problem and perhaps someone else wants to tackle this.
>
> I actually think that the solo driver is affected by this (I haven't tested it yet).
> And at some point we need to convert bttv and cx88 to vb2 as well, and I expect that
> they will hit the same problem.
>
> If someone knows a better solution than switching to sg_init_table if bounce buffers
> are needed, then let me know.
>
> Regards,
>
>         Hans



-- 
Ricardo Ribalda
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux