diff options
| author | Christoph Hellwig <hch@lst.de> | 2019-06-26 08:27:18 -0400 |
|---|---|---|
| committer | Jason Gunthorpe <jgg@mellanox.com> | 2019-07-02 13:32:44 -0400 |
| commit | 4239f267e3cd31e6e592d26a9fa6834b5a11560b (patch) | |
| tree | 558b9faea166a458bc4f95b9849ea35fb2b96c56 | |
| parent | 721be868142cb95888847dfaaf3d1c5b8c65b943 (diff) | |
nouveau: use devm_memremap_pages directly
Just use devm_memremap_pages instead of hmm_devmem_add pages to allow
killing that wrapper which doesn't provide a whole lot of benefits.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dmem.c | 82 |
1 files changed, 38 insertions, 44 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c index a50f6fd2fe24..0fb7a44b8bc4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c | |||
| @@ -72,7 +72,8 @@ struct nouveau_dmem_migrate { | |||
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | struct nouveau_dmem { | 74 | struct nouveau_dmem { |
| 75 | struct hmm_devmem *devmem; | 75 | struct nouveau_drm *drm; |
| 76 | struct dev_pagemap pagemap; | ||
| 76 | struct nouveau_dmem_migrate migrate; | 77 | struct nouveau_dmem_migrate migrate; |
| 77 | struct list_head chunk_free; | 78 | struct list_head chunk_free; |
| 78 | struct list_head chunk_full; | 79 | struct list_head chunk_full; |
| @@ -80,6 +81,11 @@ struct nouveau_dmem { | |||
| 80 | struct mutex mutex; | 81 | struct mutex mutex; |
| 81 | }; | 82 | }; |
| 82 | 83 | ||
| 84 | static inline struct nouveau_dmem *page_to_dmem(struct page *page) | ||
| 85 | { | ||
| 86 | return container_of(page->pgmap, struct nouveau_dmem, pagemap); | ||
| 87 | } | ||
| 88 | |||
| 83 | struct nouveau_dmem_fault { | 89 | struct nouveau_dmem_fault { |
| 84 | struct nouveau_drm *drm; | 90 | struct nouveau_drm *drm; |
| 85 | struct nouveau_fence *fence; | 91 | struct nouveau_fence *fence; |
| @@ -96,8 +102,7 @@ struct nouveau_migrate { | |||
| 96 | unsigned long dma_nr; | 102 | unsigned long dma_nr; |
| 97 | }; | 103 | }; |
| 98 | 104 | ||
| 99 | static void | 105 | static void nouveau_dmem_page_free(struct page *page) |
| 100 | nouveau_dmem_free(struct hmm_devmem *devmem, struct page *page) | ||
| 101 | { | 106 | { |
| 102 | struct nouveau_dmem_chunk *chunk; | 107 | struct nouveau_dmem_chunk *chunk; |
| 103 | unsigned long idx; | 108 | unsigned long idx; |
| @@ -260,29 +265,21 @@ static const struct migrate_vma_ops nouveau_dmem_fault_migrate_ops = { | |||
| 260 | .finalize_and_map = nouveau_dmem_fault_finalize_and_map, | 265 | .finalize_and_map = nouveau_dmem_fault_finalize_and_map, |
| 261 | }; | 266 | }; |
| 262 | 267 | ||
| 263 | static vm_fault_t | 268 | static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf) |
| 264 | nouveau_dmem_fault(struct hmm_devmem *devmem, | ||
| 265 | struct vm_area_struct *vma, | ||
| 266 | unsigned long addr, | ||
| 267 | const struct page *page, | ||
| 268 | unsigned int flags, | ||
| 269 | pmd_t *pmdp) | ||
| 270 | { | 269 | { |
| 271 | struct drm_device *drm_dev = dev_get_drvdata(devmem->device); | 270 | struct nouveau_dmem *dmem = page_to_dmem(vmf->page); |
| 272 | unsigned long src[1] = {0}, dst[1] = {0}; | 271 | unsigned long src[1] = {0}, dst[1] = {0}; |
| 273 | struct nouveau_dmem_fault fault = {0}; | 272 | struct nouveau_dmem_fault fault = { .drm = dmem->drm }; |
| 274 | int ret; | 273 | int ret; |
| 275 | 274 | ||
| 276 | |||
| 277 | |||
| 278 | /* | 275 | /* |
| 279 | * FIXME what we really want is to find some heuristic to migrate more | 276 | * FIXME what we really want is to find some heuristic to migrate more |
| 280 | * than just one page on CPU fault. When such fault happens it is very | 277 | * than just one page on CPU fault. When such fault happens it is very |
| 281 | * likely that more surrounding page will CPU fault too. | 278 | * likely that more surrounding page will CPU fault too. |
| 282 | */ | 279 | */ |
| 283 | fault.drm = nouveau_drm(drm_dev); | 280 | ret = migrate_vma(&nouveau_dmem_fault_migrate_ops, vmf->vma, |
| 284 | ret = migrate_vma(&nouveau_dmem_fault_migrate_ops, vma, addr, | 281 | vmf->address, vmf->address + PAGE_SIZE, |
| 285 | addr + PAGE_SIZE, src, dst, &fault); | 282 | src, dst, &fault); |
| 286 | if (ret) | 283 | if (ret) |
| 287 | return VM_FAULT_SIGBUS; | 284 | return VM_FAULT_SIGBUS; |
| 288 | 285 | ||
| @@ -292,10 +289,9 @@ nouveau_dmem_fault(struct hmm_devmem *devmem, | |||
| 292 | return 0; | 289 | return 0; |
| 293 | } | 290 | } |
| 294 | 291 | ||
| 295 | static const struct hmm_devmem_ops | 292 | static const struct dev_pagemap_ops nouveau_dmem_pagemap_ops = { |
| 296 | nouveau_dmem_devmem_ops = { | 293 | .page_free = nouveau_dmem_page_free, |
| 297 | .free = nouveau_dmem_free, | 294 | .migrate_to_ram = nouveau_dmem_migrate_to_ram, |
| 298 | .fault = nouveau_dmem_fault, | ||
| 299 | }; | 295 | }; |
| 300 | 296 | ||
| 301 | static int | 297 | static int |
| @@ -581,7 +577,8 @@ void | |||
| 581 | nouveau_dmem_init(struct nouveau_drm *drm) | 577 | nouveau_dmem_init(struct nouveau_drm *drm) |
| 582 | { | 578 | { |
| 583 | struct device *device = drm->dev->dev; | 579 | struct device *device = drm->dev->dev; |
| 584 | unsigned long i, size; | 580 | struct resource *res; |
| 581 | unsigned long i, size, pfn_first; | ||
| 585 | int ret; | 582 | int ret; |
| 586 | 583 | ||
| 587 | /* This only make sense on PASCAL or newer */ | 584 | /* This only make sense on PASCAL or newer */ |
| @@ -591,6 +588,7 @@ nouveau_dmem_init(struct nouveau_drm *drm) | |||
| 591 | if (!(drm->dmem = kzalloc(sizeof(*drm->dmem), GFP_KERNEL))) | 588 | if (!(drm->dmem = kzalloc(sizeof(*drm->dmem), GFP_KERNEL))) |
| 592 | return; | 589 | return; |
| 593 | 590 | ||
| 591 | drm->dmem->drm = drm; | ||
| 594 | mutex_init(&drm->dmem->mutex); | 592 | mutex_init(&drm->dmem->mutex); |
| 595 | INIT_LIST_HEAD(&drm->dmem->chunk_free); | 593 | INIT_LIST_HEAD(&drm->dmem->chunk_free); |
| 596 | INIT_LIST_HEAD(&drm->dmem->chunk_full); | 594 | INIT_LIST_HEAD(&drm->dmem->chunk_full); |
| @@ -600,11 +598,8 @@ nouveau_dmem_init(struct nouveau_drm *drm) | |||
| 600 | 598 | ||
| 601 | /* Initialize migration dma helpers before registering memory */ | 599 | /* Initialize migration dma helpers before registering memory */ |
| 602 | ret = nouveau_dmem_migrate_init(drm); | 600 | ret = nouveau_dmem_migrate_init(drm); |
| 603 | if (ret) { | 601 | if (ret) |
| 604 | kfree(drm->dmem); | 602 | goto out_free; |
| 605 | drm->dmem = NULL; | ||
| 606 | return; | ||
| 607 | } | ||
| 608 | 603 | ||
| 609 | /* | 604 | /* |
| 610 | * FIXME we need some kind of policy to decide how much VRAM we | 605 | * FIXME we need some kind of policy to decide how much VRAM we |
| @@ -612,14 +607,16 @@ nouveau_dmem_init(struct nouveau_drm *drm) | |||
| 612 | * and latter if we want to do thing like over commit then we | 607 | * and latter if we want to do thing like over commit then we |
| 613 | * could revisit this. | 608 | * could revisit this. |
| 614 | */ | 609 | */ |
| 615 | drm->dmem->devmem = hmm_devmem_add(&nouveau_dmem_devmem_ops, | 610 | res = devm_request_free_mem_region(device, &iomem_resource, size); |
| 616 | device, size); | 611 | if (IS_ERR(res)) |
| 617 | if (IS_ERR(drm->dmem->devmem)) { | 612 | goto out_free; |
| 618 | kfree(drm->dmem); | 613 | drm->dmem->pagemap.type = MEMORY_DEVICE_PRIVATE; |
| 619 | drm->dmem = NULL; | 614 | drm->dmem->pagemap.res = *res; |
| 620 | return; | 615 | drm->dmem->pagemap.ops = &nouveau_dmem_pagemap_ops; |
| 621 | } | 616 | if (IS_ERR(devm_memremap_pages(device, &drm->dmem->pagemap))) |
| 622 | 617 | goto out_free; | |
| 618 | |||
| 619 | pfn_first = res->start >> PAGE_SHIFT; | ||
| 623 | for (i = 0; i < (size / DMEM_CHUNK_SIZE); ++i) { | 620 | for (i = 0; i < (size / DMEM_CHUNK_SIZE); ++i) { |
| 624 | struct nouveau_dmem_chunk *chunk; | 621 | struct nouveau_dmem_chunk *chunk; |
| 625 | struct page *page; | 622 | struct page *page; |
| @@ -632,8 +629,7 @@ nouveau_dmem_init(struct nouveau_drm *drm) | |||
| 632 | } | 629 | } |
| 633 | 630 | ||
| 634 | chunk->drm = drm; | 631 | chunk->drm = drm; |
| 635 | chunk->pfn_first = drm->dmem->devmem->pfn_first; | 632 | chunk->pfn_first = pfn_first + (i * DMEM_CHUNK_NPAGES); |
| 636 | chunk->pfn_first += (i * DMEM_CHUNK_NPAGES); | ||
| 637 | list_add_tail(&chunk->list, &drm->dmem->chunk_empty); | 633 | list_add_tail(&chunk->list, &drm->dmem->chunk_empty); |
| 638 | 634 | ||
| 639 | page = pfn_to_page(chunk->pfn_first); | 635 | page = pfn_to_page(chunk->pfn_first); |
| @@ -643,6 +639,10 @@ nouveau_dmem_init(struct nouveau_drm *drm) | |||
| 643 | } | 639 | } |
| 644 | 640 | ||
| 645 | NV_INFO(drm, "DMEM: registered %ldMB of device memory\n", size >> 20); | 641 | NV_INFO(drm, "DMEM: registered %ldMB of device memory\n", size >> 20); |
| 642 | return; | ||
| 643 | out_free: | ||
| 644 | kfree(drm->dmem); | ||
| 645 | drm->dmem = NULL; | ||
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | static void | 648 | static void |
| @@ -833,13 +833,7 @@ out: | |||
| 833 | static inline bool | 833 | static inline bool |
| 834 | nouveau_dmem_page(struct nouveau_drm *drm, struct page *page) | 834 | nouveau_dmem_page(struct nouveau_drm *drm, struct page *page) |
| 835 | { | 835 | { |
| 836 | if (!is_device_private_page(page)) | 836 | return is_device_private_page(page) && drm->dmem == page_to_dmem(page); |
| 837 | return false; | ||
| 838 | |||
| 839 | if (drm->dmem->devmem != page->pgmap->data) | ||
| 840 | return false; | ||
| 841 | |||
| 842 | return true; | ||
| 843 | } | 837 | } |
| 844 | 838 | ||
| 845 | void | 839 | void |
