2019-05-28 10:29:51 +01:00
/*
* SPDX - License - Identifier : MIT
*
* Copyright © 2019 Intel Corporation
*/
# include "i915_drv.h"
# include "i915_gem_object.h"
struct stub_fence {
struct dma_fence dma ;
struct i915_sw_fence chain ;
} ;
static int __i915_sw_fence_call
stub_notify ( struct i915_sw_fence * fence , enum i915_sw_fence_notify state )
{
struct stub_fence * stub = container_of ( fence , typeof ( * stub ) , chain ) ;
switch ( state ) {
case FENCE_COMPLETE :
dma_fence_signal ( & stub - > dma ) ;
break ;
case FENCE_FREE :
dma_fence_put ( & stub - > dma ) ;
break ;
}
return NOTIFY_DONE ;
}
static const char * stub_driver_name ( struct dma_fence * fence )
{
return DRIVER_NAME ;
}
static const char * stub_timeline_name ( struct dma_fence * fence )
{
return " object " ;
}
static void stub_release ( struct dma_fence * fence )
{
struct stub_fence * stub = container_of ( fence , typeof ( * stub ) , dma ) ;
i915_sw_fence_fini ( & stub - > chain ) ;
BUILD_BUG_ON ( offsetof ( typeof ( * stub ) , dma ) ) ;
dma_fence_free ( & stub - > dma ) ;
}
static const struct dma_fence_ops stub_fence_ops = {
. get_driver_name = stub_driver_name ,
. get_timeline_name = stub_timeline_name ,
. release = stub_release ,
} ;
struct dma_fence *
i915_gem_object_lock_fence ( struct drm_i915_gem_object * obj )
{
struct stub_fence * stub ;
assert_object_held ( obj ) ;
stub = kmalloc ( sizeof ( * stub ) , GFP_KERNEL ) ;
if ( ! stub )
return NULL ;
i915_sw_fence_init ( & stub - > chain , stub_notify ) ;
dma_fence_init ( & stub - > dma , & stub_fence_ops , & stub - > chain . wait . lock ,
2019-08-19 19:44:03 +01:00
0 , 0 ) ;
2019-05-28 10:29:51 +01:00
if ( i915_sw_fence_await_reservation ( & stub - > chain ,
2019-06-18 13:58:58 +01:00
obj - > base . resv , NULL ,
2019-05-28 10:29:51 +01:00
true , I915_FENCE_TIMEOUT ,
I915_FENCE_GFP ) < 0 )
goto err ;
2019-08-11 10:06:32 +02:00
dma_resv_add_excl_fence ( obj - > base . resv , & stub - > dma ) ;
2019-05-28 10:29:51 +01:00
return & stub - > dma ;
err :
stub_release ( & stub - > dma ) ;
return NULL ;
}
void i915_gem_object_unlock_fence ( struct drm_i915_gem_object * obj ,
struct dma_fence * fence )
{
struct stub_fence * stub = container_of ( fence , typeof ( * stub ) , dma ) ;
i915_sw_fence_commit ( & stub - > chain ) ;
}