Skip to content

Commit be1cb55

Browse files
committed
drm/i915/gt: Keep a no-frills swappable copy of the default context state
We need to keep the default context state around to instantiate new contexts (aka golden rendercontext), and we also keep it pinned while the engine is active so that we can quickly reset a hanging context. However, the default contexts are large enough to merit keeping in swappable memory as opposed to kernel memory, so we store them inside shmemfs. Currently, we use the normal GEM objects to create the default context image, but we can throw away all but the shmemfs file. This greatly simplifies the tricky power management code which wants to run underneath the normal GT locking, and we definitely do not want to use any high level objects that may appear to recurse back into the GT. Though perhaps the primary advantage of the complex GEM object is that we aggressively cache the mapping, but here we are recreating the vm_area everytime time we unpark. At the worst, we add a lightweight cache, but first find a microbenchmark that is impacted. Having started to create some utility functions to make working with shmemfs objects easier, we can start putting them to wider use, where GEM objects are overkill, such as storing persistent error state. Signed-off-by: Chris Wilson <[email protected]> Cc: Matthew Auld <[email protected]> Cc: Ramalingam C <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Reviewed-by: Matthew Auld <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 8c35a19 commit be1cb55

14 files changed

+291
-123
lines changed

drivers/gpu/drm/i915/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ gt-y += \
111111
gt/intel_sseu.o \
112112
gt/intel_timeline.o \
113113
gt/intel_workarounds.o \
114+
gt/shmem_utils.o \
114115
gt/sysfs_engines.o
115116
# autogenerated null render state
116117
gt-y += \

drivers/gpu/drm/i915/gt/intel_engine_cs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,7 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
834834
intel_engine_cleanup_cmd_parser(engine);
835835

836836
if (engine->default_state)
837-
i915_gem_object_put(engine->default_state);
837+
fput(engine->default_state);
838838

839839
if (engine->kernel_context) {
840840
intel_context_unpin(engine->kernel_context);

drivers/gpu/drm/i915/gt/intel_engine_pm.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "intel_gt_pm.h"
1616
#include "intel_rc6.h"
1717
#include "intel_ring.h"
18+
#include "shmem_utils.h"
1819

1920
static int __engine_unpark(struct intel_wakeref *wf)
2021
{
@@ -30,10 +31,8 @@ static int __engine_unpark(struct intel_wakeref *wf)
3031
/* Pin the default state for fast resets from atomic context. */
3132
map = NULL;
3233
if (engine->default_state)
33-
map = i915_gem_object_pin_map(engine->default_state,
34-
I915_MAP_WB);
35-
if (!IS_ERR_OR_NULL(map))
36-
engine->pinned_default_state = map;
34+
map = shmem_pin_map(engine->default_state);
35+
engine->pinned_default_state = map;
3736

3837
/* Discard stale context state from across idling */
3938
ce = engine->kernel_context;
@@ -264,7 +263,8 @@ static int __engine_park(struct intel_wakeref *wf)
264263
engine->park(engine);
265264

266265
if (engine->pinned_default_state) {
267-
i915_gem_object_unpin_map(engine->default_state);
266+
shmem_unpin_map(engine->default_state,
267+
engine->pinned_default_state);
268268
engine->pinned_default_state = NULL;
269269
}
270270

drivers/gpu/drm/i915/gt/intel_engine_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ struct intel_engine_cs {
339339

340340
unsigned long wakeref_serial;
341341
struct intel_wakeref wakeref;
342-
struct drm_i915_gem_object *default_state;
342+
struct file *default_state;
343343
void *pinned_default_state;
344344

345345
struct {

drivers/gpu/drm/i915/gt/intel_gt.c

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "intel_rps.h"
1717
#include "intel_uncore.h"
1818
#include "intel_pm.h"
19+
#include "shmem_utils.h"
1920

2021
void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915)
2122
{
@@ -371,18 +372,6 @@ static struct i915_address_space *kernel_vm(struct intel_gt *gt)
371372
return i915_vm_get(&gt->ggtt->vm);
372373
}
373374

374-
static int __intel_context_flush_retire(struct intel_context *ce)
375-
{
376-
struct intel_timeline *tl;
377-
378-
tl = intel_context_timeline_lock(ce);
379-
if (IS_ERR(tl))
380-
return PTR_ERR(tl);
381-
382-
intel_context_timeline_unlock(tl);
383-
return 0;
384-
}
385-
386375
static int __engines_record_defaults(struct intel_gt *gt)
387376
{
388377
struct i915_request *requests[I915_NUM_ENGINES] = {};
@@ -448,8 +437,7 @@ static int __engines_record_defaults(struct intel_gt *gt)
448437

449438
for (id = 0; id < ARRAY_SIZE(requests); id++) {
450439
struct i915_request *rq;
451-
struct i915_vma *state;
452-
void *vaddr;
440+
struct file *state;
453441

454442
rq = requests[id];
455443
if (!rq)
@@ -461,48 +449,16 @@ static int __engines_record_defaults(struct intel_gt *gt)
461449
}
462450

463451
GEM_BUG_ON(!test_bit(CONTEXT_ALLOC_BIT, &rq->context->flags));
464-
state = rq->context->state;
465-
if (!state)
452+
if (!rq->context->state)
466453
continue;
467454

468-
/* Serialise with retirement on another CPU */
469-
GEM_BUG_ON(!i915_request_completed(rq));
470-
err = __intel_context_flush_retire(rq->context);
471-
if (err)
472-
goto out;
473-
474-
/* We want to be able to unbind the state from the GGTT */
475-
GEM_BUG_ON(intel_context_is_pinned(rq->context));
476-
477-
/*
478-
* As we will hold a reference to the logical state, it will
479-
* not be torn down with the context, and importantly the
480-
* object will hold onto its vma (making it possible for a
481-
* stray GTT write to corrupt our defaults). Unmap the vma
482-
* from the GTT to prevent such accidents and reclaim the
483-
* space.
484-
*/
485-
err = i915_vma_unbind(state);
486-
if (err)
487-
goto out;
488-
489-
i915_gem_object_lock(state->obj);
490-
err = i915_gem_object_set_to_cpu_domain(state->obj, false);
491-
i915_gem_object_unlock(state->obj);
492-
if (err)
493-
goto out;
494-
495-
i915_gem_object_set_cache_coherency(state->obj, I915_CACHE_LLC);
496-
497-
/* Check we can acquire the image of the context state */
498-
vaddr = i915_gem_object_pin_map(state->obj, I915_MAP_FORCE_WB);
499-
if (IS_ERR(vaddr)) {
500-
err = PTR_ERR(vaddr);
455+
/* Keep a copy of the state's backing pages; free the obj */
456+
state = shmem_create_from_object(rq->context->state->obj);
457+
if (IS_ERR(state)) {
458+
err = PTR_ERR(state);
501459
goto out;
502460
}
503-
504-
rq->engine->default_state = i915_gem_object_get(state->obj);
505-
i915_gem_object_unpin_map(state->obj);
461+
rq->engine->default_state = state;
506462
}
507463

508464
out:

drivers/gpu/drm/i915/gt/intel_lrc.c

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
#include "intel_reset.h"
148148
#include "intel_ring.h"
149149
#include "intel_workarounds.h"
150+
#include "shmem_utils.h"
150151

151152
#define RING_EXECLIST_QFULL (1 << 0x2)
152153
#define RING_EXECLIST1_VALID (1 << 0x3)
@@ -5083,30 +5084,18 @@ populate_lr_context(struct intel_context *ce,
50835084
{
50845085
bool inhibit = true;
50855086
void *vaddr;
5086-
int ret;
50875087

50885088
vaddr = i915_gem_object_pin_map(ctx_obj, I915_MAP_WB);
50895089
if (IS_ERR(vaddr)) {
5090-
ret = PTR_ERR(vaddr);
5091-
drm_dbg(&engine->i915->drm,
5092-
"Could not map object pages! (%d)\n", ret);
5093-
return ret;
5090+
drm_dbg(&engine->i915->drm, "Could not map object pages!\n");
5091+
return PTR_ERR(vaddr);
50945092
}
50955093

50965094
set_redzone(vaddr, engine);
50975095

50985096
if (engine->default_state) {
5099-
void *defaults;
5100-
5101-
defaults = i915_gem_object_pin_map(engine->default_state,
5102-
I915_MAP_WB);
5103-
if (IS_ERR(defaults)) {
5104-
ret = PTR_ERR(defaults);
5105-
goto err_unpin_ctx;
5106-
}
5107-
5108-
memcpy(vaddr, defaults, engine->context_size);
5109-
i915_gem_object_unpin_map(engine->default_state);
5097+
shmem_read(engine->default_state, 0,
5098+
vaddr, engine->context_size);
51105099
__set_bit(CONTEXT_VALID_BIT, &ce->flags);
51115100
inhibit = false;
51125101
}
@@ -5121,11 +5110,9 @@ populate_lr_context(struct intel_context *ce,
51215110
execlists_init_reg_state(vaddr + LRC_STATE_OFFSET,
51225111
ce, engine, ring, inhibit);
51235112

5124-
ret = 0;
5125-
err_unpin_ctx:
51265113
__i915_gem_object_flush_map(ctx_obj, 0, engine->context_size);
51275114
i915_gem_object_unpin_map(ctx_obj);
5128-
return ret;
5115+
return 0;
51295116
}
51305117

51315118
static int __execlists_context_alloc(struct intel_context *ce,

drivers/gpu/drm/i915/gt/intel_ring_submission.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "intel_reset.h"
4343
#include "intel_ring.h"
4444
#include "intel_workarounds.h"
45+
#include "shmem_utils.h"
4546

4647
/* Rough estimate of the typical request size, performing a flush,
4748
* set-context and then emitting the batch.
@@ -1241,23 +1242,16 @@ alloc_context_vma(struct intel_engine_cs *engine)
12411242
i915_gem_object_set_cache_coherency(obj, I915_CACHE_L3_LLC);
12421243

12431244
if (engine->default_state) {
1244-
void *defaults, *vaddr;
1245+
void *vaddr;
12451246

12461247
vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
12471248
if (IS_ERR(vaddr)) {
12481249
err = PTR_ERR(vaddr);
12491250
goto err_obj;
12501251
}
12511252

1252-
defaults = i915_gem_object_pin_map(engine->default_state,
1253-
I915_MAP_WB);
1254-
if (IS_ERR(defaults)) {
1255-
err = PTR_ERR(defaults);
1256-
goto err_map;
1257-
}
1258-
1259-
memcpy(vaddr, defaults, engine->context_size);
1260-
i915_gem_object_unpin_map(engine->default_state);
1253+
shmem_read(engine->default_state, 0,
1254+
vaddr, engine->context_size);
12611255

12621256
i915_gem_object_flush_map(obj);
12631257
i915_gem_object_unpin_map(obj);
@@ -1271,8 +1265,6 @@ alloc_context_vma(struct intel_engine_cs *engine)
12711265

12721266
return vma;
12731267

1274-
err_map:
1275-
i915_gem_object_unpin_map(obj);
12761268
err_obj:
12771269
i915_gem_object_put(obj);
12781270
return ERR_PTR(err);

drivers/gpu/drm/i915/gt/selftest_context.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ static int live_context_size(void *arg)
155155

156156
for_each_engine(engine, gt, id) {
157157
struct {
158-
struct drm_i915_gem_object *state;
158+
struct file *state;
159159
void *pinned;
160160
} saved;
161161

drivers/gpu/drm/i915/gt/selftest_lrc.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4452,8 +4452,7 @@ static int live_lrc_layout(void *arg)
44524452
if (!engine->default_state)
44534453
continue;
44544454

4455-
hw = i915_gem_object_pin_map(engine->default_state,
4456-
I915_MAP_WB);
4455+
hw = shmem_pin_map(engine->default_state);
44574456
if (IS_ERR(hw)) {
44584457
err = PTR_ERR(hw);
44594458
break;
@@ -4525,7 +4524,7 @@ static int live_lrc_layout(void *arg)
45254524
hexdump(lrc, PAGE_SIZE);
45264525
}
45274526

4528-
i915_gem_object_unpin_map(engine->default_state);
4527+
shmem_unpin_map(engine->default_state, hw);
45294528
if (err)
45304529
break;
45314530
}
@@ -4630,8 +4629,7 @@ static int live_lrc_fixed(void *arg)
46304629
if (!engine->default_state)
46314630
continue;
46324631

4633-
hw = i915_gem_object_pin_map(engine->default_state,
4634-
I915_MAP_WB);
4632+
hw = shmem_pin_map(engine->default_state);
46354633
if (IS_ERR(hw)) {
46364634
err = PTR_ERR(hw);
46374635
break;
@@ -4652,7 +4650,7 @@ static int live_lrc_fixed(void *arg)
46524650
}
46534651
}
46544652

4655-
i915_gem_object_unpin_map(engine->default_state);
4653+
shmem_unpin_map(engine->default_state, hw);
46564654
}
46574655

46584656
return err;

0 commit comments

Comments
 (0)