Ignore:
Timestamp:
May 17, 2019, 9:27:04 AM (6 years ago)
Author:
alain
Message:

Remove the "giant" rwlock protecting the GPT, and
use the GPT_LOCKED attribute in each PTE to prevent
concurrent modifications of one GPT entry.
The version number has been incremented to 2.1.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/libk/user_dir.c

    r619 r629  
    22 * user_dir.c - kernel DIR related operations implementation.
    33 *
    4  * Authors   Alain   Greiner (2016,2017,2018)
     4 * Authors   Alain   Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    9191    pid_t           ref_pid;           // reference process PID
    9292    xptr_t          gpt_xp;            // extended pointer on reference process GPT
    93     uint32_t        gpt_attributes;    // attributes for all mapped gpt entries
     93    uint32_t        attr;              // attributes for all GPT entries
    9494    uint32_t        dirents_per_page;  // number of dirent descriptors per page
    9595    xptr_t          page_xp;           // extended pointer on page descriptor 
     
    9999    uint32_t        total_dirents;     // total number of dirents in dirent array
    100100    uint32_t        total_pages;       // total number of pages for dirent array
    101     vpn_t           vpn;               // first page in dirent array vseg
     101    vpn_t           vpn_base;          // first page in dirent array vseg
     102    vpn_t           vpn;               // current page in dirent array vseg
    102103    ppn_t           ppn;               // ppn of currently allocated physical page
    103104    uint32_t        entries;           // number of dirent actually comied in one page
     
    107108    uint32_t        page_id;           // page index in list of physical pages
    108109    kmem_req_t      req;               // kmem request descriptor
     110    ppn_t           fake_ppn;          // unused, but required by hal_gptlock_pte()
     111    uint32_t        fake_attr;         // unused, but required by hal_gptlock_pte()
    109112    error_t         error;
    110113
    111     // get cluster, local pointer, and pid of reference user process
     114    // get cluster, local pointer, and pid of reference process
    112115    ref_cxy = GET_CXY( ref_xp );
    113116    ref_ptr = GET_PTR( ref_xp );
     
    256259"unconsistent vseg size for dirent array" );
    257260
    258     // build extended pointer on reference process GPT, PTE attributes and ppn
     261    // build extended pointer on reference process GPT
    259262    gpt_xp         = XPTR( ref_cxy , &ref_ptr->vmm.gpt );
    260     gpt_attributes = GPT_MAPPED   |
    261                      GPT_SMALL    |
    262                      GPT_READABLE |
    263                      GPT_CACHABLE |
    264                      GPT_USER     ;
     263
     264    // build PTE attributes
     265    attr = GPT_MAPPED   |
     266           GPT_SMALL    |
     267           GPT_READABLE |
     268           GPT_CACHABLE |
     269           GPT_USER     ;
    265270
    266271    // get first vpn from vseg descriptor
    267     vpn = hal_remote_l32( XPTR( ref_cxy , &vseg->vpn_base ) );
     272    vpn_base = hal_remote_l32( XPTR( ref_cxy , &vseg->vpn_base ) );
    268273
    269274    // scan the list of allocated physical pages to map
    270     // all physical pages in the in the reference process GPT
     275    // all physical pages in the reference process GPT
    271276    page_id = 0;
    272277    while( list_is_empty( &root ) == false )
     
    277282        // compute ppn
    278283        ppn = ppm_page2ppn( XPTR( local_cxy , page ) );
     284
     285        // compute vpn
     286        vpn = vpn_base + page_id;
    279287       
    280         error = hal_gpt_set_pte( gpt_xp,
    281                                  vpn + page_id,
    282                                  gpt_attributes,
    283                                  ppn );
     288        // lock the PTE (and create PT2 if required)
     289        error = hal_gpt_lock_pte( gpt_xp,
     290                                  vpn,
     291                                  &fake_attr,
     292                                  &fake_ppn );
    284293        if( error )
    285294        {
    286295            printk("\n[ERROR] in %s : cannot map vpn %x in GPT\n",
    287             __FUNCTION__, (vpn + page_id) );
     296            __FUNCTION__, vpn );
    288297
    289298            // delete the vseg
    290             if( ref_cxy == local_cxy) vmm_delete_vseg( ref_pid, vpn<<CONFIG_PPM_PAGE_SHIFT );
    291             else rpc_vmm_delete_vseg_client( ref_cxy, ref_pid, vpn<<CONFIG_PPM_PAGE_SHIFT );
     299            if( ref_cxy == local_cxy)
     300                vmm_delete_vseg( ref_pid, vpn_base << CONFIG_PPM_PAGE_SHIFT );
     301            else
     302                rpc_vmm_delete_vseg_client( ref_cxy, ref_pid, vpn_base << CONFIG_PPM_PAGE_SHIFT );
    292303
    293304            // release the user_dir descriptor
     
    298309        }
    299310
     311        // set PTE in GPT                         
     312        hal_gpt_set_pte( gpt_xp,
     313                         vpn,
     314                         attr,
     315                         ppn );
     316
    300317#if DEBUG_USER_DIR
    301318if( cycle > DEBUG_USER_DIR )
     
    317334    dir->current = 0;
    318335    dir->entries = total_dirents;
    319     dir->ident   = (intptr_t)(vpn << CONFIG_PPM_PAGE_SHIFT);
     336    dir->ident   = (intptr_t)(vpn_base << CONFIG_PPM_PAGE_SHIFT);
    320337
    321338    // build extended pointers on root and lock of user_dir xlist in ref process
Note: See TracChangeset for help on using the changeset viewer.