[PATCHv5 08/13] v4l: vb2-dma-contig: add support for scatterlist in userptr mode

Subash Patel subashrp at gmail.com
Tue May 8 04:15:43 PDT 2012


Hi Laurent,

On 05/08/2012 02:44 PM, Laurent Pinchart wrote:
> Hi Subash,
>
> On Monday 07 May 2012 20:08:25 Subash Patel wrote:
>> Hello Thomasz, Laurent,
>>
>> I found an issue in the function vb2_dc_pages_to_sgt() below. I saw that
>> during the attach, the size of the SGT and size requested mis-matched
>> (by atleast 8k bytes). Hence I made a small correction to the code as
>> below. I could then attach the importer properly.
>
> Thank you for the report.
>
> Could you print the content of the sglist (number of chunks and size of each
> chunk) before and after your modifications, as well as the values of n_pages,
> offset and size ?
I will put back all the printk's and generate this. As of now, my setup 
has changed and will do this when I get sometime.
>
>> On 04/20/2012 08:15 PM, Tomasz Stanislawski wrote:
>
> [snip]
>
>>> +static struct sg_table *vb2_dc_pages_to_sgt(struct page **pages,
>>> +	unsigned int n_pages, unsigned long offset, unsigned long size)
>>> +{
>>> +	struct sg_table *sgt;
>>> +	unsigned int chunks;
>>> +	unsigned int i;
>>> +	unsigned int cur_page;
>>> +	int ret;
>>> +	struct scatterlist *s;
>>> +
>>> +	sgt = kzalloc(sizeof *sgt, GFP_KERNEL);
>>> +	if (!sgt)
>>> +		return ERR_PTR(-ENOMEM);
>>> +
>>> +	/* compute number of chunks */
>>> +	chunks = 1;
>>> +	for (i = 1; i<   n_pages; ++i)
>>> +		if (pages[i] != pages[i - 1] + 1)
>>> +			++chunks;
>>> +
>>> +	ret = sg_alloc_table(sgt, chunks, GFP_KERNEL);
>>> +	if (ret) {
>>> +		kfree(sgt);
>>> +		return ERR_PTR(-ENOMEM);
>>> +	}
>>> +
>>> +	/* merging chunks and putting them into the scatterlist */
>>> +	cur_page = 0;
>>> +	for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
>>> +		unsigned long chunk_size;
>>> +		unsigned int j;
>>
>> 		size = PAGE_SIZE;
>>
>>> +
>>> +		for (j = cur_page + 1; j<   n_pages; ++j)
>>
>> 		for (j = cur_page + 1; j<  n_pages; ++j) {
>>
>>> +			if (pages[j] != pages[j - 1] + 1)
>>> +				break;
>>
>> 			size += PAGE
>> 		}
>>
>>> +
>>> +		chunk_size = ((j - cur_page)<<   PAGE_SHIFT) - offset;
>>> +		sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
>>
>> 		[DELETE] size -= chunk_size;
>>
>>> +		offset = 0;
>>> +		cur_page = j;
>>> +	}
>>> +
>>> +	return sgt;
>>> +}
>
Regards,
Subash


More information about the dri-devel mailing list