i915_timeline.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * SPDX-License-Identifier: MIT
  3. *
  4. * Copyright © 2016-2018 Intel Corporation
  5. */
  6. #include "i915_drv.h"
  7. #include "i915_timeline.h"
  8. #include "i915_syncmap.h"
  9. void i915_timeline_init(struct drm_i915_private *i915,
  10. struct i915_timeline *timeline,
  11. const char *name)
  12. {
  13. lockdep_assert_held(&i915->drm.struct_mutex);
  14. /*
  15. * Ideally we want a set of engines on a single leaf as we expect
  16. * to mostly be tracking synchronisation between engines. It is not
  17. * a huge issue if this is not the case, but we may want to mitigate
  18. * any page crossing penalties if they become an issue.
  19. */
  20. BUILD_BUG_ON(KSYNCMAP < I915_NUM_ENGINES);
  21. timeline->name = name;
  22. list_add(&timeline->link, &i915->gt.timelines);
  23. /* Called during early_init before we know how many engines there are */
  24. timeline->fence_context = dma_fence_context_alloc(1);
  25. spin_lock_init(&timeline->lock);
  26. init_request_active(&timeline->last_request, NULL);
  27. INIT_LIST_HEAD(&timeline->requests);
  28. i915_syncmap_init(&timeline->sync);
  29. }
  30. /**
  31. * i915_timelines_park - called when the driver idles
  32. * @i915: the drm_i915_private device
  33. *
  34. * When the driver is completely idle, we know that all of our sync points
  35. * have been signaled and our tracking is then entirely redundant. Any request
  36. * to wait upon an older sync point will be completed instantly as we know
  37. * the fence is signaled and therefore we will not even look them up in the
  38. * sync point map.
  39. */
  40. void i915_timelines_park(struct drm_i915_private *i915)
  41. {
  42. struct i915_timeline *timeline;
  43. lockdep_assert_held(&i915->drm.struct_mutex);
  44. list_for_each_entry(timeline, &i915->gt.timelines, link) {
  45. /*
  46. * All known fences are completed so we can scrap
  47. * the current sync point tracking and start afresh,
  48. * any attempt to wait upon a previous sync point
  49. * will be skipped as the fence was signaled.
  50. */
  51. i915_syncmap_free(&timeline->sync);
  52. }
  53. }
  54. void i915_timeline_fini(struct i915_timeline *timeline)
  55. {
  56. GEM_BUG_ON(!list_empty(&timeline->requests));
  57. i915_syncmap_free(&timeline->sync);
  58. list_del(&timeline->link);
  59. }
  60. struct i915_timeline *
  61. i915_timeline_create(struct drm_i915_private *i915, const char *name)
  62. {
  63. struct i915_timeline *timeline;
  64. timeline = kzalloc(sizeof(*timeline), GFP_KERNEL);
  65. if (!timeline)
  66. return ERR_PTR(-ENOMEM);
  67. i915_timeline_init(i915, timeline, name);
  68. kref_init(&timeline->kref);
  69. return timeline;
  70. }
  71. void __i915_timeline_free(struct kref *kref)
  72. {
  73. struct i915_timeline *timeline =
  74. container_of(kref, typeof(*timeline), kref);
  75. i915_timeline_fini(timeline);
  76. kfree(timeline);
  77. }
  78. #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
  79. #include "selftests/mock_timeline.c"
  80. #include "selftests/i915_timeline.c"
  81. #endif