Skip to content

Commit a2bbf71

Browse files
committed
drm/i915/gtt: Only keep gen6 page directories pinned while active
In order to be able to evict the gen6 ppgtt, we have to unpin it at some point. We can simply use our context activity tracking to know when the ppgtt is no longer in use by hardware, and so only keep it pinned while being used a request. For the kernel_context (and thus aliasing_ppgtt), it remains pinned at all times, as the kernel_context itself is pinned at all times. Signed-off-by: Chris Wilson <[email protected]> Cc: Joonas Lahtinen <[email protected]> Cc: Mika Kuoppala <[email protected]> Cc: Matthew Auld <[email protected]> Reviewed-by: Joonas Lahtinen <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent e62230d commit a2bbf71

File tree

3 files changed

+54
-15
lines changed

3 files changed

+54
-15
lines changed

drivers/gpu/drm/i915/i915_gem_gtt.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,7 +1912,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
19121912
{
19131913
struct gen6_hw_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm));
19141914

1915-
i915_vma_unpin(ppgtt->vma);
19161915
i915_vma_destroy(ppgtt->vma);
19171916

19181917
gen6_ppgtt_free_pd(ppgtt);
@@ -1998,10 +1997,19 @@ static struct i915_vma *pd_vma_create(struct gen6_hw_ppgtt *ppgtt, int size)
19981997
return vma;
19991998
}
20001999

2001-
static int gen6_ppgtt_pin(struct i915_hw_ppgtt *base)
2000+
int gen6_ppgtt_pin(struct i915_hw_ppgtt *base)
20022001
{
20032002
struct gen6_hw_ppgtt *ppgtt = to_gen6_ppgtt(base);
20042003

2004+
/*
2005+
* Workaround the limited maximum vma->pin_count and the aliasing_ppgtt
2006+
* which will be pinned into every active context.
2007+
* (When vma->pin_count becomes atomic, I expect we will naturally
2008+
* need a larger, unpacked, type and kill this redundancy.)
2009+
*/
2010+
if (ppgtt->pin_count++)
2011+
return 0;
2012+
20052013
/*
20062014
* PPGTT PDEs reside in the GGTT and consists of 512 entries. The
20072015
* allocator works in address space sizes, so it's multiplied by page
@@ -2012,6 +2020,17 @@ static int gen6_ppgtt_pin(struct i915_hw_ppgtt *base)
20122020
PIN_GLOBAL | PIN_HIGH);
20132021
}
20142022

2023+
void gen6_ppgtt_unpin(struct i915_hw_ppgtt *base)
2024+
{
2025+
struct gen6_hw_ppgtt *ppgtt = to_gen6_ppgtt(base);
2026+
2027+
GEM_BUG_ON(!ppgtt->pin_count);
2028+
if (--ppgtt->pin_count)
2029+
return;
2030+
2031+
i915_vma_unpin(ppgtt->vma);
2032+
}
2033+
20152034
static struct i915_hw_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915)
20162035
{
20172036
struct i915_ggtt * const ggtt = &i915->ggtt;
@@ -2053,21 +2072,8 @@ static struct i915_hw_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915)
20532072
if (err)
20542073
goto err_vma;
20552074

2056-
err = gen6_ppgtt_pin(&ppgtt->base);
2057-
if (err)
2058-
goto err_pd;
2059-
2060-
DRM_DEBUG_DRIVER("Allocated pde space (%lldM) at GTT entry: %llx\n",
2061-
ppgtt->vma->node.size >> 20,
2062-
ppgtt->vma->node.start / PAGE_SIZE);
2063-
2064-
DRM_DEBUG_DRIVER("Adding PPGTT at offset %x\n",
2065-
ppgtt->base.pd.base.ggtt_offset << 10);
2066-
20672075
return &ppgtt->base;
20682076

2069-
err_pd:
2070-
gen6_ppgtt_free_pd(ppgtt);
20712077
err_vma:
20722078
i915_vma_destroy(ppgtt->vma);
20732079
err_scratch:

drivers/gpu/drm/i915/i915_gem_gtt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,8 @@ struct gen6_hw_ppgtt {
412412

413413
struct i915_vma *vma;
414414
gen6_pte_t __iomem *pd_addr;
415+
416+
unsigned int pin_count;
415417
};
416418

417419
#define __to_gen6_ppgtt(base) container_of(base, struct gen6_hw_ppgtt, base)
@@ -625,6 +627,9 @@ static inline void i915_ppgtt_put(struct i915_hw_ppgtt *ppgtt)
625627
kref_put(&ppgtt->ref, i915_ppgtt_release);
626628
}
627629

630+
int gen6_ppgtt_pin(struct i915_hw_ppgtt *base);
631+
void gen6_ppgtt_unpin(struct i915_hw_ppgtt *base);
632+
628633
void i915_check_and_clear_faults(struct drm_i915_private *dev_priv);
629634
void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv);
630635
void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv);

drivers/gpu/drm/i915/intel_ringbuffer.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,27 @@ static void intel_ring_context_destroy(struct intel_context *ce)
11791179
__i915_gem_object_release_unless_active(ce->state->obj);
11801180
}
11811181

1182+
static int __context_pin_ppgtt(struct i915_gem_context *ctx)
1183+
{
1184+
struct i915_hw_ppgtt *ppgtt;
1185+
int err = 0;
1186+
1187+
ppgtt = ctx->ppgtt ?: ctx->i915->mm.aliasing_ppgtt;
1188+
if (ppgtt)
1189+
err = gen6_ppgtt_pin(ppgtt);
1190+
1191+
return err;
1192+
}
1193+
1194+
static void __context_unpin_ppgtt(struct i915_gem_context *ctx)
1195+
{
1196+
struct i915_hw_ppgtt *ppgtt;
1197+
1198+
ppgtt = ctx->ppgtt ?: ctx->i915->mm.aliasing_ppgtt;
1199+
if (ppgtt)
1200+
gen6_ppgtt_unpin(ppgtt);
1201+
}
1202+
11821203
static int __context_pin(struct intel_context *ce)
11831204
{
11841205
struct i915_vma *vma;
@@ -1227,6 +1248,7 @@ static void __context_unpin(struct intel_context *ce)
12271248

12281249
static void intel_ring_context_unpin(struct intel_context *ce)
12291250
{
1251+
__context_unpin_ppgtt(ce->gem_context);
12301252
__context_unpin(ce);
12311253

12321254
i915_gem_context_put(ce->gem_context);
@@ -1324,6 +1346,10 @@ __ring_context_pin(struct intel_engine_cs *engine,
13241346
if (err)
13251347
goto err;
13261348

1349+
err = __context_pin_ppgtt(ce->gem_context);
1350+
if (err)
1351+
goto err_unpin;
1352+
13271353
i915_gem_context_get(ctx);
13281354

13291355
/* One ringbuffer to rule them all */
@@ -1332,6 +1358,8 @@ __ring_context_pin(struct intel_engine_cs *engine,
13321358

13331359
return ce;
13341360

1361+
err_unpin:
1362+
__context_unpin(ce);
13351363
err:
13361364
ce->pin_count = 0;
13371365
return ERR_PTR(err);

0 commit comments

Comments
 (0)