gpu: nvgpu: fix REMAP to support small/big pages

Initially, REMAP only worked with big pages but in some cases
only small pages are supported where REMAP functionality is
also needed.

This cleans up some page size assumptions. In particular, on a
remap request, the nvgpu_vm_area is found from the passed in VA,
but can only be done from virt_offset_in_pages if we're also
told the page size.

This now occurs from _PAGESIZE_ flags which are required by
both map and unmap operations.

Jira NVGPU-6804

Change-Id: I311980a1b5e0e5e1840bdc1123479350a5c9d469
Signed-off-by: Chris Johnson <cwj@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2566087
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Chris Johnson
2022-01-16 19:28:26 -08:00
committed by mobile promotions
parent 359e83b45a
commit 14ed75e857
5 changed files with 124 additions and 66 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2017-2022, 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"),
@@ -37,14 +37,17 @@
*/
#define NVGPU_VM_REMAP_OP_FLAGS_CACHEABLE BIT32(1)
#define NVGPU_VM_REMAP_OP_FLAGS_ACCESS_NO_WRITE BIT32(7)
#define NVGPU_VM_REMAP_OP_FLAGS_PAGESIZE_4K BIT32(12)
#define NVGPU_VM_REMAP_OP_FLAGS_PAGESIZE_64K BIT32(13)
#define NVGPU_VM_REMAP_OP_FLAGS_PAGESIZE_128K BIT32(14)
/**
* This structure describes a single remap operation (either a map or unmap).
*/
struct nvgpu_vm_remap_op {
/**
* When a map operation is specified this field contains any flags
* to use when setting up the mapping. When an unmap operation is
* specified this field must be zero.
* When a map/unmap operation is specified this field contains flags
* needed to determine the page size used to generate the map/unmap
* mem and virt offsets and/or flags used when setting up the mapping.
*/
u32 flags;
@@ -56,7 +59,7 @@ struct nvgpu_vm_remap_op {
* than NVGPU_KIND_INVALID is specified but there are no compression
* resources available for the mapping then the #incompr_kind value
* is used as a fallback for the mapping. When an unmap operation
* is specified this value must be zero.
* is specified this value must be zero.
*/
s16 compr_kind;
@@ -123,7 +126,7 @@ struct nvgpu_vm_remap_mpool {
/**
* If non-NULL, the ref put function will check this l2 flag and issue
* a flush if necessary when releasing a mapping.
* a flush if necessary when releasing a mapping.
*/
bool *l2_flushed;
@@ -148,11 +151,27 @@ nvgpu_vm_remap_mpool_from_ref(struct nvgpu_ref *ref)
offsetof(struct nvgpu_vm_remap_mpool, ref));
}
static inline u64 nvgpu_vm_remap_page_size(struct nvgpu_vm_remap_op *op)
{
u64 pagesize = 0;
/* validate_map/unmap_op ensures a single pagesize flag */
if (op->flags & NVGPU_VM_REMAP_OP_FLAGS_PAGESIZE_4K)
pagesize = SZ_4K;
if (op->flags & NVGPU_VM_REMAP_OP_FLAGS_PAGESIZE_64K)
pagesize = SZ_64K;
if (op->flags & NVGPU_VM_REMAP_OP_FLAGS_PAGESIZE_128K)
pagesize = SZ_128K;
nvgpu_assert(pagesize);
return pagesize;
}
/**
* This structure describes a virtual memory pool.
* There is one virtual memory pool for each sparse VM area allocation that
* uses big pages. A virtual memory pool tracks the association between
* each mapped big page in the pool and the corresponding physical memory.
* There is one virtual memory pool for each sparse VM area allocation.
* A virtual memory pool tracks the association between each mapped page
* in the pool and the corresponding physical memory.
*/
struct nvgpu_vm_remap_vpool {
/**
@@ -160,6 +179,11 @@ struct nvgpu_vm_remap_vpool {
*/
struct vm_gk20a *vm;
/**
* Pointer to associated VM area.
*/
struct nvgpu_vm_area *vm_area;
/**
* Tree of physical memory pools that are currently mapped to this
* virtual pool.
@@ -243,7 +267,6 @@ int nvgpu_vm_remap(struct vm_gk20a *vm, struct nvgpu_vm_remap_op *ops,
* @param num_pages [in] Number of pages in virtual memory pool.
*
* - Check that #num_pages is non-zero.
* - Check that VM area is using big pages.
* - Check that VM area is configured as sparse.
* - Allocate memory for internal virtual pool management structures.
* - Initialize virtual pool management structures including storing #vm
@@ -253,7 +276,6 @@ int nvgpu_vm_remap(struct vm_gk20a *vm, struct nvgpu_vm_remap_op *ops,
* @return Zero if the virtual pool create succeeds.
* Suitable errors, for failures.
* @retval -EINVAL if a value of zero is specified for #num_pages.
* @retval -EINVAL if the VM area is not using big pages.
* @retval -EINVAL if the VM area is not configured as sparse.
* @retval -ENOMEM if memory allocation for internal resources fails.
*/