All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] staging: kpc2000: kpc_dma: Few clean up and Convert to pin_user_pages()
@ 2020-06-17  2:27 Souptick Joarder
  2020-06-17  2:27 ` [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages Souptick Joarder
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Souptick Joarder @ 2020-06-17  2:27 UTC (permalink / raw)
  To: gregkh, jane.pnx9, pakki001, ldufour, harshjain32, simon, walken
  Cc: devel, linux-kernel, Souptick Joarder

This series contains few clean up, minor bug fixes and
Convert get_user_pages() to pin_user_pages().

I'm compile tested this, but unable to run-time test,
so any testing help is much appriciated.

Souptick Joarder (4):
  staging: kpc2000: Unpin partial pinned pages
  staging: kpc2000: kpc_dma: Convert set_page_dirty() -->    
    set_page_dirty_lock()
  staging: kpc2000: kpc_dma: Convert get_user_pages() -->
    pin_user_pages()
  staging: kpc2000: kpc_dma: Remove excess goto statement

 drivers/staging/kpc2000/kpc_dma/fileops.c | 33 ++++++++++++++-----------------
 1 file changed, 15 insertions(+), 18 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages
  2020-06-17  2:27 [PATCH 0/4] staging: kpc2000: kpc_dma: Few clean up and Convert to pin_user_pages() Souptick Joarder
@ 2020-06-17  2:27 ` Souptick Joarder
  2020-06-17 11:13   ` Dan Carpenter
  2020-06-17  2:27 ` [PATCH 2/4] staging: kpc2000: kpc_dma: Convert set_page_dirty() --> set_page_dirty_lock() Souptick Joarder
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Souptick Joarder @ 2020-06-17  2:27 UTC (permalink / raw)
  To: gregkh, jane.pnx9, pakki001, ldufour, harshjain32, simon, walken
  Cc: devel, linux-kernel, Souptick Joarder, John Hubbard,
	Bharath Vedartham, Dan Carpenter

There is a bug, when get_user_pages() failed but partially pinned
pages are not unpinned. Fixed it.

Also, int is more appropriate type for rv. Changed it.

Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Bharath Vedartham <linux.bhar@gmail.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
---
 drivers/staging/kpc2000/kpc_dma/fileops.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
