dma-fence-unwrap.h (2714B)
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * fence-chain: chain fences together in a timeline 4 * 5 * Copyright (C) 2022 Advanced Micro Devices, Inc. 6 * Authors: 7 * Christian König <christian.koenig@amd.com> 8 */ 9 10#ifndef __LINUX_DMA_FENCE_UNWRAP_H 11#define __LINUX_DMA_FENCE_UNWRAP_H 12 13#include <linux/dma-fence-chain.h> 14#include <linux/dma-fence-array.h> 15 16/** 17 * struct dma_fence_unwrap - cursor into the container structure 18 * 19 * Should be used with dma_fence_unwrap_for_each() iterator macro. 20 */ 21struct dma_fence_unwrap { 22 /** 23 * @chain: potential dma_fence_chain, but can be other fence as well 24 */ 25 struct dma_fence *chain; 26 /** 27 * @array: potential dma_fence_array, but can be other fence as well 28 */ 29 struct dma_fence *array; 30 /** 31 * @index: last returned index if @array is really a dma_fence_array 32 */ 33 unsigned int index; 34}; 35 36/* Internal helper to start new array iteration, don't use directly */ 37static inline struct dma_fence * 38__dma_fence_unwrap_array(struct dma_fence_unwrap * cursor) 39{ 40 cursor->array = dma_fence_chain_contained(cursor->chain); 41 cursor->index = 0; 42 return dma_fence_array_first(cursor->array); 43} 44 45/** 46 * dma_fence_unwrap_first - return the first fence from fence containers 47 * @head: the entrypoint into the containers 48 * @cursor: current position inside the containers 49 * 50 * Unwraps potential dma_fence_chain/dma_fence_array containers and return the 51 * first fence. 52 */ 53static inline struct dma_fence * 54dma_fence_unwrap_first(struct dma_fence *head, struct dma_fence_unwrap *cursor) 55{ 56 cursor->chain = dma_fence_get(head); 57 return __dma_fence_unwrap_array(cursor); 58} 59 60/** 61 * dma_fence_unwrap_next - return the next fence from a fence containers 62 * @cursor: current position inside the containers 63 * 64 * Continue unwrapping the dma_fence_chain/dma_fence_array containers and return 65 * the next fence from them. 66 */ 67static inline struct dma_fence * 68dma_fence_unwrap_next(struct dma_fence_unwrap *cursor) 69{ 70 struct dma_fence *tmp; 71 72 ++cursor->index; 73 tmp = dma_fence_array_next(cursor->array, cursor->index); 74 if (tmp) 75 return tmp; 76 77 cursor->chain = dma_fence_chain_walk(cursor->chain); 78 return __dma_fence_unwrap_array(cursor); 79} 80 81/** 82 * dma_fence_unwrap_for_each - iterate over all fences in containers 83 * @fence: current fence 84 * @cursor: current position inside the containers 85 * @head: starting point for the iterator 86 * 87 * Unwrap dma_fence_chain and dma_fence_array containers and deep dive into all 88 * potential fences in them. If @head is just a normal fence only that one is 89 * returned. 90 */ 91#define dma_fence_unwrap_for_each(fence, cursor, head) \ 92 for (fence = dma_fence_unwrap_first(head, cursor); fence; \ 93 fence = dma_fence_unwrap_next(cursor)) 94 95#endif