diff options
author | Alex Waterman <alexw@nvidia.com> | 2017-09-20 15:21:33 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-10-04 05:29:55 -0400 |
commit | e400475a915f73abb823b00945179eec470f73e0 (patch) | |
tree | aa655eea59f2180f47f97d7ce325810cfa83cc10 /drivers/gpu/nvgpu | |
parent | 7a3dbdd43f142f7f94a19ff6a320e589f0b23324 (diff) |
gpu: nvgpu: Combine VIDMEM and SYSMEM map paths
Combine the VIDMEM and SYSMEM GMMU mapping paths into one
single function. With the proper nvgpu_sgt abstraction in
place the high level mapping code can treat these two types
of maps identically. The benefits of this are immediate: a
change to the mapping code will have much more testing
coverage - the same code runs on both vidmem and sysmem.
This also makes it easier to make changes to mapping code
since the changes will be testable no matter what type of
mem is being mapped.
JIRA NVGPU-68
Change-Id: I308eda03d426966ba8e1d4892c99cf97b45c5993
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1566706
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Konsta Holtta <kholtta@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/common/mm/gmmu.c | 114 |
1 files changed, 21 insertions, 93 deletions
diff --git a/drivers/gpu/nvgpu/common/mm/gmmu.c b/drivers/gpu/nvgpu/common/mm/gmmu.c index cad53fa1..b802cb53 100644 --- a/drivers/gpu/nvgpu/common/mm/gmmu.c +++ b/drivers/gpu/nvgpu/common/mm/gmmu.c | |||
@@ -466,79 +466,12 @@ static int __set_pd_level(struct vm_gk20a *vm, | |||
466 | return 0; | 466 | return 0; |
467 | } | 467 | } |
468 | 468 | ||
469 | /* | 469 | static int __nvgpu_gmmu_do_update_page_table(struct vm_gk20a *vm, |
470 | * VIDMEM version of the update_ptes logic. | 470 | struct nvgpu_sgt *sgt, |
471 | */ | 471 | u64 space_to_skip, |
472 | static int __nvgpu_gmmu_update_page_table_vidmem(struct vm_gk20a *vm, | 472 | u64 virt_addr, |
473 | struct nvgpu_sgt *sgt, | 473 | u64 length, |
474 | u64 space_to_skip, | 474 | struct nvgpu_gmmu_attrs *attrs) |
475 | u64 virt_addr, | ||
476 | u64 length, | ||
477 | struct nvgpu_gmmu_attrs *attrs) | ||
478 | { | ||
479 | u64 phys_addr, chunk_length; | ||
480 | int err = 0; | ||
481 | void *sgl; | ||
482 | |||
483 | if (!sgt) { | ||
484 | /* | ||
485 | * This is considered an unmap. Just pass in 0 as the physical | ||
486 | * address for the entire GPU range. | ||
487 | */ | ||
488 | err = __set_pd_level(vm, &vm->pdb, | ||
489 | 0, | ||
490 | 0, | ||
491 | virt_addr, length, | ||
492 | attrs); | ||
493 | return err; | ||
494 | } | ||
495 | |||
496 | /* | ||
497 | * Otherwise iterate across all the chunks in this allocation and | ||
498 | * map them. | ||
499 | */ | ||
500 | nvgpu_sgt_for_each_sgl(sgl, sgt) { | ||
501 | if (space_to_skip && | ||
502 | space_to_skip >= nvgpu_sgt_get_length(sgt, sgl)) { | ||
503 | space_to_skip -= nvgpu_sgt_get_length(sgt, sgl); | ||
504 | sgl = nvgpu_sgt_get_next(sgt, sgl); | ||
505 | continue; | ||
506 | } | ||
507 | |||
508 | phys_addr = nvgpu_sgt_get_phys(sgt, sgl) + space_to_skip; | ||
509 | chunk_length = min(length, (nvgpu_sgt_get_length(sgt, sgl) - | ||
510 | space_to_skip)); | ||
511 | |||
512 | err = __set_pd_level(vm, &vm->pdb, | ||
513 | 0, | ||
514 | phys_addr, | ||
515 | virt_addr, chunk_length, | ||
516 | attrs); | ||
517 | if (err) | ||
518 | break; | ||
519 | |||
520 | /* Space has been skipped so zero this for future chunks. */ | ||
521 | space_to_skip = 0; | ||
522 | |||
523 | /* | ||
524 | * Update the map pointer and the remaining length. | ||
525 | */ | ||
526 | virt_addr += chunk_length; | ||
527 | length -= chunk_length; | ||
528 | |||
529 | if (length == 0) | ||
530 | break; | ||
531 | } | ||
532 | |||
533 | return err; | ||
534 | } | ||
535 | |||
536 | static int __nvgpu_gmmu_update_page_table_sysmem(struct vm_gk20a *vm, | ||
537 | struct nvgpu_sgt *sgt, | ||
538 | u64 space_to_skip, | ||
539 | u64 virt_addr, | ||
540 | u64 length, | ||
541 | struct nvgpu_gmmu_attrs *attrs) | ||
542 | { | 475 | { |
543 | struct gk20a *g = gk20a_from_vm(vm); | 476 | struct gk20a *g = gk20a_from_vm(vm); |
544 | void *sgl; | 477 | void *sgl; |
@@ -565,7 +498,7 @@ static int __nvgpu_gmmu_update_page_table_sysmem(struct vm_gk20a *vm, | |||
565 | * mapping is simple since the "physical" address is actually a virtual | 498 | * mapping is simple since the "physical" address is actually a virtual |
566 | * IO address and will be contiguous. | 499 | * IO address and will be contiguous. |
567 | */ | 500 | */ |
568 | if (!g->mm.bypass_smmu) { | 501 | if (attrs->aperture == APERTURE_SYSMEM && !g->mm.bypass_smmu) { |
569 | u64 io_addr = nvgpu_sgt_get_gpu_addr(sgt, g, sgt->sgl, attrs); | 502 | u64 io_addr = nvgpu_sgt_get_gpu_addr(sgt, g, sgt->sgl, attrs); |
570 | 503 | ||
571 | io_addr += space_to_skip; | 504 | io_addr += space_to_skip; |
@@ -608,8 +541,15 @@ static int __nvgpu_gmmu_update_page_table_sysmem(struct vm_gk20a *vm, | |||
608 | virt_addr, | 541 | virt_addr, |
609 | chunk_length, | 542 | chunk_length, |
610 | attrs); | 543 | attrs); |
544 | if (err) | ||
545 | break; | ||
611 | 546 | ||
547 | /* Space has been skipped so zero this for future chunks. */ | ||
612 | space_to_skip = 0; | 548 | space_to_skip = 0; |
549 | |||
550 | /* | ||
551 | * Update the map pointer and the remaining length. | ||
552 | */ | ||
613 | virt_addr += chunk_length; | 553 | virt_addr += chunk_length; |
614 | length -= chunk_length; | 554 | length -= chunk_length; |
615 | 555 | ||
@@ -617,7 +557,7 @@ static int __nvgpu_gmmu_update_page_table_sysmem(struct vm_gk20a *vm, | |||
617 | break; | 557 | break; |
618 | } | 558 | } |
619 | 559 | ||
620 | return 0; | 560 | return err; |
621 | } | 561 | } |
622 | 562 | ||
623 | /* | 563 | /* |
@@ -689,24 +629,12 @@ static int __nvgpu_gmmu_update_page_table(struct vm_gk20a *vm, | |||
689 | attrs->coherent ? 'c' : '-', | 629 | attrs->coherent ? 'c' : '-', |
690 | attrs->valid ? 'V' : '-'); | 630 | attrs->valid ? 'V' : '-'); |
691 | 631 | ||
692 | /* | 632 | err = __nvgpu_gmmu_do_update_page_table(vm, |
693 | * For historical reasons these are separate, but soon these will be | 633 | sgt, |
694 | * unified. | 634 | space_to_skip, |
695 | */ | 635 | virt_addr, |
696 | if (attrs->aperture == APERTURE_VIDMEM) | 636 | length, |
697 | err = __nvgpu_gmmu_update_page_table_vidmem(vm, | 637 | attrs); |
698 | sgt, | ||
699 | space_to_skip, | ||
700 | virt_addr, | ||
701 | length, | ||
702 | attrs); | ||
703 | else | ||
704 | err = __nvgpu_gmmu_update_page_table_sysmem(vm, | ||
705 | sgt, | ||
706 | space_to_skip, | ||
707 | virt_addr, | ||
708 | length, | ||
709 | attrs); | ||
710 | 638 | ||
711 | unmap_gmmu_pages(g, &vm->pdb); | 639 | unmap_gmmu_pages(g, &vm->pdb); |
712 | nvgpu_smp_mb(); | 640 | nvgpu_smp_mb(); |