index 8975346..b136353 100644
--- a/drivers/staging/kpc2000/kpc_dma/fileops.c
+++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
@@ -35,7 +35,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
 			    unsigned long iov_base, size_t iov_len)
 {
 	unsigned int i = 0;
-	long rv = 0;
+	int rv = 0;
 	struct kpc_dma_device *ldev;
 	struct aio_cb_data *acd;
 	DECLARE_COMPLETION_ONSTACK(done);
@@ -193,6 +193,10 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
 		put_page(acd->user_pages[i]);
 
  err_get_user_pages:
+	if (rv > 0) {
+		for (i = 0; i < rv; i++)
+			put_pages(acd->user_pages[i])
+	}
 	kfree(acd->user_pages);
  err_alloc_userpages:
 	kfree(acd);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/4] staging: kpc2000: kpc_dma: Convert set_page_dirty() --> set_page_dirty_lock()
  2020-06-17  2:27 [PATCH 0/4] staging: kpc2000: kpc_dma: Few clean up and Convert to pin_user_pages() Souptick Joarder
  2020-06-17  2:27 ` [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages Souptick Joarder
@ 2020-06-17  2:27 ` Souptick Joarder
  2020-06-27 17:51   ` Souptick Joarder
  2020-06-17  2:27 ` [PATCH 3/4] staging: kpc2000: kpc_dma: Convert get_user_pages() --> pin_user_pages() Souptick Joarder
  2020-06-17  2:27 ` [PATCH 4/4] staging: kpc2000: kpc_dma: Remove excess goto statement Souptick Joarder
  3 siblings, 1 reply; 11+ messages in thread
From: Souptick Joarder @ 2020-06-17  2:27 UTC (permalink / raw)
  To: gregkh, jane.pnx9, pakki001, ldufour, harshjain32, simon, walken
  Cc: devel, linux-kernel, Souptick Joarder, Dan Carpenter,
	Bharath Vedartham

First, convert set_page_dirty() to set_page_dirty_lock()

Second, there is an interval in there after set_page_dirty() and
before put_page(), in which the device could be running and setting
pages dirty. Moving set_page_dirty_lock() after dma_unmap_sg().

Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
Suggested-by: John Hubbard <jhubbard@nvidia.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Bharath Vedartham <linux.bhar@gmail.com>
---
 drivers/staging/kpc2000/kpc_dma/fileops.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
index b136353..bcce86c 100644
--- a/drivers/staging/kpc2000/kpc_dma/fileops.c
+++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
@@ -214,13 +214,13 @@ void  transfer_complete_cb(struct aio_cb_data *acd, size_t xfr_count, u32 flags)
 	BUG_ON(!acd->ldev);
 	BUG_ON(!acd->ldev->pldev);
 
+	dma_unmap_sg(&acd->ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, acd->ldev->dir);
+
 	for (i = 0 ; i < acd->page_count ; i++) {
 		if (!PageReserved(acd->user_pages[i]))
-			set_page_dirty(acd->user_pages[i]);
+			set_page_dirty_lock(acd->user_pages[i]);
 	}
 
-	dma_unmap_sg(&acd->ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, acd->ldev->dir);
-
 	for (i = 0 ; i < acd->page_count ; i++)
 		put_page(acd->user_pages[i]);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/4] staging: kpc2000: kpc_dma: Convert get_user_pages() --> pin_user_pages()
  2020-06-17  2:27 [PATCH 0/4] staging: kpc2000: kpc_dma: Few clean up and Convert to pin_user_pages() Souptick Joarder
  2020-06-17  2:27 ` [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages Souptick Joarder
  2020-06-17  2:27 ` [PATCH 2/4] staging: kpc2000: kpc_dma: Convert set_page_dirty() --> set_page_dirty_lock() Souptick Joarder
@ 2020-06-17  2:27 ` Souptick Joarder
  2020-06-17  2:27 ` [PATCH 4/4] staging: kpc2000: kpc_dma: Remove excess goto statement Souptick Joarder
  3 siblings, 0 replies; 11+ messages in thread
From: Souptick Joarder @ 2020-06-17  2:27 UTC (permalink / raw)
  To: gregkh, jane.pnx9, pakki001, ldufour, harshjain32, simon, walken
  Cc: devel, linux-kernel, Souptick Joarder, John Hubbard,
	Bharath Vedartham, Dan Carpenter

In 2019, we introduced pin_user_pages*() and now we are converting
get_user_pages*() to the new API as appropriate. [1] & [2] could
be referred for more information.

[1] Documentation/core-api/pin_user_pages.rst

[2] "Explicit pinning of user-space pages":
        https://lwn.net/Articles/807108/

Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Bharath Vedartham <linux.bhar@gmail.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
---
 drivers/staging/kpc2000/kpc_dma/fileops.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
index bcce86c..1f5ab81 100644
--- a/drivers/staging/kpc2000/kpc_dma/fileops.c
+++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
@@ -76,10 +76,10 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
 
 	// Lock the user buffer pages in memory, and hold on to the page pointers (for the sglist)
 	mmap_read_lock(current->mm);      /*  get memory map semaphore */
-	rv = get_user_pages(iov_base, acd->page_count, FOLL_TOUCH | FOLL_WRITE | FOLL_GET, acd->user_pages, NULL);
+	rv = pin_user_pages(iov_base, acd->page_count, FOLL_TOUCH | FOLL_WRITE, acd->user_pages, NULL);
 	mmap_read_unlock(current->mm);        /*  release the semaphore */
 	if (rv != acd->page_count) {
-		dev_err(&priv->ldev->pldev->dev, "Couldn't get_user_pages (%ld)\n", rv);
+		dev_err(&priv->ldev->pldev->dev, "Couldn't pin_user_pages (%ld)\n", rv);
 		goto err_get_user_pages;
 	}
 
@@ -189,14 +189,11 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
 	sg_free_table(&acd->sgt);
  err_dma_map_sg:
  err_alloc_sg_table:
-	for (i = 0 ; i < acd->page_count ; i++)
-		put_page(acd->user_pages[i]);
+	unpin_user_pages(acd->user_pages, acd->page_count);
 
  err_get_user_pages:
-	if (rv > 0) {
-		for (i = 0; i < rv; i++)
-			put_pages(acd->user_pages[i])
-	}
+	if (rv > 0)
+		unpin_user_pages(acd->user_pages, rv);
 	kfree(acd->user_pages);
  err_alloc_userpages:
 	kfree(acd);
@@ -221,8 +218,7 @@ void  transfer_complete_cb(struct aio_cb_data *acd, size_t xfr_count, u32 flags)
 			set_page_dirty_lock(acd->user_pages[i]);
 	}
 
-	for (i = 0 ; i < acd->page_count ; i++)
-		put_page(acd->user_pages[i]);
+	unpin_user_pages(acd->user_pages, acd->page_count);
 
 	sg_free_table(&acd->sgt);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/4] staging: kpc2000: kpc_dma: Remove excess goto statement
  2020-06-17  2:27 [PATCH 0/4] staging: kpc2000: kpc_dma: Few clean up and Convert to pin_user_pages() Souptick Joarder
                   ` (2 preceding siblings ...)
  2020-06-17  2:27 ` [PATCH 3/4] staging: kpc2000: kpc_dma: Convert get_user_pages() --> pin_user_pages() Souptick Joarder
@ 2020-06-17  2:27 ` Souptick Joarder
  3 siblings, 0 replies; 11+ messages in thread
From: Souptick Joarder @ 2020-06-17  2:27 UTC (permalink / raw)
  To: gregkh, jane.pnx9, pakki001, ldufour, harshjain32, simon, walken
  Cc: devel, linux-kernel, Souptick Joarder, Dan Carpenter,
	John Hubbard

As 3 goto level referring to same common code, those can be
accomodated with a single goto level and renameing it to
unpin_user_pages.

Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: John Hubbard <jhubbard@nvidia.com>
---
 drivers/staging/kpc2000/kpc_dma/fileops.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
index 1f5ab81..b0fcde5 100644
--- a/drivers/staging/kpc2000/kpc_dma/fileops.c
+++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
@@ -35,7 +35,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
 			    unsigned long iov_base, size_t iov_len)
 {
 	unsigned int i = 0;
-	int rv = 0;
+	int rv = 0, nr_pages = 0;
 	struct kpc_dma_device *ldev;
 	struct aio_cb_data *acd;
 	DECLARE_COMPLETION_ONSTACK(done);
@@ -79,22 +79,23 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
 	rv = pin_user_pages(iov_base, acd->page_count, FOLL_TOUCH | FOLL_WRITE, acd->user_pages, NULL);
 	mmap_read_unlock(current->mm);        /*  release the semaphore */
 	if (rv != acd->page_count) {
+		nr_pages = rv;
 		dev_err(&priv->ldev->pldev->dev, "Couldn't pin_user_pages (%ld)\n", rv);
-		goto err_get_user_pages;
+		goto unpin_user_pages;
 	}
-
+	nr_pages = acd->page_count;
 	// Allocate and setup the sg_table (scatterlist entries)
 	rv = sg_alloc_table_from_pages(&acd->sgt, acd->user_pages, acd->page_count, iov_base & (PAGE_SIZE - 1), iov_len, GFP_KERNEL);
 	if (rv) {
 		dev_err(&priv->ldev->pldev->dev, "Couldn't alloc sg_table (%ld)\n", rv);
-		goto err_alloc_sg_table;
+		goto unpin_user_pages;
 	}
 
 	// Setup the DMA mapping for all the sg entries
 	acd->mapped_entry_count = dma_map_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir);
 	if (acd->mapped_entry_count <= 0) {
 		dev_err(&priv->ldev->pldev->dev, "Couldn't dma_map_sg (%d)\n", acd->mapped_entry_count);
-		goto err_dma_map_sg;
+		goto unpin_user_pages;
 	}
 
 	// Calculate how many descriptors are actually needed for this transfer.
