cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

i915_sw_fence_work.c (2085B)


      1// SPDX-License-Identifier: MIT
      2
      3/*
      4 * Copyright © 2019 Intel Corporation
      5 */
      6
      7#include "i915_sw_fence_work.h"
      8
      9static void fence_complete(struct dma_fence_work *f)
     10{
     11	if (f->ops->release)
     12		f->ops->release(f);
     13	dma_fence_signal(&f->dma);
     14}
     15
     16static void fence_work(struct work_struct *work)
     17{
     18	struct dma_fence_work *f = container_of(work, typeof(*f), work);
     19
     20	f->ops->work(f);
     21
     22	fence_complete(f);
     23	dma_fence_put(&f->dma);
     24}
     25
     26static int
     27fence_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
     28{
     29	struct dma_fence_work *f = container_of(fence, typeof(*f), chain);
     30
     31	switch (state) {
     32	case FENCE_COMPLETE:
     33		if (fence->error)
     34			dma_fence_set_error(&f->dma, fence->error);
     35
     36		if (!f->dma.error) {
     37			dma_fence_get(&f->dma);
     38			if (test_bit(DMA_FENCE_WORK_IMM, &f->dma.flags))
     39				fence_work(&f->work);
     40			else
     41				queue_work(system_unbound_wq, &f->work);
     42		} else {
     43			fence_complete(f);
     44		}
     45		break;
     46
     47	case FENCE_FREE:
     48		dma_fence_put(&f->dma);
     49		break;
     50	}
     51
     52	return NOTIFY_DONE;
     53}
     54
     55static const char *get_driver_name(struct dma_fence *fence)
     56{
     57	return "dma-fence";
     58}
     59
     60static const char *get_timeline_name(struct dma_fence *fence)
     61{
     62	struct dma_fence_work *f = container_of(fence, typeof(*f), dma);
     63
     64	return f->ops->name ?: "work";
     65}
     66
     67static void fence_release(struct dma_fence *fence)
     68{
     69	struct dma_fence_work *f = container_of(fence, typeof(*f), dma);
     70
     71	i915_sw_fence_fini(&f->chain);
     72
     73	BUILD_BUG_ON(offsetof(typeof(*f), dma));
     74	dma_fence_free(&f->dma);
     75}
     76
     77static const struct dma_fence_ops fence_ops = {
     78	.get_driver_name = get_driver_name,
     79	.get_timeline_name = get_timeline_name,
     80	.release = fence_release,
     81};
     82
     83void dma_fence_work_init(struct dma_fence_work *f,
     84			 const struct dma_fence_work_ops *ops)
     85{
     86	f->ops = ops;
     87	spin_lock_init(&f->lock);
     88	dma_fence_init(&f->dma, &fence_ops, &f->lock, 0, 0);
     89	i915_sw_fence_init(&f->chain, fence_notify);
     90	INIT_WORK(&f->work, fence_work);
     91}
     92
     93int dma_fence_work_chain(struct dma_fence_work *f, struct dma_fence *signal)
     94{
     95	if (!signal)
     96		return 0;
     97
     98	return __i915_sw_fence_await_dma_fence(&f->chain, signal, &f->cb);
     99}