LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915 - i915_active.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 5 328 1.5 %
Date: 2022-04-01 14:17:54 Functions: 1 25 4.0 %
Branches: 1 140 0.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * SPDX-License-Identifier: MIT
       3                 :            :  *
       4                 :            :  * Copyright © 2019 Intel Corporation
       5                 :            :  */
       6                 :            : 
       7                 :            : #include <linux/debugobjects.h>
       8                 :            : 
       9                 :            : #include "gt/intel_context.h"
      10                 :            : #include "gt/intel_engine_pm.h"
      11                 :            : #include "gt/intel_ring.h"
      12                 :            : 
      13                 :            : #include "i915_drv.h"
      14                 :            : #include "i915_active.h"
      15                 :            : #include "i915_globals.h"
      16                 :            : 
      17                 :            : /*
      18                 :            :  * Active refs memory management
      19                 :            :  *
      20                 :            :  * To be more economical with memory, we reap all the i915_active trees as
      21                 :            :  * they idle (when we know the active requests are inactive) and allocate the
      22                 :            :  * nodes from a local slab cache to hopefully reduce the fragmentation.
      23                 :            :  */
      24                 :            : static struct i915_global_active {
      25                 :            :         struct i915_global base;
      26                 :            :         struct kmem_cache *slab_cache;
      27                 :            : } global;
      28                 :            : 
      29                 :            : struct active_node {
      30                 :            :         struct i915_active_fence base;
      31                 :            :         struct i915_active *ref;
      32                 :            :         struct rb_node node;
      33                 :            :         u64 timeline;
      34                 :            : };
      35                 :            : 
      36                 :            : static inline struct active_node *
      37                 :          0 : node_from_active(struct i915_active_fence *active)
      38                 :            : {
      39                 :          0 :         return container_of(active, struct active_node, base);
      40                 :            : }
      41                 :            : 
      42                 :            : #define take_preallocated_barriers(x) llist_del_all(&(x)->preallocated_barriers)
      43                 :            : 
      44                 :          0 : static inline bool is_barrier(const struct i915_active_fence *active)
      45                 :            : {
      46                 :          0 :         return IS_ERR(rcu_access_pointer(active->fence));
      47                 :            : }
      48                 :            : 
      49                 :          0 : static inline struct llist_node *barrier_to_ll(struct active_node *node)
      50                 :            : {
      51                 :          0 :         GEM_BUG_ON(!is_barrier(&node->base));
      52                 :          0 :         return (struct llist_node *)&node->base.cb.node;
      53                 :            : }
      54                 :            : 
      55                 :            : static inline struct intel_engine_cs *
      56                 :          0 : __barrier_to_engine(struct active_node *node)
      57                 :            : {
      58                 :          0 :         return (struct intel_engine_cs *)READ_ONCE(node->base.cb.node.prev);
      59                 :            : }
      60                 :            : 
      61                 :            : static inline struct intel_engine_cs *
      62                 :          0 : barrier_to_engine(struct active_node *node)
      63                 :            : {
      64                 :          0 :         GEM_BUG_ON(!is_barrier(&node->base));
      65                 :          0 :         return __barrier_to_engine(node);
      66                 :            : }
      67                 :            : 
      68                 :          0 : static inline struct active_node *barrier_from_ll(struct llist_node *x)
      69                 :            : {
      70                 :          0 :         return container_of((struct list_head *)x,
      71                 :            :                             struct active_node, base.cb.node);
      72                 :            : }
      73                 :            : 
      74                 :            : #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) && IS_ENABLED(CONFIG_DEBUG_OBJECTS)
      75                 :            : 
      76                 :            : static void *active_debug_hint(void *addr)
      77                 :            : {
      78                 :            :         struct i915_active *ref = addr;
      79                 :            : 
      80                 :            :         return (void *)ref->active ?: (void *)ref->retire ?: (void *)ref;
      81                 :            : }
      82                 :            : 
      83                 :            : static struct debug_obj_descr active_debug_desc = {
      84                 :            :         .name = "i915_active",
      85                 :            :         .debug_hint = active_debug_hint,
      86                 :            : };
      87                 :            : 
      88                 :            : static void debug_active_init(struct i915_active *ref)
      89                 :            : {
      90                 :            :         debug_object_init(ref, &active_debug_desc);
      91                 :            : }
      92                 :            : 
      93                 :            : static void debug_active_activate(struct i915_active *ref)
      94                 :            : {
      95                 :            :         lockdep_assert_held(&ref->tree_lock);
      96                 :            :         if (!atomic_read(&ref->count)) /* before the first inc */
      97                 :            :                 debug_object_activate(ref, &active_debug_desc);
      98                 :            : }
      99                 :            : 
     100                 :            : static void debug_active_deactivate(struct i915_active *ref)
     101                 :            : {
     102                 :            :         lockdep_assert_held(&ref->tree_lock);
     103                 :            :         if (!atomic_read(&ref->count)) /* after the last dec */
     104                 :            :                 debug_object_deactivate(ref, &active_debug_desc);
     105                 :            : }
     106                 :            : 
     107                 :            : static void debug_active_fini(struct i915_active *ref)
     108                 :            : {
     109                 :            :         debug_object_free(ref, &active_debug_desc);
     110                 :            : }
     111                 :            : 
     112                 :            : static void debug_active_assert(struct i915_active *ref)
     113                 :            : {
     114                 :            :         debug_object_assert_init(ref, &active_debug_desc);
     115                 :            : }
     116                 :            : 
     117                 :            : #else
     118                 :            : 
     119                 :          0 : static inline void debug_active_init(struct i915_active *ref) { }
     120                 :          0 : static inline void debug_active_activate(struct i915_active *ref) { }
     121                 :          0 : static inline void debug_active_deactivate(struct i915_active *ref) { }
     122                 :            : static inline void debug_active_fini(struct i915_active *ref) { }
     123                 :          0 : static inline void debug_active_assert(struct i915_active *ref) { }
     124                 :            : 
     125                 :            : #endif
     126                 :            : 
     127                 :            : static void
     128                 :          0 : __active_retire(struct i915_active *ref)
     129                 :            : {
     130                 :          0 :         struct active_node *it, *n;
     131                 :          0 :         struct rb_root root;
     132                 :          0 :         unsigned long flags;
     133                 :            : 
     134                 :          0 :         GEM_BUG_ON(i915_active_is_idle(ref));
     135                 :            : 
     136                 :            :         /* return the unused nodes to our slabcache -- flushing the allocator */
     137         [ #  # ]:          0 :         if (!atomic_dec_and_lock_irqsave(&ref->count, &ref->tree_lock, flags))
     138                 :          0 :                 return;
     139                 :            : 
     140                 :          0 :         GEM_BUG_ON(rcu_access_pointer(ref->excl.fence));
     141                 :          0 :         debug_active_deactivate(ref);
     142                 :            : 
     143                 :          0 :         root = ref->tree;
     144                 :          0 :         ref->tree = RB_ROOT;
     145                 :          0 :         ref->cache = NULL;
     146                 :            : 
     147                 :          0 :         spin_unlock_irqrestore(&ref->tree_lock, flags);
     148                 :            : 
     149                 :            :         /* After the final retire, the entire struct may be freed */
     150         [ #  # ]:          0 :         if (ref->retire)
     151                 :          0 :                 ref->retire(ref);
     152                 :            : 
     153                 :            :         /* ... except if you wait on it, you must manage your own references! */
     154                 :          0 :         wake_up_var(ref);
     155                 :            : 
     156   [ #  #  #  #  :          0 :         rbtree_postorder_for_each_entry_safe(it, n, &root, node) {
                   #  # ]
     157                 :          0 :                 GEM_BUG_ON(i915_active_fence_isset(&it->base));
     158                 :          0 :                 kmem_cache_free(global.slab_cache, it);
     159                 :            :         }
     160                 :            : }
     161                 :            : 
     162                 :            : static void
     163                 :          0 : active_work(struct work_struct *wrk)
     164                 :            : {
     165                 :          0 :         struct i915_active *ref = container_of(wrk, typeof(*ref), work);
     166                 :            : 
     167                 :          0 :         GEM_BUG_ON(!atomic_read(&ref->count));
     168         [ #  # ]:          0 :         if (atomic_add_unless(&ref->count, -1, 1))
     169                 :            :                 return;
     170                 :            : 
     171                 :          0 :         __active_retire(ref);
     172                 :            : }
     173                 :            : 
     174                 :            : static void
     175                 :          0 : active_retire(struct i915_active *ref)
     176                 :            : {
     177                 :          0 :         GEM_BUG_ON(!atomic_read(&ref->count));
     178         [ #  # ]:          0 :         if (atomic_add_unless(&ref->count, -1, 1))
     179                 :            :                 return;
     180                 :            : 
     181         [ #  # ]:          0 :         if (ref->flags & I915_ACTIVE_RETIRE_SLEEPS) {
     182                 :          0 :                 queue_work(system_unbound_wq, &ref->work);
     183                 :          0 :                 return;
     184                 :            :         }
     185                 :            : 
     186                 :          0 :         __active_retire(ref);
     187                 :            : }
     188                 :            : 
     189                 :            : static inline struct dma_fence **
     190                 :          0 : __active_fence_slot(struct i915_active_fence *active)
     191                 :            : {
     192                 :          0 :         return (struct dma_fence ** __force)&active->fence;
     193                 :            : }
     194                 :            : 
     195                 :            : static inline bool
     196                 :          0 : active_fence_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
     197                 :            : {
     198                 :          0 :         struct i915_active_fence *active =
     199                 :          0 :                 container_of(cb, typeof(*active), cb);
     200                 :            : 
     201                 :          0 :         return cmpxchg(__active_fence_slot(active), fence, NULL) == fence;
     202                 :            : }
     203                 :            : 
     204                 :            : static void
     205                 :          0 : node_retire(struct dma_fence *fence, struct dma_fence_cb *cb)
     206                 :            : {
     207         [ #  # ]:          0 :         if (active_fence_cb(fence, cb))
     208                 :          0 :                 active_retire(container_of(cb, struct active_node, base.cb)->ref);
     209                 :          0 : }
     210                 :            : 
     211                 :            : static void
     212                 :          0 : excl_retire(struct dma_fence *fence, struct dma_fence_cb *cb)
     213                 :            : {
     214         [ #  # ]:          0 :         if (active_fence_cb(fence, cb))
     215                 :          0 :                 active_retire(container_of(cb, struct i915_active, excl.cb));
     216                 :          0 : }
     217                 :            : 
     218                 :            : static struct i915_active_fence *
     219                 :            : active_instance(struct i915_active *ref, struct intel_timeline *tl)
     220                 :            : {
     221                 :            :         struct active_node *node, *prealloc;
     222                 :            :         struct rb_node **p, *parent;
     223                 :            :         u64 idx = tl->fence_context;
     224                 :            : 
     225                 :            :         /*
     226                 :            :          * We track the most recently used timeline to skip a rbtree search
     227                 :            :          * for the common case, under typical loads we never need the rbtree
     228                 :            :          * at all. We can reuse the last slot if it is empty, that is
     229                 :            :          * after the previous activity has been retired, or if it matches the
     230                 :            :          * current timeline.
     231                 :            :          */
     232                 :            :         node = READ_ONCE(ref->cache);
     233                 :            :         if (node && node->timeline == idx)
     234                 :            :                 return &node->base;
     235                 :            : 
     236                 :            :         /* Preallocate a replacement, just in case */
     237                 :            :         prealloc = kmem_cache_alloc(global.slab_cache, GFP_KERNEL);
     238                 :            :         if (!prealloc)
     239                 :            :                 return NULL;
     240                 :            : 
     241                 :            :         spin_lock_irq(&ref->tree_lock);
     242                 :            :         GEM_BUG_ON(i915_active_is_idle(ref));
     243                 :            : 
     244                 :            :         parent = NULL;
     245                 :            :         p = &ref->tree.rb_node;
     246                 :            :         while (*p) {
     247                 :            :                 parent = *p;
     248                 :            : 
     249                 :            :                 node = rb_entry(parent, struct active_node, node);
     250                 :            :                 if (node->timeline == idx) {
     251                 :            :                         kmem_cache_free(global.slab_cache, prealloc);
     252                 :            :                         goto out;
     253                 :            :                 }
     254                 :            : 
     255                 :            :                 if (node->timeline < idx)
     256                 :            :                         p = &parent->rb_right;
     257                 :            :                 else
     258                 :            :                         p = &parent->rb_left;
     259                 :            :         }
     260                 :            : 
     261                 :            :         node = prealloc;
     262                 :            :         __i915_active_fence_init(&node->base, NULL, node_retire);
     263                 :            :         node->ref = ref;
     264                 :            :         node->timeline = idx;
     265                 :            : 
     266                 :            :         rb_link_node(&node->node, parent, p);
     267                 :            :         rb_insert_color(&node->node, &ref->tree);
     268                 :            : 
     269                 :            : out:
     270                 :            :         ref->cache = node;
     271                 :            :         spin_unlock_irq(&ref->tree_lock);
     272                 :            : 
     273                 :            :         BUILD_BUG_ON(offsetof(typeof(*node), base));
     274                 :            :         return &node->base;
     275                 :            : }
     276                 :            : 
     277                 :          0 : void __i915_active_init(struct i915_active *ref,
     278                 :            :                         int (*active)(struct i915_active *ref),
     279                 :            :                         void (*retire)(struct i915_active *ref),
     280                 :            :                         struct lock_class_key *mkey,
     281                 :            :                         struct lock_class_key *wkey)
     282                 :            : {
     283                 :          0 :         unsigned long bits;
     284                 :            : 
     285                 :          0 :         debug_active_init(ref);
     286                 :            : 
     287                 :          0 :         ref->flags = 0;
     288                 :          0 :         ref->active = active;
     289                 :          0 :         ref->retire = ptr_unpack_bits(retire, &bits, 2);
     290         [ #  # ]:          0 :         if (bits & I915_ACTIVE_MAY_SLEEP)
     291                 :          0 :                 ref->flags |= I915_ACTIVE_RETIRE_SLEEPS;
     292                 :            : 
     293                 :          0 :         spin_lock_init(&ref->tree_lock);
     294                 :          0 :         ref->tree = RB_ROOT;
     295                 :          0 :         ref->cache = NULL;
     296                 :            : 
     297                 :          0 :         init_llist_head(&ref->preallocated_barriers);
     298                 :          0 :         atomic_set(&ref->count, 0);
     299                 :          0 :         __mutex_init(&ref->mutex, "i915_active", mkey);
     300                 :          0 :         __i915_active_fence_init(&ref->excl, NULL, excl_retire);
     301                 :          0 :         INIT_WORK(&ref->work, active_work);
     302                 :            : #if IS_ENABLED(CONFIG_LOCKDEP)
     303                 :            :         lockdep_init_map(&ref->work.lockdep_map, "i915_active.work", wkey, 0);
     304                 :            : #endif
     305                 :          0 : }
     306                 :            : 
     307                 :            : static bool ____active_del_barrier(struct i915_active *ref,
     308                 :            :                                    struct active_node *node,
     309                 :            :                                    struct intel_engine_cs *engine)
     310                 :            : 
     311                 :            : {
     312                 :            :         struct llist_node *head = NULL, *tail = NULL;
     313                 :            :         struct llist_node *pos, *next;
     314                 :            : 
     315                 :            :         GEM_BUG_ON(node->timeline != engine->kernel_context->timeline->fence_context);
     316                 :            : 
     317                 :            :         /*
     318                 :            :          * Rebuild the llist excluding our node. We may perform this
     319                 :            :          * outside of the kernel_context timeline mutex and so someone
     320                 :            :          * else may be manipulating the engine->barrier_tasks, in
     321                 :            :          * which case either we or they will be upset :)
     322                 :            :          *
     323                 :            :          * A second __active_del_barrier() will report failure to claim
     324                 :            :          * the active_node and the caller will just shrug and know not to
     325                 :            :          * claim ownership of its node.
     326                 :            :          *
     327                 :            :          * A concurrent i915_request_add_active_barriers() will miss adding
     328                 :            :          * any of the tasks, but we will try again on the next -- and since
     329                 :            :          * we are actively using the barrier, we know that there will be
     330                 :            :          * at least another opportunity when we idle.
     331                 :            :          */
     332                 :            :         llist_for_each_safe(pos, next, llist_del_all(&engine->barrier_tasks)) {
     333                 :            :                 if (node == barrier_from_ll(pos)) {
     334                 :            :                         node = NULL;
     335                 :            :                         continue;
     336                 :            :                 }
     337                 :            : 
     338                 :            :                 pos->next = head;
     339                 :            :                 head = pos;
     340                 :            :                 if (!tail)
     341                 :            :                         tail = pos;
     342                 :            :         }
     343                 :            :         if (head)
     344                 :            :                 llist_add_batch(head, tail, &engine->barrier_tasks);
     345                 :            : 
     346                 :            :         return !node;
     347                 :            : }
     348                 :            : 
     349                 :            : static bool
     350                 :          0 : __active_del_barrier(struct i915_active *ref, struct active_node *node)
     351                 :            : {
     352                 :          0 :         return ____active_del_barrier(ref, node, barrier_to_engine(node));
     353                 :            : }
     354                 :            : 
     355                 :          0 : int i915_active_ref(struct i915_active *ref,
     356                 :            :                     struct intel_timeline *tl,
     357                 :            :                     struct dma_fence *fence)
     358                 :            : {
     359                 :          0 :         struct i915_active_fence *active;
     360                 :          0 :         int err;
     361                 :            : 
     362                 :          0 :         lockdep_assert_held(&tl->mutex);
     363                 :            : 
     364                 :            :         /* Prevent reaping in case we malloc/wait while building the tree */
     365                 :          0 :         err = i915_active_acquire(ref);
     366         [ #  # ]:          0 :         if (err)
     367                 :            :                 return err;
     368                 :            : 
     369                 :          0 :         active = active_instance(ref, tl);
     370         [ #  # ]:          0 :         if (!active) {
     371                 :          0 :                 err = -ENOMEM;
     372                 :          0 :                 goto out;
     373                 :            :         }
     374                 :            : 
     375         [ #  # ]:          0 :         if (is_barrier(active)) { /* proto-node used by our idle barrier */
     376                 :            :                 /*
     377                 :            :                  * This request is on the kernel_context timeline, and so
     378                 :            :                  * we can use it to substitute for the pending idle-barrer
     379                 :            :                  * request that we want to emit on the kernel_context.
     380                 :            :                  */
     381                 :          0 :                 __active_del_barrier(ref, node_from_active(active));
     382                 :          0 :                 RCU_INIT_POINTER(active->fence, NULL);
     383                 :          0 :                 atomic_dec(&ref->count);
     384                 :            :         }
     385         [ #  # ]:          0 :         if (!__i915_active_fence_set(active, fence))
     386                 :          0 :                 atomic_inc(&ref->count);
     387                 :            : 
     388                 :          0 : out:
     389                 :          0 :         i915_active_release(ref);
     390                 :          0 :         return err;
     391                 :            : }
     392                 :            : 
     393                 :          0 : void i915_active_set_exclusive(struct i915_active *ref, struct dma_fence *f)
     394                 :            : {
     395                 :            :         /* We expect the caller to manage the exclusive timeline ordering */
     396                 :          0 :         GEM_BUG_ON(i915_active_is_idle(ref));
     397                 :            : 
     398         [ #  # ]:          0 :         if (!__i915_active_fence_set(&ref->excl, f))
     399                 :          0 :                 atomic_inc(&ref->count);
     400                 :          0 : }
     401                 :            : 
     402                 :          0 : bool i915_active_acquire_if_busy(struct i915_active *ref)
     403                 :            : {
     404                 :          0 :         debug_active_assert(ref);
     405                 :          0 :         return atomic_add_unless(&ref->count, 1, 0);
     406                 :            : }
     407                 :            : 
     408                 :          0 : int i915_active_acquire(struct i915_active *ref)
     409                 :            : {
     410                 :          0 :         int err;
     411                 :            : 
     412         [ #  # ]:          0 :         if (i915_active_acquire_if_busy(ref))
     413                 :            :                 return 0;
     414                 :            : 
     415                 :          0 :         err = mutex_lock_interruptible(&ref->mutex);
     416         [ #  # ]:          0 :         if (err)
     417                 :            :                 return err;
     418                 :            : 
     419         [ #  # ]:          0 :         if (likely(!i915_active_acquire_if_busy(ref))) {
     420         [ #  # ]:          0 :                 if (ref->active)
     421                 :          0 :                         err = ref->active(ref);
     422         [ #  # ]:          0 :                 if (!err) {
     423                 :          0 :                         spin_lock_irq(&ref->tree_lock); /* __active_retire() */
     424                 :          0 :                         debug_active_activate(ref);
     425                 :          0 :                         atomic_inc(&ref->count);
     426                 :          0 :                         spin_unlock_irq(&ref->tree_lock);
     427                 :            :                 }
     428                 :            :         }
     429                 :            : 
     430                 :          0 :         mutex_unlock(&ref->mutex);
     431                 :            : 
     432                 :          0 :         return err;
     433                 :            : }
     434                 :            : 
     435                 :          0 : void i915_active_release(struct i915_active *ref)
     436                 :            : {
     437                 :          0 :         debug_active_assert(ref);
     438                 :          0 :         active_retire(ref);
     439                 :          0 : }
     440                 :            : 
     441                 :          0 : static void enable_signaling(struct i915_active_fence *active)
     442                 :            : {
     443                 :          0 :         struct dma_fence *fence;
     444                 :            : 
     445                 :          0 :         fence = i915_active_fence_get(active);
     446         [ #  # ]:          0 :         if (!fence)
     447                 :            :                 return;
     448                 :            : 
     449                 :          0 :         dma_fence_enable_sw_signaling(fence);
     450                 :          0 :         dma_fence_put(fence);
     451                 :            : }
     452                 :            : 
     453                 :          0 : int i915_active_wait(struct i915_active *ref)
     454                 :            : {
     455                 :          0 :         struct active_node *it, *n;
     456                 :          0 :         int err = 0;
     457                 :            : 
     458                 :          0 :         might_sleep();
     459                 :            : 
     460         [ #  # ]:          0 :         if (!i915_active_acquire_if_busy(ref))
     461                 :            :                 return 0;
     462                 :            : 
     463                 :            :         /* Flush lazy signals */
     464                 :          0 :         enable_signaling(&ref->excl);
     465   [ #  #  #  #  :          0 :         rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
                   #  # ]
     466         [ #  # ]:          0 :                 if (is_barrier(&it->base)) /* unconnected idle barrier */
     467                 :          0 :                         continue;
     468                 :            : 
     469                 :          0 :                 enable_signaling(&it->base);
     470                 :            :         }
     471                 :            :         /* Any fence added after the wait begins will not be auto-signaled */
     472                 :            : 
     473                 :          0 :         i915_active_release(ref);
     474                 :          0 :         if (err)
     475                 :            :                 return err;
     476                 :            : 
     477   [ #  #  #  #  :          0 :         if (wait_var_event_interruptible(ref, i915_active_is_idle(ref)))
             #  #  #  # ]
     478                 :            :                 return -EINTR;
     479                 :            : 
     480                 :          0 :         flush_work(&ref->work);
     481                 :          0 :         return 0;
     482                 :            : }
     483                 :            : 
     484                 :          0 : int i915_request_await_active(struct i915_request *rq, struct i915_active *ref)
     485                 :            : {
     486                 :          0 :         int err = 0;
     487                 :            : 
     488         [ #  # ]:          0 :         if (rcu_access_pointer(ref->excl.fence)) {
     489                 :          0 :                 struct dma_fence *fence;
     490                 :            : 
     491                 :          0 :                 rcu_read_lock();
     492                 :          0 :                 fence = dma_fence_get_rcu_safe(&ref->excl.fence);
     493                 :          0 :                 rcu_read_unlock();
     494         [ #  # ]:          0 :                 if (fence) {
     495                 :          0 :                         err = i915_request_await_dma_fence(rq, fence);
     496                 :          0 :                         dma_fence_put(fence);
     497                 :            :                 }
     498                 :            :         }
     499                 :            : 
     500                 :            :         /* In the future we may choose to await on all fences */
     501                 :            : 
     502                 :          0 :         return err;
     503                 :            : }
     504                 :            : 
     505                 :            : #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
     506                 :            : void i915_active_fini(struct i915_active *ref)
     507                 :            : {
     508                 :            :         debug_active_fini(ref);
     509                 :            :         GEM_BUG_ON(atomic_read(&ref->count));
     510                 :            :         GEM_BUG_ON(work_pending(&ref->work));
     511                 :            :         GEM_BUG_ON(!RB_EMPTY_ROOT(&ref->tree));
     512                 :            :         mutex_destroy(&ref->mutex);
     513                 :            : }
     514                 :            : #endif
     515                 :            : 
     516                 :          0 : static inline bool is_idle_barrier(struct active_node *node, u64 idx)
     517                 :            : {
     518   [ #  #  #  #  :          0 :         return node->timeline == idx && !i915_active_fence_isset(&node->base);
             #  #  #  # ]
     519                 :            : }
     520                 :            : 
     521                 :          0 : static struct active_node *reuse_idle_barrier(struct i915_active *ref, u64 idx)
     522                 :            : {
     523                 :          0 :         struct rb_node *prev, *p;
     524                 :            : 
     525         [ #  # ]:          0 :         if (RB_EMPTY_ROOT(&ref->tree))
     526                 :            :                 return NULL;
     527                 :            : 
     528                 :          0 :         spin_lock_irq(&ref->tree_lock);
     529                 :          0 :         GEM_BUG_ON(i915_active_is_idle(ref));
     530                 :            : 
     531                 :            :         /*
     532                 :            :          * Try to reuse any existing barrier nodes already allocated for this
     533                 :            :          * i915_active, due to overlapping active phases there is likely a
     534                 :            :          * node kept alive (as we reuse before parking). We prefer to reuse
     535                 :            :          * completely idle barriers (less hassle in manipulating the llists),
     536                 :            :          * but otherwise any will do.
     537                 :            :          */
     538   [ #  #  #  # ]:          0 :         if (ref->cache && is_idle_barrier(ref->cache, idx)) {
     539                 :          0 :                 p = &ref->cache->node;
     540                 :          0 :                 goto match;
     541                 :            :         }
     542                 :            : 
     543                 :          0 :         prev = NULL;
     544                 :          0 :         p = ref->tree.rb_node;
     545         [ #  # ]:          0 :         while (p) {
     546                 :          0 :                 struct active_node *node =
     547                 :          0 :                         rb_entry(p, struct active_node, node);
     548                 :            : 
     549   [ #  #  #  # ]:          0 :                 if (is_idle_barrier(node, idx))
     550                 :          0 :                         goto match;
     551                 :            : 
     552                 :          0 :                 prev = p;
     553         [ #  # ]:          0 :                 if (node->timeline < idx)
     554                 :          0 :                         p = p->rb_right;
     555                 :            :                 else
     556                 :          0 :                         p = p->rb_left;
     557                 :            :         }
     558                 :            : 
     559                 :            :         /*
     560                 :            :          * No quick match, but we did find the leftmost rb_node for the
     561                 :            :          * kernel_context. Walk the rb_tree in-order to see if there were
     562                 :            :          * any idle-barriers on this timeline that we missed, or just use
     563                 :            :          * the first pending barrier.
     564                 :            :          */
     565         [ #  # ]:          0 :         for (p = prev; p; p = rb_next(p)) {
     566                 :          0 :                 struct active_node *node =
     567                 :          0 :                         rb_entry(p, struct active_node, node);
     568                 :          0 :                 struct intel_engine_cs *engine;
     569                 :            : 
     570         [ #  # ]:          0 :                 if (node->timeline > idx)
     571                 :            :                         break;
     572                 :            : 
     573         [ #  # ]:          0 :                 if (node->timeline < idx)
     574                 :          0 :                         continue;
     575                 :            : 
     576   [ #  #  #  # ]:          0 :                 if (is_idle_barrier(node, idx))
     577                 :          0 :                         goto match;
     578                 :            : 
     579                 :            :                 /*
     580                 :            :                  * The list of pending barriers is protected by the
     581                 :            :                  * kernel_context timeline, which notably we do not hold
     582                 :            :                  * here. i915_request_add_active_barriers() may consume
     583                 :            :                  * the barrier before we claim it, so we have to check
     584                 :            :                  * for success.
     585                 :            :                  */
     586                 :          0 :                 engine = __barrier_to_engine(node);
     587                 :          0 :                 smp_rmb(); /* serialise with add_active_barriers */
     588   [ #  #  #  # ]:          0 :                 if (is_barrier(&node->base) &&
     589                 :          0 :                     ____active_del_barrier(ref, node, engine))
     590                 :          0 :                         goto match;
     591                 :            :         }
     592                 :            : 
     593                 :          0 :         spin_unlock_irq(&ref->tree_lock);
     594                 :            : 
     595                 :          0 :         return NULL;
     596                 :            : 
     597                 :          0 : match:
     598                 :          0 :         rb_erase(p, &ref->tree); /* Hide from waits and sibling allocations */
     599         [ #  # ]:          0 :         if (p == &ref->cache->node)
     600                 :          0 :                 ref->cache = NULL;
     601                 :          0 :         spin_unlock_irq(&ref->tree_lock);
     602                 :            : 
     603                 :          0 :         return rb_entry(p, struct active_node, node);
     604                 :            : }
     605                 :            : 
     606                 :          0 : int i915_active_acquire_preallocate_barrier(struct i915_active *ref,
     607                 :            :                                             struct intel_engine_cs *engine)
     608                 :            : {
     609                 :          0 :         intel_engine_mask_t tmp, mask = engine->mask;
     610                 :          0 :         struct llist_node *first = NULL, *last = NULL;
     611                 :          0 :         struct intel_gt *gt = engine->gt;
     612                 :          0 :         int err;
     613                 :            : 
     614                 :          0 :         GEM_BUG_ON(i915_active_is_idle(ref));
     615                 :            : 
     616                 :            :         /* Wait until the previous preallocation is completed */
     617         [ #  # ]:          0 :         while (!llist_empty(&ref->preallocated_barriers))
     618                 :          0 :                 cond_resched();
     619                 :            : 
     620                 :            :         /*
     621                 :            :          * Preallocate a node for each physical engine supporting the target
     622                 :            :          * engine (remember virtual engines have more than one sibling).
     623                 :            :          * We can then use the preallocated nodes in
     624                 :            :          * i915_active_acquire_barrier()
     625                 :            :          */
     626   [ #  #  #  # ]:          0 :         for_each_engine_masked(engine, gt, mask, tmp) {
     627                 :          0 :                 u64 idx = engine->kernel_context->timeline->fence_context;
     628                 :          0 :                 struct llist_node *prev = first;
     629                 :          0 :                 struct active_node *node;
     630                 :            : 
     631                 :          0 :                 node = reuse_idle_barrier(ref, idx);
     632         [ #  # ]:          0 :                 if (!node) {
     633                 :          0 :                         node = kmem_cache_alloc(global.slab_cache, GFP_KERNEL);
     634         [ #  # ]:          0 :                         if (!node) {
     635                 :          0 :                                 err = ENOMEM;
     636                 :          0 :                                 goto unwind;
     637                 :            :                         }
     638                 :            : 
     639                 :          0 :                         RCU_INIT_POINTER(node->base.fence, NULL);
     640                 :          0 :                         node->base.cb.func = node_retire;
     641                 :          0 :                         node->timeline = idx;
     642                 :          0 :                         node->ref = ref;
     643                 :            :                 }
     644                 :            : 
     645         [ #  # ]:          0 :                 if (!i915_active_fence_isset(&node->base)) {
     646                 :            :                         /*
     647                 :            :                          * Mark this as being *our* unconnected proto-node.
     648                 :            :                          *
     649                 :            :                          * Since this node is not in any list, and we have
     650                 :            :                          * decoupled it from the rbtree, we can reuse the
     651                 :            :                          * request to indicate this is an idle-barrier node
     652                 :            :                          * and then we can use the rb_node and list pointers
     653                 :            :                          * for our tracking of the pending barrier.
     654                 :            :                          */
     655                 :          0 :                         RCU_INIT_POINTER(node->base.fence, ERR_PTR(-EAGAIN));
     656                 :          0 :                         node->base.cb.node.prev = (void *)engine;
     657                 :          0 :                         atomic_inc(&ref->count);
     658                 :            :                 }
     659                 :          0 :                 GEM_BUG_ON(rcu_access_pointer(node->base.fence) != ERR_PTR(-EAGAIN));
     660                 :            : 
     661                 :          0 :                 GEM_BUG_ON(barrier_to_engine(node) != engine);
     662                 :          0 :                 first = barrier_to_ll(node);
     663                 :          0 :                 first->next = prev;
     664         [ #  # ]:          0 :                 if (!last)
     665                 :          0 :                         last = first;
     666                 :          0 :                 intel_engine_pm_get(engine);
     667                 :            :         }
     668                 :            : 
     669                 :          0 :         GEM_BUG_ON(!llist_empty(&ref->preallocated_barriers));
     670                 :          0 :         llist_add_batch(first, last, &ref->preallocated_barriers);
     671                 :            : 
     672                 :          0 :         return 0;
     673                 :            : 
     674                 :            : unwind:
     675         [ #  # ]:          0 :         while (first) {
     676                 :          0 :                 struct active_node *node = barrier_from_ll(first);
     677                 :            : 
     678                 :          0 :                 first = first->next;
     679                 :            : 
     680                 :          0 :                 atomic_dec(&ref->count);
     681                 :          0 :                 intel_engine_pm_put(barrier_to_engine(node));
     682                 :            : 
     683                 :          0 :                 kmem_cache_free(global.slab_cache, node);
     684                 :            :         }
     685                 :            :         return err;
     686                 :            : }
     687                 :            : 
     688                 :          0 : void i915_active_acquire_barrier(struct i915_active *ref)
     689                 :            : {
     690                 :          0 :         struct llist_node *pos, *next;
     691                 :          0 :         unsigned long flags;
     692                 :            : 
     693                 :          0 :         GEM_BUG_ON(i915_active_is_idle(ref));
     694                 :            : 
     695                 :            :         /*
     696                 :            :          * Transfer the list of preallocated barriers into the
     697                 :            :          * i915_active rbtree, but only as proto-nodes. They will be
     698                 :            :          * populated by i915_request_add_active_barriers() to point to the
     699                 :            :          * request that will eventually release them.
     700                 :            :          */
     701         [ #  # ]:          0 :         llist_for_each_safe(pos, next, take_preallocated_barriers(ref)) {
     702                 :          0 :                 struct active_node *node = barrier_from_ll(pos);
     703                 :          0 :                 struct intel_engine_cs *engine = barrier_to_engine(node);
     704                 :          0 :                 struct rb_node **p, *parent;
     705                 :            : 
     706                 :          0 :                 spin_lock_irqsave_nested(&ref->tree_lock, flags,
     707                 :            :                                          SINGLE_DEPTH_NESTING);
     708                 :          0 :                 parent = NULL;
     709                 :          0 :                 p = &ref->tree.rb_node;
     710         [ #  # ]:          0 :                 while (*p) {
     711                 :          0 :                         struct active_node *it;
     712                 :            : 
     713                 :          0 :                         parent = *p;
     714                 :            : 
     715                 :          0 :                         it = rb_entry(parent, struct active_node, node);
     716         [ #  # ]:          0 :                         if (it->timeline < node->timeline)
     717                 :          0 :                                 p = &parent->rb_right;
     718                 :            :                         else
     719                 :          0 :                                 p = &parent->rb_left;
     720                 :            :                 }
     721                 :          0 :                 rb_link_node(&node->node, parent, p);
     722                 :          0 :                 rb_insert_color(&node->node, &ref->tree);
     723                 :          0 :                 spin_unlock_irqrestore(&ref->tree_lock, flags);
     724                 :            : 
     725                 :          0 :                 GEM_BUG_ON(!intel_engine_pm_is_awake(engine));
     726                 :          0 :                 llist_add(barrier_to_ll(node), &engine->barrier_tasks);
     727                 :          0 :                 intel_engine_pm_put(engine);
     728                 :            :         }
     729                 :          0 : }
     730                 :            : 
     731                 :          0 : static struct dma_fence **ll_to_fence_slot(struct llist_node *node)
     732                 :            : {
     733                 :          0 :         return __active_fence_slot(&barrier_from_ll(node)->base);
     734                 :            : }
     735                 :            : 
     736                 :          0 : void i915_request_add_active_barriers(struct i915_request *rq)
     737                 :            : {
     738                 :          0 :         struct intel_engine_cs *engine = rq->engine;
     739                 :          0 :         struct llist_node *node, *next;
     740                 :          0 :         unsigned long flags;
     741                 :            : 
     742                 :          0 :         GEM_BUG_ON(!intel_context_is_barrier(rq->context));
     743                 :          0 :         GEM_BUG_ON(intel_engine_is_virtual(engine));
     744                 :          0 :         GEM_BUG_ON(i915_request_timeline(rq) != engine->kernel_context->timeline);
     745                 :            : 
     746                 :          0 :         node = llist_del_all(&engine->barrier_tasks);
     747         [ #  # ]:          0 :         if (!node)
     748                 :            :                 return;
     749                 :            :         /*
     750                 :            :          * Attach the list of proto-fences to the in-flight request such
     751                 :            :          * that the parent i915_active will be released when this request
     752                 :            :          * is retired.
     753                 :            :          */
     754                 :          0 :         spin_lock_irqsave(&rq->lock, flags);
     755         [ #  # ]:          0 :         llist_for_each_safe(node, next, node) {
     756                 :            :                 /* serialise with reuse_idle_barrier */
     757                 :          0 :                 smp_store_mb(*ll_to_fence_slot(node), &rq->fence);
     758                 :          0 :                 list_add_tail((struct list_head *)node, &rq->fence.cb_list);
     759                 :            :         }
     760                 :          0 :         spin_unlock_irqrestore(&rq->lock, flags);
     761                 :            : }
     762                 :            : 
     763                 :            : /*
     764                 :            :  * __i915_active_fence_set: Update the last active fence along its timeline
     765                 :            :  * @active: the active tracker
     766                 :            :  * @fence: the new fence (under construction)
     767                 :            :  *
     768                 :            :  * Records the new @fence as the last active fence along its timeline in
     769                 :            :  * this active tracker, moving the tracking callbacks from the previous
     770                 :            :  * fence onto this one. Returns the previous fence (if not already completed),
     771                 :            :  * which the caller must ensure is executed before the new fence. To ensure
     772                 :            :  * that the order of fences within the timeline of the i915_active_fence is
     773                 :            :  * understood, it should be locked by the caller.
     774                 :            :  */
     775                 :            : struct dma_fence *
     776                 :          0 : __i915_active_fence_set(struct i915_active_fence *active,
     777                 :            :                         struct dma_fence *fence)
     778                 :            : {
     779                 :          0 :         struct dma_fence *prev;
     780                 :          0 :         unsigned long flags;
     781                 :            : 
     782         [ #  # ]:          0 :         if (fence == rcu_access_pointer(active->fence))
     783                 :            :                 return fence;
     784                 :            : 
     785                 :          0 :         GEM_BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags));
     786                 :            : 
     787                 :            :         /*
     788                 :            :          * Consider that we have two threads arriving (A and B), with
     789                 :            :          * C already resident as the active->fence.
     790                 :            :          *
     791                 :            :          * A does the xchg first, and so it sees C or NULL depending
     792                 :            :          * on the timing of the interrupt handler. If it is NULL, the
     793                 :            :          * previous fence must have been signaled and we know that
     794                 :            :          * we are first on the timeline. If it is still present,
     795                 :            :          * we acquire the lock on that fence and serialise with the interrupt
     796                 :            :          * handler, in the process removing it from any future interrupt
     797                 :            :          * callback. A will then wait on C before executing (if present).
     798                 :            :          *
     799                 :            :          * As B is second, it sees A as the previous fence and so waits for
     800                 :            :          * it to complete its transition and takes over the occupancy for
     801                 :            :          * itself -- remembering that it needs to wait on A before executing.
     802                 :            :          *
     803                 :            :          * Note the strong ordering of the timeline also provides consistent
     804                 :            :          * nesting rules for the fence->lock; the inner lock is always the
     805                 :            :          * older lock.
     806                 :            :          */
     807                 :          0 :         spin_lock_irqsave(fence->lock, flags);
     808                 :          0 :         prev = xchg(__active_fence_slot(active), fence);
     809         [ #  # ]:          0 :         if (prev) {
     810                 :          0 :                 GEM_BUG_ON(prev == fence);
     811                 :          0 :                 spin_lock_nested(prev->lock, SINGLE_DEPTH_NESTING);
     812                 :          0 :                 __list_del_entry(&active->cb.node);
     813                 :          0 :                 spin_unlock(prev->lock); /* serialise with prev->cb_list */
     814                 :            :         }
     815                 :          0 :         GEM_BUG_ON(rcu_access_pointer(active->fence) != fence);
     816                 :          0 :         list_add_tail(&active->cb.node, &fence->cb_list);
     817                 :          0 :         spin_unlock_irqrestore(fence->lock, flags);
     818                 :            : 
     819                 :          0 :         return prev;
     820                 :            : }
     821                 :            : 
     822                 :          0 : int i915_active_fence_set(struct i915_active_fence *active,
     823                 :            :                           struct i915_request *rq)
     824                 :            : {
     825                 :          0 :         struct dma_fence *fence;
     826                 :          0 :         int err = 0;
     827                 :            : 
     828                 :            :         /* Must maintain timeline ordering wrt previous active requests */
     829                 :          0 :         rcu_read_lock();
     830                 :          0 :         fence = __i915_active_fence_set(active, &rq->fence);
     831         [ #  # ]:          0 :         if (fence) /* but the previous fence may not belong to that timeline! */
     832                 :          0 :                 fence = dma_fence_get_rcu(fence);
     833                 :          0 :         rcu_read_unlock();
     834         [ #  # ]:          0 :         if (fence) {
     835                 :          0 :                 err = i915_request_await_dma_fence(rq, fence);
     836                 :          0 :                 dma_fence_put(fence);
     837                 :            :         }
     838                 :            : 
     839                 :          0 :         return err;
     840                 :            : }
     841                 :            : 
     842                 :          0 : void i915_active_noop(struct dma_fence *fence, struct dma_fence_cb *cb)
     843                 :            : {
     844                 :          0 :         active_fence_cb(fence, cb);
     845                 :          0 : }
     846                 :            : 
     847                 :            : #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
     848                 :            : #include "selftests/i915_active.c"
     849                 :            : #endif
     850                 :            : 
     851                 :          0 : static void i915_global_active_shrink(void)
     852                 :            : {
     853                 :          0 :         kmem_cache_shrink(global.slab_cache);
     854                 :          0 : }
     855                 :            : 
     856                 :          0 : static void i915_global_active_exit(void)
     857                 :            : {
     858                 :          0 :         kmem_cache_destroy(global.slab_cache);
     859                 :          0 : }
     860                 :            : 
     861                 :            : static struct i915_global_active global = { {
     862                 :            :         .shrink = i915_global_active_shrink,
     863                 :            :         .exit = i915_global_active_exit,
     864                 :            : } };
     865                 :            : 
     866                 :         11 : int __init i915_global_active_init(void)
     867                 :            : {
     868                 :         11 :         global.slab_cache = KMEM_CACHE(active_node, SLAB_HWCACHE_ALIGN);
     869         [ +  - ]:         11 :         if (!global.slab_cache)
     870                 :            :                 return -ENOMEM;
     871                 :            : 
     872                 :         11 :         i915_global_register(&global.base);
     873                 :         11 :         return 0;
     874                 :            : }

Generated by: LCOV version 1.14