mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Huan Yang <link@vivo.com>
To: "Kasireddy, Vivek" <vivek.kasireddy@intel.com>,
	"Sumit Semwal" <sumit.semwal@linaro.org>,
	"Christian König" <christian.koenig@amd.com>,
	"Gerd Hoffmann" <kraxel@redhat.com>,
	"linux-media@vger.kernel.org" <linux-media@vger.kernel.org>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>,
	"linaro-mm-sig@lists.linaro.org" <linaro-mm-sig@lists.linaro.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: "opensource.kernel@vivo.com" <opensource.kernel@vivo.com>
Subject: Re: [PATCH v5 4/7] udmabuf: udmabuf_create pin folio codestyle cleanup
Date: Mon, 9 Sep 2024 14:31:15 +0800	[thread overview]
Message-ID: <005ca835-2768-4a7a-a76f-5ea0e318b9e4@vivo.com> (raw)
In-Reply-To: <CH3PR11MB7177760ADAF50756F886989CF8992@CH3PR11MB7177.namprd11.prod.outlook.com>


在 2024/9/9 13:03, Kasireddy, Vivek 写道:
> Hi Huan,
>
>> Subject: Re: [PATCH v5 4/7] udmabuf: udmabuf_create pin folio codestyle
>> cleanup
>>
>>
>> 在 2024/9/6 16:17, Kasireddy, Vivek 写道:
>>> Hi Huan,
>>>
>>>> Subject: [PATCH v5 4/7] udmabuf: udmabuf_create pin folio codestyle
>>>> cleanup
>>>>
>>>> This patch split pin folios into single function: udmabuf_pin_folios.
>>>>
>>>> When record folio and offset into udmabuf_folio and offsets, the outer
>>>> loop of this patch iterates through folios, while the inner loop correctly
>>>> sets the folio and corresponding offset into the udmabuf starting from
>>>> the offset. if reach to pgcnt or nr_folios, end of loop.
>>>>
>>>> By this, more readable.
>>>>
>>>> Signed-off-by: Huan Yang <link@vivo.com>
>>>> ---
>>>>    drivers/dma-buf/udmabuf.c | 132 ++++++++++++++++++++------------------
>>>>    1 file changed, 71 insertions(+), 61 deletions(-)
>>>>
>>>> diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
>>>> index 456db58446e1..ca2b21c5c57f 100644
>>>> --- a/drivers/dma-buf/udmabuf.c
>>>> +++ b/drivers/dma-buf/udmabuf.c
>>>> @@ -330,17 +330,67 @@ static int export_udmabuf(struct udmabuf
>> *ubuf,
>>>>    	return dma_buf_fd(buf, flags);
>>>>    }
>>>>
>>>> +static int udmabuf_pin_folios(struct udmabuf *ubuf, struct file *memfd,
>>>> +			      loff_t start, loff_t size)
>>>> +{
>>>> +	pgoff_t pgoff, pgcnt, upgcnt = ubuf->pagecount;
>>>> +	u32 cur_folio, cur_pgcnt;
>>>> +	struct folio **folios = NULL;
>>>> +	long nr_folios;
>>>> +	loff_t end;
>>>> +	int ret = 0;
>>> Change ret's type and this function's return type to long for consistency.
>>>
>>>> +
>>>> +	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 err;
>>>> +	}
>>>> +
>>>> +	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 err;
>>>> +
>>>> +		for (; subpgoff < fsize; subpgoff += PAGE_SIZE) {
>>>> +			ubuf->folios[upgcnt] = folios[cur_folio];
>>>> +			ubuf->offsets[upgcnt] = subpgoff;
>>>> +			++upgcnt;
>>>> +
>>>> +			if (++cur_pgcnt >= pgcnt)
>>>> +				goto end;
>>>> +		}
>>>> +
>>>> +		/**
>>>> +		 * The term range may start with offset, so the first folio
>>>> +		 * need take care of it. And the remain folio start from 0.
>>> The comments above are not very meaningful. Please rewrite them as:
>>> * 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:
>>>> +err:
>>> No need to have two labels here. Keep end and get rid of err?
>>>
>>>> +	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;
>>>> +	long ret = -EINVAL;
>>>>    	struct udmabuf *ubuf;
>>>> -	u32 i, j, k, flags;
>>>> -	loff_t end;
>>>> +	u32 i, flags;
>>>>
>>>>    	ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL);
>>>>    	if (!ubuf)
>>>> @@ -349,81 +399,43 @@ 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);
>>>> +		struct file *memfd = fget(list[i].memfd);
>>>> +
>>>>    		ret = check_memfd_seals(memfd);
>>>>    		if (ret < 0)
>>>>    			goto err;
>>>>
>>>> -		pgcnt = list[i].size >> PAGE_SHIFT;
>>>> -		folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
>>>> -		if (!folios) {
>>>> -			ret = -ENOMEM;
>>>> -			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;
>>>> -			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;
>>>> @@ -434,8 +446,6 @@ static long udmabuf_create(struct miscdevice
>>>> *device,
>>>>    	return ret;
>>>>
>>>>    err:
>>>> -	if (memfd)
>>>> -		fput(memfd);
>>> I think this needs to stay because if the seals check fails, then we would not
>> be
>>> doing fput(memfd).
>> Yes, there a mistake, but I'd like set it into here:
>>
>>    		ret = check_memfd_seals(memfd);
>>    		if (ret < 0) {
> You still need an if (memfd) check here because check_memfd_seals() might do:
>          if (!memfd)
>                  return -EBADFD;

Yes, fput do not check if pointer is NULL.

Thanks.

>
> Thanks,
> Vivek
>
>> 			fput(memfd);
>>    			goto err;
>> 		}
>> due to only in inner look, memfd can get. and memfd change into loop var.
>> Thanks
>>
>>> Thanks,
>>> Vivek
>>>
>>>>    	unpin_all_folios(&ubuf->unpin_list);
>>>>    	kvfree(ubuf->offsets);
>>>>    	kvfree(ubuf->folios);
>>>> --
>>>> 2.45.2

  reply	other threads:[~2024-09-09  6:31 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-03  8:38 [PATCH v5 0/7] udmbuf bug fix and some improvements Huan Yang
2024-09-03  8:38 ` [PATCH v5 1/7] udmabuf: pre-fault when first page fault Huan Yang
2024-09-06  8:12   ` Kasireddy, Vivek
2024-09-06  8:37     ` Huan Yang
2024-09-03  8:38 ` [PATCH v5 2/7] udmabuf: change folios array from kmalloc to kvmalloc Huan Yang
2024-09-03  8:38 ` [PATCH v5 3/7] udmabuf: fix vmap_udmabuf error page set Huan Yang
2024-09-03  8:38 ` [PATCH v5 4/7] udmabuf: udmabuf_create pin folio codestyle cleanup Huan Yang
2024-09-06  8:17   ` Kasireddy, Vivek
2024-09-06  8:30     ` Huan Yang
2024-09-09  5:03       ` Kasireddy, Vivek
2024-09-09  6:31         ` Huan Yang [this message]
2024-09-03  8:38 ` [PATCH v5 5/7] udmabuf: introduce udmabuf init and deinit helper Huan Yang
2024-09-06  8:20   ` Kasireddy, Vivek
2024-09-06  8:38     ` Huan Yang
2024-09-03  8:38 ` [PATCH v5 6/7] udmabuf: remove udmabuf_folio Huan Yang
2024-09-06  8:22   ` Kasireddy, Vivek
2024-09-06  8:39     ` Huan Yang
2024-09-03  8:38 ` [PATCH v5 7/7] udmabuf: reuse folio array when pin folios Huan Yang
2024-09-06  8:23   ` Kasireddy, Vivek
2024-09-06  8:40     ` Huan Yang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=005ca835-2768-4a7a-a76f-5ea0e318b9e4@vivo.com \
    --to=link@vivo.com \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kraxel@redhat.com \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=opensource.kernel@vivo.com \
    --cc=sumit.semwal@linaro.org \
    --cc=vivek.kasireddy@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®