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 	list_add(&obj->mm.region_link, &mem->objects.list);
22 	mutex_unlock(&mem->objects.lock);
23 }
24 
25 void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj)
26 {
27 	struct intel_memory_region *mem = obj->mm.region;
28 
29 	mutex_lock(&mem->objects.lock);
30 	list_del(&obj->mm.region_link);
31 	mutex_unlock(&mem->objects.lock);
32 
33 	intel_memory_region_put(mem);
34 }
35 
36 struct drm_i915_gem_object *
37 i915_gem_object_create_region(struct intel_memory_region *mem,
38 			      resource_size_t size,
39 			      unsigned int flags)
40 {
41 	struct drm_i915_gem_object *obj;
42 	int err;
43 
44 	/*
45 	 * NB: Our use of resource_size_t for the size stems from using struct
46 	 * resource for the mem->region. We might need to revisit this in the
47 	 * future.
48 	 */
49 
50 	GEM_BUG_ON(flags & ~I915_BO_ALLOC_FLAGS);
51 
52 	if (!mem)
53 		return ERR_PTR(-ENODEV);
54 
55 	size = round_up(size, mem->min_page_size);
56 
57 	GEM_BUG_ON(!size);
58 	GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_MIN_ALIGNMENT));
59 
60 	if (i915_gem_object_size_2big(size))
61 		return ERR_PTR(-E2BIG);
62 
63 	obj = i915_gem_object_alloc();
64 	if (!obj)
65 		return ERR_PTR(-ENOMEM);
66 
67 	err = mem->ops->init_object(mem, obj, size, flags);
68 	if (err)
69 		goto err_object_free;
70 
71 	trace_i915_gem_object_create(obj);
72 	return obj;
73 
74 err_object_free:
75 	i915_gem_object_free(obj);
76 	return ERR_PTR(err);
77 }
78