On 7/15/19 2:47 PM, Matt Sickler wrote:
> It looks like Outlook is going to absolutely trash this email. Hopefully it
> comes through okay.
>
...
>>
>> Because this is a common pattern, and because the code here doesn't likely
>> need to set page dirty before the dma_unmap_sg call, I think the following
>> would be better (it's untested), instead of the above diff hunk:
>>
>> diff --git a/drivers/staging/kpc2000/kpc_dma/fileops.c
>> b/drivers/staging/kpc2000/kpc_dma/fileops.c
>> index 48ca88bc6b0b..d486f9866449 100644
>> --- a/drivers/staging/kpc2000/kpc_dma/fileops.c
>> +++ b/drivers/staging/kpc2000/kpc_dma/fileops.c
>> @@ -211,16 +211,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]);
>> + 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);
>
> I don't think I ever really knew the right way to do this.
>
> The changes Bharath suggested look okay to me. I'm not sure about the check
> for PageReserved(), though. At first glance it appears to be equivalent to
> what was there before, but maybe I should learn what that Reserved page flag
> really means.
> From [1], the only comment that seems applicable is
> * - MMIO/DMA pages. Some architectures don't allow to ioremap pages that are
> * not marked PG_reserved (as they might be in use by somebody else who does
> * not respect the caching strategy).
>
> These pages should be coming from anonymous (RAM, not file backed) memory in
> userspace. Sometimes it comes from hugepage backed memory, though I don't
> think that makes a difference. I should note that transfer_complete_cb
> handles both RAM to device and device to RAM DMAs, if that matters.
>
> [1]
> https://elixir.bootlin.com/linux/v5.2/source/include/linux/page-flags.h#L17
>
I agree: the PageReserved check looks unnecessary here, from my
outside-the-kpc_2000-team
perspective, anyway. Assuming that your analysis above is correct, you could
collapse that
whole think into just:
@@ -211,17 +209,8 @@ 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]);
- }
+ put_user_pages_dirty(&acd->user_pages[i], acd->page_count);
sg_free_table(&acd->sgt);
(Also, Matt, I failed to Cc: you on a semi-related cleanup that I just sent out
for this
driver, as long as I have your attention:
https://lore.kernel.org/r/[email protected]
)
thanks,
--
John Hubbard
NVIDIA
_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel