lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <80718789-b3de-c30a-03c5-7c8cbf41f7d9@nvidia.com>
Date:   Wed, 7 Oct 2020 13:32:55 -0700
From:   John Hubbard <jhubbard@...dia.com>
To:     Daniel Vetter <daniel.vetter@...ll.ch>,
        DRI Development <dri-devel@...ts.freedesktop.org>,
        LKML <linux-kernel@...r.kernel.org>
CC:     <kvm@...r.kernel.org>, <linux-mm@...ck.org>,
        <linux-arm-kernel@...ts.infradead.org>,
        <linux-samsung-soc@...r.kernel.org>, <linux-media@...r.kernel.org>,
        <linux-s390@...r.kernel.org>,
        Daniel Vetter <daniel.vetter@...el.com>,
        Jason Gunthorpe <jgg@...pe.ca>,
        Inki Dae <inki.dae@...sung.com>,
        Joonyoung Shim <jy0922.shim@...sung.com>,
        "Seung-Woo Kim" <sw0312.kim@...sung.com>,
        Kyungmin Park <kyungmin.park@...sung.com>,
        Kukjin Kim <kgene@...nel.org>,
        Krzysztof Kozlowski <krzk@...nel.org>,
        "Andrew Morton" <akpm@...ux-foundation.org>,
        Jérôme Glisse <jglisse@...hat.com>,
        Jan Kara <jack@...e.cz>,
        Dan Williams <dan.j.williams@...el.com>
Subject: Re: [PATCH 01/13] drm/exynos: Stop using frame_vector helpers

