Commit c83dee9b authored by Alex Sierra's avatar Alex Sierra Committed by akpm

drm/amdkfd: add SPM support for SVM

When CPU is connected throug XGMI, it has coherent access to VRAM
resource.  In this case that resource is taken from a table in the device
gmc aperture base.  This resource is used along with the device type,
which could be DEVICE_PRIVATE or DEVICE_COHERENT to create the device page
map region.

Also, MIGRATE_VMA_SELECT_DEVICE_COHERENT flag is selected for coherent
type case during migration to device.

Link: https://lkml.kernel.org/r/20220715150521.18165-8-alex.sierra@amd.comSigned-off-by: default avatarAlex Sierra <alex.sierra@amd.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: Jerome Glisse <jglisse@redhat.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Ralph Campbell <rcampbell@nvidia.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent b05a79d4
...@@ -671,13 +671,15 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange, ...@@ -671,13 +671,15 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
migrate.vma = vma; migrate.vma = vma;
migrate.start = start; migrate.start = start;
migrate.end = end; migrate.end = end;
migrate.flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
migrate.pgmap_owner = SVM_ADEV_PGMAP_OWNER(adev); migrate.pgmap_owner = SVM_ADEV_PGMAP_OWNER(adev);
if (adev->gmc.xgmi.connected_to_cpu)
migrate.flags = MIGRATE_VMA_SELECT_DEVICE_COHERENT;
else
migrate.flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
buf = kvcalloc(npages, buf = kvcalloc(npages,
2 * sizeof(*migrate.src) + sizeof(uint64_t) + sizeof(dma_addr_t), 2 * sizeof(*migrate.src) + sizeof(uint64_t) + sizeof(dma_addr_t),
GFP_KERNEL); GFP_KERNEL);
if (!buf) if (!buf)
goto out; goto out;
...@@ -947,7 +949,7 @@ int svm_migrate_init(struct amdgpu_device *adev) ...@@ -947,7 +949,7 @@ int svm_migrate_init(struct amdgpu_device *adev)
{ {
struct kfd_dev *kfddev = adev->kfd.dev; struct kfd_dev *kfddev = adev->kfd.dev;
struct dev_pagemap *pgmap; struct dev_pagemap *pgmap;
struct resource *res; struct resource *res = NULL;
unsigned long size; unsigned long size;
void *r; void *r;
...@@ -962,28 +964,34 @@ int svm_migrate_init(struct amdgpu_device *adev) ...@@ -962,28 +964,34 @@ int svm_migrate_init(struct amdgpu_device *adev)
* should remove reserved size * should remove reserved size
*/ */
size = ALIGN(adev->gmc.real_vram_size, 2ULL << 20); size = ALIGN(adev->gmc.real_vram_size, 2ULL << 20);
res = devm_request_free_mem_region(adev->dev, &iomem_resource, size); if (adev->gmc.xgmi.connected_to_cpu) {
if (IS_ERR(res)) pgmap->range.start = adev->gmc.aper_base;
return -ENOMEM; pgmap->range.end = adev->gmc.aper_base + adev->gmc.aper_size - 1;
pgmap->type = MEMORY_DEVICE_COHERENT;
} else {
res = devm_request_free_mem_region(adev->dev, &iomem_resource, size);
if (IS_ERR(res))
return -ENOMEM;
pgmap->range.start = res->start;
pgmap->range.end = res->end;
pgmap->type = MEMORY_DEVICE_PRIVATE;
}
pgmap->type = MEMORY_DEVICE_PRIVATE;
pgmap->nr_range = 1; pgmap->nr_range = 1;
pgmap->range.start = res->start;
pgmap->range.end = res->end;
pgmap->ops = &svm_migrate_pgmap_ops; pgmap->ops = &svm_migrate_pgmap_ops;
pgmap->owner = SVM_ADEV_PGMAP_OWNER(adev); pgmap->owner = SVM_ADEV_PGMAP_OWNER(adev);
pgmap->flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE; pgmap->flags = 0;
/* Device manager releases device-specific resources, memory region and /* Device manager releases device-specific resources, memory region and
* pgmap when driver disconnects from device. * pgmap when driver disconnects from device.
*/ */
r = devm_memremap_pages(adev->dev, pgmap); r = devm_memremap_pages(adev->dev, pgmap);
if (IS_ERR(r)) { if (IS_ERR(r)) {
pr_err("failed to register HMM device memory\n"); pr_err("failed to register HMM device memory\n");
/* Disable SVM support capability */ /* Disable SVM support capability */
pgmap->type = 0; pgmap->type = 0;
devm_release_mem_region(adev->dev, res->start, resource_size(res)); if (pgmap->type == MEMORY_DEVICE_PRIVATE)
devm_release_mem_region(adev->dev, res->start,
res->end - res->start + 1);
return PTR_ERR(r); return PTR_ERR(r);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment