staging: kpc2000: Convert put_page() to put_user_page*()
Subsystems (2)
PATCH v4 1/1 staging: kpc2000: Convert put_page() to put_user_page*()
For pages that were retained via get_user_pages*(), release those pages via the new put_user_page*() routines, instead of via put_page().
This is part a tree-wide conversion, as described in commit fc1d8e7cca2d ("mm: introduce put_user_page*(), placeholder versions").
---
Changes since v1
- Improved changelog by John's suggestion.
- Moved logic to dirty pages below sg_dma_unmap and removed PageReserved check.
Changes since v2
- Added back PageResevered check as suggested by John Hubbard.
Changes since v3
- Changed the changelog as suggested by John.
- Added John's Reviewed-By tag.
Changes since v4
- Rebased the patch on the staging tree.
- Improved commit log by fixing a line wrap.
--- drivers/staging/kpc2000/kpc_dma/fileops.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-)
drivers/staging/kpc2000/kpc_dma/fileops.c +6 -11
@@ -190,9 +190,7 @@ 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]); - } +put_user_pages (acd->user_pages, acd->page_count); err_get_user_pages:kfree (acd->user_pages); err_alloc_userpages:
@@ -211,16 +209,13 @@ void transfer_complete_cb(struct aio_cb_data *acd, size_t xfr_count, u32 flags)BUG_ON (acd->ldev ==NULL );BUG_ON (acd->ldev->pldev ==NULL ); -for (i =0 ; i < acd->page_count ; i++) { -if (!PageReserved (acd->user_pages[i])) { -set_page_dirty (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]); +for (i =0 ; i < acd->page_count; i++) { +if (!PageReserved (acd->user_pages[i])) +put_user_pages_dirty (&acd->user_pages[i],1 ); +else +put_user_page (acd->user_pages[i]); }sg_free_table (&acd->sgt);
Signature · 1 line
2.7.4
Quoted 6 lines · Bharath Vedartham
For pages that were retained via get_user_pages*(), release those pages via the new put_user_page*() routines, instead of via
put_page().This is part a tree-wide conversion, as described in commit
fc1d8e7cca2d("mm: introduce put_user_page*(), placeholder versions").
Hi Bharath,
If you like, I could re-post your patch here, modified slightly, as part of the next version of the miscellaneous call site conversion series [1].
As part of that, we should change this to use put_user_pages_dirty_lock() (see below).
Quoted 50 lines
Cc Ira Weiny <[email protected]>Cc John Hubbard <[email protected]>Cc Jérôme Glisse <[email protected]>Cc Greg Kroah-Hartman <[email protected]>Cc Matt Sickler <[email protected]>Reviewed-by John Hubbard <[email protected]>Signed-off-by Bharath Vedartham <[email protected]>---
Changes since v1
- Improved changelog by John's suggestion.
- Moved logic to dirty pages belowsg_dma_unmapand removed PageReserved check.
Changes since v2
- Added back PageResevered check as suggested by John Hubbard.
Changes since v3
- Changed the changelog as suggested by John.
- Added John's Reviewed-By tag.
Changes since v4
- Rebased the patch on the staging tree.
- Improved commit log by fixing a line wrap.--- drivers/staging/kpc2000/kpc_dma/fileops.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-)drivers/staging/kpc2000/kpc_dma/fileops.c +1
-6@@ -190,9 +190,7 @@ 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]); - } +put_user_pages (acd->user_pages, acd->page_count); err_get_user_pages:kfree (acd->user_pages); err_alloc_userpages:@@ -211,16 +209,13 @@ void transfer_complete_cb(struct aio_cb_data *acd, size_t xfr_count, u32 flags)BUG_ON (acd->ldev ==NULL );BUG_ON (acd->ldev->pldev ==NULL ); -for (i =0 ; i < acd->page_count ; i++) { -if (!PageReserved (acd->user_pages[i])) { -set_page_dirty (acd->user_pages[i]);
drivers/staging/kpc2000/kpc_dma/fileops.c void transfer_complete_cb(struct aio_cb_data *acd, size_t xfr_count, u32 flags) · line 216
Quoted 10 lines
drivers/staging/kpc2000/kpc_dma/fileops.c +3
-5- } - } -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]); +for (i =0 ; i < acd->page_count; i++) { +if (!PageReserved (acd->user_pages[i])) +put_user_pages_dirty (&acd->user_pages[i],1 );
This would change to:
put_user_pages_dirty_lock(&acd->user_pages[i], 1, true);
...and we'd add this blurb (this time with CH's name spelled properly) to the commit description:
Note that this effectively changes the code's behavior in qp_release_pages(): it now ultimately calls set_page_dirty_lock(), instead of set_page_dirty(). This is probably more accurate.
As Christoph Hellwig put it, "set_page_dirty() is only safe if we are dealing with a file backed page where we have reference on the inode it hangs off." [1]
[1] https://lore.kernel.org/r/[email protected]
Also, future: I don't know the driver well enough to say, but maybe "true" could be replaced by "acd->ldev->dir == DMA_FROM_DEVICE", there, but that would be a separate patch.
thanks,
Signature · 2 lines
John Hubbard NVIDIA
Quoted 6 lines
drivers/staging/kpc2000/kpc_dma/fileops.c +2
-0+else +put_user_page (acd->user_pages[i]); }sg_free_table (&acd->sgt);