drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
|
|
|
/*
|
|
|
|
* Copyright 2020-2021 Advanced Micro Devices, Inc.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef KFD_SVM_H_
|
|
|
|
#define KFD_SVM_H_
|
|
|
|
|
2021-03-29 22:49:12 +00:00
|
|
|
#if IS_ENABLED(CONFIG_HSA_AMD_SVM)
|
|
|
|
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
#include <linux/rwsem.h>
|
|
|
|
#include <linux/list.h>
|
|
|
|
#include <linux/mutex.h>
|
|
|
|
#include <linux/sched/mm.h>
|
|
|
|
#include <linux/hmm.h>
|
|
|
|
#include "amdgpu.h"
|
|
|
|
#include "kfd_priv.h"
|
|
|
|
|
2021-05-05 19:15:50 +00:00
|
|
|
#define SVM_RANGE_VRAM_DOMAIN (1UL << 0)
|
2021-05-05 17:43:10 +00:00
|
|
|
#define SVM_ADEV_PGMAP_OWNER(adev)\
|
|
|
|
((adev)->hive ? (void *)(adev)->hive : (void *)(adev))
|
|
|
|
|
2021-02-25 00:56:09 +00:00
|
|
|
struct svm_range_bo {
|
2021-02-25 04:24:53 +00:00
|
|
|
struct amdgpu_bo *bo;
|
|
|
|
struct kref kref;
|
|
|
|
struct list_head range_list; /* all svm ranges shared this bo */
|
|
|
|
spinlock_t list_lock;
|
|
|
|
struct amdgpu_amdkfd_fence *eviction_fence;
|
|
|
|
struct work_struct eviction_work;
|
|
|
|
struct svm_range_list *svms;
|
|
|
|
uint32_t evicting;
|
2021-02-25 00:56:09 +00:00
|
|
|
};
|
|
|
|
|
2020-04-08 15:09:45 +00:00
|
|
|
enum svm_work_list_ops {
|
|
|
|
SVM_OP_NULL,
|
|
|
|
SVM_OP_UNMAP_RANGE,
|
|
|
|
SVM_OP_UPDATE_RANGE_NOTIFIER,
|
2021-02-25 03:34:11 +00:00
|
|
|
SVM_OP_UPDATE_RANGE_NOTIFIER_AND_MAP,
|
|
|
|
SVM_OP_ADD_RANGE,
|
|
|
|
SVM_OP_ADD_RANGE_AND_MAP
|
2020-04-08 15:09:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct svm_work_list_item {
|
|
|
|
enum svm_work_list_ops op;
|
|
|
|
struct mm_struct *mm;
|
|
|
|
};
|
|
|
|
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
/**
|
|
|
|
* struct svm_range - shared virtual memory range
|
|
|
|
*
|
|
|
|
* @svms: list of svm ranges, structure defined in kfd_process
|
drm/amdkfd: HMM migrate ram to vram
Register svm range with same address and size but perferred_location
is changed from CPU to GPU or from GPU to CPU, trigger migration the svm
range from ram to vram or from vram to ram.
If svm range prefetch location is GPU with flags
KFD_IOCTL_SVM_FLAG_HOST_ACCESS, validate the svm range on ram first,
then migrate it from ram to vram.
After migrating to vram is done, CPU access will have cpu page fault,
page fault handler migrate it back to ram and resume cpu access.
Migration steps:
1. migrate_vma_pages get svm range ram pages, notify the
interval is invalidated and unmap from CPU page table, HMM interval
notifier callback evict process queues
2. Allocate new pages in vram using TTM
3. Use svm copy memory to sdma copy data from ram to vram
4. migrate_vma_pages copy ram pages structure to vram pages structure
5. migrate_vma_finalize put ram pages to free ram pages and memory
6. Restore work wait for migration is finished, then update GPUs page
table mapping to new vram pages, resume process queues
If migrate_vma_setup failed to collect all ram pages of range, retry 3
times until success to start migration.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2021-02-25 01:40:20 +00:00
|
|
|
* @migrate_mutex: to serialize range migration, validation and mapping update
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
* @start: range start address in pages
|
|
|
|
* @last: range last address in pages
|
|
|
|
* @it_node: node [start, last] stored in interval tree, start, last are page
|
|
|
|
* aligned, page size is (last - start + 1)
|
|
|
|
* @list: link list node, used to scan all ranges of svms
|
|
|
|
* @update_list:link list node used to add to update_list
|
|
|
|
* @remove_list:link list node used to add to remove list
|
|
|
|
* @insert_list:link list node used to add to insert list
|
2021-02-24 23:29:06 +00:00
|
|
|
* @mapping: bo_va mapping structure to create and update GPU page table
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
* @npages: number of pages
|
2021-02-24 23:29:06 +00:00
|
|
|
* @dma_addr: dma mapping address on each GPU for system memory physical page
|
2021-02-25 00:56:09 +00:00
|
|
|
* @ttm_res: vram ttm resource map
|
|
|
|
* @offset: range start offset within mm_nodes
|
|
|
|
* @svm_bo: struct to manage splited amdgpu_bo
|
|
|
|
* @svm_bo_list:link list node, to scan all ranges which share same svm_bo
|
2020-02-15 20:02:49 +00:00
|
|
|
* @lock: protect prange start, last, child_list, svm_bo_list
|
|
|
|
* @saved_flags:save/restore current PF_MEMALLOC flags
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
* @flags: flags defined as KFD_IOCTL_SVM_FLAG_*
|
|
|
|
* @perferred_loc: perferred location, 0 for CPU, or GPU id
|
|
|
|
* @perfetch_loc: last prefetch location, 0 for CPU, or GPU id
|
|
|
|
* @actual_loc: the actual location, 0 for CPU, or GPU id
|
|
|
|
* @granularity:migration granularity, log2 num pages
|
2021-02-24 23:47:52 +00:00
|
|
|
* @invalid: not 0 means cpu page table is invalidated
|
2021-02-25 04:55:27 +00:00
|
|
|
* @validate_timestamp: system timestamp when range is validated
|
2020-02-15 20:02:49 +00:00
|
|
|
* @notifier: register mmu interval notifier
|
2020-04-08 15:09:45 +00:00
|
|
|
* @work_item: deferred work item information
|
|
|
|
* @deferred_list: list header used to add range to deferred list
|
|
|
|
* @child_list: list header for split ranges which are not added to svms yet
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
* @bitmap_access: index bitmap of GPUs which can access the range
|
|
|
|
* @bitmap_aip: index bitmap of GPUs which can access the range in place
|
|
|
|
*
|
|
|
|
* Data structure for virtual memory range shared by CPU and GPUs, it can be
|
|
|
|
* allocated from system memory ram or device vram, and migrate from ram to vram
|
|
|
|
* or from vram to ram.
|
|
|
|
*/
|
|
|
|
struct svm_range {
|
|
|
|
struct svm_range_list *svms;
|
drm/amdkfd: HMM migrate ram to vram
Register svm range with same address and size but perferred_location
is changed from CPU to GPU or from GPU to CPU, trigger migration the svm
range from ram to vram or from vram to ram.
If svm range prefetch location is GPU with flags
KFD_IOCTL_SVM_FLAG_HOST_ACCESS, validate the svm range on ram first,
then migrate it from ram to vram.
After migrating to vram is done, CPU access will have cpu page fault,
page fault handler migrate it back to ram and resume cpu access.
Migration steps:
1. migrate_vma_pages get svm range ram pages, notify the
interval is invalidated and unmap from CPU page table, HMM interval
notifier callback evict process queues
2. Allocate new pages in vram using TTM
3. Use svm copy memory to sdma copy data from ram to vram
4. migrate_vma_pages copy ram pages structure to vram pages structure
5. migrate_vma_finalize put ram pages to free ram pages and memory
6. Restore work wait for migration is finished, then update GPUs page
table mapping to new vram pages, resume process queues
If migrate_vma_setup failed to collect all ram pages of range, retry 3
times until success to start migration.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2021-02-25 01:40:20 +00:00
|
|
|
struct mutex migrate_mutex;
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
unsigned long start;
|
|
|
|
unsigned long last;
|
|
|
|
struct interval_tree_node it_node;
|
|
|
|
struct list_head list;
|
|
|
|
struct list_head update_list;
|
|
|
|
struct list_head remove_list;
|
|
|
|
struct list_head insert_list;
|
|
|
|
uint64_t npages;
|
2021-02-24 23:29:06 +00:00
|
|
|
dma_addr_t *dma_addr[MAX_GPU_INSTANCE];
|
2021-02-25 00:56:09 +00:00
|
|
|
struct ttm_resource *ttm_res;
|
|
|
|
uint64_t offset;
|
|
|
|
struct svm_range_bo *svm_bo;
|
|
|
|
struct list_head svm_bo_list;
|
2020-02-15 20:02:49 +00:00
|
|
|
struct mutex lock;
|
|
|
|
unsigned int saved_flags;
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
uint32_t flags;
|
|
|
|
uint32_t preferred_loc;
|
|
|
|
uint32_t prefetch_loc;
|
|
|
|
uint32_t actual_loc;
|
|
|
|
uint8_t granularity;
|
2021-02-24 23:47:52 +00:00
|
|
|
atomic_t invalid;
|
2021-02-25 04:55:27 +00:00
|
|
|
uint64_t validate_timestamp;
|
2020-02-15 20:02:49 +00:00
|
|
|
struct mmu_interval_notifier notifier;
|
2020-04-08 15:09:45 +00:00
|
|
|
struct svm_work_list_item work_item;
|
|
|
|
struct list_head deferred_list;
|
|
|
|
struct list_head child_list;
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
DECLARE_BITMAP(bitmap_access, MAX_GPU_INSTANCE);
|
|
|
|
DECLARE_BITMAP(bitmap_aip, MAX_GPU_INSTANCE);
|
drm/amdkfd: HMM migrate ram to vram
Register svm range with same address and size but perferred_location
is changed from CPU to GPU or from GPU to CPU, trigger migration the svm
range from ram to vram or from vram to ram.
If svm range prefetch location is GPU with flags
KFD_IOCTL_SVM_FLAG_HOST_ACCESS, validate the svm range on ram first,
then migrate it from ram to vram.
After migrating to vram is done, CPU access will have cpu page fault,
page fault handler migrate it back to ram and resume cpu access.
Migration steps:
1. migrate_vma_pages get svm range ram pages, notify the
interval is invalidated and unmap from CPU page table, HMM interval
notifier callback evict process queues
2. Allocate new pages in vram using TTM
3. Use svm copy memory to sdma copy data from ram to vram
4. migrate_vma_pages copy ram pages structure to vram pages structure
5. migrate_vma_finalize put ram pages to free ram pages and memory
6. Restore work wait for migration is finished, then update GPUs page
table mapping to new vram pages, resume process queues
If migrate_vma_setup failed to collect all ram pages of range, retry 3
times until success to start migration.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2021-02-25 01:40:20 +00:00
|
|
|
bool validated_once;
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
};
|
|
|
|
|
2020-02-15 20:02:49 +00:00
|
|
|
static inline void svm_range_lock(struct svm_range *prange)
|
|
|
|
{
|
|
|
|
mutex_lock(&prange->lock);
|
|
|
|
prange->saved_flags = memalloc_noreclaim_save();
|
|
|
|
|
|
|
|
}
|
|
|
|
static inline void svm_range_unlock(struct svm_range *prange)
|
|
|
|
{
|
|
|
|
memalloc_noreclaim_restore(prange->saved_flags);
|
|
|
|
mutex_unlock(&prange->lock);
|
|
|
|
}
|
|
|
|
|
2021-03-10 04:12:15 +00:00
|
|
|
static inline struct svm_range_bo *svm_range_bo_ref(struct svm_range_bo *svm_bo)
|
|
|
|
{
|
|
|
|
if (svm_bo)
|
|
|
|
kref_get(&svm_bo->kref);
|
|
|
|
|
|
|
|
return svm_bo;
|
|
|
|
}
|
|
|
|
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
int svm_range_list_init(struct kfd_process *p);
|
|
|
|
void svm_range_list_fini(struct kfd_process *p);
|
|
|
|
int svm_ioctl(struct kfd_process *p, enum kfd_ioctl_svm_op op, uint64_t start,
|
|
|
|
uint64_t size, uint32_t nattrs,
|
|
|
|
struct kfd_ioctl_svm_attribute *attrs);
|
2021-03-17 04:24:12 +00:00
|
|
|
struct svm_range *svm_range_from_addr(struct svm_range_list *svms,
|
|
|
|
unsigned long addr,
|
|
|
|
struct svm_range **parent);
|
2021-02-25 00:56:09 +00:00
|
|
|
struct amdgpu_device *svm_range_get_adev_by_id(struct svm_range *prange,
|
|
|
|
uint32_t id);
|
|
|
|
int svm_range_vram_node_new(struct amdgpu_device *adev,
|
|
|
|
struct svm_range *prange, bool clear);
|
|
|
|
void svm_range_vram_node_free(struct svm_range *prange);
|
2021-03-17 04:24:12 +00:00
|
|
|
int svm_range_split_by_granularity(struct kfd_process *p, struct mm_struct *mm,
|
|
|
|
unsigned long addr, struct svm_range *parent,
|
|
|
|
struct svm_range *prange);
|
2021-02-25 04:02:21 +00:00
|
|
|
int svm_range_restore_pages(struct amdgpu_device *adev,
|
2021-08-15 18:42:33 +00:00
|
|
|
unsigned int pasid, uint64_t addr, bool write_fault);
|
2021-02-25 04:24:53 +00:00
|
|
|
int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence);
|
2021-03-17 04:24:12 +00:00
|
|
|
void svm_range_add_list_work(struct svm_range_list *svms,
|
|
|
|
struct svm_range *prange, struct mm_struct *mm,
|
|
|
|
enum svm_work_list_ops op);
|
|
|
|
void schedule_deferred_list_work(struct svm_range_list *svms);
|
drm/amdkfd: HMM migrate ram to vram
Register svm range with same address and size but perferred_location
is changed from CPU to GPU or from GPU to CPU, trigger migration the svm
range from ram to vram or from vram to ram.
If svm range prefetch location is GPU with flags
KFD_IOCTL_SVM_FLAG_HOST_ACCESS, validate the svm range on ram first,
then migrate it from ram to vram.
After migrating to vram is done, CPU access will have cpu page fault,
page fault handler migrate it back to ram and resume cpu access.
Migration steps:
1. migrate_vma_pages get svm range ram pages, notify the
interval is invalidated and unmap from CPU page table, HMM interval
notifier callback evict process queues
2. Allocate new pages in vram using TTM
3. Use svm copy memory to sdma copy data from ram to vram
4. migrate_vma_pages copy ram pages structure to vram pages structure
5. migrate_vma_finalize put ram pages to free ram pages and memory
6. Restore work wait for migration is finished, then update GPUs page
table mapping to new vram pages, resume process queues
If migrate_vma_setup failed to collect all ram pages of range, retry 3
times until success to start migration.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2021-02-25 01:40:20 +00:00
|
|
|
void svm_range_dma_unmap(struct device *dev, dma_addr_t *dma_addr,
|
|
|
|
unsigned long offset, unsigned long npages);
|
|
|
|
void svm_range_free_dma_mappings(struct svm_range *prange);
|
2021-05-06 18:06:54 +00:00
|
|
|
void svm_range_prefault(struct svm_range *prange, struct mm_struct *mm,
|
|
|
|
void *owner);
|
2021-06-22 04:12:32 +00:00
|
|
|
struct kfd_process_device *
|
|
|
|
svm_range_get_pdd_by_adev(struct svm_range *prange, struct amdgpu_device *adev);
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
|
2021-06-10 22:39:56 +00:00
|
|
|
/* SVM API and HMM page migration work together, device memory type
|
|
|
|
* is initialized to not 0 when page migration register device memory.
|
|
|
|
*/
|
|
|
|
#define KFD_IS_SVM_API_SUPPORTED(dev) ((dev)->pgmap.type != 0)
|
|
|
|
|
2021-03-10 04:12:15 +00:00
|
|
|
void svm_range_bo_unref(struct svm_range_bo *svm_bo);
|
2021-03-29 22:49:12 +00:00
|
|
|
#else
|
|
|
|
|
|
|
|
struct kfd_process;
|
|
|
|
|
|
|
|
static inline int svm_range_list_init(struct kfd_process *p)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static inline void svm_range_list_fini(struct kfd_process *p)
|
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int svm_range_restore_pages(struct amdgpu_device *adev,
|
2021-08-15 18:42:33 +00:00
|
|
|
unsigned int pasid, uint64_t addr,
|
|
|
|
bool write_fault)
|
2021-03-29 22:49:12 +00:00
|
|
|
{
|
|
|
|
return -EFAULT;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int svm_range_schedule_evict_svm_bo(
|
|
|
|
struct amdgpu_amdkfd_fence *fence)
|
|
|
|
{
|
|
|
|
WARN_ONCE(1, "SVM eviction fence triggered, but SVM is disabled");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2021-06-10 22:39:56 +00:00
|
|
|
#define KFD_IS_SVM_API_SUPPORTED(dev) false
|
|
|
|
|
2021-03-29 22:49:12 +00:00
|
|
|
#endif /* IS_ENABLED(CONFIG_HSA_AMD_SVM) */
|
|
|
|
|
drm/amdkfd: register svm range
svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.
Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.
No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.
Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Signed-off-by: Alex Sierra <alex.sierra@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2020-02-06 18:43:56 +00:00
|
|
|
#endif /* KFD_SVM_H_ */
|