Changeset de0af3a in mainline for kernel/generic/src/mm/as.c
- Timestamp:
- 2018-12-03T18:29:53Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0777a933, 7be8d4d
- Parents:
- a0765f6
- git-author:
- Jiri Svoboda <jiri@…> (2018-12-03 16:53:27)
- git-committer:
- jxsvoboda <5887334+jxsvoboda@…> (2018-12-03 18:29:53)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/as.c
ra0765f6 rde0af3a 89 89 as_operations_t *as_operations = NULL; 90 90 91 /** Slab for as_t objects. 92 * 93 */ 91 /** Cache for as_t objects */ 94 92 static slab_cache_t *as_cache; 93 94 /** Cache for as_page_mapping_t objects */ 95 static slab_cache_t *as_page_mapping_cache; 95 96 96 97 /** ASID subsystem lock. … … 138 139 as_cache = slab_cache_create("as_t", sizeof(as_t), 0, 139 140 as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED); 141 142 as_page_mapping_cache = slab_cache_create("as_page_mapping_t", 143 sizeof(as_page_mapping_t), 0, NULL, NULL, SLAB_CACHE_MAGDEFERRED); 140 144 141 145 AS_KERNEL = as_create(FLAG_AS_KERNEL); … … 524 528 } 525 529 530 /** Get key function for pagemap ordered dictionary. 531 * 532 * The key is the virtual address of the page (as_page_mapping_t.vaddr) 533 * 534 * @param odlink Link to as_pagemap_t.map ordered dictionary 535 * @return Pointer to virtual address cast as @c void * 536 */ 537 static void *as_pagemap_getkey(odlink_t *odlink) 538 { 539 as_page_mapping_t *mapping; 540 541 mapping = odict_get_instance(odlink, as_page_mapping_t, lpagemap); 542 return (void *) &mapping->vaddr; 543 } 544 545 /** Comparison function for pagemap ordered dictionary. 546 * 547 * @param a Pointer to virtual address cast as @c void * 548 * @param b Pointer to virtual address cast as @c void * 549 * @return <0, =0, >0 if virtual address a is less than, equal to, or 550 * greater-than b, respectively. 551 */ 552 static int as_pagemap_cmp(void *a, void *b) 553 { 554 uintptr_t va = *(uintptr_t *)a; 555 uintptr_t vb = *(uintptr_t *)b; 556 557 return va - vb; 558 } 559 560 /** Initialize pagemap. 561 * 562 * @param pagemap Pagemap 563 */ 564 NO_TRACE void as_pagemap_initialize(as_pagemap_t *pagemap) 565 { 566 odict_initialize(&pagemap->map, as_pagemap_getkey, as_pagemap_cmp); 567 } 568 569 /** Finalize pagemap. 570 * 571 * Destroy any entries in the pagemap. 572 * 573 * @param pagemap Pagemap 574 */ 575 NO_TRACE void as_pagemap_finalize(as_pagemap_t *pagemap) 576 { 577 as_page_mapping_t *mapping = as_pagemap_first(pagemap); 578 while (mapping != NULL) { 579 as_pagemap_remove(mapping); 580 mapping = as_pagemap_first(pagemap); 581 } 582 odict_finalize(&pagemap->map); 583 } 584 585 /** Get first page mapping. 586 * 587 * @param pagemap Pagemap 588 * @return First mapping or @c NULL if there is none 589 */ 590 NO_TRACE as_page_mapping_t *as_pagemap_first(as_pagemap_t *pagemap) 591 { 592 odlink_t *odlink; 593 594 odlink = odict_first(&pagemap->map); 595 if (odlink == NULL) 596 return NULL; 597 598 return odict_get_instance(odlink, as_page_mapping_t, lpagemap); 599 } 600 601 /** Get next page mapping. 602 * 603 * @param cur Current mapping 604 * @return Next mapping or @c NULL if @a cur is the last one 605 */ 606 NO_TRACE as_page_mapping_t *as_pagemap_next(as_page_mapping_t *cur) 607 { 608 odlink_t *odlink; 609 610 odlink = odict_next(&cur->lpagemap, &cur->pagemap->map); 611 if (odlink == NULL) 612 return NULL; 613 614 return odict_get_instance(odlink, as_page_mapping_t, lpagemap); 615 } 616 617 /** Find frame by virtual address. 618 * 619 * @param pagemap Pagemap 620 * @param vaddr Virtual address of page 621 * @param rframe Place to store physical frame address 622 * @return EOK on succcess or ENOENT if no mapping found 623 */ 624 NO_TRACE errno_t as_pagemap_find(as_pagemap_t *pagemap, uintptr_t vaddr, 625 uintptr_t *rframe) 626 { 627 odlink_t *odlink; 628 as_page_mapping_t *mapping; 629 630 odlink = odict_find_eq(&pagemap->map, &vaddr, NULL); 631 if (odlink == NULL) 632 return ENOENT; 633 634 mapping = odict_get_instance(odlink, as_page_mapping_t, lpagemap); 635 *rframe = mapping->frame; 636 return EOK; 637 } 638 639 /** Insert new page mapping. 640 * 641 * This function can block to allocate kernel memory. 642 * 643 * @param pagemap Pagemap 644 * @param vaddr Virtual page address 645 * @param frame Physical frame address 646 */ 647 NO_TRACE void as_pagemap_insert(as_pagemap_t *pagemap, uintptr_t vaddr, 648 uintptr_t frame) 649 { 650 as_page_mapping_t *mapping; 651 652 mapping = slab_alloc(as_page_mapping_cache, 0); 653 mapping->pagemap = pagemap; 654 odlink_initialize(&mapping->lpagemap); 655 mapping->vaddr = vaddr; 656 mapping->frame = frame; 657 odict_insert(&mapping->lpagemap, &pagemap->map, NULL); 658 } 659 660 /** Remove page mapping. 661 * 662 * @param mapping Mapping 663 */ 664 NO_TRACE void as_pagemap_remove(as_page_mapping_t *mapping) 665 { 666 odict_remove(&mapping->lpagemap); 667 slab_free(as_page_mapping_cache, mapping); 668 } 669 526 670 /** Remove reference to address space area share info. 527 671 * … … 545 689 * reference from all frames found there. 546 690 */ 547 list_foreach(sh_info->pagemap.leaf_list, leaf_link, 548 btree_node_t, node) { 549 btree_key_t i; 550 551 for (i = 0; i < node->keys; i++) 552 frame_free((uintptr_t) node->value[i], 1); 691 as_page_mapping_t *mapping = as_pagemap_first(&sh_info->pagemap); 692 while (mapping != NULL) { 693 frame_free(mapping->frame, 1); 694 mapping = as_pagemap_next(mapping); 553 695 } 554 696 … … 561 703 sh_info->backend_shared_data); 562 704 } 563 btree_destroy(&sh_info->pagemap);705 as_pagemap_finalize(&sh_info->pagemap); 564 706 free(sh_info); 565 707 } … … 665 807 si->backend_shared_data = NULL; 666 808 si->backend = backend; 667 btree_create(&si->pagemap);809 as_pagemap_initialize(&si->pagemap); 668 810 669 811 area->sh_info = si;
Note:
See TracChangeset
for help on using the changeset viewer.