@@ -187,13 +188,9 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
 	unlock_engine(ldev);
 	dma_unmap_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir);
 	sg_free_table(&acd->sgt);
- err_dma_map_sg:
- err_alloc_sg_table:
-	unpin_user_pages(acd->user_pages, acd->page_count);
-
- err_get_user_pages:
-	if (rv > 0)
-		unpin_user_pages(acd->user_pages, rv);
+ unpin_user_pages:
+	if (nr_pages > 0)
+		unpin_user_pages(acd->user_pages, nr_pages);
 	kfree(acd->user_pages);
  err_alloc_userpages:
 	kfree(acd);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages
  2020-06-17  2:27 ` [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages Souptick Joarder
@ 2020-06-17 11:13   ` Dan Carpenter
  2020-06-17 17:43     ` Souptick Joarder
  0 siblings, 1 reply; 11+ messages in thread
From: Dan Carpenter @ 2020-06-17 11:13 UTC (permalink / raw)
  To: Souptick Joarder
  Cc: gregkh, jane.pnx9, pakki001, ldufour, harshjain32, simon, walken,
	devel, linux-kernel, John Hubbard, Bharath Vedartham

On Wed, Jun 17, 2020 at 07:57:20AM +0530, Souptick Joarder wrote:
> There is a bug, when get_user_pages() failed but partially pinned
> pages are not unpinned. Fixed it.
> 
> Also, int is more appropriate type for rv. Changed it.
> 
> Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
> Cc: John Hubbard <jhubbard@nvidia.com>
> Cc: Bharath Vedartham <linux.bhar@gmail.com>
> Cc: Dan Carpenter <dan.carpenter@oracle.com>
> ---
>  drivers/staging/kpc2000/kpc_dma/fileops.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
> index 8975346..b136353 100644
> --- a/drivers/staging/kpc2000/kpc_dma/fileops.c
> +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
> @@ -35,7 +35,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
>  			    unsigned long iov_base, size_t iov_len)
>  {
>  	unsigned int i = 0;
> -	long rv = 0;
> +	int rv = 0;
>  	struct kpc_dma_device *ldev;
>  	struct aio_cb_data *acd;
>  	DECLARE_COMPLETION_ONSTACK(done);
> @@ -193,6 +193,10 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
>  		put_page(acd->user_pages[i]);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>  
>   err_get_user_pages:
> +	if (rv > 0) {
> +		for (i = 0; i < rv; i++)
> +			put_pages(acd->user_pages[i])
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> +	}

This isn't a complete fix.  "rv" is the negative error code but here we
are returning a positive value on this path.  Also it's ugly to have
same put_page() loop repeated twice.

It would be better to write it like this:

	rv = get_user_pages(iov_base, acd->page_count, FOLL_TOUCH | FOLL_WRITE | FOLL_GET, acd->user_pages, NULL);
	mmap_read_unlock(current->mm);        /*  release the semaphore */
	if (rv < 0)
		goto free_pages;
	if (rv != acd->page_count) {
		acd->page_count = rv;
		rv = -EFAULT;
		goto put_pages;
	}

	...

put_pages:
	for (i = 0 ; i < acd->page_count ; i++)
		put_pages(acd->user_pages[i]);
free_pages:
	kfree(acd->user_pages);

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages
  2020-06-17 11:13   ` Dan Carpenter
