mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-04 17:44:14 +08:00
drm/i915/pool: constrain pool objects by mapping type
In a few places we always end up mapping the pool object with the FORCE constraint(to prevent hitting -EBUSY) which will destroy the cached mapping if it has a different type. As a simple first step, make the mapping type part of the pool interface, where the behaviour is to only give out pool objects which match the requested mapping type. Suggested-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Matthew Auld <matthew.auld@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20210119133106.66294-4-matthew.auld@intel.com
This commit is contained in:
parent
e2f4367a47
commit
8f47c8c3b0
@ -1276,7 +1276,10 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb,
|
||||
int err;
|
||||
|
||||
if (!pool) {
|
||||
pool = intel_gt_get_buffer_pool(engine->gt, PAGE_SIZE);
|
||||
pool = intel_gt_get_buffer_pool(engine->gt, PAGE_SIZE,
|
||||
cache->has_llc ?
|
||||
I915_MAP_WB :
|
||||
I915_MAP_WC);
|
||||
if (IS_ERR(pool))
|
||||
return PTR_ERR(pool);
|
||||
}
|
||||
@ -1286,10 +1289,7 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb,
|
||||
if (err)
|
||||
goto err_pool;
|
||||
|
||||
cmd = i915_gem_object_pin_map(pool->obj,
|
||||
cache->has_llc ?
|
||||
I915_MAP_FORCE_WB :
|
||||
I915_MAP_FORCE_WC);
|
||||
cmd = i915_gem_object_pin_map(pool->obj, pool->type);
|
||||
if (IS_ERR(cmd)) {
|
||||
err = PTR_ERR(cmd);
|
||||
goto err_pool;
|
||||
@ -2458,7 +2458,8 @@ static int eb_parse(struct i915_execbuffer *eb)
|
||||
return -EINVAL;
|
||||
|
||||
if (!pool) {
|
||||
pool = intel_gt_get_buffer_pool(eb->engine->gt, len);
|
||||
pool = intel_gt_get_buffer_pool(eb->engine->gt, len,
|
||||
I915_MAP_WB);
|
||||
if (IS_ERR(pool))
|
||||
return PTR_ERR(pool);
|
||||
eb->batch_pool = pool;
|
||||
|
@ -35,7 +35,7 @@ struct i915_vma *intel_emit_vma_fill_blt(struct intel_context *ce,
|
||||
count = div_u64(round_up(vma->size, block_size), block_size);
|
||||
size = (1 + 8 * count) * sizeof(u32);
|
||||
size = round_up(size, PAGE_SIZE);
|
||||
pool = intel_gt_get_buffer_pool(ce->engine->gt, size);
|
||||
pool = intel_gt_get_buffer_pool(ce->engine->gt, size, I915_MAP_WC);
|
||||
if (IS_ERR(pool)) {
|
||||
err = PTR_ERR(pool);
|
||||
goto out_pm;
|
||||
@ -55,7 +55,7 @@ struct i915_vma *intel_emit_vma_fill_blt(struct intel_context *ce,
|
||||
if (unlikely(err))
|
||||
goto out_put;
|
||||
|
||||
cmd = i915_gem_object_pin_map(pool->obj, I915_MAP_WC);
|
||||
cmd = i915_gem_object_pin_map(pool->obj, pool->type);
|
||||
if (IS_ERR(cmd)) {
|
||||
err = PTR_ERR(cmd);
|
||||
goto out_unpin;
|
||||
@ -257,7 +257,7 @@ struct i915_vma *intel_emit_vma_copy_blt(struct intel_context *ce,
|
||||
count = div_u64(round_up(dst->size, block_size), block_size);
|
||||
size = (1 + 11 * count) * sizeof(u32);
|
||||
size = round_up(size, PAGE_SIZE);
|
||||
pool = intel_gt_get_buffer_pool(ce->engine->gt, size);
|
||||
pool = intel_gt_get_buffer_pool(ce->engine->gt, size, I915_MAP_WC);
|
||||
if (IS_ERR(pool)) {
|
||||
err = PTR_ERR(pool);
|
||||
goto out_pm;
|
||||
@ -277,7 +277,7 @@ struct i915_vma *intel_emit_vma_copy_blt(struct intel_context *ce,
|
||||
if (unlikely(err))
|
||||
goto out_put;
|
||||
|
||||
cmd = i915_gem_object_pin_map(pool->obj, I915_MAP_WC);
|
||||
cmd = i915_gem_object_pin_map(pool->obj, pool->type);
|
||||
if (IS_ERR(cmd)) {
|
||||
err = PTR_ERR(cmd);
|
||||
goto out_unpin;
|
||||
|
@ -145,7 +145,8 @@ static void pool_retire(struct i915_active *ref)
|
||||
}
|
||||
|
||||
static struct intel_gt_buffer_pool_node *
|
||||
node_create(struct intel_gt_buffer_pool *pool, size_t sz)
|
||||
node_create(struct intel_gt_buffer_pool *pool, size_t sz,
|
||||
enum i915_map_type type)
|
||||
{
|
||||
struct intel_gt *gt = to_gt(pool);
|
||||
struct intel_gt_buffer_pool_node *node;
|
||||
@ -169,12 +170,14 @@ node_create(struct intel_gt_buffer_pool *pool, size_t sz)
|
||||
|
||||
i915_gem_object_set_readonly(obj);
|
||||
|
||||
node->type = type;
|
||||
node->obj = obj;
|
||||
return node;
|
||||
}
|
||||
|
||||
struct intel_gt_buffer_pool_node *
|
||||
intel_gt_get_buffer_pool(struct intel_gt *gt, size_t size)
|
||||
intel_gt_get_buffer_pool(struct intel_gt *gt, size_t size,
|
||||
enum i915_map_type type)
|
||||
{
|
||||
struct intel_gt_buffer_pool *pool = >->buffer_pool;
|
||||
struct intel_gt_buffer_pool_node *node;
|
||||
@ -191,6 +194,9 @@ intel_gt_get_buffer_pool(struct intel_gt *gt, size_t size)
|
||||
if (node->obj->base.size < size)
|
||||
continue;
|
||||
|
||||
if (node->type != type)
|
||||
continue;
|
||||
|
||||
age = READ_ONCE(node->age);
|
||||
if (!age)
|
||||
continue;
|
||||
@ -205,7 +211,7 @@ intel_gt_get_buffer_pool(struct intel_gt *gt, size_t size)
|
||||
rcu_read_unlock();
|
||||
|
||||
if (&node->link == list) {
|
||||
node = node_create(pool, size);
|
||||
node = node_create(pool, size, type);
|
||||
if (IS_ERR(node))
|
||||
return node;
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ struct intel_gt;
|
||||
struct i915_request;
|
||||
|
||||
struct intel_gt_buffer_pool_node *
|
||||
intel_gt_get_buffer_pool(struct intel_gt *gt, size_t size);
|
||||
intel_gt_get_buffer_pool(struct intel_gt *gt, size_t size,
|
||||
enum i915_map_type type);
|
||||
|
||||
static inline int
|
||||
intel_gt_buffer_pool_mark_active(struct intel_gt_buffer_pool_node *node,
|
||||
|
@ -11,10 +11,9 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include "gem/i915_gem_object_types.h"
|
||||
#include "i915_active_types.h"
|
||||
|
||||
struct drm_i915_gem_object;
|
||||
|
||||
struct intel_gt_buffer_pool {
|
||||
spinlock_t lock;
|
||||
struct list_head cache_list[4];
|
||||
@ -31,6 +30,7 @@ struct intel_gt_buffer_pool_node {
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
unsigned long age;
|
||||
enum i915_map_type type;
|
||||
};
|
||||
|
||||
#endif /* INTEL_GT_BUFFER_POOL_TYPES_H */
|
||||
|
@ -1143,7 +1143,7 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj,
|
||||
void *dst, *src;
|
||||
int ret;
|
||||
|
||||
dst = i915_gem_object_pin_map(dst_obj, I915_MAP_FORCE_WB);
|
||||
dst = i915_gem_object_pin_map(dst_obj, I915_MAP_WB);
|
||||
if (IS_ERR(dst))
|
||||
return dst;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user