LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/gem - i915_gem_busy.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 46 0.0 %
Date: 2022-04-01 14:17:54 Functions: 0 1 0.0 %
Branches: 0 30 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * SPDX-License-Identifier: MIT
       3                 :            :  *
       4                 :            :  * Copyright © 2014-2016 Intel Corporation
       5                 :            :  */
       6                 :            : 
       7                 :            : #include "gt/intel_engine.h"
       8                 :            : 
       9                 :            : #include "i915_gem_ioctls.h"
      10                 :            : #include "i915_gem_object.h"
      11                 :            : 
      12                 :          0 : static __always_inline u32 __busy_read_flag(u16 id)
      13                 :            : {
      14                 :          0 :         if (id == (u16)I915_ENGINE_CLASS_INVALID)
      15                 :            :                 return 0xffff0000u;
      16                 :            : 
      17                 :          0 :         GEM_BUG_ON(id >= 16);
      18                 :          0 :         return 0x10000u << id;
      19                 :            : }
      20                 :            : 
      21                 :          0 : static __always_inline u32 __busy_write_id(u16 id)
      22                 :            : {
      23                 :            :         /*
      24                 :            :          * The uABI guarantees an active writer is also amongst the read
      25                 :            :          * engines. This would be true if we accessed the activity tracking
      26                 :            :          * under the lock, but as we perform the lookup of the object and
      27                 :            :          * its activity locklessly we can not guarantee that the last_write
      28                 :            :          * being active implies that we have set the same engine flag from
      29                 :            :          * last_read - hence we always set both read and write busy for
      30                 :            :          * last_write.
      31                 :            :          */
      32                 :          0 :         if (id == (u16)I915_ENGINE_CLASS_INVALID)
      33                 :            :                 return 0xffffffffu;
      34                 :            : 
      35                 :          0 :         return (id + 1) | __busy_read_flag(id);
      36                 :            : }
      37                 :            : 
      38                 :            : static __always_inline unsigned int
      39                 :          0 : __busy_set_if_active(const struct dma_fence *fence, u32 (*flag)(u16 id))
      40                 :            : {
      41                 :          0 :         const struct i915_request *rq;
      42                 :            : 
      43                 :            :         /*
      44                 :            :          * We have to check the current hw status of the fence as the uABI
      45                 :            :          * guarantees forward progress. We could rely on the idle worker
      46                 :            :          * to eventually flush us, but to minimise latency just ask the
      47                 :            :          * hardware.
      48                 :            :          *
      49                 :            :          * Note we only report on the status of native fences.
      50                 :            :          */
      51                 :          0 :         if (!dma_fence_is_i915(fence))
      52                 :            :                 return 0;
      53                 :            : 
      54                 :            :         /* opencode to_request() in order to avoid const warnings */
      55                 :          0 :         rq = container_of(fence, const struct i915_request, fence);
      56   [ #  #  #  # ]:          0 :         if (i915_request_completed(rq))
      57                 :            :                 return 0;
      58                 :            : 
      59                 :            :         /* Beware type-expansion follies! */
      60                 :          0 :         BUILD_BUG_ON(!typecheck(u16, rq->engine->uabi_class));
      61   [ #  #  #  # ]:          0 :         return flag(rq->engine->uabi_class);
      62                 :            : }
      63                 :            : 
      64                 :            : static __always_inline unsigned int
      65                 :          0 : busy_check_reader(const struct dma_fence *fence)
      66                 :            : {
      67                 :          0 :         return __busy_set_if_active(fence, __busy_read_flag);
      68                 :            : }
      69                 :            : 
      70                 :            : static __always_inline unsigned int
      71                 :          0 : busy_check_writer(const struct dma_fence *fence)
      72                 :            : {
      73         [ #  # ]:          0 :         if (!fence)
      74                 :            :                 return 0;
      75                 :            : 
      76         [ #  # ]:          0 :         return __busy_set_if_active(fence, __busy_write_id);
      77                 :            : }
      78                 :            : 
      79                 :            : int
      80                 :          0 : i915_gem_busy_ioctl(struct drm_device *dev, void *data,
      81                 :            :                     struct drm_file *file)
      82                 :            : {
      83                 :          0 :         struct drm_i915_gem_busy *args = data;
      84                 :          0 :         struct drm_i915_gem_object *obj;
      85                 :          0 :         struct dma_resv_list *list;
      86                 :          0 :         unsigned int seq;
      87                 :          0 :         int err;
      88                 :            : 
      89                 :          0 :         err = -ENOENT;
      90                 :          0 :         rcu_read_lock();
      91                 :          0 :         obj = i915_gem_object_lookup_rcu(file, args->handle);
      92         [ #  # ]:          0 :         if (!obj)
      93                 :          0 :                 goto out;
      94                 :            : 
      95                 :            :         /*
      96                 :            :          * A discrepancy here is that we do not report the status of
      97                 :            :          * non-i915 fences, i.e. even though we may report the object as idle,
      98                 :            :          * a call to set-domain may still stall waiting for foreign rendering.
      99                 :            :          * This also means that wait-ioctl may report an object as busy,
     100                 :            :          * where busy-ioctl considers it idle.
     101                 :            :          *
     102                 :            :          * We trade the ability to warn of foreign fences to report on which
     103                 :            :          * i915 engines are active for the object.
     104                 :            :          *
     105                 :            :          * Alternatively, we can trade that extra information on read/write
     106                 :            :          * activity with
     107                 :            :          *      args->busy =
     108                 :            :          *              !dma_resv_test_signaled_rcu(obj->resv, true);
     109                 :            :          * to report the overall busyness. This is what the wait-ioctl does.
     110                 :            :          *
     111                 :            :          */
     112                 :          0 : retry:
     113                 :          0 :         seq = raw_read_seqcount(&obj->base.resv->seq);
     114                 :            : 
     115                 :            :         /* Translate the exclusive fence to the READ *and* WRITE engine */
     116                 :          0 :         args->busy =
     117         [ #  # ]:          0 :                 busy_check_writer(rcu_dereference(obj->base.resv->fence_excl));
     118                 :            : 
     119                 :            :         /* Translate shared fences to READ set of engines */
     120         [ #  # ]:          0 :         list = rcu_dereference(obj->base.resv->fence);
     121         [ #  # ]:          0 :         if (list) {
     122                 :          0 :                 unsigned int shared_count = list->shared_count, i;
     123                 :            : 
     124         [ #  # ]:          0 :                 for (i = 0; i < shared_count; ++i) {
     125                 :          0 :                         struct dma_fence *fence =
     126         [ #  # ]:          0 :                                 rcu_dereference(list->shared[i]);
     127                 :            : 
     128         [ #  # ]:          0 :                         args->busy |= busy_check_reader(fence);
     129                 :            :                 }
     130                 :            :         }
     131                 :            : 
     132   [ #  #  #  # ]:          0 :         if (args->busy && read_seqcount_retry(&obj->base.resv->seq, seq))
     133                 :          0 :                 goto retry;
     134                 :            : 
     135                 :            :         err = 0;
     136                 :          0 : out:
     137                 :          0 :         rcu_read_unlock();
     138                 :          0 :         return err;
     139                 :            : }

Generated by: LCOV version 1.14