1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2019 Intel Corporation
4  */
5 
6 #include "intel_memory_region.h"
7 #include "i915_gem_region.h"
8 #include "i915_drv.h"
9 #include "i915_trace.h"
10 
11 void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj,
12 					struct intel_memory_region *mem)
13 {
14 	obj->mm.region = intel_memory_region_get(mem);
15 
16 	if (obj->base.size <= mem->min_page_size)
17 		obj->flags |= I915_BO_ALLOC_CONTIGUOUS;
18 
19 	mutex_lock(&mem->objects.lock);
20 
21 	if (obj->flags & I915_BO_ALLOC_VOLATILE)
22 		list_add(&obj->mm.region_link, &mem->objects.purgeable);
23 	else
24 		list_add(&obj->mm.region_link, &mem->objects.list);
25 
26 	mutex_unlock(&mem->objects.lock);
27 }
28 
29 void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj)
30 {
31 	struct intel_memory_region *mem = obj->mm.region;
32 
33 	mutex_lock(&mem->objects.lock);
34 	list_del(&obj->mm.region_link);
35 	mutex_unlock(&mem->objects.lock);
36 
37 	intel_memory_region_put(mem);
38 }
39 
40 struct drm_i915_gem_object *
41 i915_gem_object_create_region(struct intel_memory_region *mem,
42 			      resource_size_t size,
43 			      unsigned int flags)
44 {
45 	struct drm_i915_gem_object *obj;
46 	int err;
47 
48 	/*
49 	 * NB: Our use of resource_size_t for the size stems from using struct
50 	 * resource for the mem->region. We might need to revisit this in the
51 	 * future.
52 	 */
53 
54 	GEM_BUG_ON(flags & ~I915_BO_ALLOC_FLAGS);
55 
56 	if (!mem)
57 		return ERR_PTR(-ENODEV);
58 
59 	size = round_up(size, mem->min_page_size);
60 
61 	GEM_BUG_ON(!size);
62 	GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_MIN_ALIGNMENT));
63 
64 	if (i915_gem_object_size_2big(size))
65 		return ERR_PTR(-E2BIG);
66 
67 	obj = i915_gem_object_alloc();
68 	if (!obj)
69 		return ERR_PTR(-ENOMEM);
70 
71 	err = mem->ops->init_object(mem, obj, size, flags);
72 	if (err)
73 		goto err_object_free;
74 
75 	trace_i915_gem_object_create(obj);
76 	return obj;
77 
78 err_object_free:
79 	i915_gem_object_free(obj);
80 	return ERR_PTR(err);
81 }
82