Changeset 611 for trunk/kernel/mm/vmm.c


Ignore:
Timestamp:
Jan 9, 2019, 3:02:51 PM (5 years ago)
Author:
alain
Message:

Introduce sigificant modifs in VFS to support the <ls> command,
and the . and .. directories entries.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/mm/vmm.c

    r610 r611  
    11/*
    2  * vmm.c - virtual memory manager related operations interface.
     2 * vmm.c - virtual memory manager related operations definition.
    33 *
    44 * Authors   Ghassan Almaless (2008,2009,2010,2011, 2012)
     
    254254}  // vmm_display()
    255255
    256 ///////////////////////////////////
    257 void vmm_vseg_attach( vmm_t  * vmm,
    258                       vseg_t * vseg )
     256//////////////////////////////////////////
     257void vmm_attach_vseg_to_vsl( vmm_t  * vmm,
     258                             vseg_t * vseg )
    259259{
    260260    // build extended pointer on rwlock protecting VSL
     
    275275}
    276276
    277 ///////////////////////////////////
    278 void vmm_vseg_detach( vmm_t  * vmm,
    279                       vseg_t * vseg )
     277////////////////////////////////////////////
     278void vmm_detach_vseg_from_vsl( vmm_t  * vmm,
     279                               vseg_t * vseg )
    280280{
     281    // get vseg type
     282    uint32_t type = vseg->type;
     283
    281284    // build extended pointer on rwlock protecting VSL
    282285    xptr_t lock_xp = XPTR( local_cxy , &vmm->vsegs_lock );
     
    288291    vseg->vmm = NULL;
    289292
    290     // remove vseg from vmm list
     293    // remove vseg from VSL
    291294    xlist_unlink( XPTR( local_cxy , &vseg->xlist ) );
    292295
    293296    // release rwlock in write mode
    294297    remote_rwlock_wr_release( lock_xp );
    295 }
     298
     299    // release the stack slot to VMM stack allocator if STACK type
     300    if( type == VSEG_TYPE_STACK )
     301    {
     302        // get pointer on stack allocator
     303        stack_mgr_t * mgr = &vmm->stack_mgr;
     304
     305        // compute slot index
     306        uint32_t index = ((vseg->vpn_base - mgr->vpn_base - 1) / CONFIG_VMM_STACK_SIZE);
     307
     308        // update stacks_bitmap
     309        busylock_acquire( &mgr->lock );
     310        bitmap_clear( &mgr->bitmap , index );
     311        busylock_release( &mgr->lock );
     312    }
     313
     314    // release the vseg to VMM mmap allocator if MMAP type
     315    if( (type == VSEG_TYPE_ANON) || (type == VSEG_TYPE_FILE) || (type == VSEG_TYPE_REMOTE) )
     316    {
     317        // get pointer on mmap allocator
     318        mmap_mgr_t * mgr = &vmm->mmap_mgr;
     319
     320        // compute zombi_list index
     321        uint32_t index = bits_log2( vseg->vpn_size );
     322
     323        // update zombi_list
     324        busylock_acquire( &mgr->lock );
     325        list_add_first( &mgr->zombi_list[index] , &vseg->zlist );
     326        busylock_release( &mgr->lock );
     327    }
     328
     329    // release physical memory allocated for vseg descriptor if no MMAP type
     330    if( (type != VSEG_TYPE_ANON) && (type != VSEG_TYPE_FILE) && (type != VSEG_TYPE_REMOTE) )
     331    {
     332        vseg_free( vseg );
     333    }
     334
     335}  // end vmm_remove_vseg_from_vsl()
    296336
    297337////////////////////////////////////////////////
     
    616656
    617657            // register child vseg in child VSL
    618             vmm_vseg_attach( child_vmm , child_vseg );
     658            vmm_attach_vseg_to_vsl( child_vmm , child_vseg );
    619659
    620660#if DEBUG_VMM_FORK_COPY
     
    759799    xptr_t   root_xp = XPTR( local_cxy , &vmm->vsegs_root );
    760800
    761     // remove all user vsegs registered in VSL
     801    // scan the VSL to delete all registered vsegs
     802    // (don't use a FOREACH for item deletion in xlist)
    762803        while( !xlist_is_empty( root_xp ) )
    763804        {
     
    766807        vseg    = GET_PTR( vseg_xp );
    767808
    768         // unmap and release physical pages
    769         vmm_unmap_vseg( process , vseg );
    770 
    771         // remove vseg from VSL
    772                 vmm_vseg_detach( vmm , vseg );
    773 
    774         // release memory allocated to vseg descriptor
    775         vseg_free( vseg );
     809        // delete vseg and release physical pages
     810        vmm_delete_vseg( process->pid , vseg->min );
    776811
    777812#if( DEBUG_VMM_DESTROY & 1 )
    778813if( DEBUG_VMM_DESTROY < cycle )
    779 printk("\n[%s] %s vseg released / vpn_base %x / vpn_size %d\n",
     814printk("\n[%s] %s vseg deleted / vpn_base %x / vpn_size %d\n",
    780815__FUNCTION__ , vseg_type_str( vseg->type ), vseg->vpn_base, vseg->vpn_size );
    781816#endif
     
    796831__FUNCTION__ , vseg_type_str( vseg->type ), vseg->vpn_base, vseg->vpn_size );
    797832#endif
    798                     vmm_vseg_detach( vmm , vseg );
     833            // clean vseg descriptor
     834            vseg->vmm = NULL;
     835
     836            // remove vseg from  xlist
     837            xlist_unlink( XPTR( local_cxy , &vseg->xlist ) );
     838
     839                    // release vseg descriptor
    799840            vseg_free( vseg );
    800841
     
    10791120
    10801121    // attach vseg to VSL
    1081         vmm_vseg_attach( vmm , vseg );
     1122        vmm_attach_vseg_to_vsl( vmm , vseg );
    10821123
    10831124#if DEBUG_VMM_CREATE_VSEG
     
    10921133}  // vmm_create_vseg()
    10931134
    1094 /////////////////////////////////////
    1095 void vmm_remove_vseg( vseg_t * vseg )
     1135///////////////////////////////////
     1136void vmm_delete_vseg( pid_t    pid,
     1137                      intptr_t vaddr )
    10961138{
    1097     // get pointers on calling process and VMM
    1098     thread_t   * this    = CURRENT_THREAD;
    1099     vmm_t      * vmm     = &this->process->vmm;
    1100     uint32_t     type    = vseg->type;
    1101 
    1102     // detach vseg from VSL
    1103         vmm_vseg_detach( vmm , vseg );
    1104 
    1105     // release the stack slot to VMM stack allocator if STACK type
    1106     if( type == VSEG_TYPE_STACK )
    1107     {
    1108         // get pointer on stack allocator
    1109         stack_mgr_t * mgr = &vmm->stack_mgr;
    1110 
    1111         // compute slot index
    1112         uint32_t index = ((vseg->vpn_base - mgr->vpn_base - 1) / CONFIG_VMM_STACK_SIZE);
    1113 
    1114         // update stacks_bitmap
    1115         busylock_acquire( &mgr->lock );
    1116         bitmap_clear( &mgr->bitmap , index );
    1117         busylock_release( &mgr->lock );
    1118     }
    1119 
    1120     // release the vseg to VMM mmap allocator if MMAP type
    1121     if( (type == VSEG_TYPE_ANON) || (type == VSEG_TYPE_FILE) || (type == VSEG_TYPE_REMOTE) )
    1122     {
    1123         // get pointer on mmap allocator
    1124         mmap_mgr_t * mgr = &vmm->mmap_mgr;
    1125 
    1126         // compute zombi_list index
    1127         uint32_t index = bits_log2( vseg->vpn_size );
    1128 
    1129         // update zombi_list
    1130         busylock_acquire( &mgr->lock );
    1131         list_add_first( &mgr->zombi_list[index] , &vseg->zlist );
    1132         busylock_release( &mgr->lock );
    1133     }
    1134 
    1135     // release physical memory allocated for vseg descriptor if no MMAP type
    1136     if( (type != VSEG_TYPE_ANON) && (type != VSEG_TYPE_FILE) && (type != VSEG_TYPE_REMOTE) )
    1137     {
    1138         vseg_free( vseg );
    1139     }
    1140 }  // end vmm_remove_vseg()
    1141 
    1142 /////////////////////////////////////////
    1143 void vmm_unmap_vseg( process_t * process,
    1144                      vseg_t    * vseg )
    1145 {
     1139    process_t * process;    // local pointer on local process
     1140    vmm_t     * vmm;        // local pointer on local process VMM
     1141    vseg_t    * vseg;       // local pointer on local vseg containing vaddr
     1142    gpt_t     * gpt;        // local pointer on local process GPT
    11461143    vpn_t       vpn;        // VPN of current PTE
    11471144    vpn_t       vpn_min;    // VPN of first PTE
     
    11571154    uint32_t    forks;      // actual number of pendinf forks
    11581155
    1159 #if DEBUG_VMM_UNMAP_VSEG
     1156#if DEBUG_VMM_DELETE_VSEG
    11601157uint32_t   cycle = (uint32_t)hal_get_cycles();
    11611158thread_t * this  = CURRENT_THREAD;
    1162 if( DEBUG_VMM_UNMAP_VSEG < cycle )
    1163 printk("\n[%s] thread[%x,%x] enter / process %x / vseg %s / base %x / cycle %d\n",
    1164 __FUNCTION__, this->process->pid, this->trdid, process->pid,
    1165 vseg_type_str( vseg->type ), vseg->vpn_base, cycle );
    1166 #endif
    1167 
    1168     // get pointer on local GPT
    1169     gpt_t     * gpt = &process->vmm.gpt;
    1170 
    1171     // loop on pages in vseg
     1159if( DEBUG_VMM_DELETE_VSEG < cycle )
     1160printk("\n[%s] thread[%x,%x] enter / process %x / vaddr %x / cycle %d\n",
     1161__FUNCTION__, this->process->pid, this->trdid, pid, vaddr, cycle );
     1162#endif
     1163
     1164    // get local pointer on local process descriptor
     1165    process = cluster_get_local_process_from_pid( pid );
     1166
     1167    if( process == NULL ) return;
     1168
     1169    // get pointers on local process VMM an GPT
     1170    vmm = &process->vmm;
     1171    gpt = &process->vmm.gpt;
     1172
     1173    // get local pointer on vseg containing vaddr
     1174    vseg = vmm_vseg_from_vaddr( vmm , vaddr );
     1175
     1176    if( vseg == NULL ) return;
     1177
     1178    // loop to invalidate all vseg PTEs in GPT
    11721179    vpn_min = vseg->vpn_base;
    11731180    vpn_max = vpn_min + vseg->vpn_size;
     
    11801187        {
    11811188
    1182 #if( DEBUG_VMM_UNMAP_VSEG & 1 )
    1183 if( DEBUG_VMM_UNMAP_VSEG < cycle )
    1184 printk("- vpn %x / ppn %x\n" , vpn , ppn );
     1189#if( DEBUG_VMM_DELETE_VSEG & 1 )
     1190if( DEBUG_VMM_DELETE_VSEG < cycle )
     1191printk("- unmap vpn %x / ppn %x / vseg %s \n" , vpn , ppn, vseg_type_str(vseg->type) );
    11851192#endif
    11861193
     
    12251232                        rpc_pmem_release_pages_client( page_cxy , page_ptr );
    12261233                    }
     1234
     1235#if( DEBUG_VMM_DELETE_VSEG & 1 )
     1236if( DEBUG_VMM_DELETE_VSEG < cycle )
     1237printk("- release ppn %x\n", ppn );
     1238#endif
    12271239                }
    12281240            }
     
    12301242    }
    12311243
    1232 #if DEBUG_VMM_UNMAP_VSEG
     1244    // remove vseg from VSL and release vseg descriptor (if not MMAP)
     1245    vmm_detach_vseg_from_vsl( vmm , vseg );
     1246
     1247#if DEBUG_VMM_DELETE_VSEG
    12331248cycle = (uint32_t)hal_get_cycles();
    1234 if( DEBUG_VMM_UNMAP_VSEG < cycle )
     1249if( DEBUG_VMM_DELETE_VSEG < cycle )
    12351250printk("\n[%s] thread[%x,%x] exit / process %x / vseg %s / base %x / cycle %d\n",
    1236 __FUNCTION__, this->process->pid, this->trdid, process->pid,
    1237 vseg_type_str( vseg->type ), vseg->vpn_base, cycle );
    1238 #endif
    1239 
    1240 }  // end vmm_unmap_vseg()
    1241 
    1242 //////////////////////////////////////////////////////////////////////////////////////////
    1243 // This low-level static function is called by the vmm_get_vseg(), vmm_get_pte(),
    1244 // and vmm_resize_vseg() functions.  It scan the local VSL to find the unique vseg
    1245 // containing a given virtual address.
    1246 //////////////////////////////////////////////////////////////////////////////////////////
    1247 // @ vmm     : pointer on the process VMM.
    1248 // @ vaddr   : virtual address.
    1249 // @ return vseg pointer if success / return NULL if not found.
    1250 //////////////////////////////////////////////////////////////////////////////////////////
    1251 static vseg_t * vmm_vseg_from_vaddr( vmm_t    * vmm,
    1252                                      intptr_t   vaddr )
     1251__FUNCTION__, this->process->pid, this->trdid, pid, vseg_type_str(vseg->type), vaddr, cycle );
     1252#endif
     1253
     1254}  // end vmm_delete_vseg()
     1255
     1256/////////////////////////////////////////////
     1257vseg_t * vmm_vseg_from_vaddr( vmm_t    * vmm,
     1258                              intptr_t   vaddr )
    12531259{
    12541260    xptr_t   iter_xp;
     
    13101316        remote_rwlock_wr_acquire( lock_xp );
    13111317
    1312         if( (vseg->min > addr_min) || (vseg->max < addr_max) )   // region not included in vseg
    1313     {
    1314         error = EINVAL;
    1315     }
    1316         else if( (vseg->min == addr_min) && (vseg->max == addr_max) ) // vseg must be removed
    1317     {
    1318         vmm_remove_vseg( vseg );
     1318        if( (vseg->min > addr_min) || (vseg->max < addr_max) )        // not included in vseg
     1319    {
     1320        error = -1;
     1321    }
     1322        else if( (vseg->min == addr_min) && (vseg->max == addr_max) )  // vseg must be deleted
     1323    {
     1324        vmm_delete_vseg( process->pid , vseg->min );
    13191325        error = 0;
    13201326    }
    1321         else if( vseg->min == addr_min )                         // vseg must be resized
     1327        else if( vseg->min == addr_min )                               // vseg must be resized
    13221328    {
    13231329        // update vseg base address
     
    13311337        error = 0;
    13321338    }
    1333         else if( vseg->max == addr_max )                          // vseg must be resized
     1339        else if( vseg->max == addr_max )                              // vseg must be resized
    13341340    {
    13351341        // update vseg max address
     
    13431349        error = 0;
    13441350    }
    1345     else                                                      // vseg cut in three regions
     1351    else                                                          // vseg cut in three regions
    13461352    {
    13471353        // resize existing vseg
     
    14151421        vseg_init_from_ref( vseg , vseg_xp );
    14161422
    1417         // register local vseg in local VMM
    1418         vmm_vseg_attach( vmm , vseg );
     1423        // register local vseg in local VSL
     1424        vmm_attach_vseg_to_vsl( vmm , vseg );
    14191425    }   
    14201426
Note: See TracChangeset for help on using the changeset viewer.