Home | History | Annotate | Line # | Download | only in gt
      1  1.5  riastrad /*	$NetBSD: intel_timeline.c,v 1.5 2021/12/19 12:32:15 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * SPDX-License-Identifier: MIT
      5  1.1  riastrad  *
      6  1.1  riastrad  * Copyright  2016-2018 Intel Corporation
      7  1.1  riastrad  */
      8  1.1  riastrad 
      9  1.1  riastrad #include <sys/cdefs.h>
     10  1.5  riastrad __KERNEL_RCSID(0, "$NetBSD: intel_timeline.c,v 1.5 2021/12/19 12:32:15 riastradh Exp $");
     11  1.1  riastrad 
     12  1.1  riastrad #include "i915_drv.h"
     13  1.1  riastrad 
     14  1.1  riastrad #include "i915_active.h"
     15  1.1  riastrad #include "i915_syncmap.h"
     16  1.1  riastrad #include "intel_gt.h"
     17  1.1  riastrad #include "intel_ring.h"
     18  1.1  riastrad #include "intel_timeline.h"
     19  1.1  riastrad 
     20  1.3  riastrad #include <linux/nbsd-namespace.h>
     21  1.3  riastrad 
     22  1.1  riastrad #define ptr_set_bit(ptr, bit) ((typeof(ptr))((unsigned long)(ptr) | BIT(bit)))
     23  1.1  riastrad #define ptr_test_bit(ptr, bit) ((unsigned long)(ptr) & BIT(bit))
     24  1.1  riastrad 
     25  1.1  riastrad #define CACHELINE_BITS 6
     26  1.1  riastrad #define CACHELINE_FREE CACHELINE_BITS
     27  1.1  riastrad 
     28  1.1  riastrad struct intel_timeline_hwsp {
     29  1.1  riastrad 	struct intel_gt *gt;
     30  1.1  riastrad 	struct intel_gt_timelines *gt_timelines;
     31  1.1  riastrad 	struct list_head free_link;
     32  1.1  riastrad 	struct i915_vma *vma;
     33  1.1  riastrad 	u64 free_bitmap;
     34  1.1  riastrad };
     35  1.1  riastrad 
     36  1.1  riastrad static struct i915_vma *__hwsp_alloc(struct intel_gt *gt)
     37  1.1  riastrad {
     38  1.1  riastrad 	struct drm_i915_private *i915 = gt->i915;
     39  1.1  riastrad 	struct drm_i915_gem_object *obj;
     40  1.1  riastrad 	struct i915_vma *vma;
     41  1.1  riastrad 
     42  1.1  riastrad 	obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
     43  1.1  riastrad 	if (IS_ERR(obj))
     44  1.1  riastrad 		return ERR_CAST(obj);
     45  1.1  riastrad 
     46  1.1  riastrad 	i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC);
     47  1.1  riastrad 
     48  1.1  riastrad 	vma = i915_vma_instance(obj, &gt->ggtt->vm, NULL);
     49  1.1  riastrad 	if (IS_ERR(vma))
     50  1.1  riastrad 		i915_gem_object_put(obj);
     51  1.1  riastrad 
     52  1.1  riastrad 	return vma;
     53  1.1  riastrad }
     54  1.1  riastrad 
     55  1.1  riastrad static struct i915_vma *
     56  1.1  riastrad hwsp_alloc(struct intel_timeline *timeline, unsigned int *cacheline)
     57  1.1  riastrad {
     58  1.1  riastrad 	struct intel_gt_timelines *gt = &timeline->gt->timelines;
     59  1.1  riastrad 	struct intel_timeline_hwsp *hwsp;
     60  1.1  riastrad 
     61  1.1  riastrad 	BUILD_BUG_ON(BITS_PER_TYPE(u64) * CACHELINE_BYTES > PAGE_SIZE);
     62  1.1  riastrad 
     63  1.1  riastrad 	spin_lock_irq(&gt->hwsp_lock);
     64  1.1  riastrad 
     65  1.1  riastrad 	/* hwsp_free_list only contains HWSP that have available cachelines */
     66  1.1  riastrad 	hwsp = list_first_entry_or_null(&gt->hwsp_free_list,
     67  1.1  riastrad 					typeof(*hwsp), free_link);
     68  1.1  riastrad 	if (!hwsp) {
     69  1.1  riastrad 		struct i915_vma *vma;
     70  1.1  riastrad 
     71  1.1  riastrad 		spin_unlock_irq(&gt->hwsp_lock);
     72  1.1  riastrad 
     73  1.1  riastrad 		hwsp = kmalloc(sizeof(*hwsp), GFP_KERNEL);
     74  1.1  riastrad 		if (!hwsp)
     75  1.1  riastrad 			return ERR_PTR(-ENOMEM);
     76  1.1  riastrad 
     77  1.1  riastrad 		vma = __hwsp_alloc(timeline->gt);
     78  1.1  riastrad 		if (IS_ERR(vma)) {
     79  1.1  riastrad 			kfree(hwsp);
     80  1.1  riastrad 			return vma;
     81  1.1  riastrad 		}
     82  1.1  riastrad 
     83  1.1  riastrad 		vma->private = hwsp;
     84  1.1  riastrad 		hwsp->gt = timeline->gt;
     85  1.1  riastrad 		hwsp->vma = vma;
     86  1.1  riastrad 		hwsp->free_bitmap = ~0ull;
     87  1.1  riastrad 		hwsp->gt_timelines = gt;
     88  1.1  riastrad 
     89  1.1  riastrad 		spin_lock_irq(&gt->hwsp_lock);
     90  1.1  riastrad 		list_add(&hwsp->free_link, &gt->hwsp_free_list);
     91  1.1  riastrad 	}
     92  1.1  riastrad 
     93  1.1  riastrad 	GEM_BUG_ON(!hwsp->free_bitmap);
     94  1.1  riastrad 	*cacheline = __ffs64(hwsp->free_bitmap);
     95  1.1  riastrad 	hwsp->free_bitmap &= ~BIT_ULL(*cacheline);
     96  1.1  riastrad 	if (!hwsp->free_bitmap)
     97  1.1  riastrad 		list_del(&hwsp->free_link);
     98  1.1  riastrad 
     99  1.1  riastrad 	spin_unlock_irq(&gt->hwsp_lock);
    100  1.1  riastrad 
    101  1.1  riastrad 	GEM_BUG_ON(hwsp->vma->private != hwsp);
    102  1.1  riastrad 	return hwsp->vma;
    103  1.1  riastrad }
    104  1.1  riastrad 
    105  1.1  riastrad static void __idle_hwsp_free(struct intel_timeline_hwsp *hwsp, int cacheline)
    106  1.1  riastrad {
    107  1.1  riastrad 	struct intel_gt_timelines *gt = hwsp->gt_timelines;
    108  1.1  riastrad 	unsigned long flags;
    109  1.1  riastrad 
    110  1.1  riastrad 	spin_lock_irqsave(&gt->hwsp_lock, flags);
    111  1.1  riastrad 
    112  1.1  riastrad 	/* As a cacheline becomes available, publish the HWSP on the freelist */
    113  1.1  riastrad 	if (!hwsp->free_bitmap)
    114  1.1  riastrad 		list_add_tail(&hwsp->free_link, &gt->hwsp_free_list);
    115  1.1  riastrad 
    116  1.1  riastrad 	GEM_BUG_ON(cacheline >= BITS_PER_TYPE(hwsp->free_bitmap));
    117  1.1  riastrad 	hwsp->free_bitmap |= BIT_ULL(cacheline);
    118  1.1  riastrad 
    119  1.1  riastrad 	/* And if no one is left using it, give the page back to the system */
    120  1.1  riastrad 	if (hwsp->free_bitmap == ~0ull) {
    121  1.1  riastrad 		i915_vma_put(hwsp->vma);
    122  1.1  riastrad 		list_del(&hwsp->free_link);
    123  1.1  riastrad 		kfree(hwsp);
    124  1.1  riastrad 	}
    125  1.1  riastrad 
    126  1.1  riastrad 	spin_unlock_irqrestore(&gt->hwsp_lock, flags);
    127  1.1  riastrad }
    128  1.1  riastrad 
    129  1.1  riastrad static void __idle_cacheline_free(struct intel_timeline_cacheline *cl)
    130  1.1  riastrad {
    131  1.1  riastrad 	GEM_BUG_ON(!i915_active_is_idle(&cl->active));
    132  1.1  riastrad 
    133  1.1  riastrad 	i915_gem_object_unpin_map(cl->hwsp->vma->obj);
    134  1.1  riastrad 	i915_vma_put(cl->hwsp->vma);
    135  1.1  riastrad 	__idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS));
    136  1.1  riastrad 
    137  1.1  riastrad 	i915_active_fini(&cl->active);
    138  1.1  riastrad 	kfree_rcu(cl, rcu);
    139  1.1  riastrad }
    140  1.1  riastrad 
    141  1.1  riastrad __i915_active_call
    142  1.1  riastrad static void __cacheline_retire(struct i915_active *active)
    143  1.1  riastrad {
    144  1.1  riastrad 	struct intel_timeline_cacheline *cl =
    145  1.1  riastrad 		container_of(active, typeof(*cl), active);
    146  1.1  riastrad 
    147  1.1  riastrad 	i915_vma_unpin(cl->hwsp->vma);
    148  1.1  riastrad 	if (ptr_test_bit(cl->vaddr, CACHELINE_FREE))
    149  1.1  riastrad 		__idle_cacheline_free(cl);
    150  1.1  riastrad }
    151  1.1  riastrad 
    152  1.1  riastrad static int __cacheline_active(struct i915_active *active)
    153  1.1  riastrad {
    154  1.1  riastrad 	struct intel_timeline_cacheline *cl =
    155  1.1  riastrad 		container_of(active, typeof(*cl), active);
    156  1.1  riastrad 
    157  1.1  riastrad 	__i915_vma_pin(cl->hwsp->vma);
    158  1.1  riastrad 	return 0;
    159  1.1  riastrad }
    160  1.1  riastrad 
    161  1.1  riastrad static struct intel_timeline_cacheline *
    162  1.1  riastrad cacheline_alloc(struct intel_timeline_hwsp *hwsp, unsigned int cacheline)
    163  1.1  riastrad {
    164  1.1  riastrad 	struct intel_timeline_cacheline *cl;
    165  1.1  riastrad 	void *vaddr;
    166  1.1  riastrad 
    167  1.1  riastrad 	GEM_BUG_ON(cacheline >= BIT(CACHELINE_BITS));
    168  1.1  riastrad 
    169  1.1  riastrad 	cl = kmalloc(sizeof(*cl), GFP_KERNEL);
    170  1.1  riastrad 	if (!cl)
    171  1.1  riastrad 		return ERR_PTR(-ENOMEM);
    172  1.1  riastrad 
    173  1.1  riastrad 	vaddr = i915_gem_object_pin_map(hwsp->vma->obj, I915_MAP_WB);
    174  1.1  riastrad 	if (IS_ERR(vaddr)) {
    175  1.1  riastrad 		kfree(cl);
    176  1.1  riastrad 		return ERR_CAST(vaddr);
    177  1.1  riastrad 	}
    178  1.1  riastrad 
    179  1.1  riastrad 	i915_vma_get(hwsp->vma);
    180  1.1  riastrad 	cl->hwsp = hwsp;
    181  1.1  riastrad 	cl->vaddr = page_pack_bits(vaddr, cacheline);
    182  1.1  riastrad 
    183  1.1  riastrad 	i915_active_init(&cl->active, __cacheline_active, __cacheline_retire);
    184  1.1  riastrad 
    185  1.1  riastrad 	return cl;
    186  1.1  riastrad }
    187  1.1  riastrad 
    188  1.1  riastrad static void cacheline_acquire(struct intel_timeline_cacheline *cl)
    189  1.1  riastrad {
    190  1.1  riastrad 	if (cl)
    191  1.1  riastrad 		i915_active_acquire(&cl->active);
    192  1.1  riastrad }
    193  1.1  riastrad 
    194  1.1  riastrad static void cacheline_release(struct intel_timeline_cacheline *cl)
    195  1.1  riastrad {
    196  1.1  riastrad 	if (cl)
    197  1.1  riastrad 		i915_active_release(&cl->active);
    198  1.1  riastrad }
    199  1.1  riastrad 
    200  1.1  riastrad static void cacheline_free(struct intel_timeline_cacheline *cl)
    201  1.1  riastrad {
    202  1.1  riastrad 	GEM_BUG_ON(ptr_test_bit(cl->vaddr, CACHELINE_FREE));
    203  1.1  riastrad 	cl->vaddr = ptr_set_bit(cl->vaddr, CACHELINE_FREE);
    204  1.1  riastrad 
    205  1.1  riastrad 	if (i915_active_is_idle(&cl->active))
    206  1.1  riastrad 		__idle_cacheline_free(cl);
    207  1.1  riastrad }
    208  1.1  riastrad 
    209  1.1  riastrad int intel_timeline_init(struct intel_timeline *timeline,
    210  1.1  riastrad 			struct intel_gt *gt,
    211  1.1  riastrad 			struct i915_vma *hwsp)
    212  1.1  riastrad {
    213  1.1  riastrad 	void *vaddr;
    214  1.1  riastrad 
    215  1.1  riastrad 	kref_init(&timeline->kref);
    216  1.1  riastrad 	atomic_set(&timeline->pin_count, 0);
    217  1.1  riastrad 
    218  1.1  riastrad 	timeline->gt = gt;
    219  1.1  riastrad 
    220  1.1  riastrad 	timeline->has_initial_breadcrumb = !hwsp;
    221  1.1  riastrad 	timeline->hwsp_cacheline = NULL;
    222  1.1  riastrad 
    223  1.1  riastrad 	if (!hwsp) {
    224  1.1  riastrad 		struct intel_timeline_cacheline *cl;
    225  1.1  riastrad 		unsigned int cacheline;
    226  1.1  riastrad 
    227  1.1  riastrad 		hwsp = hwsp_alloc(timeline, &cacheline);
    228  1.1  riastrad 		if (IS_ERR(hwsp))
    229  1.1  riastrad 			return PTR_ERR(hwsp);
    230  1.1  riastrad 
    231  1.1  riastrad 		cl = cacheline_alloc(hwsp->private, cacheline);
    232  1.1  riastrad 		if (IS_ERR(cl)) {
    233  1.1  riastrad 			__idle_hwsp_free(hwsp->private, cacheline);
    234  1.1  riastrad 			return PTR_ERR(cl);
    235  1.1  riastrad 		}
    236  1.1  riastrad 
    237  1.1  riastrad 		timeline->hwsp_cacheline = cl;
    238  1.1  riastrad 		timeline->hwsp_offset = cacheline * CACHELINE_BYTES;
    239  1.1  riastrad 
    240  1.1  riastrad 		vaddr = page_mask_bits(cl->vaddr);
    241  1.1  riastrad 	} else {
    242  1.1  riastrad 		timeline->hwsp_offset = I915_GEM_HWS_SEQNO_ADDR;
    243  1.1  riastrad 
    244  1.1  riastrad 		vaddr = i915_gem_object_pin_map(hwsp->obj, I915_MAP_WB);
    245  1.1  riastrad 		if (IS_ERR(vaddr))
    246  1.1  riastrad 			return PTR_ERR(vaddr);
    247  1.1  riastrad 	}
    248  1.1  riastrad 
    249  1.1  riastrad 	timeline->hwsp_seqno =
    250  1.1  riastrad 		memset(vaddr + timeline->hwsp_offset, 0, CACHELINE_BYTES);
    251  1.1  riastrad 
    252  1.1  riastrad 	timeline->hwsp_ggtt = i915_vma_get(hwsp);
    253  1.1  riastrad 	GEM_BUG_ON(timeline->hwsp_offset >= hwsp->size);
    254  1.1  riastrad 
    255  1.1  riastrad 	timeline->fence_context = dma_fence_context_alloc(1);
    256  1.1  riastrad 
    257  1.1  riastrad 	mutex_init(&timeline->mutex);
    258  1.1  riastrad 
    259  1.1  riastrad 	INIT_ACTIVE_FENCE(&timeline->last_request);
    260  1.1  riastrad 	INIT_LIST_HEAD(&timeline->requests);
    261  1.1  riastrad 
    262  1.1  riastrad 	i915_syncmap_init(&timeline->sync);
    263  1.1  riastrad 
    264  1.1  riastrad 	return 0;
    265  1.1  riastrad }
    266  1.1  riastrad 
    267  1.1  riastrad void intel_gt_init_timelines(struct intel_gt *gt)
    268  1.1  riastrad {
    269  1.1  riastrad 	struct intel_gt_timelines *timelines = &gt->timelines;
    270  1.1  riastrad 
    271  1.1  riastrad 	spin_lock_init(&timelines->lock);
    272  1.1  riastrad 	INIT_LIST_HEAD(&timelines->active_list);
    273  1.1  riastrad 
    274  1.1  riastrad 	spin_lock_init(&timelines->hwsp_lock);
    275  1.1  riastrad 	INIT_LIST_HEAD(&timelines->hwsp_free_list);
    276  1.1  riastrad }
    277  1.1  riastrad 
    278  1.1  riastrad void intel_timeline_fini(struct intel_timeline *timeline)
    279  1.1  riastrad {
    280  1.1  riastrad 	GEM_BUG_ON(atomic_read(&timeline->pin_count));
    281  1.1  riastrad 	GEM_BUG_ON(!list_empty(&timeline->requests));
    282  1.1  riastrad 	GEM_BUG_ON(timeline->retire);
    283  1.1  riastrad 
    284  1.1  riastrad 	if (timeline->hwsp_cacheline)
    285  1.1  riastrad 		cacheline_free(timeline->hwsp_cacheline);
    286  1.1  riastrad 	else
    287  1.1  riastrad 		i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj);
    288  1.1  riastrad 
    289  1.1  riastrad 	i915_vma_put(timeline->hwsp_ggtt);
    290  1.4  riastrad 
    291  1.4  riastrad 	mutex_destroy(&timeline->mutex);
    292  1.1  riastrad }
    293  1.1  riastrad 
    294  1.1  riastrad struct intel_timeline *
    295  1.1  riastrad intel_timeline_create(struct intel_gt *gt, struct i915_vma *global_hwsp)
    296  1.1  riastrad {
    297  1.1  riastrad 	struct intel_timeline *timeline;
    298  1.1  riastrad 	int err;
    299  1.1  riastrad 
    300  1.1  riastrad 	timeline = kzalloc(sizeof(*timeline), GFP_KERNEL);
    301  1.1  riastrad 	if (!timeline)
    302  1.1  riastrad 		return ERR_PTR(-ENOMEM);
    303  1.1  riastrad 
    304  1.1  riastrad 	err = intel_timeline_init(timeline, gt, global_hwsp);
    305  1.1  riastrad 	if (err) {
    306  1.1  riastrad 		kfree(timeline);
    307  1.1  riastrad 		return ERR_PTR(err);
    308  1.1  riastrad 	}
    309  1.1  riastrad 
    310  1.1  riastrad 	return timeline;
    311  1.1  riastrad }
    312  1.1  riastrad 
    313  1.1  riastrad int intel_timeline_pin(struct intel_timeline *tl)
    314  1.1  riastrad {
    315  1.1  riastrad 	int err;
    316  1.1  riastrad 
    317  1.1  riastrad 	if (atomic_add_unless(&tl->pin_count, 1, 0))
    318  1.1  riastrad 		return 0;
    319  1.1  riastrad 
    320  1.1  riastrad 	err = i915_vma_pin(tl->hwsp_ggtt, 0, 0, PIN_GLOBAL | PIN_HIGH);
    321  1.1  riastrad 	if (err)
    322  1.1  riastrad 		return err;
    323  1.1  riastrad 
    324  1.1  riastrad 	tl->hwsp_offset =
    325  1.1  riastrad 		i915_ggtt_offset(tl->hwsp_ggtt) +
    326  1.1  riastrad 		offset_in_page(tl->hwsp_offset);
    327  1.1  riastrad 
    328  1.1  riastrad 	cacheline_acquire(tl->hwsp_cacheline);
    329  1.1  riastrad 	if (atomic_fetch_inc(&tl->pin_count)) {
    330  1.1  riastrad 		cacheline_release(tl->hwsp_cacheline);
    331  1.1  riastrad 		__i915_vma_unpin(tl->hwsp_ggtt);
    332  1.1  riastrad 	}
    333  1.1  riastrad 
    334  1.1  riastrad 	return 0;
    335  1.1  riastrad }
    336  1.1  riastrad 
    337  1.1  riastrad void intel_timeline_enter(struct intel_timeline *tl)
    338  1.1  riastrad {
    339  1.1  riastrad 	struct intel_gt_timelines *timelines = &tl->gt->timelines;
    340  1.1  riastrad 
    341  1.1  riastrad 	/*
    342  1.1  riastrad 	 * Pretend we are serialised by the timeline->mutex.
    343  1.1  riastrad 	 *
    344  1.1  riastrad 	 * While generally true, there are a few exceptions to the rule
    345  1.1  riastrad 	 * for the engine->kernel_context being used to manage power
    346  1.1  riastrad 	 * transitions. As the engine_park may be called from under any
    347  1.1  riastrad 	 * timeline, it uses the power mutex as a global serialisation
    348  1.1  riastrad 	 * lock to prevent any other request entering its timeline.
    349  1.1  riastrad 	 *
    350  1.1  riastrad 	 * The rule is generally tl->mutex, otherwise engine->wakeref.mutex.
    351  1.1  riastrad 	 *
    352  1.1  riastrad 	 * However, intel_gt_retire_request() does not know which engine
    353  1.1  riastrad 	 * it is retiring along and so cannot partake in the engine-pm
    354  1.1  riastrad 	 * barrier, and there we use the tl->active_count as a means to
    355  1.1  riastrad 	 * pin the timeline in the active_list while the locks are dropped.
    356  1.1  riastrad 	 * Ergo, as that is outside of the engine-pm barrier, we need to
    357  1.1  riastrad 	 * use atomic to manipulate tl->active_count.
    358  1.1  riastrad 	 */
    359  1.1  riastrad 	lockdep_assert_held(&tl->mutex);
    360  1.1  riastrad 
    361  1.1  riastrad 	if (atomic_add_unless(&tl->active_count, 1, 0))
    362  1.1  riastrad 		return;
    363  1.1  riastrad 
    364  1.1  riastrad 	spin_lock(&timelines->lock);
    365  1.1  riastrad 	if (!atomic_fetch_inc(&tl->active_count))
    366  1.1  riastrad 		list_add_tail(&tl->link, &timelines->active_list);
    367  1.1  riastrad 	spin_unlock(&timelines->lock);
    368  1.1  riastrad }
    369  1.1  riastrad 
    370  1.1  riastrad void intel_timeline_exit(struct intel_timeline *tl)
    371  1.1  riastrad {
    372  1.1  riastrad 	struct intel_gt_timelines *timelines = &tl->gt->timelines;
    373  1.1  riastrad 
    374  1.1  riastrad 	/* See intel_timeline_enter() */
    375  1.1  riastrad 	lockdep_assert_held(&tl->mutex);
    376  1.1  riastrad 
    377  1.1  riastrad 	GEM_BUG_ON(!atomic_read(&tl->active_count));
    378  1.1  riastrad 	if (atomic_add_unless(&tl->active_count, -1, 1))
    379  1.1  riastrad 		return;
    380  1.1  riastrad 
    381  1.1  riastrad 	spin_lock(&timelines->lock);
    382  1.1  riastrad 	if (atomic_dec_and_test(&tl->active_count))
    383  1.1  riastrad 		list_del(&tl->link);
    384  1.1  riastrad 	spin_unlock(&timelines->lock);
    385  1.1  riastrad 
    386  1.1  riastrad 	/*
    387  1.1  riastrad 	 * Since this timeline is idle, all bariers upon which we were waiting
    388  1.1  riastrad 	 * must also be complete and so we can discard the last used barriers
    389  1.1  riastrad 	 * without loss of information.
    390  1.1  riastrad 	 */
    391  1.1  riastrad 	i915_syncmap_free(&tl->sync);
    392  1.1  riastrad }
    393  1.1  riastrad 
    394  1.1  riastrad static u32 timeline_advance(struct intel_timeline *tl)
    395  1.1  riastrad {
    396  1.1  riastrad 	GEM_BUG_ON(!atomic_read(&tl->pin_count));
    397  1.1  riastrad 	GEM_BUG_ON(tl->seqno & tl->has_initial_breadcrumb);
    398  1.1  riastrad 
    399  1.1  riastrad 	return tl->seqno += 1 + tl->has_initial_breadcrumb;
    400  1.1  riastrad }
    401  1.1  riastrad 
    402  1.1  riastrad static void timeline_rollback(struct intel_timeline *tl)
    403  1.1  riastrad {
    404  1.1  riastrad 	tl->seqno -= 1 + tl->has_initial_breadcrumb;
    405  1.1  riastrad }
    406  1.1  riastrad 
    407  1.1  riastrad static noinline int
    408  1.1  riastrad __intel_timeline_get_seqno(struct intel_timeline *tl,
    409  1.1  riastrad 			   struct i915_request *rq,
    410  1.1  riastrad 			   u32 *seqno)
    411  1.1  riastrad {
    412  1.1  riastrad 	struct intel_timeline_cacheline *cl;
    413  1.1  riastrad 	unsigned int cacheline;
    414  1.1  riastrad 	struct i915_vma *vma;
    415  1.1  riastrad 	void *vaddr;
    416  1.1  riastrad 	int err;
    417  1.1  riastrad 
    418  1.1  riastrad 	/*
    419  1.1  riastrad 	 * If there is an outstanding GPU reference to this cacheline,
    420  1.1  riastrad 	 * such as it being sampled by a HW semaphore on another timeline,
    421  1.1  riastrad 	 * we cannot wraparound our seqno value (the HW semaphore does
    422  1.1  riastrad 	 * a strict greater-than-or-equals compare, not i915_seqno_passed).
    423  1.1  riastrad 	 * So if the cacheline is still busy, we must detach ourselves
    424  1.1  riastrad 	 * from it and leave it inflight alongside its users.
    425  1.1  riastrad 	 *
    426  1.1  riastrad 	 * However, if nobody is watching and we can guarantee that nobody
    427  1.1  riastrad 	 * will, we could simply reuse the same cacheline.
    428  1.1  riastrad 	 *
    429  1.1  riastrad 	 * if (i915_active_request_is_signaled(&tl->last_request) &&
    430  1.1  riastrad 	 *     i915_active_is_signaled(&tl->hwsp_cacheline->active))
    431  1.1  riastrad 	 *	return 0;
    432  1.1  riastrad 	 *
    433  1.1  riastrad 	 * That seems unlikely for a busy timeline that needed to wrap in
    434  1.1  riastrad 	 * the first place, so just replace the cacheline.
    435  1.1  riastrad 	 */
    436  1.1  riastrad 
    437  1.1  riastrad 	vma = hwsp_alloc(tl, &cacheline);
    438  1.1  riastrad 	if (IS_ERR(vma)) {
    439  1.1  riastrad 		err = PTR_ERR(vma);
    440  1.1  riastrad 		goto err_rollback;
    441  1.1  riastrad 	}
    442  1.1  riastrad 
    443  1.1  riastrad 	err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
    444  1.1  riastrad 	if (err) {
    445  1.1  riastrad 		__idle_hwsp_free(vma->private, cacheline);
    446  1.1  riastrad 		goto err_rollback;
    447  1.1  riastrad 	}
    448  1.1  riastrad 
    449  1.1  riastrad 	cl = cacheline_alloc(vma->private, cacheline);
    450  1.1  riastrad 	if (IS_ERR(cl)) {
    451  1.1  riastrad 		err = PTR_ERR(cl);
    452  1.1  riastrad 		__idle_hwsp_free(vma->private, cacheline);
    453  1.1  riastrad 		goto err_unpin;
    454  1.1  riastrad 	}
    455  1.1  riastrad 	GEM_BUG_ON(cl->hwsp->vma != vma);
    456  1.1  riastrad 
    457  1.1  riastrad 	/*
    458  1.1  riastrad 	 * Attach the old cacheline to the current request, so that we only
    459  1.1  riastrad 	 * free it after the current request is retired, which ensures that
    460  1.1  riastrad 	 * all writes into the cacheline from previous requests are complete.
    461  1.1  riastrad 	 */
    462  1.1  riastrad 	err = i915_active_ref(&tl->hwsp_cacheline->active, tl, &rq->fence);
    463  1.1  riastrad 	if (err)
    464  1.1  riastrad 		goto err_cacheline;
    465  1.1  riastrad 
    466  1.1  riastrad 	cacheline_release(tl->hwsp_cacheline); /* ownership now xfered to rq */
    467  1.1  riastrad 	cacheline_free(tl->hwsp_cacheline);
    468  1.1  riastrad 
    469  1.1  riastrad 	i915_vma_unpin(tl->hwsp_ggtt); /* binding kept alive by old cacheline */
    470  1.1  riastrad 	i915_vma_put(tl->hwsp_ggtt);
    471  1.1  riastrad 
    472  1.1  riastrad 	tl->hwsp_ggtt = i915_vma_get(vma);
    473  1.1  riastrad 
    474  1.1  riastrad 	vaddr = page_mask_bits(cl->vaddr);
    475  1.1  riastrad 	tl->hwsp_offset = cacheline * CACHELINE_BYTES;
    476  1.1  riastrad 	tl->hwsp_seqno =
    477  1.1  riastrad 		memset(vaddr + tl->hwsp_offset, 0, CACHELINE_BYTES);
    478  1.1  riastrad 
    479  1.1  riastrad 	tl->hwsp_offset += i915_ggtt_offset(vma);
    480  1.1  riastrad 
    481  1.1  riastrad 	cacheline_acquire(cl);
    482  1.1  riastrad 	tl->hwsp_cacheline = cl;
    483  1.1  riastrad 
    484  1.1  riastrad 	*seqno = timeline_advance(tl);
    485  1.1  riastrad 	GEM_BUG_ON(i915_seqno_passed(*tl->hwsp_seqno, *seqno));
    486  1.1  riastrad 	return 0;
    487  1.1  riastrad 
    488  1.1  riastrad err_cacheline:
    489  1.1  riastrad 	cacheline_free(cl);
    490  1.1  riastrad err_unpin:
    491  1.1  riastrad 	i915_vma_unpin(vma);
    492  1.1  riastrad err_rollback:
    493  1.1  riastrad 	timeline_rollback(tl);
    494  1.1  riastrad 	return err;
    495  1.1  riastrad }
    496  1.1  riastrad 
    497  1.1  riastrad int intel_timeline_get_seqno(struct intel_timeline *tl,
    498  1.1  riastrad 			     struct i915_request *rq,
    499  1.1  riastrad 			     u32 *seqno)
    500  1.1  riastrad {
    501  1.1  riastrad 	*seqno = timeline_advance(tl);
    502  1.1  riastrad 
    503  1.1  riastrad 	/* Replace the HWSP on wraparound for HW semaphores */
    504  1.1  riastrad 	if (unlikely(!*seqno && tl->hwsp_cacheline))
    505  1.1  riastrad 		return __intel_timeline_get_seqno(tl, rq, seqno);
    506  1.1  riastrad 
    507  1.1  riastrad 	return 0;
    508  1.1  riastrad }
    509  1.1  riastrad 
    510  1.1  riastrad static int cacheline_ref(struct intel_timeline_cacheline *cl,
    511  1.1  riastrad 			 struct i915_request *rq)
    512  1.1  riastrad {
    513  1.1  riastrad 	return i915_active_add_request(&cl->active, rq);
    514  1.1  riastrad }
    515  1.1  riastrad 
    516  1.1  riastrad int intel_timeline_read_hwsp(struct i915_request *from,
    517  1.1  riastrad 			     struct i915_request *to,
    518  1.1  riastrad 			     u32 *hwsp)
    519  1.1  riastrad {
    520  1.1  riastrad 	struct intel_timeline_cacheline *cl;
    521  1.1  riastrad 	int err;
    522  1.1  riastrad 
    523  1.1  riastrad 	GEM_BUG_ON(!rcu_access_pointer(from->hwsp_cacheline));
    524  1.1  riastrad 
    525  1.1  riastrad 	rcu_read_lock();
    526  1.1  riastrad 	cl = rcu_dereference(from->hwsp_cacheline);
    527  1.1  riastrad 	if (unlikely(!i915_active_acquire_if_busy(&cl->active)))
    528  1.1  riastrad 		goto unlock; /* seqno wrapped and completed! */
    529  1.1  riastrad 	if (unlikely(i915_request_completed(from)))
    530  1.1  riastrad 		goto release;
    531  1.1  riastrad 	rcu_read_unlock();
    532  1.1  riastrad 
    533  1.1  riastrad 	err = cacheline_ref(cl, to);
    534  1.1  riastrad 	if (err)
    535  1.1  riastrad 		goto out;
    536  1.1  riastrad 
    537  1.1  riastrad 	*hwsp = i915_ggtt_offset(cl->hwsp->vma) +
    538  1.1  riastrad 		ptr_unmask_bits(cl->vaddr, CACHELINE_BITS) * CACHELINE_BYTES;
    539  1.1  riastrad 
    540  1.1  riastrad out:
    541  1.1  riastrad 	i915_active_release(&cl->active);
    542  1.1  riastrad 	return err;
    543  1.1  riastrad 
    544  1.1  riastrad release:
    545  1.1  riastrad 	i915_active_release(&cl->active);
    546  1.1  riastrad unlock:
    547  1.1  riastrad 	rcu_read_unlock();
    548  1.1  riastrad 	return 1;
    549  1.1  riastrad }
    550  1.1  riastrad 
    551  1.1  riastrad void intel_timeline_unpin(struct intel_timeline *tl)
    552  1.1  riastrad {
    553  1.1  riastrad 	GEM_BUG_ON(!atomic_read(&tl->pin_count));
    554  1.1  riastrad 	if (!atomic_dec_and_test(&tl->pin_count))
    555  1.1  riastrad 		return;
    556  1.1  riastrad 
    557  1.1  riastrad 	cacheline_release(tl->hwsp_cacheline);
    558  1.1  riastrad 
    559  1.1  riastrad 	__i915_vma_unpin(tl->hwsp_ggtt);
    560  1.1  riastrad }
    561  1.1  riastrad 
    562  1.1  riastrad void __intel_timeline_free(struct kref *kref)
    563  1.1  riastrad {
    564  1.1  riastrad 	struct intel_timeline *timeline =
    565  1.1  riastrad 		container_of(kref, typeof(*timeline), kref);
    566  1.1  riastrad 
    567  1.1  riastrad 	intel_timeline_fini(timeline);
    568  1.1  riastrad 	kfree_rcu(timeline, rcu);
    569  1.1  riastrad }
    570  1.1  riastrad 
    571  1.1  riastrad void intel_gt_fini_timelines(struct intel_gt *gt)
    572  1.1  riastrad {
    573  1.1  riastrad 	struct intel_gt_timelines *timelines = &gt->timelines;
    574  1.1  riastrad 
    575  1.1  riastrad 	GEM_BUG_ON(!list_empty(&timelines->active_list));
    576  1.1  riastrad 	GEM_BUG_ON(!list_empty(&timelines->hwsp_free_list));
    577  1.5  riastrad 
    578  1.5  riastrad 	spin_lock_destroy(&timelines->hwsp_lock);
    579  1.5  riastrad 	spin_lock_destroy(&timelines->lock);
    580  1.1  riastrad }
    581  1.1  riastrad 
    582  1.1  riastrad #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
    583  1.1  riastrad #include "gt/selftests/mock_timeline.c"
    584  1.1  riastrad #include "gt/selftest_timeline.c"
    585  1.1  riastrad #endif
    586