Avoid unlocking and putting device pages unless they were successfully
locked, and do not calculate migrated_pages on error paths.

Cc: Thomas Hellström <[email protected]>
Fixes: 75af93b3f5d0 ("drm/pagemap, drm/xe: Support destination migration over 
interconnect")
Signed-off-by: Matthew Brost <[email protected]>
---
 drivers/gpu/drm/drm_pagemap.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c
index ba099aa7c52f..aa43a8475100 100644
--- a/drivers/gpu/drm/drm_pagemap.c
+++ b/drivers/gpu/drm/drm_pagemap.c
@@ -582,7 +582,7 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem 
*devmem_allocation,
 
        err = ops->populate_devmem_pfn(devmem_allocation, npages, migrate.dst);
        if (err)
-               goto err_finalize;
+               goto err_aborted_migration;
 
        own_pages = 0;
 
@@ -621,8 +621,10 @@ int drm_pagemap_migrate_to_devmem(struct 
drm_pagemap_devmem *devmem_allocation,
                err = drm_pagemap_migrate_range(devmem_allocation, migrate.src, 
migrate.dst,
                                                pages, pagemap_addr, &last, 
&cur,
                                                mdetails);
-               if (err)
+               if (err) {
+                       npages = i + 1;
                        goto err_finalize;
+               }
        }
        cur.start = npages;
        cur.ops = NULL; /* Force migration */
@@ -646,7 +648,7 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem 
*devmem_allocation,
 err_aborted_migration:
        migrate_vma_pages(&migrate);
 
-       for (i = 0; i < npages;) {
+       for (i = 0; !err && i < npages;) {
                struct page *page = migrate_pfn_to_page(migrate.src[i]);
                unsigned long nr_pages = page ? 
NR_PAGES(folio_order(page_folio(page))) : 1;
 
-- 
2.34.1

Reply via email to