[PATCH v6 4/7] udmabuf: udmabuf_create pin folio codestyle cleanup

Huan Yang link at vivo.com
Fri Sep 13 06:33:15 UTC 2024


在 2024/9/13 6:43, Kasireddy, Vivek 写道:
> Hi Huan,
>
>> Subject: [PATCH v6 4/7] udmabuf: udmabuf_create pin folio codestyle
>> cleanup
>>
>> This patch aims to simplify the pinning of folio during the udmabuf
>> creation. No functional changes.
>>
>> This patch moves the memfd pin folio to udmabuf_pin_folios and modifies
>> the original loop condition, using the pinned folio as the external
>> loop condition, and sets the offset and folio during the traversal process.
>>
>> By this, more readable.
>>
>> Suggested-by: Vivek Kasireddy <vivek.kasireddy at intel.com>
>> Signed-off-by: Huan Yang <link at vivo.com>
>> ---
>>   drivers/dma-buf/udmabuf.c | 134 +++++++++++++++++++++-----------------
>>   1 file changed, 76 insertions(+), 58 deletions(-)
>>
>> diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
>> index aa182a9dcdfa..fe1466f7d55a 100644
>> --- a/drivers/dma-buf/udmabuf.c
>> +++ b/drivers/dma-buf/udmabuf.c
>> @@ -328,17 +328,68 @@ static int export_udmabuf(struct udmabuf *ubuf,
>>   	return dma_buf_fd(buf, flags);
>>   }
>>
>> +static long udmabuf_pin_folios(struct udmabuf *ubuf, struct file *memfd,
>> +			       loff_t start, loff_t size)
>> +{
>> +	pgoff_t pgoff, pgcnt, upgcnt = ubuf->pagecount;
>> +	struct folio **folios = NULL;
>> +	u32 cur_folio, cur_pgcnt;
>> +	long nr_folios;
>> +	long ret = 0;
>> +	loff_t end;
>> +
>> +	pgcnt = size >> PAGE_SHIFT;
>> +	folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
>> +	if (!folios)
>> +		return -ENOMEM;
>> +
>> +	end = start + (pgcnt << PAGE_SHIFT) - 1;
>> +	nr_folios = memfd_pin_folios(memfd, start, end, folios, pgcnt,
>> &pgoff);
>> +	if (nr_folios <= 0) {
>> +		ret = nr_folios ? nr_folios : -EINVAL;
>> +		goto end;
>> +	}
>> +
>> +	cur_pgcnt = 0;
>> +	for (cur_folio = 0; cur_folio < nr_folios; ++cur_folio) {
>> +		pgoff_t subpgoff = pgoff;
>> +		size_t fsize = folio_size(folios[cur_folio]);
>> +
>> +		ret = add_to_unpin_list(&ubuf->unpin_list, folios[cur_folio]);
>> +		if (ret < 0)
>> +			goto end;
>> +
>> +		for (; subpgoff < fsize; subpgoff += PAGE_SIZE) {
>> +			ubuf->folios[upgcnt] = folios[cur_folio];
>> +			ubuf->offsets[upgcnt] = subpgoff;
>> +			++upgcnt;
>> +
>> +			if (++cur_pgcnt >= pgcnt)
>> +				goto end;
>> +		}
>> +
>> +		/**
>> +		 * In a given range, only the first subpage of the first folio
>> +		 * has an offset, that is returned by memfd_pin_folios().
>> +		 * The first subpages of other folios (in the range) have an
>> +		 * offset of 0.
>> +		 */
>> +		pgoff = 0;
>> +	}
>> +end:
>> +	ubuf->pagecount = upgcnt;
>> +	kvfree(folios);
>> +	return ret;
>> +}
>> +
>>   static long udmabuf_create(struct miscdevice *device,
>>   			   struct udmabuf_create_list *head,
>>   			   struct udmabuf_create_item *list)
>>   {
>> -	pgoff_t pgoff, pgcnt, pglimit, pgbuf = 0;
>> -	long nr_folios, ret = -EINVAL;
>> -	struct file *memfd = NULL;
>> -	struct folio **folios;
>> +	pgoff_t pgcnt = 0, pglimit;
>>   	struct udmabuf *ubuf;
>> -	u32 i, j, k, flags;
>> -	loff_t end;
>> +	long ret = -EINVAL;
>> +	u32 i, flags;
>>
>>   	ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL);
>>   	if (!ubuf)
>> @@ -347,81 +398,50 @@ static long udmabuf_create(struct miscdevice
>> *device,
>>   	INIT_LIST_HEAD(&ubuf->unpin_list);
>>   	pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT;
>>   	for (i = 0; i < head->count; i++) {
>> -		if (!IS_ALIGNED(list[i].offset, PAGE_SIZE))
>> +		if (!PAGE_ALIGNED(list[i].offset))
>>   			goto err;
>> -		if (!IS_ALIGNED(list[i].size, PAGE_SIZE))
>> +		if (!PAGE_ALIGNED(list[i].size))
>>   			goto err;
>> -		ubuf->pagecount += list[i].size >> PAGE_SHIFT;
>> -		if (ubuf->pagecount > pglimit)
>> +
>> +		pgcnt += list[i].size >> PAGE_SHIFT;
>> +		if (pgcnt > pglimit)
>>   			goto err;
>>   	}
>>
>> -	if (!ubuf->pagecount)
>> +	if (!pgcnt)
>>   		goto err;
>>
>> -	ubuf->folios = kvmalloc_array(ubuf->pagecount, sizeof(*ubuf-
>>> folios),
>> -				      GFP_KERNEL);
>> +	ubuf->folios = kvmalloc_array(pgcnt, sizeof(*ubuf->folios),
>> GFP_KERNEL);
>>   	if (!ubuf->folios) {
>>   		ret = -ENOMEM;
>>   		goto err;
>>   	}
>> -	ubuf->offsets = kvcalloc(ubuf->pagecount, sizeof(*ubuf->offsets),
>> -				 GFP_KERNEL);
>> +
>> +	ubuf->offsets = kvcalloc(pgcnt, sizeof(*ubuf->offsets), GFP_KERNEL);
>>   	if (!ubuf->offsets) {
>>   		ret = -ENOMEM;
>>   		goto err;
>>   	}
>>
>> -	pgbuf = 0;
>>   	for (i = 0; i < head->count; i++) {
>> -		memfd = fget(list[i].memfd);
>> -		ret = check_memfd_seals(memfd);
>> -		if (ret < 0)
>> -			goto err;
>> +		struct file *memfd = fget(list[i].memfd);
>>
>> -		pgcnt = list[i].size >> PAGE_SHIFT;
>> -		folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
>> -		if (!folios) {
>> -			ret = -ENOMEM;
>> +		if (!memfd) {
>> +			ret = -EBADFD;
> Nit: with the above change added, please remove the redundant if (!memfd)
> check from check_memfd_seals().

Yes, right, I'll do it.

Thank you.

>
> Acked-by: Vivek Kasireddy <vivek.kasireddy at intel.com>
>
>>   			goto err;
>>   		}
>>
>> -		end = list[i].offset + (pgcnt << PAGE_SHIFT) - 1;
>> -		ret = memfd_pin_folios(memfd, list[i].offset, end,
>> -				       folios, pgcnt, &pgoff);
>> -		if (ret <= 0) {
>> -			kvfree(folios);
>> -			if (!ret)
>> -				ret = -EINVAL;
>> +		ret = check_memfd_seals(memfd);
>> +		if (ret < 0) {
>> +			fput(memfd);
>>   			goto err;
>>   		}
>>
>> -		nr_folios = ret;
>> -		pgoff >>= PAGE_SHIFT;
>> -		for (j = 0, k = 0; j < pgcnt; j++) {
>> -			ubuf->folios[pgbuf] = folios[k];
>> -			ubuf->offsets[pgbuf] = pgoff << PAGE_SHIFT;
>> -
>> -			if (j == 0 || ubuf->folios[pgbuf-1] != folios[k]) {
>> -				ret = add_to_unpin_list(&ubuf->unpin_list,
>> -							folios[k]);
>> -				if (ret < 0) {
>> -					kfree(folios);
>> -					goto err;
>> -				}
>> -			}
>> -
>> -			pgbuf++;
>> -			if (++pgoff == folio_nr_pages(folios[k])) {
>> -				pgoff = 0;
>> -				if (++k == nr_folios)
>> -					break;
>> -			}
>> -		}
>> -
>> -		kvfree(folios);
>> +		ret = udmabuf_pin_folios(ubuf, memfd, list[i].offset,
>> +					 list[i].size);
>>   		fput(memfd);
>> -		memfd = NULL;
>> +		if (ret)
>> +			goto err;
>>   	}
>>
>>   	flags = head->flags & UDMABUF_FLAGS_CLOEXEC ? O_CLOEXEC : 0;
>> @@ -432,8 +452,6 @@ static long udmabuf_create(struct miscdevice
>> *device,
>>   	return ret;
>>
>>   err:
>> -	if (memfd)
>> -		fput(memfd);
>>   	unpin_all_folios(&ubuf->unpin_list);
>>   	kvfree(ubuf->offsets);
>>   	kvfree(ubuf->folios);
>> --
>> 2.45.2


More information about the dri-devel mailing list