Skip to content

Commit 36ebaeb

Browse files
committed
Merge tag 'drm-intel-fixes-2021-07-22' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
Couple reverts from Jason getting rid of asynchronous command parsing and fence error propagation and a GVT fix of shadow ppgtt invalidation with proper D3 state tracking from Colin. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/YPl1sIyruD0U5Orl@intel.com
2 parents 995a146 + 6e0b652 commit 36ebaeb

File tree

6 files changed

+109
-288
lines changed

6 files changed

+109
-288
lines changed

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

Lines changed: 13 additions & 214 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,8 @@
2525
#include "i915_gem_clflush.h"
2626
#include "i915_gem_context.h"
2727
#include "i915_gem_ioctls.h"
28-
#include "i915_sw_fence_work.h"
2928
#include "i915_trace.h"
3029
#include "i915_user_extensions.h"
31-
#include "i915_memcpy.h"
3230

3331
struct eb_vma {
3432
struct i915_vma *vma;
@@ -1456,6 +1454,10 @@ static u32 *reloc_gpu(struct i915_execbuffer *eb,
14561454
int err;
14571455
struct intel_engine_cs *engine = eb->engine;
14581456

1457+
/* If we need to copy for the cmdparser, we will stall anyway */
1458+
if (eb_use_cmdparser(eb))
1459+
return ERR_PTR(-EWOULDBLOCK);
1460+
14591461
if (!reloc_can_use_engine(engine)) {
14601462
engine = engine->gt->engine_class[COPY_ENGINE_CLASS][0];
14611463
if (!engine)
@@ -2372,217 +2374,6 @@ shadow_batch_pin(struct i915_execbuffer *eb,
23722374
return vma;
23732375
}
23742376

2375-
struct eb_parse_work {
2376-
struct dma_fence_work base;
2377-
struct intel_engine_cs *engine;
2378-
struct i915_vma *batch;
2379-
struct i915_vma *shadow;
2380-
struct i915_vma *trampoline;
2381-
unsigned long batch_offset;
2382-
unsigned long batch_length;
2383-
unsigned long *jump_whitelist;
2384-
const void *batch_map;
2385-
void *shadow_map;
2386-
};
2387-
2388-
static int __eb_parse(struct dma_fence_work *work)
2389-
{
2390-
struct eb_parse_work *pw = container_of(work, typeof(*pw), base);
2391-
int ret;
2392-
bool cookie;
2393-
2394-
cookie = dma_fence_begin_signalling();
2395-
ret = intel_engine_cmd_parser(pw->engine,
2396-
pw->batch,
2397-
pw->batch_offset,
2398-
pw->batch_length,
2399-
pw->shadow,
2400-
pw->jump_whitelist,
2401-
pw->shadow_map,
2402-
pw->batch_map);
2403-
dma_fence_end_signalling(cookie);
2404-
2405-
return ret;
2406-
}
2407-
2408-
static void __eb_parse_release(struct dma_fence_work *work)
2409-
{
2410-
struct eb_parse_work *pw = container_of(work, typeof(*pw), base);
2411-
2412-
if (!IS_ERR_OR_NULL(pw->jump_whitelist))
2413-
kfree(pw->jump_whitelist);
2414-
2415-
if (pw->batch_map)
2416-
i915_gem_object_unpin_map(pw->batch->obj);
2417-
else
2418-
i915_gem_object_unpin_pages(pw->batch->obj);
2419-
2420-
i915_gem_object_unpin_map(pw->shadow->obj);
2421-
2422-
if (pw->trampoline)
2423-
i915_active_release(&pw->trampoline->active);
2424-
i915_active_release(&pw->shadow->active);
2425-
i915_active_release(&pw->batch->active);
2426-
}
2427-
2428-
static const struct dma_fence_work_ops eb_parse_ops = {
2429-
.name = "eb_parse",
2430-
.work = __eb_parse,
2431-
.release = __eb_parse_release,
2432-
};
2433-
2434-
static inline int
2435-
__parser_mark_active(struct i915_vma *vma,
2436-
struct intel_timeline *tl,
2437-
struct dma_fence *fence)
2438-
{
2439-
struct intel_gt_buffer_pool_node *node = vma->private;
2440-
2441-
return i915_active_ref(&node->active, tl->fence_context, fence);
2442-
}
2443-
2444-
static int
2445-
parser_mark_active(struct eb_parse_work *pw, struct intel_timeline *tl)
2446-
{
2447-
int err;
2448-
2449-
mutex_lock(&tl->mutex);
2450-
2451-
err = __parser_mark_active(pw->shadow, tl, &pw->base.dma);
2452-
if (err)
2453-
goto unlock;
2454-
2455-
if (pw->trampoline) {
2456-
err = __parser_mark_active(pw->trampoline, tl, &pw->base.dma);
2457-
if (err)
2458-
goto unlock;
2459-
}
2460-
2461-
unlock:
2462-
mutex_unlock(&tl->mutex);
2463-
return err;
2464-
}
2465-
2466-
static int eb_parse_pipeline(struct i915_execbuffer *eb,
2467-
struct i915_vma *shadow,
2468-
struct i915_vma *trampoline)
2469-
{
2470-
struct eb_parse_work *pw;
2471-
struct drm_i915_gem_object *batch = eb->batch->vma->obj;
2472-
bool needs_clflush;
2473-
int err;
2474-
2475-
GEM_BUG_ON(overflows_type(eb->batch_start_offset, pw->batch_offset));
2476-
GEM_BUG_ON(overflows_type(eb->batch_len, pw->batch_length));
2477-
2478-
pw = kzalloc(sizeof(*pw), GFP_KERNEL);
2479-
if (!pw)
2480-
return -ENOMEM;
2481-
2482-
err = i915_active_acquire(&eb->batch->vma->active);
2483-
if (err)
2484-
goto err_free;
2485-
2486-
err = i915_active_acquire(&shadow->active);
2487-
if (err)
2488-
goto err_batch;
2489-
2490-
if (trampoline) {
2491-
err = i915_active_acquire(&trampoline->active);
2492-
if (err)
2493-
goto err_shadow;
2494-
}
2495-
2496-
pw->shadow_map = i915_gem_object_pin_map(shadow->obj, I915_MAP_WB);
2497-
if (IS_ERR(pw->shadow_map)) {
2498-
err = PTR_ERR(pw->shadow_map);
2499-
goto err_trampoline;
2500-
}
2501-
2502-
needs_clflush =
2503-
!(batch->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ);
2504-
2505-
pw->batch_map = ERR_PTR(-ENODEV);
2506-
if (needs_clflush && i915_has_memcpy_from_wc())
2507-
pw->batch_map = i915_gem_object_pin_map(batch, I915_MAP_WC);
2508-
2509-
if (IS_ERR(pw->batch_map)) {
2510-
err = i915_gem_object_pin_pages(batch);
2511-
if (err)
2512-
goto err_unmap_shadow;
2513-
pw->batch_map = NULL;
2514-
}
2515-
2516-
pw->jump_whitelist =
2517-
intel_engine_cmd_parser_alloc_jump_whitelist(eb->batch_len,
2518-
trampoline);
2519-
if (IS_ERR(pw->jump_whitelist)) {
2520-
err = PTR_ERR(pw->jump_whitelist);
2521-
goto err_unmap_batch;
2522-
}
2523-
2524-
dma_fence_work_init(&pw->base, &eb_parse_ops);
2525-
2526-
pw->engine = eb->engine;
2527-
pw->batch = eb->batch->vma;
2528-
pw->batch_offset = eb->batch_start_offset;
2529-
pw->batch_length = eb->batch_len;
2530-
pw->shadow = shadow;
2531-
pw->trampoline = trampoline;
2532-
2533-
/* Mark active refs early for this worker, in case we get interrupted */
2534-
err = parser_mark_active(pw, eb->context->timeline);
2535-
if (err)
2536-
goto err_commit;
2537-
2538-
err = dma_resv_reserve_shared(pw->batch->resv, 1);
2539-
if (err)
2540-
goto err_commit;
2541-
2542-
err = dma_resv_reserve_shared(shadow->resv, 1);
2543-
if (err)
2544-
goto err_commit;
2545-
2546-
/* Wait for all writes (and relocs) into the batch to complete */
2547-
err = i915_sw_fence_await_reservation(&pw->base.chain,
2548-
pw->batch->resv, NULL, false,
2549-
0, I915_FENCE_GFP);
2550-
if (err < 0)
2551-
goto err_commit;
2552-
2553-
/* Keep the batch alive and unwritten as we parse */
2554-
dma_resv_add_shared_fence(pw->batch->resv, &pw->base.dma);
2555-
2556-
/* Force execution to wait for completion of the parser */
2557-
dma_resv_add_excl_fence(shadow->resv, &pw->base.dma);
2558-
2559-
dma_fence_work_commit_imm(&pw->base);
2560-
return 0;
2561-
2562-
err_commit:
2563-
i915_sw_fence_set_error_once(&pw->base.chain, err);
2564-
dma_fence_work_commit_imm(&pw->base);
2565-
return err;
2566-
2567-
err_unmap_batch:
2568-
if (pw->batch_map)
2569-
i915_gem_object_unpin_map(batch);
2570-
else
2571-
i915_gem_object_unpin_pages(batch);
2572-
err_unmap_shadow:
2573-
i915_gem_object_unpin_map(shadow->obj);
2574-
err_trampoline:
2575-
if (trampoline)
2576-
i915_active_release(&trampoline->active);
2577-
err_shadow:
2578-
i915_active_release(&shadow->active);
2579-
err_batch:
2580-
i915_active_release(&eb->batch->vma->active);
2581-
err_free:
2582-
kfree(pw);
2583-
return err;
2584-
}
2585-
25862377
static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i915_vma *vma)
25872378
{
25882379
/*
@@ -2672,7 +2463,15 @@ static int eb_parse(struct i915_execbuffer *eb)
26722463
goto err_trampoline;
26732464
}
26742465

2675-
err = eb_parse_pipeline(eb, shadow, trampoline);
2466+
err = dma_resv_reserve_shared(shadow->resv, 1);
2467+
if (err)
2468+
goto err_trampoline;
2469+
2470+
err = intel_engine_cmd_parser(eb->engine,
2471+
eb->batch->vma,
2472+
eb->batch_start_offset,
2473+
eb->batch_len,
2474+
shadow, trampoline);
26762475
if (err)
26772476
goto err_unpin_batch;
26782477

drivers/gpu/drm/i915/gem/selftests/i915_gem_execbuffer.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ static int igt_gpu_reloc(void *arg)
125125
intel_gt_pm_get(&eb.i915->gt);
126126

127127
for_each_uabi_engine(eb.engine, eb.i915) {
128+
if (intel_engine_requires_cmd_parser(eb.engine) ||
129+
intel_engine_using_cmd_parser(eb.engine))
130+
continue;
131+
128132
reloc_cache_init(&eb.reloc_cache, eb.i915);
129133
memset(map, POISON_INUSE, 4096);
130134

drivers/gpu/drm/i915/gvt/handlers.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,6 +1977,21 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
19771977
if (drm_WARN_ON(&i915->drm, !engine))
19781978
return -EINVAL;
19791979

1980+
/*
1981+
* Due to d3_entered is used to indicate skipping PPGTT invalidation on
1982+
* vGPU reset, it's set on D0->D3 on PCI config write, and cleared after
1983+
* vGPU reset if in resuming.
1984+
* In S0ix exit, the device power state also transite from D3 to D0 as
1985+
* S3 resume, but no vGPU reset (triggered by QEMU devic model). After
1986+
* S0ix exit, all engines continue to work. However the d3_entered
1987+
* remains set which will break next vGPU reset logic (miss the expected
1988+
* PPGTT invalidation).
1989+
* Engines can only work in D0. Thus the 1st elsp write gives GVT a
1990+
* chance to clear d3_entered.
1991+
*/
1992+
if (vgpu->d3_entered)
1993+
vgpu->d3_entered = false;
1994+
19801995
execlist = &vgpu->submission.execlist[engine->id];
19811996

19821997
execlist->elsp_dwords.data[3 - execlist->elsp_dwords.index] = data;

0 commit comments

Comments
 (0)