Since the lifetime of the uc_fw is virtually identical to the current
pinned range, simplify the setup to avoid using a swappable shmem file,
and just use an internal bo. The immediate advantage is in removing the
extra pin/unpin stages during init that are very difficult to balance
along error paths.

Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gem/i915_gem_internal.c | 43 +++++++++++++++++
 drivers/gpu/drm/i915/gem/i915_gem_object.h   |  4 +-
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c    | 51 --------------------
 drivers/gpu/drm/i915/gt/uc/intel_guc.c       | 12 ++---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c       | 12 ++---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c     | 30 +-----------
 6 files changed, 56 insertions(+), 96 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c 
b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index 9cfb0e41ff06..a8eb0eb27390 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -198,3 +198,46 @@ i915_gem_object_create_internal(struct drm_i915_private 
*i915,
 
        return obj;
 }
+
+/* Allocate a new GEM object and fill it with the supplied data */
+struct drm_i915_gem_object *
+i915_gem_object_create_from_data(struct drm_i915_private *i915,
+                                const void *data, resource_size_t size)
+{
+       struct drm_i915_gem_object *obj;
+       resource_size_t offset;
+       struct sgt_iter it;
+       struct page *page;
+       int err;
+
+       obj = i915_gem_object_create_internal(i915, round_up(size, PAGE_SIZE));
+       if (IS_ERR(obj))
+               return obj;
+
+       GEM_BUG_ON(obj->write_domain != I915_GEM_DOMAIN_CPU);
+
+       err = i915_gem_object_pin_pages(obj);
+       if (err)
+               goto err;
+
+       offset = 0;
+       for_each_sgt_page(page, it, obj->mm.pages) {
+               int len = min_t(typeof(size), size - offset, PAGE_SIZE);
+               void *ptr;
+
+               ptr = kmap(page);
+
+               memcpy(ptr, data + offset, len);
+               if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE))
+                       drm_clflush_virt_range(ptr, len);
+
+               kunmap(page);
+               offset += len;
+       }
+
+       return obj; /* keep pages pinned */
+
+err:
+       i915_gem_object_put(obj);
+       return ERR_PTR(err);
+}
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index a1eb7c0b23ac..994dd654b5c1 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -29,8 +29,8 @@ struct drm_i915_gem_object *
 i915_gem_object_create_shmem(struct drm_i915_private *i915,
                             resource_size_t size);
 struct drm_i915_gem_object *
-i915_gem_object_create_shmem_from_data(struct drm_i915_private *i915,
-                                      const void *data, resource_size_t size);
+i915_gem_object_create_from_data(struct drm_i915_private *i915,
+                                const void *data, resource_size_t size);
 
 extern const struct drm_i915_gem_object_ops i915_gem_shmem_ops;
 void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 4d69c3fc3439..0f4c8fc38bba 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -533,57 +533,6 @@ i915_gem_object_create_shmem(struct drm_i915_private *i915,
                                             size, 0);
 }
 