@ 2020-06-17 17:43     ` Souptick Joarder
  2020-06-17 17:59       ` Dan Carpenter
  0 siblings, 1 reply; 11+ messages in thread
From: Souptick Joarder @ 2020-06-17 17:43 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Greg KH, jane.pnx9, pakki001, ldufour, harshjain32,
	Simon Sandström, Michel Lespinasse,
	open list:ANDROID DRIVERS, linux-kernel, John Hubbard,
	Bharath Vedartham

On Wed, Jun 17, 2020 at 4:43 PM Dan Carpenter <dan.carpenter@oracle.com> wrote:
>
> On Wed, Jun 17, 2020 at 07:57:20AM +0530, Souptick Joarder wrote:
> > There is a bug, when get_user_pages() failed but partially pinned
> > pages are not unpinned. Fixed it.
> >
> > Also, int is more appropriate type for rv. Changed it.
> >
> > Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
> > Cc: John Hubbard <jhubbard@nvidia.com>
> > Cc: Bharath Vedartham <linux.bhar@gmail.com>
> > Cc: Dan Carpenter <dan.carpenter@oracle.com>
> > ---
> >  drivers/staging/kpc2000/kpc_dma/fileops.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
> > index 8975346..b136353 100644
> > --- a/drivers/staging/kpc2000/kpc_dma/fileops.c
> > +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
> > @@ -35,7 +35,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
> >                           unsigned long iov_base, size_t iov_len)
> >  {
> >       unsigned int i = 0;
> > -     long rv = 0;
> > +     int rv = 0;
> >       struct kpc_dma_device *ldev;
> >       struct aio_cb_data *acd;
> >       DECLARE_COMPLETION_ONSTACK(done);
> > @@ -193,6 +193,10 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
> >               put_page(acd->user_pages[i]);
>                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >
> >   err_get_user_pages:
> > +     if (rv > 0) {
> > +             for (i = 0; i < rv; i++)
> > +                     put_pages(acd->user_pages[i])
>                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> > +     }
>
> This isn't a complete fix.  "rv" is the negative error code but here we
> are returning a positive value on this path.

In case of error of get_user_pages(), it will return -errno, 0 and 3rd one is
(rv > 0 && rv != acd->page_count). When rv is -errno or 0 there is no need
to call put_pages() in error path. But for 3rd case partially mapped pages
need to unpin.

Correct me if I am missing anything.

>Also it's ugly to have
> same put_page() loop repeated twice.

Yes, I agree, but these are intermediate steps. Patch [4/4] of this series
finally did the same.

>
> It would be better to write it like this:
>
>         rv = get_user_pages(iov_base, acd->page_count, FOLL_TOUCH | FOLL_WRITE | FOLL_GET, acd->user_pages, NULL);
>         mmap_read_unlock(current->mm);        /*  release the semaphore */
>         if (rv < 0)
>                 goto free_pages;
>         if (rv != acd->page_count) {
>                 acd->page_count = rv;
>                 rv = -EFAULT;
>                 goto put_pages;
>         }
>
>         ...
>
> put_pages:
>         for (i = 0 ; i < acd->page_count ; i++)
>                 put_pages(acd->user_pages[i]);
> free_pages:
>         kfree(acd->user_pages);
>
> regards,
> dan carpenter
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages
  2020-06-17 17:43     ` Souptick Joarder
@ 2020-06-17 17:59       ` Dan Carpenter
  2020-06-17 19:29         ` Souptick Joarder
  0 siblings, 1 reply; 11+ messages in thread
From: Dan Carpenter @ 2020-06-17 17:59 UTC (permalink / raw)
  To: Souptick Joarder
  Cc: open list:ANDROID DRIVERS, Bharath Vedartham, harshjain32,
	John Hubbard, Greg KH, pakki001, linux-kernel,
	Simon Sandström, ldufour, Michel Lespinasse, jane.pnx9

On Wed, Jun 17, 2020 at 11:13:32PM +0530, Souptick Joarder wrote:
> On Wed, Jun 17, 2020 at 4:43 PM Dan Carpenter <dan.carpenter@oracle.com> wrote:
> >
> > On Wed, Jun 17, 2020 at 07:57:20AM +0530, Souptick Joarder wrote:
> > > There is a bug, when get_user_pages() failed but partially pinned
> > > pages are not unpinned. Fixed it.
> > >
> > > Also, int is more appropriate type for rv. Changed it.
> > >
> > > Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
> > > Cc: John Hubbard <jhubbard@nvidia.com>
> > > Cc: Bharath Vedartham <linux.bhar@gmail.com>
> > > Cc: Dan Carpenter <dan.carpenter@oracle.com>
> > > ---
> > >  drivers/staging/kpc2000/kpc_dma/fileops.c | 6 +++++-
> > >  1 file changed, 5 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
> > > index 8975346..b136353 100644
> > > --- a/drivers/staging/kpc2000/kpc_dma/fileops.c
> > > +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
> > > @@ -35,7 +35,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
> > >                           unsigned long iov_base, size_t iov_len)
> > >  {
> > >       unsigned int i = 0;
> > > -     long rv = 0;
> > > +     int rv = 0;
> > >       struct kpc_dma_device *ldev;
> > >       struct aio_cb_data *acd;
> > >       DECLARE_COMPLETION_ONSTACK(done);
> > > @@ -193,6 +193,10 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
> > >               put_page(acd->user_pages[i]);
> >                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > >
> > >   err_get_user_pages:
> > > +     if (rv > 0) {
> > > +             for (i = 0; i < rv; i++)
> > > +                     put_pages(acd->user_pages[i])
> >                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >
> > > +     }
> >
> > This isn't a complete fix.  "rv" is the negative error code but here we
> > are returning a positive value on this path.
> 
> In case of error of get_user_pages(), it will return -errno, 0 and 3rd one is
> (rv > 0 && rv != acd->page_count). When rv is -errno or 0 there is no need
> to call put_pages() in error path. But for 3rd case partially mapped pages
> need to unpin.
> 
> Correct me if I am missing anything.
>

   182                  kfree(acd);
   183          }
   184          return rv;
   185  
   186   err_descr_too_many:
   187          unlock_engine(ldev);
   188          dma_unmap_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir);
   189          sg_free_table(&acd->sgt);
   190   err_dma_map_sg:
   191   err_alloc_sg_table:
   192          for (i = 0 ; i < acd->page_count ; i++)
   193                  put_page(acd->user_pages[i]);
   194  
   195   err_get_user_pages:
   196          if (rv > 0) {
                    ^^^^^^
"rv" is positive.

   197                  for (i = 0; i < rv; i++)
   198                          put_pages(acd->user_pages[i])
   199          }
   200          kfree(acd->user_pages);
   201   err_alloc_userpages:
   202          kfree(acd);
   203          dev_dbg(&priv->ldev->pldev->dev, "%s returning with error %ld\n", __func__, rv);
   204          return rv;
                       ^^
"rv" is still positive but it should be -EFAULT.

   205  }

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages
  2020-06-17 17:59       ` Dan Carpenter
@ 2020-06-17 19:29         ` Souptick Joarder
  2020-06-18 10:50           ` Dan Carpenter
  0 siblings, 1 reply; 11+ messages in thread
From: Souptick Joarder @ 2020-06-17 19:29 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: open list:ANDROID DRIVERS, Bharath Vedartham, harshjain32,
	John Hubbard, Greg KH, pakki001, linux-kernel,
	Simon Sandström, ldufour, Michel Lespinasse, jane.pnx9

On Wed, Jun 17, 2020 at 11:29 PM Dan Carpenter <dan.carpenter@oracle.com> wrote:
>
> On Wed, Jun 17, 2020 at 11:13:32PM +0530, Souptick Joarder wrote:
> > On Wed, Jun 17, 2020 at 4:43 PM Dan Carpenter <dan.carpenter@oracle.com> wrote:
> > >
> > > On Wed, Jun 17, 2020 at 07:57:20AM +0530, Souptick Joarder wrote:
> > > > There is a bug, when get_user_pages() failed but partially pinned
> > > > pages are not unpinned. Fixed it.
> > > >
> > > > Also, int is more appropriate type for rv. Changed it.
> > > >
> > > > Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
> > > > Cc: John Hubbard <jhubbard@nvidia.com>
> > > > Cc: Bharath Vedartham <linux.bhar@gmail.com>
> > > > Cc: Dan Carpenter <dan.carpenter@oracle.com>
> > > > ---
> > > >  drivers/staging/kpc2000/kpc_dma/fileops.c | 6 +++++-
> > > >  1 file changed, 5 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
> > > > index 8975346..b136353 100644
> > > > --- a/drivers/staging/kpc2000/kpc_dma/fileops.c
> > > > +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
> > > > @@ -35,7 +35,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
> > > >                           unsigned long iov_base, size_t iov_len)
> > > >  {
> > > >       unsigned int i = 0;
> > > > -     long rv = 0;
> > > > +     int rv = 0;
> > > >       struct kpc_dma_device *ldev;
> > > >       struct aio_cb_data *acd;
> > > >       DECLARE_COMPLETION_ONSTACK(done);
> > > > @@ -193,6 +193,10 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
> > > >               put_page(acd->user_pages[i]);
> > >                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > >
> > > >   err_get_user_pages:
> > > > +     if (rv > 0) {
> > > > +             for (i = 0; i < rv; i++)
> > > > +                     put_pages(acd->user_pages[i])
> > >                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > >
> > > > +     }
> > >
> > > This isn't a complete fix.  "rv" is the negative error code but here we
> > > are returning a positive value on this path.
> >
> > In case of error of get_user_pages(), it will return -errno, 0 and 3rd one is
> > (rv > 0 && rv != acd->page_count). When rv is -errno or 0 there is no need
> > to call put_pages() in error path. But for 3rd case partially mapped pages
> > need to unpin.
> >
> > Correct me if I am missing anything.
> >
>
>    182                  kfree(acd);
>    183          }
>    184          return rv;
>    185
>    186   err_descr_too_many:
>    187          unlock_engine(ldev);
>    188          dma_unmap_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir);
>    189          sg_free_table(&acd->sgt);
>    190   err_dma_map_sg:
>    191   err_alloc_sg_table:
>    192          for (i = 0 ; i < acd->page_count ; i++)
>    193                  put_page(acd->user_pages[i]);
>    194
>    195   err_get_user_pages:
>    196          if (rv > 0) {
>                     ^^^^^^
> "rv" is positive.
>
>    197                  for (i = 0; i < rv; i++)
>    198                          put_pages(acd->user_pages[i])
>    199          }
>    200          kfree(acd->user_pages);
>    201   err_alloc_userpages:
>    202          kfree(acd);
>    203          dev_dbg(&priv->ldev->pldev->dev, "%s returning with error %ld\n", __func__, rv);
>    204          return rv;
>                        ^^
> "rv" is still positive but it should be -EFAULT.
>

