drivers/dma-buf/dma-fence-array.c
Source file repositories/reference/linux-study-clean/drivers/dma-buf/dma-fence-array.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dma-buf/dma-fence-array.c- Extension
.c- Size
- 9669 bytes
- Lines
- 333
- Domain
- Driver Families
- Bucket
- drivers/dma-buf
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hlinux/slab.hlinux/dma-fence-array.h
Detected Declarations
function Copyrightfunction dma_fence_array_set_pending_errorfunction dma_fence_array_clear_pending_errorfunction irq_dma_fence_array_workfunction dma_fence_array_cb_funcfunction dma_fence_array_enable_signalingfunction dma_fence_array_signaledfunction dma_fence_array_releasefunction dma_fence_array_set_deadlinefunction dma_fence_array_initfunction dma_fence_initfunction dma_fence_match_contextexport dma_fence_array_opsexport dma_fence_array_allocexport dma_fence_array_initexport dma_fence_array_createexport dma_fence_match_contextexport dma_fence_array_firstexport dma_fence_array_next
Annotated Snippet
if (atomic_dec_and_test(&array->num_pending)) {
dma_fence_array_clear_pending_error(array);
return false;
}
}
}
return true;
}
static bool dma_fence_array_signaled(struct dma_fence *fence)
{
struct dma_fence_array *array = to_dma_fence_array(fence);
int num_pending;
unsigned int i;
/*
* We need to read num_pending before checking the enable_signal bit
* to avoid racing with the enable_signaling() implementation, which
* might decrement the counter, and cause a partial check.
* atomic_read_acquire() pairs with atomic_dec_and_test() in
* dma_fence_array_enable_signaling()
*
* The !--num_pending check is here to account for the any_signaled case
* if we race with enable_signaling(), that means the !num_pending check
* in the is_signalling_enabled branch might be outdated (num_pending
* might have been decremented), but that's fine. The user will get the
* right value when testing again later.
*/
num_pending = atomic_read_acquire(&array->num_pending);
if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &array->base.flags)) {
if (num_pending <= 0)
goto signal;
return false;
}
for (i = 0; i < array->num_fences; ++i) {
if (dma_fence_is_signaled(array->fences[i]) && !--num_pending)
goto signal;
}
return false;
signal:
dma_fence_array_clear_pending_error(array);
return true;
}
static void dma_fence_array_release(struct dma_fence *fence)
{
struct dma_fence_array *array = to_dma_fence_array(fence);
unsigned i;
for (i = 0; i < array->num_fences; ++i)
dma_fence_put(array->fences[i]);
kfree(array->fences);
dma_fence_free(fence);
}
static void dma_fence_array_set_deadline(struct dma_fence *fence,
ktime_t deadline)
{
struct dma_fence_array *array = to_dma_fence_array(fence);
unsigned i;
for (i = 0; i < array->num_fences; ++i)
dma_fence_set_deadline(array->fences[i], deadline);
}
const struct dma_fence_ops dma_fence_array_ops = {
.get_driver_name = dma_fence_array_get_driver_name,
.get_timeline_name = dma_fence_array_get_timeline_name,
.enable_signaling = dma_fence_array_enable_signaling,
.signaled = dma_fence_array_signaled,
.release = dma_fence_array_release,
.set_deadline = dma_fence_array_set_deadline,
};
EXPORT_SYMBOL(dma_fence_array_ops);
/**
* dma_fence_array_alloc - Allocate a custom fence array
* @num_fences: [in] number of fences to add in the array
*
* Return dma fence array on success, NULL on failure
*/
struct dma_fence_array *dma_fence_array_alloc(int num_fences)
{
struct dma_fence_array *array;
return kzalloc_flex(*array, callbacks, num_fences);
Annotation
- Immediate include surface: `linux/export.h`, `linux/slab.h`, `linux/dma-fence-array.h`.
- Detected declarations: `function Copyright`, `function dma_fence_array_set_pending_error`, `function dma_fence_array_clear_pending_error`, `function irq_dma_fence_array_work`, `function dma_fence_array_cb_func`, `function dma_fence_array_enable_signaling`, `function dma_fence_array_signaled`, `function dma_fence_array_release`, `function dma_fence_array_set_deadline`, `function dma_fence_array_init`.
- Atlas domain: Driver Families / drivers/dma-buf.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.