Restore after shrinker backup always allocates on the pool's default
node, so a placement chosen with ttm_pool_alloc_node() is lost. The
internal restore path already uses __ttm_pool_alloc(), which takes a
nid; add ttm_tt_restore_node() to pass it through.

ttm_tt_restore() passes NUMA_NO_NODE, keeping current behaviour.

Signed-off-by: Himal Prasad Ghimiray <[email protected]>
---
 drivers/gpu/drm/ttm/ttm_pool.c          | 32 ++++++++++++++++++++++++-
 drivers/gpu/drm/ttm/ttm_pool_internal.h |  4 ++++
 drivers/gpu/drm/ttm/ttm_tt.c            | 20 ++++++++++++++--
 include/drm/ttm/ttm_tt.h                |  2 ++
 4 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index 54d2f6b5c229..2107dc6c69b3 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -962,6 +962,30 @@ EXPORT_SYMBOL(ttm_pool_alloc_node);
  */
 int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
                               const struct ttm_operation_ctx *ctx)
+{
+       return ttm_pool_restore_and_alloc_node(pool, tt, ctx, NUMA_NO_NODE);
+}
+EXPORT_SYMBOL(ttm_pool_restore_and_alloc);
+
+/**
+ * ttm_pool_restore_and_alloc_node - Fill a ttm_tt, restoring previously
+ * backed-up content, placing pages on a given node.
+ *
+ * @pool: ttm_pool to use
+ * @tt: ttm_tt object to fill
+ * @ctx: operation context
+ * @nid: NUMA node id to allocate the backing system pages from, or
+ * NUMA_NO_NODE to use the pool's default node (@ttm_pool.nid)
+ *
+ * Like ttm_pool_restore_and_alloc(), but allows the caller to keep the NUMA
+ * placement requested at ttm_pool_alloc_node() time across backup / restore.
+ *
+ * Returns: 0 on success, -EOPNOTSUPP if @nid is specified on a coherent/dma
+ * pool, negative error code otherwise.
+ */
+int ttm_pool_restore_and_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
+                                   const struct ttm_operation_ctx *ctx,
+                                   int nid)
 {
        struct ttm_pool_tt_restore *restore = tt->restore;
        struct ttm_pool_alloc_state alloc;
@@ -970,6 +994,12 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, 
struct ttm_tt *tt,
        if (WARN_ON(!ttm_tt_is_backed_up(tt)))
                return -EINVAL;
 
+       if (nid != NUMA_NO_NODE && ttm_pool_uses_dma_alloc(pool))
+               return -EOPNOTSUPP;
+
+       if (nid == NUMA_NO_NODE)
+               nid = ttm_pool_nid(pool);
+
        if (!restore) {
                gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;
 
@@ -1007,7 +1037,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, 
struct ttm_tt *tt,
                }
        }
 
-       return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore, 
ttm_pool_nid(pool));
+       return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore, nid);
 }
 
 /**
diff --git a/drivers/gpu/drm/ttm/ttm_pool_internal.h 
b/drivers/gpu/drm/ttm/ttm_pool_internal.h
index cbb17a2129fe..66ee0e57cdeb 100644
--- a/drivers/gpu/drm/ttm/ttm_pool_internal.h
+++ b/drivers/gpu/drm/ttm/ttm_pool_internal.h
@@ -22,6 +22,10 @@ static inline unsigned int ttm_pool_beneficial_order(struct 
ttm_pool *pool)
        return pool->alloc_flags & 0xff;
 }
 
+int ttm_pool_restore_and_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt,
+                                   const struct ttm_operation_ctx *ctx,
+                                   int nid);
+
 /*
  * Implemented in ttm_pool.c, used by ttm_backup.c. Returns true if a fault
  * should be injected mid-compound to test the reactive split-and-retry
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index b645a1818184..775219ae5367 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -298,7 +298,23 @@ long ttm_tt_backup(struct ttm_device *bdev, struct ttm_tt 
*tt,
 int ttm_tt_restore(struct ttm_device *bdev, struct ttm_tt *tt,
                   const struct ttm_operation_ctx *ctx)
 {
-       int ret = ttm_pool_restore_and_alloc(&bdev->pool, tt, ctx);
+       return ttm_tt_restore_node(bdev, tt, ctx, NUMA_NO_NODE);
+}
+EXPORT_SYMBOL(ttm_tt_restore);
+
+/**
+ * ttm_tt_restore_node - Restore a backed-up tt, placing pages on a given node
+ * @bdev: The TTM device.
+ * @tt: The struct ttm_tt to restore.
+ * @ctx: The operation context.
+ * @nid: NUMA node for the restored pages, or NUMA_NO_NODE for the pool 
default.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int ttm_tt_restore_node(struct ttm_device *bdev, struct ttm_tt *tt,
+                       const struct ttm_operation_ctx *ctx, int nid)
+{
+       int ret = ttm_pool_restore_and_alloc_node(&bdev->pool, tt, ctx, nid);
 
        if (ret)
                return ret;
@@ -307,7 +323,7 @@ int ttm_tt_restore(struct ttm_device *bdev, struct ttm_tt 
*tt,
 
        return 0;
 }
-EXPORT_SYMBOL(ttm_tt_restore);
+EXPORT_SYMBOL(ttm_tt_restore_node);
 
 /**
  * ttm_tt_swapout - swap out tt object
diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h
index 406437ad674b..7a75e22a7f70 100644
--- a/include/drm/ttm/ttm_tt.h
+++ b/include/drm/ttm/ttm_tt.h
@@ -297,6 +297,8 @@ long ttm_tt_backup(struct ttm_device *bdev, struct ttm_tt 
*tt,
 
 int ttm_tt_restore(struct ttm_device *bdev, struct ttm_tt *tt,
                   const struct ttm_operation_ctx *ctx);
+int ttm_tt_restore_node(struct ttm_device *bdev, struct ttm_tt *tt,
+                       const struct ttm_operation_ctx *ctx, int nid);
 
 int ttm_tt_setup_backup(struct ttm_tt *tt);
 
-- 
2.43.0

Reply via email to