On 10/7/20 9:44 AM, Daniel Vetter wrote:
> All we need are a pages array, pin_user_pages_fast can give us that
> directly. Plus this avoids the entire raw pfn side of get_vaddr_frames.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@...el.com>
> Cc: Jason Gunthorpe <jgg@...pe.ca>
> Cc: Inki Dae <inki.dae@...sung.com>
> Cc: Joonyoung Shim <jy0922.shim@...sung.com>
> Cc: Seung-Woo Kim <sw0312.kim@...sung.com>
> Cc: Kyungmin Park <kyungmin.park@...sung.com>
> Cc: Kukjin Kim <kgene@...nel.org>
> Cc: Krzysztof Kozlowski <krzk@...nel.org>
> Cc: Andrew Morton <akpm@...ux-foundation.org>
> Cc: John Hubbard <jhubbard@...dia.com>
> Cc: Jérôme Glisse <jglisse@...hat.com>
> Cc: Jan Kara <jack@...e.cz>
> Cc: Dan Williams <dan.j.williams@...el.com>
> Cc: linux-mm@...ck.org
> Cc: linux-arm-kernel@...ts.infradead.org
> Cc: linux-samsung-soc@...r.kernel.org
> Cc: linux-media@...r.kernel.org
> ---
>   drivers/gpu/drm/exynos/Kconfig          |  1 -
>   drivers/gpu/drm/exynos/exynos_drm_g2d.c | 48 ++++++++++++-------------
>   2 files changed, 22 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
> index 6417f374b923..43257ef3c09d 100644
> --- a/drivers/gpu/drm/exynos/Kconfig
> +++ b/drivers/gpu/drm/exynos/Kconfig
> @@ -88,7 +88,6 @@ comment "Sub-drivers"
>   config DRM_EXYNOS_G2D
>   	bool "G2D"
>   	depends on VIDEO_SAMSUNG_S5P_G2D=n || COMPILE_TEST
> -	select FRAME_VECTOR
>   	help
>   	  Choose this option if you want to use Exynos G2D for DRM.
>   
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> index 967a5cdc120e..c83f6faac9de 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
> @@ -205,7 +205,8 @@ struct g2d_cmdlist_userptr {
>   	dma_addr_t		dma_addr;
>   	unsigned long		userptr;
>   	unsigned long		size;
> -	struct frame_vector	*vec;
> +	struct page		**pages;
> +	unsigned int		npages;
>   	struct sg_table		*sgt;
>   	atomic_t		refcount;
>   	bool			in_pool;
> @@ -378,7 +379,7 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,
>   					bool force)
>   {
>   	struct g2d_cmdlist_userptr *g2d_userptr = obj;
> -	struct page **pages;
> +	int i;

The above line can also be deleted, see below.

>   
>   	if (!obj)
>   		return;
> @@ -398,15 +399,11 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,
>   	dma_unmap_sgtable(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt,
>   			  DMA_BIDIRECTIONAL, 0);
>   
> -	pages = frame_vector_pages(g2d_userptr->vec);
> -	if (!IS_ERR(pages)) {
> -		int i;
> +	for (i = 0; i < g2d_userptr->npages; i++)
> +		set_page_dirty_lock(g2d_userptr->pages[i]);
>   
> -		for (i = 0; i < frame_vector_count(g2d_userptr->vec); i++)
> -			set_page_dirty_lock(pages[i]);
> -	}
> -	put_vaddr_frames(g2d_userptr->vec);
> -	frame_vector_destroy(g2d_userptr->vec);
> +	unpin_user_pages(g2d_userptr->pages, g2d_userptr->npages);
> +	kvfree(g2d_userptr->pages);

You can avoid writing your own loop, and just simplify the whole thing down to
two lines:

	unpin_user_pages_dirty_lock(g2d_userptr->pages, g2d_userptr->npages,
				    true);
	kvfree(g2d_userptr->pages);


>   
>   	if (!g2d_userptr->out_of_list)
>   		list_del_init(&g2d_userptr->list);
> @@ -474,35 +471,34 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
>   	offset = userptr & ~PAGE_MASK;
>   	end = PAGE_ALIGN(userptr + size);
>   	npages = (end - start) >> PAGE_SHIFT;
> -	g2d_userptr->vec = frame_vector_create(npages);
> -	if (!g2d_userptr->vec) {
> +	g2d_userptr->pages = kvmalloc_array(npages, sizeof(*g2d_userptr->pages),
> +					    GFP_KERNEL);
> +	if (!g2d_userptr->pages) {
>   		ret = -ENOMEM;
>   		goto err_free;
>   	}
>   
> -	ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE,
> -		g2d_userptr->vec);
> +	ret = pin_user_pages_fast(start, npages, FOLL_FORCE | FOLL_WRITE,
> +				  g2d_userptr->pages);
>   	if (ret != npages) {
>   		DRM_DEV_ERROR(g2d->dev,
>   			      "failed to get user pages from userptr.\n");
>   		if (ret < 0)
> -			goto err_destroy_framevec;
> -		ret = -EFAULT;
> -		goto err_put_framevec;
> -	}
> -	if (frame_vector_to_pages(g2d_userptr->vec) < 0) {
> +			goto err_destroy_pages;
> +		npages = ret;
>   		ret = -EFAULT;
> -		goto err_put_framevec;
> +		goto err_unpin_pages;
>   	}
> +	g2d_userptr->npages = npages;
>   
>   	sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
>   	if (!sgt) {
>   		ret = -ENOMEM;
> -		goto err_put_framevec;
> +		goto err_unpin_pages;
>   	}
>   
>   	ret = sg_alloc_table_from_pages(sgt,
> -					frame_vector_pages(g2d_userptr->vec),
> +					g2d_userptr->pages,
>   					npages, offset, size, GFP_KERNEL);
>   	if (ret < 0) {
>   		DRM_DEV_ERROR(g2d->dev, "failed to get sgt from pages.\n");
> @@ -538,11 +534,11 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
>   err_free_sgt:
>   	kfree(sgt);
>   
> -err_put_framevec:
> -	put_vaddr_frames(g2d_userptr->vec);
> +err_unpin_pages:
> +	unpin_user_pages(g2d_userptr->pages, npages);
>   
> -err_destroy_framevec:
> -	frame_vector_destroy(g2d_userptr->vec);
> +err_destroy_pages:
> +	kvfree(g2d_userptr->pages);
>   
>   err_free:
>   	kfree(g2d_userptr);
> 

The rest all looks good, you've avoided the usual API pitfalls. :)

thanks,
-- 
John Hubbard
NVIDIA

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