Ahh,  my mistake. Will correct it in v2.
Do other patches in the series looks good ?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages
  2020-06-17 19:29         ` Souptick Joarder
@ 2020-06-18 10:50           ` Dan Carpenter
  0 siblings, 0 replies; 11+ messages in thread
From: Dan Carpenter @ 2020-06-18 10:50 UTC (permalink / raw)
  To: Souptick Joarder
  Cc: open list:ANDROID DRIVERS, Bharath Vedartham, harshjain32,
	John Hubbard, Greg KH, Simon Sandström, linux-kernel,
	pakki001, ldufour, Michel Lespinasse, jane.pnx9

On Thu, Jun 18, 2020 at 12:59:57AM +0530, Souptick Joarder wrote:
> On Wed, Jun 17, 2020 at 11:29 PM Dan Carpenter <dan.carpenter@oracle.com> wrote:
> >
> > On Wed, Jun 17, 2020 at 11:13:32PM +0530, Souptick Joarder wrote:
> > > On Wed, Jun 17, 2020 at 4:43 PM Dan Carpenter <dan.carpenter@oracle.com> wrote:
> > > >
> > > > On Wed, Jun 17, 2020 at 07:57:20AM +0530, Souptick Joarder wrote:
> > > > > There is a bug, when get_user_pages() failed but partially pinned
> > > > > pages are not unpinned. Fixed it.
> > > > >
> > > > > Also, int is more appropriate type for rv. Changed it.
> > > > >
> > > > > Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
> > > > > Cc: John Hubbard <jhubbard@nvidia.com>
> > > > > Cc: Bharath Vedartham <linux.bhar@gmail.com>
> > > > > Cc: Dan Carpenter <dan.carpenter@oracle.com>
> > > > > ---
> > > > >  drivers/staging/kpc2000/kpc_dma/fileops.c | 6 +++++-
> > > > >  1 file changed, 5 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
> > > > > index 8975346..b136353 100644
> > > > > --- a/drivers/staging/kpc2000/kpc_dma/fileops.c
> > > > > +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
> > > > > @@ -35,7 +35,7 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
> > > > >                           unsigned long iov_base, size_t iov_len)
> > > > >  {
> > > > >       unsigned int i = 0;
> > > > > -     long rv = 0;
> > > > > +     int rv = 0;
> > > > >       struct kpc_dma_device *ldev;
> > > > >       struct aio_cb_data *acd;
> > > > >       DECLARE_COMPLETION_ONSTACK(done);
> > > > > @@ -193,6 +193,10 @@ static int kpc_dma_transfer(struct dev_private_data *priv,
> > > > >               put_page(acd->user_pages[i]);
> > > >                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > > >
> > > > >   err_get_user_pages:
> > > > > +     if (rv > 0) {
> > > > > +             for (i = 0; i < rv; i++)
> > > > > +                     put_pages(acd->user_pages[i])
> > > >                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > >
> > > > > +     }
> > > >
> > > > This isn't a complete fix.  "rv" is the negative error code but here we
> > > > are returning a positive value on this path.
> > >
> > > In case of error of get_user_pages(), it will return -errno, 0 and 3rd one is
> > > (rv > 0 && rv != acd->page_count). When rv is -errno or 0 there is no need
> > > to call put_pages() in error path. But for 3rd case partially mapped pages
> > > need to unpin.
> > >
> > > Correct me if I am missing anything.
> > >
> >
> >    182                  kfree(acd);
> >    183          }
> >    184          return rv;
> >    185
> >    186   err_descr_too_many:
> >    187          unlock_engine(ldev);
> >    188          dma_unmap_sg(&ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, ldev->dir);
> >    189          sg_free_table(&acd->sgt);
> >    190   err_dma_map_sg:
> >    191   err_alloc_sg_table:
> >    192          for (i = 0 ; i < acd->page_count ; i++)
> >    193                  put_page(acd->user_pages[i]);
> >    194
> >    195   err_get_user_pages:
> >    196          if (rv > 0) {
> >                     ^^^^^^
> > "rv" is positive.
> >
> >    197                  for (i = 0; i < rv; i++)
> >    198                          put_pages(acd->user_pages[i])
> >    199          }
> >    200          kfree(acd->user_pages);
> >    201   err_alloc_userpages:
> >    202          kfree(acd);
> >    203          dev_dbg(&priv->ldev->pldev->dev, "%s returning with error %ld\n", __func__, rv);
> >    204          return rv;
> >                        ^^
> > "rv" is still positive but it should be -EFAULT.
> >
> 
> Ahh,  my mistake. Will correct it in v2.
> Do other patches in the series looks good ?

The others will have to be re-worked if you change patch 1/4, especially
patch 4/4.  But otherwise it seems okay with me.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] staging: kpc2000: kpc_dma: Convert set_page_dirty() --> set_page_dirty_lock()
  2020-06-17  2:27 ` [PATCH 2/4] staging: kpc2000: kpc_dma: Convert set_page_dirty() --> set_page_dirty_lock() Souptick Joarder
@ 2020-06-27 17:51   ` Souptick Joarder
  0 siblings, 0 replies; 11+ messages in thread
