diff options
author | Sunny He <suhe@nvidia.com> | 2017-08-15 15:01:04 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-09-22 15:55:24 -0400 |
commit | 17c581d75514c32d1e8c1e416beb33b3ccce22a5 (patch) | |
tree | a25d063f19b8e1f83f61af418f3aa2ac32fe0cce /drivers/gpu/nvgpu/include | |
parent | 0090ee5aca268a3c359f34c74b8c521df3bd8593 (diff) |
gpu: nvgpu: SGL passthrough implementation
The basic nvgpu_mem_sgl implementation provides support
for OS specific scatter-gather list implementations by
simply copying them node by node. This is inefficient,
taking extra time and memory.
This patch implements an nvgpu_mem_sgt struct to act as
a header which is inserted at the front of any scatter-
gather list implementation. This labels every struct
with a set of ops which can be used to interact with
the attached scatter gather list.
Since nvgpu common code only has to interact with these
function pointers, any sgl implementation can be used.
Initialization only requires the allocation of a single
struct, removing the need to copy or iterate through the
sgl being converted.
Jira NVGPU-186
Change-Id: I2994f804a4a4cc141b702e987e9081d8560ba2e8
Signed-off-by: Sunny He <suhe@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1541426
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/include')
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/linux/nvgpu_mem.h | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/nvgpu_mem.h | 80 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/page_allocator.h | 4 |
3 files changed, 64 insertions, 27 deletions
diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/nvgpu_mem.h b/drivers/gpu/nvgpu/include/nvgpu/linux/nvgpu_mem.h index f96c2801..517d834c 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/linux/nvgpu_mem.h +++ b/drivers/gpu/nvgpu/include/nvgpu/linux/nvgpu_mem.h | |||
@@ -20,6 +20,7 @@ | |||
20 | struct page; | 20 | struct page; |
21 | struct sg_table; | 21 | struct sg_table; |
22 | struct scatterlist; | 22 | struct scatterlist; |
23 | struct nvgpu_sgt; | ||
23 | 24 | ||
24 | struct gk20a; | 25 | struct gk20a; |
25 | struct nvgpu_mem; | 26 | struct nvgpu_mem; |
@@ -32,9 +33,11 @@ struct nvgpu_mem_priv { | |||
32 | }; | 33 | }; |
33 | 34 | ||
34 | u64 nvgpu_mem_get_addr_sgl(struct gk20a *g, struct scatterlist *sgl); | 35 | u64 nvgpu_mem_get_addr_sgl(struct gk20a *g, struct scatterlist *sgl); |
35 | struct nvgpu_mem_sgl *nvgpu_mem_sgl_create(struct gk20a *g, | 36 | struct nvgpu_sgt *nvgpu_mem_linux_sgt_create(struct gk20a *g, |
37 | struct sg_table *sgt); | ||
38 | void nvgpu_mem_linux_sgt_free(struct gk20a *g, struct nvgpu_sgt *sgt); | ||
39 | struct nvgpu_sgt *nvgpu_linux_sgt_create(struct gk20a *g, | ||
36 | struct sg_table *sgt); | 40 | struct sg_table *sgt); |
37 | |||
38 | /** | 41 | /** |
39 | * __nvgpu_mem_create_from_pages - Create an nvgpu_mem from physical pages. | 42 | * __nvgpu_mem_create_from_pages - Create an nvgpu_mem from physical pages. |
40 | * | 43 | * |
diff --git a/drivers/gpu/nvgpu/include/nvgpu/nvgpu_mem.h b/drivers/gpu/nvgpu/include/nvgpu/nvgpu_mem.h index 7d19cf81..beffbfe8 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/nvgpu_mem.h +++ b/drivers/gpu/nvgpu/include/nvgpu/nvgpu_mem.h | |||
@@ -46,12 +46,41 @@ enum nvgpu_aperture { | |||
46 | APERTURE_VIDMEM | 46 | APERTURE_VIDMEM |
47 | }; | 47 | }; |
48 | 48 | ||
49 | struct nvgpu_sgt_ops { | ||
50 | void *(*sgl_next)(void *sgl); | ||
51 | u64 (*sgl_phys)(void *sgl); | ||
52 | u64 (*sgl_dma)(void *sgl); | ||
53 | u64 (*sgl_length)(void *sgl); | ||
54 | u64 (*sgl_gpu_addr)(struct gk20a *g, void *sgl, | ||
55 | struct nvgpu_gmmu_attrs *attrs); | ||
56 | /* | ||
57 | * Note: this operates on the whole SGT not a specific SGL entry. | ||
58 | */ | ||
59 | void (*sgt_free)(struct gk20a *g, struct nvgpu_sgt *sgt); | ||
60 | }; | ||
61 | |||
62 | /* | ||
63 | * Scatter gather table: this is a list of scatter list entries and the ops for | ||
64 | * interacting with those entries. | ||
65 | */ | ||
66 | struct nvgpu_sgt { | ||
67 | /* | ||
68 | * Ops for interacting with the underlying scatter gather list entries. | ||
69 | */ | ||
70 | const struct nvgpu_sgt_ops *ops; | ||
71 | |||
72 | /* | ||
73 | * The first node in the scatter gather list. | ||
74 | */ | ||
75 | void *sgl; | ||
76 | }; | ||
77 | |||
49 | /* | 78 | /* |
50 | * This struct holds the necessary information for describing a struct | 79 | * This struct holds the necessary information for describing a struct |
51 | * nvgpu_mem's scatter gather list. | 80 | * nvgpu_mem's scatter gather list. |
52 | * | 81 | * |
53 | * These are created in a platform dependent way. As a result the function | 82 | * Not all nvgpu_sgt's use this particular implementation. Nor is a given OS |
54 | * definition for allocating these lives in the <nvgpu/_OS_/nvgpu_mem.h> file. | 83 | * required to use this at all. |
55 | */ | 84 | */ |
56 | struct nvgpu_mem_sgl { | 85 | struct nvgpu_mem_sgl { |
57 | /* | 86 | /* |
@@ -164,6 +193,32 @@ static inline bool nvgpu_mem_is_valid(struct nvgpu_mem *mem) | |||
164 | 193 | ||
165 | } | 194 | } |
166 | 195 | ||
196 | /* | ||
197 | * Create a nvgpu_sgt of the default implementation | ||
198 | */ | ||
199 | struct nvgpu_sgt *nvgpu_sgt_create(struct gk20a *g); | ||
200 | |||
201 | /** | ||
202 | * nvgpu_mem_sgt_create_from_mem - Create a scatter list from an nvgpu_mem. | ||
203 | * | ||
204 | * @g - The GPU. | ||
205 | * @mem - The source memory allocation to use. | ||
206 | * | ||
207 | * Create a scatter gather table from the passed @mem struct. This list lets the | ||
208 | * calling code iterate across each chunk of a DMA allocation for when that DMA | ||
209 | * allocation is not completely contiguous. | ||
210 | */ | ||
211 | struct nvgpu_sgt *nvgpu_sgt_create_from_mem(struct gk20a *g, | ||
212 | struct nvgpu_mem *mem); | ||
213 | |||
214 | void *nvgpu_sgt_get_next(struct nvgpu_sgt *sgt, void *sgl); | ||
215 | u64 nvgpu_sgt_get_phys(struct nvgpu_sgt *sgt, void *sgl); | ||
216 | u64 nvgpu_sgt_get_dma(struct nvgpu_sgt *sgt, void *sgl); | ||
217 | u64 nvgpu_sgt_get_length(struct nvgpu_sgt *sgt, void *sgl); | ||
218 | u64 nvgpu_sgt_get_gpu_addr(struct nvgpu_sgt *sgt, struct gk20a *g, void *sgl, | ||
219 | struct nvgpu_gmmu_attrs *attrs); | ||
220 | void nvgpu_sgt_free(struct nvgpu_sgt *sgt, struct gk20a *g); | ||
221 | |||
167 | /** | 222 | /** |
168 | * nvgpu_mem_create_from_mem - Create a new nvgpu_mem struct from an old one. | 223 | * nvgpu_mem_create_from_mem - Create a new nvgpu_mem struct from an old one. |
169 | * | 224 | * |
@@ -200,27 +255,6 @@ int nvgpu_mem_create_from_mem(struct gk20a *g, | |||
200 | struct nvgpu_mem *dest, struct nvgpu_mem *src, | 255 | struct nvgpu_mem *dest, struct nvgpu_mem *src, |
201 | int start_page, int nr_pages); | 256 | int start_page, int nr_pages); |
202 | 257 | ||
203 | /** | ||
204 | * nvgpu_mem_sgl_create_from_mem - Create a scatter list from an nvgpu_mem. | ||
205 | * | ||
206 | * @g - The GPU. | ||
207 | * @mem - The source memory allocation to use. | ||
208 | * | ||
209 | * Create a scatter gather list from the passed @mem struct. This list lets the | ||
210 | * calling code iterate across each chunk of a DMA allocation for when that DMA | ||
211 | * allocation is not completely contiguous. | ||
212 | */ | ||
213 | struct nvgpu_mem_sgl *nvgpu_mem_sgl_create_from_mem(struct gk20a *g, | ||
214 | struct nvgpu_mem *mem); | ||
215 | void nvgpu_mem_sgl_free(struct gk20a *g, struct nvgpu_mem_sgl *sgl); | ||
216 | |||
217 | struct nvgpu_mem_sgl *nvgpu_mem_sgl_next(struct nvgpu_mem_sgl *sgl); | ||
218 | u64 nvgpu_mem_sgl_phys(struct nvgpu_mem_sgl *sgl); | ||
219 | u64 nvgpu_mem_sgl_dma(struct nvgpu_mem_sgl *sgl); | ||
220 | u64 nvgpu_mem_sgl_length(struct nvgpu_mem_sgl *sgl); | ||
221 | u64 nvgpu_mem_sgl_gpu_addr(struct gk20a *g, struct nvgpu_mem_sgl *sgl, | ||
222 | struct nvgpu_gmmu_attrs *attrs); | ||
223 | |||
224 | /* | 258 | /* |
225 | * Buffer accessors - wrap between begin() and end() if there is no permanent | 259 | * Buffer accessors - wrap between begin() and end() if there is no permanent |
226 | * kernel mapping for this buffer. | 260 | * kernel mapping for this buffer. |
diff --git a/drivers/gpu/nvgpu/include/nvgpu/page_allocator.h b/drivers/gpu/nvgpu/include/nvgpu/page_allocator.h index de83ca7f..b22c55d0 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/page_allocator.h +++ b/drivers/gpu/nvgpu/include/nvgpu/page_allocator.h | |||
@@ -91,10 +91,10 @@ page_alloc_slab_page_from_list_entry(struct nvgpu_list_node *node) | |||
91 | */ | 91 | */ |
92 | struct nvgpu_page_alloc { | 92 | struct nvgpu_page_alloc { |
93 | /* | 93 | /* |
94 | * nvgpu_mem_sgl for describing the actual allocation. Convenient for | 94 | * nvgpu_sgt for describing the actual allocation. Convenient for |
95 | * GMMU mapping. | 95 | * GMMU mapping. |
96 | */ | 96 | */ |
97 | struct nvgpu_mem_sgl *sgl; | 97 | struct nvgpu_sgt sgt; |
98 | 98 | ||
99 | int nr_chunks; | 99 | int nr_chunks; |
100 | u64 length; | 100 | u64 length; |