1a85cb24fSFrançois Tigeot /*
2a85cb24fSFrançois Tigeot * Copyright © 2016 Intel Corporation
3a85cb24fSFrançois Tigeot *
4a85cb24fSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a
5a85cb24fSFrançois Tigeot * copy of this software and associated documentation files (the "Software"),
6a85cb24fSFrançois Tigeot * to deal in the Software without restriction, including without limitation
7a85cb24fSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8a85cb24fSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the
9a85cb24fSFrançois Tigeot * Software is furnished to do so, subject to the following conditions:
10a85cb24fSFrançois Tigeot *
11a85cb24fSFrançois Tigeot * The above copyright notice and this permission notice (including the next
12a85cb24fSFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the
13a85cb24fSFrançois Tigeot * Software.
14a85cb24fSFrançois Tigeot *
15a85cb24fSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16a85cb24fSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17a85cb24fSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18a85cb24fSFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19a85cb24fSFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20a85cb24fSFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21a85cb24fSFrançois Tigeot * IN THE SOFTWARE.
22a85cb24fSFrançois Tigeot *
23a85cb24fSFrançois Tigeot */
24a85cb24fSFrançois Tigeot
25a85cb24fSFrançois Tigeot #ifndef __I915_GEM_CONTEXT_H__
26a85cb24fSFrançois Tigeot #define __I915_GEM_CONTEXT_H__
27a85cb24fSFrançois Tigeot
28a85cb24fSFrançois Tigeot #include <linux/bitops.h>
29a85cb24fSFrançois Tigeot #include <linux/list.h>
30*3f2dd94aSFrançois Tigeot #include <linux/radix-tree.h>
31a85cb24fSFrançois Tigeot
32a85cb24fSFrançois Tigeot struct pid;
33a85cb24fSFrançois Tigeot
34a85cb24fSFrançois Tigeot struct drm_device;
35a85cb24fSFrançois Tigeot struct drm_file;
36a85cb24fSFrançois Tigeot
37a85cb24fSFrançois Tigeot struct drm_i915_private;
38a85cb24fSFrançois Tigeot struct drm_i915_file_private;
39a85cb24fSFrançois Tigeot struct i915_hw_ppgtt;
40a85cb24fSFrançois Tigeot struct i915_vma;
41a85cb24fSFrançois Tigeot struct intel_ring;
42a85cb24fSFrançois Tigeot
43a85cb24fSFrançois Tigeot #define DEFAULT_CONTEXT_HANDLE 0
44a85cb24fSFrançois Tigeot
45a85cb24fSFrançois Tigeot /**
46a85cb24fSFrançois Tigeot * struct i915_gem_context - client state
47a85cb24fSFrançois Tigeot *
48a85cb24fSFrançois Tigeot * The struct i915_gem_context represents the combined view of the driver and
49a85cb24fSFrançois Tigeot * logical hardware state for a particular client.
50a85cb24fSFrançois Tigeot */
51a85cb24fSFrançois Tigeot struct i915_gem_context {
52a85cb24fSFrançois Tigeot /** i915: i915 device backpointer */
53a85cb24fSFrançois Tigeot struct drm_i915_private *i915;
54a85cb24fSFrançois Tigeot
55a85cb24fSFrançois Tigeot /** file_priv: owning file descriptor */
56a85cb24fSFrançois Tigeot struct drm_i915_file_private *file_priv;
57a85cb24fSFrançois Tigeot
58a85cb24fSFrançois Tigeot /**
59a85cb24fSFrançois Tigeot * @ppgtt: unique address space (GTT)
60a85cb24fSFrançois Tigeot *
61a85cb24fSFrançois Tigeot * In full-ppgtt mode, each context has its own address space ensuring
62a85cb24fSFrançois Tigeot * complete seperation of one client from all others.
63a85cb24fSFrançois Tigeot *
64a85cb24fSFrançois Tigeot * In other modes, this is a NULL pointer with the expectation that
65a85cb24fSFrançois Tigeot * the caller uses the shared global GTT.
66a85cb24fSFrançois Tigeot */
67a85cb24fSFrançois Tigeot struct i915_hw_ppgtt *ppgtt;
68a85cb24fSFrançois Tigeot
69a85cb24fSFrançois Tigeot /**
70a85cb24fSFrançois Tigeot * @pid: process id of creator
71a85cb24fSFrançois Tigeot *
72a85cb24fSFrançois Tigeot * Note that who created the context may not be the principle user,
73a85cb24fSFrançois Tigeot * as the context may be shared across a local socket. However,
74a85cb24fSFrançois Tigeot * that should only affect the default context, all contexts created
75a85cb24fSFrançois Tigeot * explicitly by the client are expected to be isolated.
76a85cb24fSFrançois Tigeot */
77a85cb24fSFrançois Tigeot pid_t pid;
78a85cb24fSFrançois Tigeot
79a85cb24fSFrançois Tigeot /**
80a85cb24fSFrançois Tigeot * @name: arbitrary name
81a85cb24fSFrançois Tigeot *
82a85cb24fSFrançois Tigeot * A name is constructed for the context from the creator's process
83a85cb24fSFrançois Tigeot * name, pid and user handle in order to uniquely identify the
84a85cb24fSFrançois Tigeot * context in messages.
85a85cb24fSFrançois Tigeot */
86a85cb24fSFrançois Tigeot const char *name;
87a85cb24fSFrançois Tigeot
88a85cb24fSFrançois Tigeot /** link: place with &drm_i915_private.context_list */
89a85cb24fSFrançois Tigeot struct list_head link;
90*3f2dd94aSFrançois Tigeot struct llist_node free_link;
91a85cb24fSFrançois Tigeot
92a85cb24fSFrançois Tigeot /**
93a85cb24fSFrançois Tigeot * @ref: reference count
94a85cb24fSFrançois Tigeot *
95a85cb24fSFrançois Tigeot * A reference to a context is held by both the client who created it
96a85cb24fSFrançois Tigeot * and on each request submitted to the hardware using the request
97a85cb24fSFrançois Tigeot * (to ensure the hardware has access to the state until it has
98a85cb24fSFrançois Tigeot * finished all pending writes). See i915_gem_context_get() and
99a85cb24fSFrançois Tigeot * i915_gem_context_put() for access.
100a85cb24fSFrançois Tigeot */
101a85cb24fSFrançois Tigeot struct kref ref;
102a85cb24fSFrançois Tigeot
103a85cb24fSFrançois Tigeot /**
104*3f2dd94aSFrançois Tigeot * @rcu: rcu_head for deferred freeing.
105*3f2dd94aSFrançois Tigeot */
106*3f2dd94aSFrançois Tigeot struct rcu_head rcu;
107*3f2dd94aSFrançois Tigeot
108*3f2dd94aSFrançois Tigeot /**
109a85cb24fSFrançois Tigeot * @flags: small set of booleans
110a85cb24fSFrançois Tigeot */
111a85cb24fSFrançois Tigeot unsigned long flags;
112a85cb24fSFrançois Tigeot #define CONTEXT_NO_ZEROMAP BIT(0)
113a85cb24fSFrançois Tigeot #define CONTEXT_NO_ERROR_CAPTURE 1
114a85cb24fSFrançois Tigeot #define CONTEXT_CLOSED 2
115a85cb24fSFrançois Tigeot #define CONTEXT_BANNABLE 3
116a85cb24fSFrançois Tigeot #define CONTEXT_BANNED 4
117a85cb24fSFrançois Tigeot #define CONTEXT_FORCE_SINGLE_SUBMISSION 5
118a85cb24fSFrançois Tigeot
119a85cb24fSFrançois Tigeot /**
120a85cb24fSFrançois Tigeot * @hw_id: - unique identifier for the context
121a85cb24fSFrançois Tigeot *
122a85cb24fSFrançois Tigeot * The hardware needs to uniquely identify the context for a few
123a85cb24fSFrançois Tigeot * functions like fault reporting, PASID, scheduling. The
124a85cb24fSFrançois Tigeot * &drm_i915_private.context_hw_ida is used to assign a unqiue
125a85cb24fSFrançois Tigeot * id for the lifetime of the context.
126a85cb24fSFrançois Tigeot */
127a85cb24fSFrançois Tigeot unsigned int hw_id;
128a85cb24fSFrançois Tigeot
129a85cb24fSFrançois Tigeot /**
130a85cb24fSFrançois Tigeot * @user_handle: userspace identifier
131a85cb24fSFrançois Tigeot *
132a85cb24fSFrançois Tigeot * A unique per-file identifier is generated from
133a85cb24fSFrançois Tigeot * &drm_i915_file_private.contexts.
134a85cb24fSFrançois Tigeot */
135a85cb24fSFrançois Tigeot u32 user_handle;
136a85cb24fSFrançois Tigeot
137a85cb24fSFrançois Tigeot /**
138a85cb24fSFrançois Tigeot * @priority: execution and service priority
139a85cb24fSFrançois Tigeot *
140a85cb24fSFrançois Tigeot * All clients are equal, but some are more equal than others!
141a85cb24fSFrançois Tigeot *
142a85cb24fSFrançois Tigeot * Requests from a context with a greater (more positive) value of
143a85cb24fSFrançois Tigeot * @priority will be executed before those with a lower @priority
144a85cb24fSFrançois Tigeot * value, forming a simple QoS.
145a85cb24fSFrançois Tigeot *
146a85cb24fSFrançois Tigeot * The &drm_i915_private.kernel_context is assigned the lowest priority.
147a85cb24fSFrançois Tigeot */
148a85cb24fSFrançois Tigeot int priority;
149a85cb24fSFrançois Tigeot
150a85cb24fSFrançois Tigeot /** ggtt_offset_bias: placement restriction for context objects */
151a85cb24fSFrançois Tigeot u32 ggtt_offset_bias;
152a85cb24fSFrançois Tigeot
153a85cb24fSFrançois Tigeot /** engine: per-engine logical HW state */
154a85cb24fSFrançois Tigeot struct intel_context {
155a85cb24fSFrançois Tigeot struct i915_vma *state;
156a85cb24fSFrançois Tigeot struct intel_ring *ring;
157a85cb24fSFrançois Tigeot u32 *lrc_reg_state;
158a85cb24fSFrançois Tigeot u64 lrc_desc;
159a85cb24fSFrançois Tigeot int pin_count;
160a85cb24fSFrançois Tigeot bool initialised;
161a85cb24fSFrançois Tigeot } engine[I915_NUM_ENGINES];
162a85cb24fSFrançois Tigeot
163a85cb24fSFrançois Tigeot /** ring_size: size for allocating the per-engine ring buffer */
164a85cb24fSFrançois Tigeot u32 ring_size;
165a85cb24fSFrançois Tigeot /** desc_template: invariant fields for the HW context descriptor */
166a85cb24fSFrançois Tigeot u32 desc_template;
167a85cb24fSFrançois Tigeot
168a85cb24fSFrançois Tigeot /** guilty_count: How many times this context has caused a GPU hang. */
169*3f2dd94aSFrançois Tigeot atomic_t guilty_count;
170a85cb24fSFrançois Tigeot /**
171a85cb24fSFrançois Tigeot * @active_count: How many times this context was active during a GPU
172a85cb24fSFrançois Tigeot * hang, but did not cause it.
173a85cb24fSFrançois Tigeot */
174*3f2dd94aSFrançois Tigeot atomic_t active_count;
175a85cb24fSFrançois Tigeot
176a85cb24fSFrançois Tigeot #define CONTEXT_SCORE_GUILTY 10
177a85cb24fSFrançois Tigeot #define CONTEXT_SCORE_BAN_THRESHOLD 40
178a85cb24fSFrançois Tigeot /** ban_score: Accumulated score of all hangs caused by this context. */
179*3f2dd94aSFrançois Tigeot atomic_t ban_score;
180a85cb24fSFrançois Tigeot
181a85cb24fSFrançois Tigeot /** remap_slice: Bitmask of cache lines that need remapping */
182a85cb24fSFrançois Tigeot u8 remap_slice;
183*3f2dd94aSFrançois Tigeot
184*3f2dd94aSFrançois Tigeot /** handles_vma: rbtree to look up our context specific obj/vma for
185*3f2dd94aSFrançois Tigeot * the user handle. (user handles are per fd, but the binding is
186*3f2dd94aSFrançois Tigeot * per vm, which may be one per context or shared with the global GTT)
187*3f2dd94aSFrançois Tigeot */
188*3f2dd94aSFrançois Tigeot struct radix_tree_root handles_vma;
189*3f2dd94aSFrançois Tigeot
190*3f2dd94aSFrançois Tigeot /** handles_list: reverse list of all the rbtree entries in use for
191*3f2dd94aSFrançois Tigeot * this context, which allows us to free all the allocations on
192*3f2dd94aSFrançois Tigeot * context close.
193*3f2dd94aSFrançois Tigeot */
194*3f2dd94aSFrançois Tigeot struct list_head handles_list;
195a85cb24fSFrançois Tigeot };
196a85cb24fSFrançois Tigeot
i915_gem_context_is_closed(const struct i915_gem_context * ctx)197a85cb24fSFrançois Tigeot static inline bool i915_gem_context_is_closed(const struct i915_gem_context *ctx)
198a85cb24fSFrançois Tigeot {
199a85cb24fSFrançois Tigeot return test_bit(CONTEXT_CLOSED, &ctx->flags);
200a85cb24fSFrançois Tigeot }
201a85cb24fSFrançois Tigeot
i915_gem_context_set_closed(struct i915_gem_context * ctx)202a85cb24fSFrançois Tigeot static inline void i915_gem_context_set_closed(struct i915_gem_context *ctx)
203a85cb24fSFrançois Tigeot {
204a85cb24fSFrançois Tigeot GEM_BUG_ON(i915_gem_context_is_closed(ctx));
205a85cb24fSFrançois Tigeot __set_bit(CONTEXT_CLOSED, &ctx->flags);
206a85cb24fSFrançois Tigeot }
207a85cb24fSFrançois Tigeot
i915_gem_context_no_error_capture(const struct i915_gem_context * ctx)208a85cb24fSFrançois Tigeot static inline bool i915_gem_context_no_error_capture(const struct i915_gem_context *ctx)
209a85cb24fSFrançois Tigeot {
210a85cb24fSFrançois Tigeot return test_bit(CONTEXT_NO_ERROR_CAPTURE, &ctx->flags);
211a85cb24fSFrançois Tigeot }
212a85cb24fSFrançois Tigeot
i915_gem_context_set_no_error_capture(struct i915_gem_context * ctx)213a85cb24fSFrançois Tigeot static inline void i915_gem_context_set_no_error_capture(struct i915_gem_context *ctx)
214a85cb24fSFrançois Tigeot {
215a85cb24fSFrançois Tigeot __set_bit(CONTEXT_NO_ERROR_CAPTURE, &ctx->flags);
216a85cb24fSFrançois Tigeot }
217a85cb24fSFrançois Tigeot
i915_gem_context_clear_no_error_capture(struct i915_gem_context * ctx)218a85cb24fSFrançois Tigeot static inline void i915_gem_context_clear_no_error_capture(struct i915_gem_context *ctx)
219a85cb24fSFrançois Tigeot {
220a85cb24fSFrançois Tigeot __clear_bit(CONTEXT_NO_ERROR_CAPTURE, &ctx->flags);
221a85cb24fSFrançois Tigeot }
222a85cb24fSFrançois Tigeot
i915_gem_context_is_bannable(const struct i915_gem_context * ctx)223a85cb24fSFrançois Tigeot static inline bool i915_gem_context_is_bannable(const struct i915_gem_context *ctx)
224a85cb24fSFrançois Tigeot {
225a85cb24fSFrançois Tigeot return test_bit(CONTEXT_BANNABLE, &ctx->flags);
226a85cb24fSFrançois Tigeot }
227a85cb24fSFrançois Tigeot
i915_gem_context_set_bannable(struct i915_gem_context * ctx)228a85cb24fSFrançois Tigeot static inline void i915_gem_context_set_bannable(struct i915_gem_context *ctx)
229a85cb24fSFrançois Tigeot {
230a85cb24fSFrançois Tigeot __set_bit(CONTEXT_BANNABLE, &ctx->flags);
231a85cb24fSFrançois Tigeot }
232a85cb24fSFrançois Tigeot
i915_gem_context_clear_bannable(struct i915_gem_context * ctx)233a85cb24fSFrançois Tigeot static inline void i915_gem_context_clear_bannable(struct i915_gem_context *ctx)
234a85cb24fSFrançois Tigeot {
235a85cb24fSFrançois Tigeot __clear_bit(CONTEXT_BANNABLE, &ctx->flags);
236a85cb24fSFrançois Tigeot }
237a85cb24fSFrançois Tigeot
i915_gem_context_is_banned(const struct i915_gem_context * ctx)238a85cb24fSFrançois Tigeot static inline bool i915_gem_context_is_banned(const struct i915_gem_context *ctx)
239a85cb24fSFrançois Tigeot {
240a85cb24fSFrançois Tigeot return test_bit(CONTEXT_BANNED, &ctx->flags);
241a85cb24fSFrançois Tigeot }
242a85cb24fSFrançois Tigeot
i915_gem_context_set_banned(struct i915_gem_context * ctx)243a85cb24fSFrançois Tigeot static inline void i915_gem_context_set_banned(struct i915_gem_context *ctx)
244a85cb24fSFrançois Tigeot {
245a85cb24fSFrançois Tigeot __set_bit(CONTEXT_BANNED, &ctx->flags);
246a85cb24fSFrançois Tigeot }
247a85cb24fSFrançois Tigeot
i915_gem_context_force_single_submission(const struct i915_gem_context * ctx)248a85cb24fSFrançois Tigeot static inline bool i915_gem_context_force_single_submission(const struct i915_gem_context *ctx)
249a85cb24fSFrançois Tigeot {
250a85cb24fSFrançois Tigeot return test_bit(CONTEXT_FORCE_SINGLE_SUBMISSION, &ctx->flags);
251a85cb24fSFrançois Tigeot }
252a85cb24fSFrançois Tigeot
i915_gem_context_set_force_single_submission(struct i915_gem_context * ctx)253a85cb24fSFrançois Tigeot static inline void i915_gem_context_set_force_single_submission(struct i915_gem_context *ctx)
254a85cb24fSFrançois Tigeot {
255a85cb24fSFrançois Tigeot __set_bit(CONTEXT_FORCE_SINGLE_SUBMISSION, &ctx->flags);
256a85cb24fSFrançois Tigeot }
257a85cb24fSFrançois Tigeot
i915_gem_context_is_default(const struct i915_gem_context * c)258a85cb24fSFrançois Tigeot static inline bool i915_gem_context_is_default(const struct i915_gem_context *c)
259a85cb24fSFrançois Tigeot {
260a85cb24fSFrançois Tigeot return c->user_handle == DEFAULT_CONTEXT_HANDLE;
261a85cb24fSFrançois Tigeot }
262a85cb24fSFrançois Tigeot
i915_gem_context_is_kernel(struct i915_gem_context * ctx)263a85cb24fSFrançois Tigeot static inline bool i915_gem_context_is_kernel(struct i915_gem_context *ctx)
264a85cb24fSFrançois Tigeot {
265a85cb24fSFrançois Tigeot return !ctx->file_priv;
266a85cb24fSFrançois Tigeot }
267a85cb24fSFrançois Tigeot
268a85cb24fSFrançois Tigeot /* i915_gem_context.c */
269*3f2dd94aSFrançois Tigeot int __must_check i915_gem_contexts_init(struct drm_i915_private *dev_priv);
270*3f2dd94aSFrançois Tigeot void i915_gem_contexts_lost(struct drm_i915_private *dev_priv);
271*3f2dd94aSFrançois Tigeot void i915_gem_contexts_fini(struct drm_i915_private *dev_priv);
272*3f2dd94aSFrançois Tigeot
273*3f2dd94aSFrançois Tigeot int i915_gem_context_open(struct drm_i915_private *i915,
274*3f2dd94aSFrançois Tigeot struct drm_file *file);
275*3f2dd94aSFrançois Tigeot void i915_gem_context_close(struct drm_file *file);
276*3f2dd94aSFrançois Tigeot
277a85cb24fSFrançois Tigeot int i915_switch_context(struct drm_i915_gem_request *req);
278a85cb24fSFrançois Tigeot int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv);
279*3f2dd94aSFrançois Tigeot
280*3f2dd94aSFrançois Tigeot void i915_gem_context_release(struct kref *ctx_ref);
281a85cb24fSFrançois Tigeot struct i915_gem_context *
282a85cb24fSFrançois Tigeot i915_gem_context_create_gvt(struct drm_device *dev);
283a85cb24fSFrançois Tigeot
284a85cb24fSFrançois Tigeot int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
285a85cb24fSFrançois Tigeot struct drm_file *file);
286a85cb24fSFrançois Tigeot int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
287a85cb24fSFrançois Tigeot struct drm_file *file);
288a85cb24fSFrançois Tigeot int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
289a85cb24fSFrançois Tigeot struct drm_file *file_priv);
290a85cb24fSFrançois Tigeot int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
291a85cb24fSFrançois Tigeot struct drm_file *file_priv);
292a85cb24fSFrançois Tigeot int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
293a85cb24fSFrançois Tigeot struct drm_file *file);
294a85cb24fSFrançois Tigeot
295*3f2dd94aSFrançois Tigeot static inline struct i915_gem_context *
i915_gem_context_get(struct i915_gem_context * ctx)296*3f2dd94aSFrançois Tigeot i915_gem_context_get(struct i915_gem_context *ctx)
297*3f2dd94aSFrançois Tigeot {
298*3f2dd94aSFrançois Tigeot kref_get(&ctx->ref);
299*3f2dd94aSFrançois Tigeot return ctx;
300*3f2dd94aSFrançois Tigeot }
301*3f2dd94aSFrançois Tigeot
i915_gem_context_put(struct i915_gem_context * ctx)302*3f2dd94aSFrançois Tigeot static inline void i915_gem_context_put(struct i915_gem_context *ctx)
303*3f2dd94aSFrançois Tigeot {
304*3f2dd94aSFrançois Tigeot kref_put(&ctx->ref, i915_gem_context_release);
305*3f2dd94aSFrançois Tigeot }
306*3f2dd94aSFrançois Tigeot
307a85cb24fSFrançois Tigeot #endif /* !__I915_GEM_CONTEXT_H__ */
308