162306a36Sopenharmony_ci/* SPDX-License-Identifier: MIT */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright © 2021 Intel Corporation
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef __I915_FILE_PRIVATE_H__
762306a36Sopenharmony_ci#define __I915_FILE_PRIVATE_H__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/mutex.h>
1062306a36Sopenharmony_ci#include <linux/types.h>
1162306a36Sopenharmony_ci#include <linux/xarray.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cistruct drm_i915_private;
1462306a36Sopenharmony_cistruct drm_file;
1562306a36Sopenharmony_cistruct i915_drm_client;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistruct drm_i915_file_private {
1862306a36Sopenharmony_ci	struct drm_i915_private *i915;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci	union {
2162306a36Sopenharmony_ci		struct drm_file *file;
2262306a36Sopenharmony_ci		struct rcu_head rcu;
2362306a36Sopenharmony_ci	};
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	/** @proto_context_lock: Guards all struct i915_gem_proto_context
2662306a36Sopenharmony_ci	 * operations
2762306a36Sopenharmony_ci	 *
2862306a36Sopenharmony_ci	 * This not only guards @proto_context_xa, but is always held
2962306a36Sopenharmony_ci	 * whenever we manipulate any struct i915_gem_proto_context,
3062306a36Sopenharmony_ci	 * including finalizing it on first actual use of the GEM context.
3162306a36Sopenharmony_ci	 *
3262306a36Sopenharmony_ci	 * See i915_gem_proto_context.
3362306a36Sopenharmony_ci	 */
3462306a36Sopenharmony_ci	struct mutex proto_context_lock;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	/** @proto_context_xa: xarray of struct i915_gem_proto_context
3762306a36Sopenharmony_ci	 *
3862306a36Sopenharmony_ci	 * Historically, the context uAPI allowed for two methods of
3962306a36Sopenharmony_ci	 * setting context parameters: SET_CONTEXT_PARAM and
4062306a36Sopenharmony_ci	 * CONTEXT_CREATE_EXT_SETPARAM.  The former is allowed to be called
4162306a36Sopenharmony_ci	 * at any time while the later happens as part of
4262306a36Sopenharmony_ci	 * GEM_CONTEXT_CREATE.  Everything settable via one was settable
4362306a36Sopenharmony_ci	 * via the other.  While some params are fairly simple and setting
4462306a36Sopenharmony_ci	 * them on a live context is harmless such as the context priority,
4562306a36Sopenharmony_ci	 * others are far trickier such as the VM or the set of engines.
4662306a36Sopenharmony_ci	 * In order to swap out the VM, for instance, we have to delay
4762306a36Sopenharmony_ci	 * until all current in-flight work is complete, swap in the new
4862306a36Sopenharmony_ci	 * VM, and then continue.  This leads to a plethora of potential
4962306a36Sopenharmony_ci	 * race conditions we'd really rather avoid.
5062306a36Sopenharmony_ci	 *
5162306a36Sopenharmony_ci	 * We have since disallowed setting these more complex parameters
5262306a36Sopenharmony_ci	 * on active contexts.  This works by delaying the creation of the
5362306a36Sopenharmony_ci	 * actual context until after the client is done configuring it
5462306a36Sopenharmony_ci	 * with SET_CONTEXT_PARAM.  From the perspective of the client, it
5562306a36Sopenharmony_ci	 * has the same u32 context ID the whole time.  From the
5662306a36Sopenharmony_ci	 * perspective of i915, however, it's a struct i915_gem_proto_context
5762306a36Sopenharmony_ci	 * right up until the point where we attempt to do something which
5862306a36Sopenharmony_ci	 * the proto-context can't handle.  Then the struct i915_gem_context
5962306a36Sopenharmony_ci	 * gets created.
6062306a36Sopenharmony_ci	 *
6162306a36Sopenharmony_ci	 * This is accomplished via a little xarray dance.  When
6262306a36Sopenharmony_ci	 * GEM_CONTEXT_CREATE is called, we create a struct
6362306a36Sopenharmony_ci	 * i915_gem_proto_context, reserve a slot in @context_xa but leave
6462306a36Sopenharmony_ci	 * it NULL, and place the proto-context in the corresponding slot
6562306a36Sopenharmony_ci	 * in @proto_context_xa.  Then, in i915_gem_context_lookup(), we
6662306a36Sopenharmony_ci	 * first check @context_xa.  If it's there, we return the struct
6762306a36Sopenharmony_ci	 * i915_gem_context and we're done.  If it's not, we look in
6862306a36Sopenharmony_ci	 * @proto_context_xa and, if we find it there, we create the actual
6962306a36Sopenharmony_ci	 * context and kill the proto-context.
7062306a36Sopenharmony_ci	 *
7162306a36Sopenharmony_ci	 * In order for this dance to work properly, everything which ever
7262306a36Sopenharmony_ci	 * touches a struct i915_gem_proto_context is guarded by
7362306a36Sopenharmony_ci	 * @proto_context_lock, including context creation.  Yes, this
7462306a36Sopenharmony_ci	 * means context creation now takes a giant global lock but it
7562306a36Sopenharmony_ci	 * can't really be helped and that should never be on any driver's
7662306a36Sopenharmony_ci	 * fast-path anyway.
7762306a36Sopenharmony_ci	 */
7862306a36Sopenharmony_ci	struct xarray proto_context_xa;
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	/** @context_xa: xarray of fully created i915_gem_context
8162306a36Sopenharmony_ci	 *
8262306a36Sopenharmony_ci	 * Write access to this xarray is guarded by @proto_context_lock.
8362306a36Sopenharmony_ci	 * Otherwise, writers may race with finalize_create_context_locked().
8462306a36Sopenharmony_ci	 *
8562306a36Sopenharmony_ci	 * See @proto_context_xa.
8662306a36Sopenharmony_ci	 */
8762306a36Sopenharmony_ci	struct xarray context_xa;
8862306a36Sopenharmony_ci	struct xarray vm_xa;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	unsigned int bsd_engine;
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci/*
9362306a36Sopenharmony_ci * Every context ban increments per client ban score. Also
9462306a36Sopenharmony_ci * hangs in short succession increments ban score. If ban threshold
9562306a36Sopenharmony_ci * is reached, client is considered banned and submitting more work
9662306a36Sopenharmony_ci * will fail. This is a stop gap measure to limit the badly behaving
9762306a36Sopenharmony_ci * clients access to gpu. Note that unbannable contexts never increment
9862306a36Sopenharmony_ci * the client ban score.
9962306a36Sopenharmony_ci */
10062306a36Sopenharmony_ci#define I915_CLIENT_SCORE_HANG_FAST	1
10162306a36Sopenharmony_ci#define   I915_CLIENT_FAST_HANG_JIFFIES (60 * HZ)
10262306a36Sopenharmony_ci#define I915_CLIENT_SCORE_CONTEXT_BAN   3
10362306a36Sopenharmony_ci#define I915_CLIENT_SCORE_BANNED	9
10462306a36Sopenharmony_ci	/** ban_score: Accumulated score of all ctx bans and fast hangs. */
10562306a36Sopenharmony_ci	atomic_t ban_score;
10662306a36Sopenharmony_ci	unsigned long hang_timestamp;
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci	struct i915_drm_client *client;
10962306a36Sopenharmony_ci};
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci#endif /* __I915_FILE_PRIVATE_H__ */
112