mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'drm-intel-gt-next-2021-01-14' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
UAPI Changes: - Deprecate I915_PMU_LAST and optimize state tracking (Tvrtko) Avoid relying on last item ABI marker in i915_drm.h, add a comment to mark as deprecated. Cross-subsystem Changes: Core Changes: Driver Changes: - Restore clear residuals security mitigations for Ivybridge and Baytrail (Chris) - Close #1858: Allow sysadmin to choose applied GPU security mitigations through i915.mitigations=... similar to CPU (Chris) - Fix for #2024: GPU hangs on HSW GT1 (Chris) - Fix for #2707: Driver hang when editing UVs in Blender (Chris, Ville) - Fix for #2797: False positive GuC loading error message (Chris) - Fix for #2859: Missing GuC firmware for older Cometlakes (Chris) - Lessen probability of GPU hang due to DMAR faults [reason 7, next page table ptr is invalid] on Tigerlake (Chris) - Fix REVID macros for TGL to fetch correct stepping (Aditya) - Limit frequency drop to RPe on parking (Chris, Edward) - Limit W/A 1406941453 to TGL, RKL and DG1 (Swathi) - Make W/A 22010271021 permanent on DG1 (Lucas) - Implement W/A 16011163337 to prevent a HS/DS hang on DG1 (Swathi) - Only disable preemption on gen8 render engines (Chris) - Disable arbitration around Braswell's PDP updates (Chris) - Disable arbitration on no-preempt requests (Chris) - Check for arbitration after writing start seqno before busywaiting (Chris) - Retain default context state across shrinking (Venkata, CQ) - Fix mismatch between misplaced vma check and vma insert for 32-bit addressing userspaces (Chris, CQ) - Propagate error for vmap() failure instead kernel NULL deref (Chris) - Propagate error from cancelled submit due to context closure immediately (Chris) - Fix RCU race on HWSP tracking per request (Chris) - Clear CMD parser shadow and GPU reloc batches (Matt A) - Populate logical context during first pin (Maarten) - Optimistically prune dma-resv from the shrinker (Chris) - Fix for virtual engine ownership race (Chris) - Remove timeslice suppression to restore fairness for virtual engines (Chris) - Rearrange IVB/HSW workarounds properly between GT and engine (Chris) - Taint the reset mutex with the shrinker (Chris) - Replace direct submit with direct call to tasklet (Chris) - Multiple corrections to virtual engine dequeue and breadcrumbs code (Chris) - Avoid wakeref from potentially hard IRQ context in PMU (Tvrtko) - Use raw clock for RC6 time estimation in PMU (Tvrtko) - Differentiate OOM failures from invalid map types (Chris) - Fix Gen9 to have 64 MOCS entries similar to Gen11 (Chris) - Ignore repeated attempts to suspend request flow across reset (Chris) - Remove livelock from "do_idle_maps" VT-d W/A (Chris) - Cancel the preemption timeout early in case engine reset fails (Chris) - Code flow optimization in the scheduling code (Chris) - Clear the execlists timers upon reset (Chris) - Drain the breadcrumbs just once (Chris, Matt A) - Track the overall GT awake/busy time (Chris) - Tweak submission tasklet flushing to avoid starvation (Chris) - Track timelines created using the HWSP to restore on resume (Chris) - Use cmpxchg64 for 32b compatilibity for active tracking (Chris) - Prefer recycling an idle GGTT fence to avoid GPU wait (Chris) - Restructure GT code organization for clearer split between GuC and execlists (Chris, Daniele, John, Matt A) - Remove GuC code that will remain unused by new interfaces (Matt B) - Restructure the CS timestamp clocks code to local to GT (Chris) - Fix error return paths in perf code (Zhang) - Replace idr_init() by idr_init_base() in perf (Deepak) - Fix shmem_pin_map error path (Colin) - Drop redundant free_work worker for GEM contexts (Chris, Mika) - Increase readability and understandability of intel_workarounds.c (Lucas) - Defer enabling the breadcrumb interrupt to after submission (Chris) - Deal with buddy alloc block sizes beyond 4G (Venkata, Chris) - Encode fence specific waitqueue behaviour into the wait.flags (Chris) - Don't cancel the breadcrumb interrupt shadow too early (Chris) - Cancel submitted requests upon context reset (Chris) - Use correct locks in GuC code (Tvrtko) - Prevent use of engine->wa_ctx after error (Chris, Matt R) - Fix build warning on 32-bit (Arnd) - Avoid memory leak if platform would have more than 16 W/A (Tvrtko) - Avoid unnecessary #if CONFIG_PM in PMU code (Chris, Tvrtko) - Improve debugging output (Chris, Tvrtko, Matt R) - Make file local variables static (Jani) - Avoid uint*_t types in i915 (Jani) - Selftest improvements (Chris, Matt A, Dan) - Documentation fixes (Chris, Jose) Signed-off-by: Dave Airlie <airlied@redhat.com> # Conflicts: # drivers/gpu/drm/i915/gt/intel_breadcrumbs.c # drivers/gpu/drm/i915/gt/intel_breadcrumbs_types.h # drivers/gpu/drm/i915/gt/intel_lrc.c # drivers/gpu/drm/i915/gvt/mmio_context.h # drivers/gpu/drm/i915/i915_drv.h From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210114152232.GA21588@jlahtine-mobl.ger.corp.intel.com
This commit is contained in:
@@ -428,7 +428,7 @@ User Batchbuffer Execution
|
||||
Logical Rings, Logical Ring Contexts and Execlists
|
||||
--------------------------------------------------
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_lrc.c
|
||||
.. kernel-doc:: drivers/gpu/drm/i915/gt/intel_execlists_submission.c
|
||||
:doc: Logical Rings, Logical Ring Contexts and Execlists
|
||||
|
||||
Global GTT views
|
||||
|
||||
@@ -38,6 +38,7 @@ i915-y += i915_drv.o \
|
||||
i915_config.o \
|
||||
i915_irq.o \
|
||||
i915_getparam.o \
|
||||
i915_mitigations.o \
|
||||
i915_params.o \
|
||||
i915_pci.o \
|
||||
i915_scatterlist.o \
|
||||
@@ -58,6 +59,7 @@ i915-y += i915_drv.o \
|
||||
|
||||
# core library code
|
||||
i915-y += \
|
||||
dma_resv_utils.o \
|
||||
i915_memcpy.o \
|
||||
i915_mm.o \
|
||||
i915_sw_fence.o \
|
||||
@@ -82,6 +84,7 @@ gt-y += \
|
||||
gt/gen6_engine_cs.o \
|
||||
gt/gen6_ppgtt.o \
|
||||
gt/gen7_renderclear.o \
|
||||
gt/gen8_engine_cs.o \
|
||||
gt/gen8_ppgtt.o \
|
||||
gt/intel_breadcrumbs.o \
|
||||
gt/intel_context.o \
|
||||
@@ -91,6 +94,7 @@ gt-y += \
|
||||
gt/intel_engine_heartbeat.o \
|
||||
gt/intel_engine_pm.o \
|
||||
gt/intel_engine_user.o \
|
||||
gt/intel_execlists_submission.o \
|
||||
gt/intel_ggtt.o \
|
||||
gt/intel_ggtt_fencing.o \
|
||||
gt/intel_gt.o \
|
||||
@@ -106,6 +110,7 @@ gt-y += \
|
||||
gt/intel_mocs.o \
|
||||
gt/intel_ppgtt.o \
|
||||
gt/intel_rc6.o \
|
||||
gt/intel_region_lmem.o \
|
||||
gt/intel_renderstate.o \
|
||||
gt/intel_reset.o \
|
||||
gt/intel_ring.o \
|
||||
@@ -166,7 +171,6 @@ i915-y += \
|
||||
i915_scheduler.o \
|
||||
i915_trace_points.o \
|
||||
i915_vma.o \
|
||||
intel_region_lmem.o \
|
||||
intel_wopcm.o
|
||||
|
||||
# general-purpose microcontroller (GuC) support
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "gem/i915_gem_pm.h"
|
||||
#include "gt/intel_gpu_commands.h"
|
||||
#include "gt/intel_ring.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
|
||||
17
drivers/gpu/drm/i915/dma_resv_utils.c
Normal file
17
drivers/gpu/drm/i915/dma_resv_utils.c
Normal file
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright © 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/dma-resv.h>
|
||||
|
||||
#include "dma_resv_utils.h"
|
||||
|
||||
void dma_resv_prune(struct dma_resv *resv)
|
||||
{
|
||||
if (dma_resv_trylock(resv)) {
|
||||
if (dma_resv_test_signaled_rcu(resv, true))
|
||||
dma_resv_add_excl_fence(resv, NULL);
|
||||
dma_resv_unlock(resv);
|
||||
}
|
||||
}
|
||||
13
drivers/gpu/drm/i915/dma_resv_utils.h
Normal file
13
drivers/gpu/drm/i915/dma_resv_utils.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef DMA_RESV_UTILS_H
|
||||
#define DMA_RESV_UTILS_H
|
||||
|
||||
struct dma_resv;
|
||||
|
||||
void dma_resv_prune(struct dma_resv *resv);
|
||||
|
||||
#endif /* DMA_RESV_UTILS_H */
|
||||
@@ -72,6 +72,8 @@
|
||||
#include "gt/intel_context_param.h"
|
||||
#include "gt/intel_engine_heartbeat.h"
|
||||
#include "gt/intel_engine_user.h"
|
||||
#include "gt/intel_execlists_submission.h" /* virtual_engine */
|
||||
#include "gt/intel_gpu_commands.h"
|
||||
#include "gt/intel_ring.h"
|
||||
|
||||
#include "i915_gem_context.h"
|
||||
@@ -333,13 +335,12 @@ static struct i915_gem_engines *default_engines(struct i915_gem_context *ctx)
|
||||
return e;
|
||||
}
|
||||
|
||||
static void i915_gem_context_free(struct i915_gem_context *ctx)
|
||||
void i915_gem_context_release(struct kref *ref)
|
||||
{
|
||||
GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
|
||||
struct i915_gem_context *ctx = container_of(ref, typeof(*ctx), ref);
|
||||
|
||||
spin_lock(&ctx->i915->gem.contexts.lock);
|
||||
list_del(&ctx->link);
|
||||
spin_unlock(&ctx->i915->gem.contexts.lock);
|
||||
trace_i915_context_free(ctx);
|
||||
GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
|
||||
|
||||
mutex_destroy(&ctx->engines_mutex);
|
||||
mutex_destroy(&ctx->lut_mutex);
|
||||
@@ -353,37 +354,6 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
|
||||
kfree_rcu(ctx, rcu);
|
||||
}
|
||||
|
||||
static void contexts_free_all(struct llist_node *list)
|
||||
{
|
||||
struct i915_gem_context *ctx, *cn;
|
||||
|
||||
llist_for_each_entry_safe(ctx, cn, list, free_link)
|
||||
i915_gem_context_free(ctx);
|
||||
}
|
||||
|
||||
static void contexts_flush_free(struct i915_gem_contexts *gc)
|
||||
{
|
||||
contexts_free_all(llist_del_all(&gc->free_list));
|
||||
}
|
||||
|
||||
static void contexts_free_worker(struct work_struct *work)
|
||||
{
|
||||
struct i915_gem_contexts *gc =
|
||||
container_of(work, typeof(*gc), free_work);
|
||||
|
||||
contexts_flush_free(gc);
|
||||
}
|
||||
|
||||
void i915_gem_context_release(struct kref *ref)
|
||||
{
|
||||
struct i915_gem_context *ctx = container_of(ref, typeof(*ctx), ref);
|
||||
struct i915_gem_contexts *gc = &ctx->i915->gem.contexts;
|
||||
|
||||
trace_i915_context_free(ctx);
|
||||
if (llist_add(&ctx->free_link, &gc->free_list))
|
||||
schedule_work(&gc->free_work);
|
||||
}
|
||||
|
||||
static inline struct i915_gem_engines *
|
||||
__context_engines_static(const struct i915_gem_context *ctx)
|
||||
{
|
||||
@@ -453,6 +423,9 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce)
|
||||
struct intel_engine_cs *engine = NULL;
|
||||
struct i915_request *rq;
|
||||
|
||||
if (intel_context_has_inflight(ce))
|
||||
return intel_context_inflight(ce);
|
||||
|
||||
if (!ce->timeline)
|
||||
return NULL;
|
||||
|
||||
@@ -632,6 +605,10 @@ static void context_close(struct i915_gem_context *ctx)
|
||||
*/
|
||||
lut_close(ctx);
|
||||
|
||||
spin_lock(&ctx->i915->gem.contexts.lock);
|
||||
list_del(&ctx->link);
|
||||
spin_unlock(&ctx->i915->gem.contexts.lock);
|
||||
|
||||
mutex_unlock(&ctx->mutex);
|
||||
|
||||
/*
|
||||
@@ -849,9 +826,6 @@ i915_gem_create_context(struct drm_i915_private *i915, unsigned int flags)
|
||||
!HAS_EXECLISTS(i915))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* Reap the stale contexts */
|
||||
contexts_flush_free(&i915->gem.contexts);
|
||||
|
||||
ctx = __create_context(i915);
|
||||
if (IS_ERR(ctx))
|
||||
return ctx;
|
||||
@@ -896,23 +870,11 @@ static void init_contexts(struct i915_gem_contexts *gc)
|
||||
{
|
||||
spin_lock_init(&gc->lock);
|
||||
INIT_LIST_HEAD(&gc->list);
|
||||
|
||||
INIT_WORK(&gc->free_work, contexts_free_worker);
|
||||
init_llist_head(&gc->free_list);
|
||||
}
|
||||
|
||||
void i915_gem_init__contexts(struct drm_i915_private *i915)
|
||||
{
|
||||
init_contexts(&i915->gem.contexts);
|
||||
drm_dbg(&i915->drm, "%s context support initialized\n",
|
||||
DRIVER_CAPS(i915)->has_logical_contexts ?
|
||||
"logical" : "fake");
|
||||
}
|
||||
|
||||
void i915_gem_driver_release__contexts(struct drm_i915_private *i915)
|
||||
{
|
||||
flush_work(&i915->gem.contexts.free_work);
|
||||
rcu_barrier(); /* and flush the left over RCU frees */
|
||||
}
|
||||
|
||||
static int gem_context_register(struct i915_gem_context *ctx,
|
||||
@@ -988,7 +950,6 @@ err:
|
||||
void i915_gem_context_close(struct drm_file *file)
|
||||
{
|
||||
struct drm_i915_file_private *file_priv = file->driver_priv;
|
||||
struct drm_i915_private *i915 = file_priv->dev_priv;
|
||||
struct i915_address_space *vm;
|
||||
struct i915_gem_context *ctx;
|
||||
unsigned long idx;
|
||||
@@ -1000,8 +961,6 @@ void i915_gem_context_close(struct drm_file *file)
|
||||
xa_for_each(&file_priv->vm_xa, idx, vm)
|
||||
i915_vm_put(vm);
|
||||
xa_destroy(&file_priv->vm_xa);
|
||||
|
||||
contexts_flush_free(&i915->gem.contexts);
|
||||
}
|
||||
|
||||
int i915_gem_vm_create_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
@@ -110,7 +110,6 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
|
||||
|
||||
/* i915_gem_context.c */
|
||||
void i915_gem_init__contexts(struct drm_i915_private *i915);
|
||||
void i915_gem_driver_release__contexts(struct drm_i915_private *i915);
|
||||
|
||||
int i915_gem_context_open(struct drm_i915_private *i915,
|
||||
struct drm_file *file);
|
||||
|
||||
@@ -108,7 +108,6 @@ struct i915_gem_context {
|
||||
|
||||
/** link: place with &drm_i915_private.context_list */
|
||||
struct list_head link;
|
||||
struct llist_node free_link;
|
||||
|
||||
/**
|
||||
* @ref: reference count
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "gem/i915_gem_ioctls.h"
|
||||
#include "gt/intel_context.h"
|
||||
#include "gt/intel_gpu_commands.h"
|
||||
#include "gt/intel_gt.h"
|
||||
#include "gt/intel_gt_buffer_pool.h"
|
||||
#include "gt/intel_gt_pm.h"
|
||||
@@ -534,8 +535,6 @@ eb_add_vma(struct i915_execbuffer *eb,
|
||||
struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
|
||||
struct eb_vma *ev = &eb->vma[i];
|
||||
|
||||
GEM_BUG_ON(i915_vma_is_closed(vma));
|
||||
|
||||
ev->vma = vma;
|
||||
ev->exec = entry;
|
||||
ev->flags = entry->flags;
|
||||
@@ -1046,7 +1045,7 @@ static void reloc_gpu_flush(struct i915_execbuffer *eb, struct reloc_cache *cach
|
||||
GEM_BUG_ON(cache->rq_size >= obj->base.size / sizeof(u32));
|
||||
cache->rq_cmd[cache->rq_size] = MI_BATCH_BUFFER_END;
|
||||
|
||||
__i915_gem_object_flush_map(obj, 0, sizeof(u32) * (cache->rq_size + 1));
|
||||
i915_gem_object_flush_map(obj);
|
||||
i915_gem_object_unpin_map(obj);
|
||||
|
||||
intel_gt_chipset_flush(cache->rq->engine->gt);
|
||||
@@ -1296,6 +1295,8 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb,
|
||||
goto err_pool;
|
||||
}
|
||||
|
||||
memset32(cmd, 0, pool->obj->base.size / sizeof(u32));
|
||||
|
||||
batch = i915_vma_instance(pool->obj, vma->vm, NULL);
|
||||
if (IS_ERR(batch)) {
|
||||
err = PTR_ERR(batch);
|
||||
@@ -2533,6 +2534,9 @@ static int eb_submit(struct i915_execbuffer *eb, struct i915_vma *batch)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (intel_context_nopreempt(eb->context))
|
||||
__set_bit(I915_FENCE_FLAG_NOPREEMPT, &eb->request->fence.flags);
|
||||
|
||||
err = eb_move_to_gpu(eb);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -2573,15 +2577,12 @@ static int eb_submit(struct i915_execbuffer *eb, struct i915_vma *batch)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (intel_context_nopreempt(eb->context))
|
||||
__set_bit(I915_FENCE_FLAG_NOPREEMPT, &eb->request->fence.flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int num_vcs_engines(const struct drm_i915_private *i915)
|
||||
{
|
||||
return hweight64(VDBOX_MASK(&i915->gt));
|
||||
return hweight_long(VDBOX_MASK(&i915->gt));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "i915_drv.h"
|
||||
#include "gt/intel_context.h"
|
||||
#include "gt/intel_engine_pm.h"
|
||||
#include "gt/intel_gpu_commands.h"
|
||||
#include "gt/intel_gt.h"
|
||||
#include "gt/intel_gt_buffer_pool.h"
|
||||
#include "gt/intel_ring.h"
|
||||
|
||||
@@ -238,7 +238,7 @@ unlock:
|
||||
|
||||
/* The 'mapping' part of i915_gem_object_pin_map() below */
|
||||
static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj,
|
||||
enum i915_map_type type)
|
||||
enum i915_map_type type)
|
||||
{
|
||||
unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i;
|
||||
struct page *stack[32], **pages = stack, *page;
|
||||
@@ -281,7 +281,7 @@ static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj,
|
||||
/* Too big for stack -- allocate temporary array instead */
|
||||
pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
|
||||
if (!pages)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
@@ -290,11 +290,12 @@ static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj,
|
||||
vaddr = vmap(pages, n_pages, 0, pgprot);
|
||||
if (pages != stack)
|
||||
kvfree(pages);
|
||||
return vaddr;
|
||||
|
||||
return vaddr ?: ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj,
|
||||
enum i915_map_type type)
|
||||
enum i915_map_type type)
|
||||
{
|
||||
resource_size_t iomap = obj->mm.region->iomap.base -
|
||||
obj->mm.region->region.start;
|
||||
@@ -305,13 +306,13 @@ static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj,
|
||||
void *vaddr;
|
||||
|
||||
if (type != I915_MAP_WC)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
if (n_pfn > ARRAY_SIZE(stack)) {
|
||||
/* Too big for stack -- allocate temporary array instead */
|
||||
pfns = kvmalloc_array(n_pfn, sizeof(*pfns), GFP_KERNEL);
|
||||
if (!pfns)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
@@ -320,7 +321,8 @@ static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj,
|
||||
vaddr = vmap_pfn(pfns, n_pfn, pgprot_writecombine(PAGE_KERNEL_IO));
|
||||
if (pfns != stack)
|
||||
kvfree(pfns);
|
||||
return vaddr;
|
||||
|
||||
return vaddr ?: ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
/* get, pin, and map the pages of the object into kernel space */
|
||||
@@ -349,8 +351,10 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
|
||||
GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj));
|
||||
|
||||
err = ____i915_gem_object_get_pages(obj);
|
||||
if (err)
|
||||
goto err_unlock;
|
||||
if (err) {
|
||||
ptr = ERR_PTR(err);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
smp_mb__before_atomic();
|
||||
}
|
||||
@@ -362,7 +366,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
|
||||
ptr = page_unpack_bits(obj->mm.mapping, &has_type);
|
||||
if (ptr && has_type != type) {
|
||||
if (pinned) {
|
||||
err = -EBUSY;
|
||||
ptr = ERR_PTR(-EBUSY);
|
||||
goto err_unpin;
|
||||
}
|
||||
|
||||
@@ -374,15 +378,13 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
|
||||
if (!ptr) {
|
||||
if (GEM_WARN_ON(type == I915_MAP_WC &&
|
||||
!static_cpu_has(X86_FEATURE_PAT)))
|
||||
ptr = NULL;
|
||||
ptr = ERR_PTR(-ENODEV);
|
||||
else if (i915_gem_object_has_struct_page(obj))
|
||||
ptr = i915_gem_object_map_page(obj, type);
|
||||
else
|
||||
ptr = i915_gem_object_map_pfn(obj, type);
|
||||
if (!ptr) {
|
||||
err = -ENOMEM;
|
||||
if (IS_ERR(ptr))
|
||||
goto err_unpin;
|
||||
}
|
||||
|
||||
obj->mm.mapping = page_pack_bits(ptr, type);
|
||||
}
|
||||
@@ -393,8 +395,6 @@ out_unlock:
|
||||
|
||||
err_unpin:
|
||||
atomic_dec(&obj->mm.pages_pin_count);
|
||||
err_unlock:
|
||||
ptr = ERR_PTR(err);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj,
|
||||
int
|
||||
i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
const u64 max_segment = i915_sg_segment_size();
|
||||
struct intel_memory_region *mem = obj->mm.region;
|
||||
struct list_head *blocks = &obj->mm.blocks;
|
||||
resource_size_t size = obj->base.size;
|
||||
@@ -37,7 +38,7 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
|
||||
if (!st)
|
||||
return -ENOMEM;
|
||||
|
||||
if (sg_alloc_table(st, size >> ilog2(mem->mm.chunk_size), GFP_KERNEL)) {
|
||||
if (sg_alloc_table(st, size >> PAGE_SHIFT, GFP_KERNEL)) {
|
||||
kfree(st);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -64,27 +65,30 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
|
||||
i915_buddy_block_size(&mem->mm, block));
|
||||
offset = i915_buddy_block_offset(block);
|
||||
|
||||
GEM_BUG_ON(overflows_type(block_size, sg->length));
|
||||
while (block_size) {
|
||||
u64 len;
|
||||
|
||||
if (offset != prev_end ||
|
||||
add_overflows_t(typeof(sg->length), sg->length, block_size)) {
|
||||
if (st->nents) {
|
||||
sg_page_sizes |= sg->length;
|
||||
sg = __sg_next(sg);
|
||||
if (offset != prev_end || sg->length >= max_segment) {
|
||||
if (st->nents) {
|
||||
sg_page_sizes |= sg->length;
|
||||
sg = __sg_next(sg);
|
||||
}
|
||||
|
||||
sg_dma_address(sg) = mem->region.start + offset;
|
||||
sg_dma_len(sg) = 0;
|
||||
sg->length = 0;
|
||||
st->nents++;
|
||||
}
|
||||
|
||||
sg_dma_address(sg) = mem->region.start + offset;
|
||||
sg_dma_len(sg) = block_size;
|
||||
len = min(block_size, max_segment - sg->length);
|
||||
sg->length += len;
|
||||
sg_dma_len(sg) += len;
|
||||
|
||||
sg->length = block_size;
|
||||
offset += len;
|
||||
block_size -= len;
|
||||
|
||||
st->nents++;
|
||||
} else {
|
||||
sg->length += block_size;
|
||||
sg_dma_len(sg) += block_size;
|
||||
prev_end = offset;
|
||||
}
|
||||
|
||||
prev_end = offset + block_size;
|
||||
}
|
||||
|
||||
sg_page_sizes |= sg->length;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "gt/intel_gt_requests.h"
|
||||
|
||||
#include "dma_resv_utils.h"
|
||||
#include "i915_trace.h"
|
||||
|
||||
static bool swap_available(void)
|
||||
@@ -209,6 +210,8 @@ i915_gem_shrink(struct drm_i915_private *i915,
|
||||
mutex_unlock(&obj->mm.lock);
|
||||
}
|
||||
|
||||
dma_resv_prune(obj->base.resv);
|
||||
|
||||
scanned += obj->base.size >> PAGE_SHIFT;
|
||||
i915_gem_object_put(obj);
|
||||
|
||||
|
||||
@@ -608,11 +608,10 @@ i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)
|
||||
struct drm_mm_node *stolen = fetch_and_zero(&obj->stolen);
|
||||
|
||||
GEM_BUG_ON(!stolen);
|
||||
|
||||
i915_gem_object_release_memory_region(obj);
|
||||
|
||||
i915_gem_stolen_remove_node(i915, stolen);
|
||||
kfree(stolen);
|
||||
|
||||
i915_gem_object_release_memory_region(obj);
|
||||
}
|
||||
|
||||
static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "gt/intel_engine.h"
|
||||
|
||||
#include "dma_resv_utils.h"
|
||||
#include "i915_gem_ioctls.h"
|
||||
#include "i915_gem_object.h"
|
||||
|
||||
@@ -84,11 +85,8 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
|
||||
* Opportunistically prune the fences iff we know they have *all* been
|
||||
* signaled.
|
||||
*/
|
||||
if (prune_fences && dma_resv_trylock(resv)) {
|
||||
if (dma_resv_test_signaled_rcu(resv, true))
|
||||
dma_resv_add_excl_fence(resv, NULL);
|
||||
dma_resv_unlock(resv);
|
||||
}
|
||||
if (prune_fences)
|
||||
dma_resv_prune(resv);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ static void huge_free_pages(struct drm_i915_gem_object *obj,
|
||||
|
||||
static int huge_get_pages(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
#define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY)
|
||||
#define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_RETRY_MAYFAIL)
|
||||
const unsigned long nreal = obj->scratch / PAGE_SIZE;
|
||||
const unsigned long npages = obj->base.size / PAGE_SIZE;
|
||||
struct scatterlist *sg, *src, *end;
|
||||
|
||||
@@ -368,6 +368,27 @@ static int igt_check_page_sizes(struct i915_vma *vma)
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The dma-api is like a box of chocolates when it comes to the
|
||||
* alignment of dma addresses, however for LMEM we have total control
|
||||
* and so can guarantee alignment, likewise when we allocate our blocks
|
||||
* they should appear in descending order, and if we know that we align
|
||||
* to the largest page size for the GTT address, we should be able to
|
||||
* assert that if we see 2M physical pages then we should also get 2M
|
||||
* GTT pages. If we don't then something might be wrong in our
|
||||
* construction of the backing pages.
|
||||
*
|
||||
* Maintaining alignment is required to utilise huge pages in the ppGGT.
|
||||
*/
|
||||
if (i915_gem_object_is_lmem(obj) &&
|
||||
IS_ALIGNED(vma->node.start, SZ_2M) &&
|
||||
vma->page_sizes.sg & SZ_2M &&
|
||||
vma->page_sizes.gtt < SZ_2M) {
|
||||
pr_err("gtt pages mismatch for LMEM, expected 2M GTT pages, sg(%u), gtt(%u)\n",
|
||||
vma->page_sizes.sg, vma->page_sizes.gtt);
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
if (obj->mm.page_sizes.gtt) {
|
||||
pr_err("obj->page_sizes.gtt(%u) should never be set\n",
|
||||
obj->mm.page_sizes.gtt);
|
||||
@@ -1333,6 +1354,7 @@ static int igt_ppgtt_sanity_check(void *arg)
|
||||
unsigned int flags;
|
||||
} backends[] = {
|
||||
{ igt_create_system, 0, },
|
||||
{ igt_create_local, 0, },
|
||||
{ igt_create_local, I915_BO_ALLOC_CONTIGUOUS, },
|
||||
};
|
||||
struct {
|
||||
|
||||
@@ -20,13 +20,11 @@ static int __igt_client_fill(struct intel_engine_cs *engine)
|
||||
{
|
||||
struct intel_context *ce = engine->kernel_context;
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct rnd_state prng;
|
||||
I915_RND_STATE(prng);
|
||||
IGT_TIMEOUT(end);
|
||||
u32 *vaddr;
|
||||
int err = 0;
|
||||
|
||||
prandom_seed_state(&prng, i915_selftest.random_seed);
|
||||
|
||||
intel_engine_pm_get(engine);
|
||||
do {
|
||||
const u32 max_block_size = S16_MAX * PAGE_SIZE;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/prime_numbers.h>
|
||||
|
||||
#include "gt/intel_engine_pm.h"
|
||||
#include "gt/intel_gpu_commands.h"
|
||||
#include "gt/intel_gt.h"
|
||||
#include "gt/intel_gt_pm.h"
|
||||
#include "gt/intel_ring.h"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/prime_numbers.h>
|
||||
|
||||
#include "gt/intel_engine_pm.h"
|
||||
#include "gt/intel_gpu_commands.h"
|
||||
#include "gt/intel_gt.h"
|
||||
#include "gt/intel_gt_pm.h"
|
||||
#include "gem/i915_gem_region.h"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user