drivers/md/dm-vdo/funnel-workqueue.c
Source file repositories/reference/linux-study-clean/drivers/md/dm-vdo/funnel-workqueue.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/md/dm-vdo/funnel-workqueue.c- Extension
.c- Size
- 19927 bytes
- Lines
- 643
- Domain
- Driver Families
- Bucket
- drivers/md
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
funnel-workqueue.hlinux/atomic.hlinux/cache.hlinux/completion.hlinux/err.hlinux/kthread.hlinux/percpu.hfunnel-queue.hlogger.hmemory-alloc.hnumeric.hpermassert.hstring-utils.hcompletion.hstatus-codes.h
Detected Declarations
struct vdo_work_queuestruct simple_work_queuestruct round_robin_work_queuefunction enqueue_work_queue_completionfunction run_start_hookfunction run_finish_hookfunction process_completionfunction service_work_queuefunction work_queue_runnerfunction free_simple_work_queuefunction free_round_robin_work_queuefunction vdo_free_work_queuefunction make_simple_work_queuefunction vdo_make_work_queuefunction finish_simple_work_queuefunction finish_round_robin_work_queuefunction vdo_finish_work_queuefunction dump_simple_work_queuefunction vdo_dump_work_queuefunction get_function_namefunction vdo_dump_completion_to_bufferfunction vdo_enqueue_work_queuefunction vdo_get_work_queue_private_datafunction vdo_work_queue_type_is
Annotated Snippet
struct vdo_work_queue {
/* Name of just the work queue (e.g., "cpuQ12") */
char *name;
bool round_robin_mode;
struct vdo_thread *owner;
/* Life cycle functions, etc */
const struct vdo_work_queue_type *type;
};
struct simple_work_queue {
struct vdo_work_queue common;
struct funnel_queue *priority_lists[VDO_WORK_Q_MAX_PRIORITY + 1];
void *private;
/*
* The fields above are unchanged after setup but often read, and are good candidates for
* caching -- and if the max priority is 2, just fit in one x86-64 cache line if aligned.
* The fields below are often modified as we sleep and wake, so we want a separate cache
* line for performance.
*/
/* Any (0 or 1) worker threads waiting for new work to do */
wait_queue_head_t waiting_worker_threads ____cacheline_aligned;
/* Hack to reduce wakeup calls if the worker thread is running */
atomic_t idle;
/* These are infrequently used so in terms of performance we don't care where they land. */
struct task_struct *thread;
/* Notify creator once worker has initialized */
struct completion *started;
};
struct round_robin_work_queue {
struct vdo_work_queue common;
struct simple_work_queue **service_queues;
unsigned int num_service_queues;
};
static inline struct simple_work_queue *as_simple_work_queue(struct vdo_work_queue *queue)
{
return ((queue == NULL) ?
NULL : container_of(queue, struct simple_work_queue, common));
}
static inline struct round_robin_work_queue *as_round_robin_work_queue(struct vdo_work_queue *queue)
{
return ((queue == NULL) ?
NULL :
container_of(queue, struct round_robin_work_queue, common));
}
/* Processing normal completions. */
/*
* Dequeue and return the next waiting completion, if any.
*
* We scan the funnel queues from highest priority to lowest, once; there is therefore a race
* condition where a high-priority completion can be enqueued followed by a lower-priority one, and
* we'll grab the latter (but we'll catch the high-priority item on the next call). If strict
* enforcement of priorities becomes necessary, this function will need fixing.
*/
static struct vdo_completion *poll_for_completion(struct simple_work_queue *queue)
{
int i;
for (i = queue->common.type->max_priority; i >= 0; i--) {
struct funnel_queue_entry *link = vdo_funnel_queue_poll(queue->priority_lists[i]);
if (link != NULL)
return container_of(link, struct vdo_completion, work_queue_entry_link);
}
return NULL;
}
static void enqueue_work_queue_completion(struct simple_work_queue *queue,
struct vdo_completion *completion)
{
VDO_ASSERT_LOG_ONLY(completion->my_queue == NULL,
"completion %px (fn %px) to enqueue (%px) is not already queued (%px)",
completion, completion->callback, queue, completion->my_queue);
if (completion->priority == VDO_WORK_Q_DEFAULT_PRIORITY)
completion->priority = queue->common.type->default_priority;
if (VDO_ASSERT(completion->priority <= queue->common.type->max_priority,
"priority is in range for queue") != VDO_SUCCESS)
completion->priority = 0;
completion->my_queue = &queue->common;
Annotation
- Immediate include surface: `funnel-workqueue.h`, `linux/atomic.h`, `linux/cache.h`, `linux/completion.h`, `linux/err.h`, `linux/kthread.h`, `linux/percpu.h`, `funnel-queue.h`.
- Detected declarations: `struct vdo_work_queue`, `struct simple_work_queue`, `struct round_robin_work_queue`, `function enqueue_work_queue_completion`, `function run_start_hook`, `function run_finish_hook`, `function process_completion`, `function service_work_queue`, `function work_queue_runner`, `function free_simple_work_queue`.
- Atlas domain: Driver Families / drivers/md.
- Implementation status: source 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.