深入分析——Linux DMA Fence

目录

一 简介

二 基本原理

三 代码实现

3.1 Init

3.2 wait

3.3 signaling

3.4 callback

3.5 signaled

3.6 signal

3.7 refcount & release

四 Fence Status


一 简介

        dma-fence是linux 内核中同步原语,它只有两种状态signaled和unsigned。因为其本身的精简,在融入其他概念中时,在不同的环境下,赋予了dma-fence不同的含义。所以通常需要根据dma-fence的具体使用的情况来理解其含义。

二 基本原理

        一个被初始化的dma-fence,使用wait函数后,会将当前进程换出,即当前进程会sleep,而当调用signal函数时会唤醒被wait函数换出的进程。

        dma-fence的使用还可以通过向dma-fence添加一个或多个callback函数,当dma-fence调用signal操作时,会依次遍历callback list,并调用每个callback函数。当调用wait函数时,会把默认的一个callback函数加入到dma-fence中,而这个函数就起到唤醒的作用。

三 代码实现

3.1 Init

dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,

              spinlock_t *lock, u64 context, u64 seqno)

传入参数:

dma_fencefence这个软件同步原语(software synchronization primitive)的自身struct。

dma_fence_ops是fence回调函数,fence许多功能都是在此实现:

  • use_64bit_seqno
  • get_driver_name : fence所属驱动的名称
  • get_timeline_name:fence所属上下文(进程)的名称,一般是task_struct-> comm
  • enable_signaling:dma_fence_add_callback()和dma_fence_default_wait()调用。
  • signaled:dma_fence_is_signaled()调用。
  • wait:自定义实现dma_fence_wait(),否则就是用默认的dma_fence_default_wait().
  • release:如果refcount等于0,会回调该函数,或者调用dma_fence_release()
  • fence_value_str:用于调试,具体实现根据调试方式使用
  • timeline_value_str:用字符串的形式填充时间线(timeline)

spinlock_t:自旋锁防止竞争

context使用dma_fence_context_alloc分配一个序列号,这是整个OS管理。

seqno一个顺序增长的数,是由驱动自身管理,用原子变量定义最好,防止竞争

作用:

初始化dma_fence中结构体成员,

实现:

有以下几个方面:

  1. 初始化refcount
  2. 挂载dma_fence_ops
  3. 初始化cb_list
  4. 初始化dma_fence ->spinlock
  5. 将dma_fence_context_alloc分配一个序列号赋值给context
  6. 将驱动自身管理的seqno赋值给dma_fence ->seqno
  7. fence->flags=0
  8. fence->error = 0

3.2 wait

dma_fence_wait(struct dma_fence *fence, bool intr)

传入参数:

intr:如果为true,请进行可中断的等待,false为不可中断的等待。

作用:

睡眠,直到fence被signaled或者超时

实现:

如果实现dma_fence_ops->wait则使用,否则使用dma_fence_default_wait(),

dma_fence_default_wait实现:

__dma_fence_enable_signaling(struct dma_fence *fence)

  1. 设置fence->flags为DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT
  2. 如果没有设置过第一步则进行dma_fence_ops->enable_signaling
  3. 第二步成功后执行dma_fence_signal_locked,设置DMA_FENCE_FLAG_SIGNALED_BIT,设置DMA_FENCE_FLAG_TIMESTAMP_BIT,执行cb_list中func

3.3 signaling

dma_fence_enable_sw_signaling(struct dma_fence *fence)

  1. 设置DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT
  2. 如果实现dma_fence_ops ->enable_signaling,则调用否则返回
  3. 如果dma_fence_ops ->enable_signaling调用失败会直接调用dma_fence_signal_locked函数signaled该fence。

3.4 callback

dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb,

                        dma_fence_func_t func)

__dma_fence_enable_signaling(struct dma_fence *fence)

  1. 设置fence->flags为DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT
  2. 如果没有设置过第一步则进行dma_fence_ops->enable_signaling
  3. 第二步成功后执行dma_fence_signal_locked,设置DMA_FENCE_FLAG_SIGNALED_BIT,设置DMA_FENCE_FLAG_TIMESTAMP_BIT,执行cb_list中func
  4. 把callback函数加入到callback list中。

3.5 signaled

 dma_fence_is_signaled(struct dma_fence *fence)

作用:

查看fence是否被signaled,如果被signaled返回true,否则返回false。

实现:

  1. 如果实现dma_fence_ops -> signaled则调用dma_fence_ops -> signaled然后dma_fence_signal(),如果没有实现dma_fence_ops -> signaled则返回false。

3.6 signal

dma_fence_signal (struct dma_fence *fence)

作用:

完成一个fence,会调用callback list中每个callback函数

实现:

执行dma_fence_signal_locked,设置DMA_FENCE_FLAG_SIGNALED_BIT,设置DMA_FENCE_FLAG_TIMESTAMP_BIT,执行cb_list中func。

3.7 refcount & release

dma_fence_get(struct dma_fence *fence)

作用:

增加fence refcount,返回fence

dma_fence_put(struct dma_fence *fence)

作用:

减少fence refcount,返回fence,当refcount减少到0时将release fence。

实现:

  1. refcount减1
  2. 如果refcount等于0则调用dma_fence_release()
  3. dma_fence_release()
  • 如果fence->flag= DMA_FENCE_FLAG_SIGNALED_BIT则需要signal该fence
  • dma_fence_ops-> release实现则使用,否则使用dma_fence_free()释放该fence.

四 Fence Status

DMA_FENCE_FLAG_SIGNALED_BIT - fence is already signaled

DMA_FENCE_FLAG_TIMESTAMP_BIT - timestamp recorded for fence signaling

DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT - enable_signaling might have been called

DMA_FENCE_FLAG_USER_BITS - start of the unused bits, can be used by the implementer of the fence for its own purposes.

signaling fail原因是fence已经被signaled。fence有个特性是只能从signaling到signaled。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值