2 * SPDX-License-Identifier: MIT
4 * Copyright © 2016 Intel Corporation
7 #include "i915_scatterlist.h"
9 #include "huge_gem_object.h"
11 static void huge_free_pages(struct drm_i915_gem_object
*obj
,
12 struct sg_table
*pages
)
14 unsigned long nreal
= obj
->scratch
/ PAGE_SIZE
;
15 struct sgt_iter sgt_iter
;
18 for_each_sgt_page(page
, sgt_iter
, pages
) {
28 static int huge_get_pages(struct drm_i915_gem_object
*obj
)
30 #define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY)
31 const unsigned long nreal
= obj
->scratch
/ PAGE_SIZE
;
32 const unsigned long npages
= obj
->base
.size
/ PAGE_SIZE
;
33 struct scatterlist
*sg
, *src
, *end
;
34 struct sg_table
*pages
;
37 pages
= kmalloc(sizeof(*pages
), GFP
);
41 if (sg_alloc_table(pages
, npages
, GFP
)) {
47 for (n
= 0; n
< nreal
; n
++) {
50 page
= alloc_page(GFP
| __GFP_HIGHMEM
);
56 sg_set_page(sg
, page
, PAGE_SIZE
, 0);
60 for (end
= sg
, src
= pages
->sgl
; sg
; sg
= __sg_next(sg
)) {
61 sg_set_page(sg
, sg_page(src
), PAGE_SIZE
, 0);
68 if (i915_gem_gtt_prepare_pages(obj
, pages
))
71 __i915_gem_object_set_pages(obj
, pages
, PAGE_SIZE
);
76 huge_free_pages(obj
, pages
);
81 static void huge_put_pages(struct drm_i915_gem_object
*obj
,
82 struct sg_table
*pages
)
84 i915_gem_gtt_finish_pages(obj
, pages
);
85 huge_free_pages(obj
, pages
);
87 obj
->mm
.dirty
= false;
90 static const struct drm_i915_gem_object_ops huge_ops
= {
92 .flags
= I915_GEM_OBJECT_HAS_STRUCT_PAGE
,
93 .get_pages
= huge_get_pages
,
94 .put_pages
= huge_put_pages
,
97 struct drm_i915_gem_object
*
98 huge_gem_object(struct drm_i915_private
*i915
,
99 phys_addr_t phys_size
,
102 static struct lock_class_key lock_class
;
103 struct drm_i915_gem_object
*obj
;
104 unsigned int cache_level
;
106 GEM_BUG_ON(!phys_size
|| phys_size
> dma_size
);
107 GEM_BUG_ON(!IS_ALIGNED(phys_size
, PAGE_SIZE
));
108 GEM_BUG_ON(!IS_ALIGNED(dma_size
, I915_GTT_PAGE_SIZE
));
110 if (overflows_type(dma_size
, obj
->base
.size
))
111 return ERR_PTR(-E2BIG
);
113 obj
= i915_gem_object_alloc();
115 return ERR_PTR(-ENOMEM
);
117 drm_gem_private_object_init(&i915
->drm
, &obj
->base
, dma_size
);
118 i915_gem_object_init(obj
, &huge_ops
, &lock_class
);
120 obj
->read_domains
= I915_GEM_DOMAIN_CPU
;
121 obj
->write_domain
= I915_GEM_DOMAIN_CPU
;
122 cache_level
= HAS_LLC(i915
) ? I915_CACHE_LLC
: I915_CACHE_NONE
;
123 i915_gem_object_set_cache_coherency(obj
, cache_level
);
124 obj
->scratch
= phys_size
;