Commit 8f47c8c3 authored by Matthew Auld's avatar Matthew Auld Committed by Chris Wilson
Browse files

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: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarMatthew Auld <matthew.auld@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20210119133106.66294-4-matthew.auld@intel.com
parent e2f4367a
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -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;
+4 −4
Original line number Diff line number Diff line
@@ -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;
+9 −3
Original line number Diff line number Diff line
@@ -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 = &gt->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;
	}
+2 −1
Original line number Diff line number Diff line
@@ -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,
+2 −2
Original line number Diff line number Diff line
@@ -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 */
Loading