From: Souptick Joarder @ 2020-06-27 17:51 UTC (permalink / raw)
  To: Greg KH, jane.pnx9, pakki001, ldufour, harshjain32,
	Simon Sandström, Michel Lespinasse
  Cc: open list:ANDROID DRIVERS, linux-kernel, Dan Carpenter,
	Bharath Vedartham

On Wed, Jun 17, 2020 at 7:50 AM Souptick Joarder <jrdr.linux@gmail.com> wrote:
>
> First, convert set_page_dirty() to set_page_dirty_lock()
>
> Second, there is an interval in there after set_page_dirty() and
> before put_page(), in which the device could be running and setting
> pages dirty. Moving set_page_dirty_lock() after dma_unmap_sg().
>
> Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
> Suggested-by: John Hubbard <jhubbard@nvidia.com>
> Cc: Dan Carpenter <dan.carpenter@oracle.com>
> Cc: Bharath Vedartham <linux.bhar@gmail.com>
> ---
>  drivers/staging/kpc2000/kpc_dma/fileops.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c b/drivers/staging/kpc2000/kpc_dma/fileops.c
> index b136353..bcce86c 100644
> --- a/drivers/staging/kpc2000/kpc_dma/fileops.c
> +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
> @@ -214,13 +214,13 @@ void  transfer_complete_cb(struct aio_cb_data *acd, size_t xfr_count, u32 flags)
>         BUG_ON(!acd->ldev);
>         BUG_ON(!acd->ldev->pldev);
>
> +       dma_unmap_sg(&acd->ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, acd->ldev->dir);
> +
>         for (i = 0 ; i < acd->page_count ; i++) {
>                 if (!PageReserved(acd->user_pages[i]))

Question -> is PageReserved() used with specific purpose not PageDirty() ??

> -                       set_page_dirty(acd->user_pages[i]);
> +                       set_page_dirty_lock(acd->user_pages[i]);
>         }
>
> -       dma_unmap_sg(&acd->ldev->pldev->dev, acd->sgt.sgl, acd->sgt.nents, acd->ldev->dir);
> -
>         for (i = 0 ; i < acd->page_count ; i++)
>                 put_page(acd->user_pages[i]);
>
> --
> 1.9.1
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-06-27 17:43 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-06-17  2:27 [PATCH 0/4] staging: kpc2000: kpc_dma: Few clean up and Convert to pin_user_pages() Souptick Joarder
2020-06-17  2:27 ` [PATCH 1/4] staging: kpc2000: Unpin partial pinned pages Souptick Joarder
2020-06-17 11:13   ` Dan Carpenter
2020-06-17 17:43     ` Souptick Joarder
2020-06-17 17:59       ` Dan Carpenter
2020-06-17 19:29         ` Souptick Joarder
2020-06-18 10:50           ` Dan Carpenter
2020-06-17  2:27 ` [PATCH 2/4] staging: kpc2000: kpc_dma: Convert set_page_dirty() --> set_page_dirty_lock() Souptick Joarder
2020-06-27 17:51   ` Souptick Joarder
2020-06-17  2:27 ` [PATCH 3/4] staging: kpc2000: kpc_dma: Convert get_user_pages() --> pin_user_pages() Souptick Joarder
2020-06-17  2:27 ` [PATCH 4/4] staging: kpc2000: kpc_dma: Remove excess goto statement Souptick Joarder

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.