gpu: nvgpu: posix: add APIs to create sgl's/sgt's

This adds APIs to the POSIX sgt module to allow unit tests to create
sgt's and sgl's more easily. The new APIs allow the caller to pass in a
table of sgl's and creates the new sgt/sgl as needed.

Since this there is a new API to create an sgl, this also includes a new
nvgpu_sgl_free() API.

JIRA NVGPU-1563

Change-Id: I27ab7654289cbd2212a75625b6dd24d2b742e3bf
Signed-off-by: Philip Elcan <pelcan@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1966151
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Alex Waterman <alexw@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Philip Elcan
2018-12-05 09:28:46 -05:00
committed by mobile promotions
parent 8f15a2903c
commit 01bfd5ed68
2 changed files with 113 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -24,9 +24,20 @@
#define __NVGPU_POSIX_NVGPU_MEM_H__
struct nvgpu_mem_priv {
/*
* Eventually this will require an implementation using nvmap.
*/
struct nvgpu_sgt *sgt;
};
struct nvgpu_mem;
struct nvgpu_mem_sgl;
struct nvgpu_mem_sgl *nvgpu_mem_sgl_posix_create_from_list(struct gk20a *g,
struct nvgpu_mem_sgl *sgl_list, u32 nr_sgls,
u64 *total_size);
void nvgpu_mem_sgl_free(struct gk20a *g, struct nvgpu_mem_sgl *sgl);
struct nvgpu_sgt *nvgpu_mem_sgt_posix_create_from_list(struct gk20a *g,
struct nvgpu_mem_sgl *sgl_list, u32 nr_sgls,
u64 *total_size);
int nvgpu_mem_posix_create_from_list(struct gk20a *g, struct nvgpu_mem *mem,
struct nvgpu_mem_sgl *sgl_list, u32 nr_sgls);
#endif

View File

@@ -102,11 +102,20 @@ static bool nvgpu_mem_sgt_iommuable(struct gk20a *g, struct nvgpu_sgt *sgt)
return p->mm_sgt_is_iommuable;
}
void nvgpu_mem_sgl_free(struct gk20a *g, struct nvgpu_mem_sgl *sgl)
{
struct nvgpu_mem_sgl *tptr;
while (sgl != NULL) {
tptr = sgl->next;
nvgpu_kfree(g, sgl);
sgl = tptr;
}
}
static void nvgpu_mem_sgt_free(struct gk20a *g, struct nvgpu_sgt *sgt)
{
if (sgt->sgl != NULL) {
nvgpu_kfree(g, sgt->sgl);
}
nvgpu_mem_sgl_free(g, (struct nvgpu_mem_sgl *)sgt->sgl);
nvgpu_kfree(g, sgt);
}
@@ -122,6 +131,79 @@ static struct nvgpu_sgt_ops nvgpu_sgt_posix_ops = {
.sgt_free = nvgpu_mem_sgt_free,
};
struct nvgpu_mem_sgl *nvgpu_mem_sgl_posix_create_from_list(struct gk20a *g,
struct nvgpu_mem_sgl *sgl_list, u32 nr_sgls,
u64 *total_size)
{
struct nvgpu_mem_sgl *sgl_ptr, *tptr, *head = NULL;
u32 i;
*total_size = 0;
for (i = 0; i < nr_sgls; i++) {
tptr = (struct nvgpu_mem_sgl *)nvgpu_kzalloc(g,
sizeof(struct nvgpu_mem_sgl));
if (tptr == NULL) {
return NULL;
}
if (i == 0U) {
sgl_ptr = tptr;
head = sgl_ptr;
} else {
sgl_ptr->next = tptr;
sgl_ptr = sgl_ptr->next;
}
sgl_ptr->next = NULL;
sgl_ptr->phys = sgl_list[i].phys;
sgl_ptr->dma = sgl_list[i].dma;
sgl_ptr->length = sgl_list[i].length;
*total_size += sgl_list[i].length;
}
return head;
}
struct nvgpu_sgt *nvgpu_mem_sgt_posix_create_from_list(struct gk20a *g,
struct nvgpu_mem_sgl *sgl_list, u32 nr_sgls,
u64 *total_size)
{
struct nvgpu_sgt *sgt = nvgpu_kzalloc(g, sizeof(struct nvgpu_sgt));
struct nvgpu_mem_sgl *sgl;
if (sgt == NULL) {
return NULL;
}
sgl = nvgpu_mem_sgl_posix_create_from_list(g, sgl_list, nr_sgls,
total_size);
if (sgl == NULL) {
nvgpu_kfree(g, sgt);
return NULL;
}
sgt->sgl = (struct nvgpu_sgl *)sgl;
sgt->ops = &nvgpu_sgt_posix_ops;
return sgt;
}
int nvgpu_mem_posix_create_from_list(struct gk20a *g, struct nvgpu_mem *mem,
struct nvgpu_mem_sgl *sgl_list, u32 nr_sgls)
{
u64 sgl_size;
mem->priv.sgt = nvgpu_mem_sgt_posix_create_from_list(g, sgl_list,
nr_sgls, &sgl_size);
if (mem->priv.sgt == NULL) {
return -ENOMEM;
}
mem->aperture = APERTURE_SYSMEM;
mem->aligned_size = PAGE_ALIGN(sgl_size);
mem->size = sgl_size;
return 0;
}
struct nvgpu_sgt *nvgpu_sgt_os_create_from_mem(struct gk20a *g,
struct nvgpu_mem *mem)
{
@@ -138,16 +220,20 @@ struct nvgpu_sgt *nvgpu_sgt_os_create_from_mem(struct gk20a *g,
*/
sgt->ops = &nvgpu_sgt_posix_ops;
sgl = (struct nvgpu_mem_sgl *) nvgpu_kzalloc(g, sizeof(
struct nvgpu_mem_sgl));
if (sgl == NULL) {
nvgpu_kfree(g, sgt);
return NULL;
}
if (mem->priv.sgt != NULL) {
return mem->priv.sgt;
} else {
sgl = (struct nvgpu_mem_sgl *) nvgpu_kzalloc(g, sizeof(
struct nvgpu_mem_sgl));
if (sgl == NULL) {
nvgpu_kfree(g, sgt);
return NULL;
}
sgl->length = mem->size;
sgl->phys = (u64) mem->cpu_va;
sgt->sgl = (struct nvgpu_sgl *) sgl;
sgl->length = mem->size;
sgl->phys = (u64) mem->cpu_va;
sgt->sgl = (struct nvgpu_sgl *) sgl;
}
return sgt;
}