| 1 | /* SPDX-License-Identifier: MIT */ | 
|---|
| 2 | /* | 
|---|
| 3 | * Copyright © 2021 Intel Corporation | 
|---|
| 4 | */ | 
|---|
| 5 |  | 
|---|
| 6 | #ifndef __I915_FILE_PRIVATE_H__ | 
|---|
| 7 | #define __I915_FILE_PRIVATE_H__ | 
|---|
| 8 |  | 
|---|
| 9 | #include <linux/mutex.h> | 
|---|
| 10 | #include <linux/types.h> | 
|---|
| 11 | #include <linux/xarray.h> | 
|---|
| 12 |  | 
|---|
| 13 | struct drm_i915_private; | 
|---|
| 14 | struct drm_file; | 
|---|
| 15 | struct i915_drm_client; | 
|---|
| 16 |  | 
|---|
| 17 | struct drm_i915_file_private { | 
|---|
| 18 | struct drm_i915_private *i915; | 
|---|
| 19 |  | 
|---|
| 20 | union { | 
|---|
| 21 | struct drm_file *file; | 
|---|
| 22 | struct rcu_head rcu; | 
|---|
| 23 | }; | 
|---|
| 24 |  | 
|---|
| 25 | /** @proto_context_lock: Guards all struct i915_gem_proto_context | 
|---|
| 26 | * operations | 
|---|
| 27 | * | 
|---|
| 28 | * This not only guards @proto_context_xa, but is always held | 
|---|
| 29 | * whenever we manipulate any struct i915_gem_proto_context, | 
|---|
| 30 | * including finalizing it on first actual use of the GEM context. | 
|---|
| 31 | * | 
|---|
| 32 | * See i915_gem_proto_context. | 
|---|
| 33 | */ | 
|---|
| 34 | struct mutex proto_context_lock; | 
|---|
| 35 |  | 
|---|
| 36 | /** @proto_context_xa: xarray of struct i915_gem_proto_context | 
|---|
| 37 | * | 
|---|
| 38 | * Historically, the context uAPI allowed for two methods of | 
|---|
| 39 | * setting context parameters: SET_CONTEXT_PARAM and | 
|---|
| 40 | * CONTEXT_CREATE_EXT_SETPARAM.  The former is allowed to be called | 
|---|
| 41 | * at any time while the later happens as part of | 
|---|
| 42 | * GEM_CONTEXT_CREATE.  Everything settable via one was settable | 
|---|
| 43 | * via the other.  While some params are fairly simple and setting | 
|---|
| 44 | * them on a live context is harmless such as the context priority, | 
|---|
| 45 | * others are far trickier such as the VM or the set of engines. | 
|---|
| 46 | * In order to swap out the VM, for instance, we have to delay | 
|---|
| 47 | * until all current in-flight work is complete, swap in the new | 
|---|
| 48 | * VM, and then continue.  This leads to a plethora of potential | 
|---|
| 49 | * race conditions we'd really rather avoid. | 
|---|
| 50 | * | 
|---|
| 51 | * We have since disallowed setting these more complex parameters | 
|---|
| 52 | * on active contexts.  This works by delaying the creation of the | 
|---|
| 53 | * actual context until after the client is done configuring it | 
|---|
| 54 | * with SET_CONTEXT_PARAM.  From the perspective of the client, it | 
|---|
| 55 | * has the same u32 context ID the whole time.  From the | 
|---|
| 56 | * perspective of i915, however, it's a struct i915_gem_proto_context | 
|---|
| 57 | * right up until the point where we attempt to do something which | 
|---|
| 58 | * the proto-context can't handle.  Then the struct i915_gem_context | 
|---|
| 59 | * gets created. | 
|---|
| 60 | * | 
|---|
| 61 | * This is accomplished via a little xarray dance.  When | 
|---|
| 62 | * GEM_CONTEXT_CREATE is called, we create a struct | 
|---|
| 63 | * i915_gem_proto_context, reserve a slot in @context_xa but leave | 
|---|
| 64 | * it NULL, and place the proto-context in the corresponding slot | 
|---|
| 65 | * in @proto_context_xa.  Then, in i915_gem_context_lookup(), we | 
|---|
| 66 | * first check @context_xa.  If it's there, we return the struct | 
|---|
| 67 | * i915_gem_context and we're done.  If it's not, we look in | 
|---|
| 68 | * @proto_context_xa and, if we find it there, we create the actual | 
|---|
| 69 | * context and kill the proto-context. | 
|---|
| 70 | * | 
|---|
| 71 | * In order for this dance to work properly, everything which ever | 
|---|
| 72 | * touches a struct i915_gem_proto_context is guarded by | 
|---|
| 73 | * @proto_context_lock, including context creation.  Yes, this | 
|---|
| 74 | * means context creation now takes a giant global lock but it | 
|---|
| 75 | * can't really be helped and that should never be on any driver's | 
|---|
| 76 | * fast-path anyway. | 
|---|
| 77 | */ | 
|---|
| 78 | struct xarray proto_context_xa; | 
|---|
| 79 |  | 
|---|
| 80 | /** @context_xa: xarray of fully created i915_gem_context | 
|---|
| 81 | * | 
|---|
| 82 | * Write access to this xarray is guarded by @proto_context_lock. | 
|---|
| 83 | * Otherwise, writers may race with finalize_create_context_locked(). | 
|---|
| 84 | * | 
|---|
| 85 | * See @proto_context_xa. | 
|---|
| 86 | */ | 
|---|
| 87 | struct xarray context_xa; | 
|---|
| 88 | struct xarray vm_xa; | 
|---|
| 89 |  | 
|---|
| 90 | unsigned int bsd_engine; | 
|---|
| 91 |  | 
|---|
| 92 | /* | 
|---|
| 93 | * Every context ban increments per client ban score. Also | 
|---|
| 94 | * hangs in short succession increments ban score. If ban threshold | 
|---|
| 95 | * is reached, client is considered banned and submitting more work | 
|---|
| 96 | * will fail. This is a stop gap measure to limit the badly behaving | 
|---|
| 97 | * clients access to gpu. Note that unbannable contexts never increment | 
|---|
| 98 | * the client ban score. | 
|---|
| 99 | */ | 
|---|
| 100 | #define I915_CLIENT_SCORE_HANG_FAST	1 | 
|---|
| 101 | #define   I915_CLIENT_FAST_HANG_JIFFIES (60 * HZ) | 
|---|
| 102 | #define I915_CLIENT_SCORE_CONTEXT_BAN   3 | 
|---|
| 103 | #define I915_CLIENT_SCORE_BANNED	9 | 
|---|
| 104 | /** ban_score: Accumulated score of all ctx bans and fast hangs. */ | 
|---|
| 105 | atomic_t ban_score; | 
|---|
| 106 | unsigned long hang_timestamp; | 
|---|
| 107 |  | 
|---|
| 108 | struct i915_drm_client *client; | 
|---|
| 109 | }; | 
|---|
| 110 |  | 
|---|
| 111 | #endif /* __I915_FILE_PRIVATE_H__ */ | 
|---|
| 112 |  | 
|---|