xref: /linux/drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h (revision eeb9f5c2dcec90009d7cf12e780e7f9631993fc5)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright © 2019 Intel Corporation
4  */
5 
6 #ifndef __INTEL_BREADCRUMBS_TYPES__
7 #define __INTEL_BREADCRUMBS_TYPES__
8 
9 #include <linux/irq_work.h>
10 #include <linux/kref.h>
11 #include <linux/list.h>
12 #include <linux/spinlock.h>
13 #include <linux/types.h>
14 
15 #include "intel_engine_types.h"
16 #include "intel_wakeref.h"
17 
18 /*
19  * Rather than have every client wait upon all user interrupts,
20  * with the herd waking after every interrupt and each doing the
21  * heavyweight seqno dance, we delegate the task (of being the
22  * bottom-half of the user interrupt) to the first client. After
23  * every interrupt, we wake up one client, who does the heavyweight
24  * coherent seqno read and either goes back to sleep (if incomplete),
25  * or wakes up all the completed clients in parallel, before then
26  * transferring the bottom-half status to the next client in the queue.
27  *
28  * Compared to walking the entire list of waiters in a single dedicated
29  * bottom-half, we reduce the latency of the first waiter by avoiding
30  * a context switch, but incur additional coherent seqno reads when
31  * following the chain of request breadcrumbs. Since it is most likely
32  * that we have a single client waiting on each seqno, then reducing
33  * the overhead of waking that client is much preferred.
34  */
35 struct intel_breadcrumbs {
36 	struct kref ref;
37 	atomic_t active;
38 
39 	spinlock_t signalers_lock; /* protects the list of signalers */
40 	struct list_head signalers;
41 	struct llist_head signaled_requests;
42 	atomic_t signaler_active;
43 
44 	spinlock_t irq_lock; /* protects the interrupt from hardirq context */
45 	struct irq_work irq_work; /* for use from inside irq_lock */
46 	unsigned int irq_enabled;
47 	intel_wakeref_t irq_armed;
48 
49 	/* Not all breadcrumbs are attached to physical HW */
50 	intel_engine_mask_t	engine_mask;
51 	struct intel_engine_cs *irq_engine;
52 	bool	(*irq_enable)(struct intel_breadcrumbs *b);
53 	void	(*irq_disable)(struct intel_breadcrumbs *b);
54 };
55 
56 #endif /* __INTEL_BREADCRUMBS_TYPES__ */
57