summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2016-07-21 17:01:58 -0400
committerAlex Waterman <alexw@nvidia.com>2016-07-22 14:26:52 -0400
commit51a32d8f2c97ae42fd714078c97af83c7136878f (patch)
tree935e9cce54cd20496cdc25621ce4041b7b349c64
parent7a2e30267bdb9ab2ff15a1e9d7e57bb7ea9bd3a3 (diff)
gpu: nvgpu: Ensure PDE alignment for GVA spaces
When managing GVA spaces the buddy allocator requires PDE size alignment. This is to ensure that PTE size in buddies always remains consistent. Consider the following hypothetical GVA space: it is 32 elements long, order 0 block size is 1, and PDE size is 8. This leads to: Base: 8 Size: 24 Managed space: [8, 32) The start of the space will be 8 (base must be aligned to a PDE and we need a hole at the bottom for handling errors). Size is simply the max, 32, minus what we cut out for the low hole. The two top level buddies are [8 -> 24), and [24 -> 32). Now, suppose, instead the base were 4: Base: 4 Size: 28 Managed space: [4, 32) The top level buddies would be [4 -> 20), [20 -> 28), and [28 -> 32). This presents several problems: none of the buddies are PDE aligned and one top level buddy is smaller than the PDE size. The simplest issue is how to determine the PTE size of the [28 -> 32) block. We can just set it as small but that's not ideal. The bigger issue is the mis-alignment of the larger buddies. [20 -> 28) is halfway in one PDE and halfway in another. That means the allocator would have to manage the two sub-buddies [20 -> 24) and [24 -> 28) separately. Instead of dealing with the above issues in the allocator it is much more simple to require that any GVA space is PDE aligned since they are already massive and already, in practice, have this alignment. Change-Id: I9eacd2db6485291db9f9f1d6c4c03c2a5c22de03 Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: http://git-master/r/1185137 Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a_allocator_buddy.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_allocator_buddy.c b/drivers/gpu/nvgpu/gk20a/gk20a_allocator_buddy.c
index 4ed55971..8cd1bd0b 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a_allocator_buddy.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a_allocator_buddy.c
@@ -1143,6 +1143,16 @@ int __gk20a_buddy_allocator_init(struct gk20a_allocator *__a,
1143 if (flags & GPU_ALLOC_GVA_SPACE) 1143 if (flags & GPU_ALLOC_GVA_SPACE)
1144 a->pte_blk_order = balloc_get_order(a, vm->big_page_size << 10); 1144 a->pte_blk_order = balloc_get_order(a, vm->big_page_size << 10);
1145 1145
1146 /*
1147 * When we have a GVA space with big_pages enabled the size and base
1148 * must be PDE aligned. If big_pages are not enabled then this
1149 * requirement is not necessary.
1150 */
1151 if (flags & GPU_ALLOC_GVA_SPACE && vm->big_pages &&
1152 (base & ((vm->big_page_size << 10) - 1) ||
1153 size & ((vm->big_page_size << 10) - 1)))
1154 return -EINVAL;
1155
1146 a->flags = flags; 1156 a->flags = flags;
1147 a->max_order = max_order; 1157 a->max_order = max_order;
1148 1158