-/* Allocate a new GEM object and fill it with the supplied data */
-struct drm_i915_gem_object *
-i915_gem_object_create_shmem_from_data(struct drm_i915_private *dev_priv,
-                                      const void *data, resource_size_t size)
-{
-       struct drm_i915_gem_object *obj;
-       struct file *file;
-       resource_size_t offset;
-       int err;
-
-       obj = i915_gem_object_create_shmem(dev_priv, round_up(size, PAGE_SIZE));
-       if (IS_ERR(obj))
-               return obj;
-
-       GEM_BUG_ON(obj->write_domain != I915_GEM_DOMAIN_CPU);
-
-       file = obj->base.filp;
-       offset = 0;
-       do {
-               unsigned int len = min_t(typeof(size), size, PAGE_SIZE);
-               struct page *page;
-               void *pgdata, *vaddr;
-
-               err = pagecache_write_begin(file, file->f_mapping,
-                                           offset, len, 0,
-                                           &page, &pgdata);
-               if (err < 0)
-                       goto fail;
-
-               vaddr = kmap(page);
-               memcpy(vaddr, data, len);
-               kunmap(page);
-
-               err = pagecache_write_end(file, file->f_mapping,
-                                         offset, len, len,
-                                         page, pgdata);
-               if (err < 0)
-                       goto fail;
-
-               size -= len;
-               data += len;
-               offset += len;
-       } while (size);
-
-       return obj;
-
-fail:
-       i915_gem_object_put(obj);
-       return ERR_PTR(err);
-}
-
 static int init_shmem(struct intel_memory_region *mem)
 {
        int err;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 922a19635d20..b5639548b8fc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -334,13 +334,14 @@ int intel_guc_init(struct intel_guc *guc)
        struct intel_gt *gt = guc_to_gt(guc);
        int ret;
 
-       ret = intel_uc_fw_init(&guc->fw);
-       if (ret)
-               goto err_fetch;
+       /* This should happen before the load! */
+       GEM_BUG_ON(intel_uc_fw_is_loaded(&guc->fw));
+       if (!intel_uc_fw_is_available(&guc->fw))
+               return -ENOEXEC;
 
        ret = intel_guc_log_create(&guc->log);
        if (ret)
-               goto err_fw;
+               goto err_fetch;
 
        ret = intel_guc_ads_create(guc);
        if (ret)
@@ -375,8 +376,6 @@ int intel_guc_init(struct intel_guc *guc)
        intel_guc_ads_destroy(guc);
 err_log:
        intel_guc_log_destroy(&guc->log);
-err_fw:
-       intel_uc_fw_fini(&guc->fw);
 err_fetch:
        intel_uc_fw_cleanup_fetch(&guc->fw);
        DRM_DEV_DEBUG_DRIVER(gt->i915->drm.dev, "failed with %d\n", ret);
@@ -399,7 +398,6 @@ void intel_guc_fini(struct intel_guc *guc)
 
        intel_guc_ads_destroy(guc);
        intel_guc_log_destroy(&guc->log);
-       intel_uc_fw_fini(&guc->fw);
        intel_uc_fw_cleanup_fetch(&guc->fw);
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 32a069841c14..f0b555fb6dd2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -108,9 +108,10 @@ int intel_huc_init(struct intel_huc *huc)
        struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
        int err;
 
-       err = intel_uc_fw_init(&huc->fw);
-       if (err)
-               goto out;
+       /* This should happen before the load! */
+       GEM_BUG_ON(intel_uc_fw_is_loaded(&huc->fw));
+       if (!intel_uc_fw_is_available(&huc->fw))
+               return -ENOEXEC;
 
        /*
         * HuC firmware image is outside GuC accessible range.
@@ -119,12 +120,10 @@ int intel_huc_init(struct intel_huc *huc)
         */
        err = intel_huc_rsa_data_create(huc);
        if (err)
-               goto out_fini;
+               goto out;
 
        return 0;
 
-out_fini:
-       intel_uc_fw_fini(&huc->fw);
 out:
        intel_uc_fw_cleanup_fetch(&huc->fw);
        DRM_DEV_DEBUG_DRIVER(i915->drm.dev, "failed with %d\n", err);
@@ -137,7 +136,6 @@ void intel_huc_fini(struct intel_huc *huc)
                return;
 
        intel_huc_rsa_data_destroy(huc);
-       intel_uc_fw_fini(&huc->fw);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 4d02e06480e5..f19636d4bed7 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -364,7 +364,7 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
                }
        }
 
-       obj = i915_gem_object_create_shmem_from_data(i915, fw->data, fw->size);
+       obj = i915_gem_object_create_from_data(i915, fw->data, fw->size);
        if (IS_ERR(obj)) {
                err = PTR_ERR(obj);
                goto fail;
@@ -524,34 +524,6 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 
dst_offset, u32 dma_flags)
        return err;
 }
 
-int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
-{
-       int err;
-
-       /* this should happen before the load! */
-       GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw));
-
-       if (!intel_uc_fw_is_available(uc_fw))
-               return -ENOEXEC;
-
-       err = i915_gem_object_pin_pages(uc_fw->obj);
-       if (err) {
-               DRM_DEBUG_DRIVER("%s fw pin-pages err=%d\n",
-                                intel_uc_fw_type_repr(uc_fw->type), err);
-               intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_FAIL);
-       }
-
-       return err;
-}
-
-void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
-{
-       if (!intel_uc_fw_is_available(uc_fw))
-               return;
-
-       i915_gem_object_unpin_pages(uc_fw->obj);
-}
-
 /**
  * intel_uc_fw_cleanup_fetch - cleanup uC firmware
  * @uc_fw: uC firmware
-- 
2.24.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to