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


Ignore:
Timestamp:
Dec 6, 2019, 12:07:51 PM (4 years ago)
Author:
alain
Message:

Fix several bugs in the FATFS and in the VFS,
related to the creation of big files requiring
more than 4 Kbytes (one cluster) on device.

File:
1 edited

Legend:

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

    r651 r656  
    17451745
    17461746////////////////////////////////////////////////////////////////////////////////////////////
    1747 // This static function is called by the vmm_remove_vseg() and vmm_resize_vseg() functions.
    1748 // Depending on the vseg <type>, it decrements the physical page refcount, and
    1749 // conditionnally release to the relevant kmem the physical page identified by <ppn>.
     1747// This static function is called by the vmm_remove_vseg() and vmm_resize_vseg() functions
     1748// to update the physical page descriptor identified by the <ppn> argument.
     1749// It decrements the refcount, set the dirty bit when required, and releases the physical
     1750// page to kmem depending on the vseg type.
     1751// - KERNEL : refcount decremented / not released to kmem    / dirty bit not set
     1752// - FILE   : refcount decremented / not released to kmem    / dirty bit set when required.
     1753// - CODE   : refcount decremented / released to kmem        / dirty bit not set.
     1754// - STAK   : refcount decremented / released to kmem        / dirty bit not set.
     1755// - DATA   : refcount decremented / released to kmem if ref / dirty bit not set.
     1756// - MMAP   : refcount decremented / released to kmem if ref / dirty bit not set.
    17501757////////////////////////////////////////////////////////////////////////////////////////////
    17511758// @ process  : local pointer on process.
    17521759// @ vseg     : local pointer on vseg.
    17531760// @ ppn      : released pysical page index.
     1761// @ dirty    : set the dirty bit in page descriptor when non zero.
    17541762////////////////////////////////////////////////////////////////////////////////////////////
    17551763static void vmm_ppn_release( process_t * process,
    17561764                             vseg_t    * vseg,
    1757                              ppn_t       ppn )
     1765                             ppn_t       ppn,
     1766                             uint32_t    dirty )
    17581767{
    1759     bool_t do_release;
     1768    bool_t do_kmem_release;
    17601769
    17611770    // get vseg type
    17621771    vseg_type_t type = vseg->type;
    17631772
    1764     // compute is_ref
     1773    // compute is_ref <=> this vseg is the reference vseg
    17651774    bool_t is_ref = (GET_CXY( process->ref_xp ) == local_cxy);
    17661775
     
    17741783    hal_remote_atomic_add( count_xp , -1 );
    17751784
    1776     // compute the do_release condition depending on vseg type
    1777     if( (type == VSEG_TYPE_FILE)  ||
    1778         (type == VSEG_TYPE_KCODE) ||
     1785    // compute the do_kmem_release condition depending on vseg type
     1786    if( (type == VSEG_TYPE_KCODE) ||
    17791787        (type == VSEG_TYPE_KDATA) ||
    17801788        (type == VSEG_TYPE_KDEV) )           
    17811789    {
    1782         // no physical page release for FILE and KERNEL
    1783         do_release = false;
    1784     }
     1790        // no physical page release for KERNEL
     1791        do_kmem_release = false;
     1792    }
     1793    else if( type == VSEG_TYPE_FILE )
     1794    {
     1795        // no physical page release for KERNEL
     1796        do_kmem_release = false;
     1797
     1798        // set dirty bit if required
     1799        if( dirty ) ppm_page_do_dirty( page_xp );
     1800    }   
    17851801    else if( (type == VSEG_TYPE_CODE)  ||
    17861802             (type == VSEG_TYPE_STACK) )
    17871803    {
    17881804        // always release physical page for private vsegs
    1789         do_release = true;
     1805        do_kmem_release = true;
    17901806    }
    17911807    else if( (type == VSEG_TYPE_ANON)  ||
     
    17931809    {
    17941810        // release physical page if reference cluster
    1795         do_release = is_ref;
     1811        do_kmem_release = is_ref;
    17961812    }
    17971813    else if( is_ref )  // vseg_type == DATA in reference cluster
     
    18141830
    18151831        // release physical page if forks == 0
    1816         do_release = (forks == 0);
     1832        do_kmem_release = (forks == 0);
    18171833    }
    18181834    else              // vseg_type == DATA not in reference cluster
    18191835    {
    18201836        // no physical page release if not in reference cluster
    1821         do_release = false;
     1837        do_kmem_release = false;
    18221838    }
    18231839
    18241840    // release physical page to relevant kmem when required
    1825     if( do_release )
    1826     {
    1827         ppm_remote_free_pages( page_cxy , page_ptr );
     1841    if( do_kmem_release )
     1842    {
     1843        kmem_req_t req;
     1844        req.type = KMEM_PPM;
     1845        req.ptr  = GET_PTR( ppm_ppn2base( ppn ) );
     1846
     1847        kmem_remote_free( page_cxy , &req );
    18281848
    18291849#if DEBUG_VMM_PPN_RELEASE
     
    18921912            hal_gpt_reset_pte( gpt_xp , vpn );
    18931913
    1894             // release physical page when required
    1895             vmm_ppn_release( process , vseg , ppn );
     1914            // release physical page depending on vseg type
     1915            vmm_ppn_release( process , vseg , ppn , attr & GPT_DIRTY );
    18961916        }
    18971917    }
     
    19862006
    19872007            // release physical page when required
    1988             vmm_ppn_release( process , vseg , ppn );
     2008            vmm_ppn_release( process , vseg , ppn , attr & GPT_DIRTY );
    19892009        }
    19902010    }
     
    20082028
    20092029            // release physical page when required
    2010             vmm_ppn_release( process , vseg , ppn );
     2030            vmm_ppn_release( process , vseg , ppn , attr & GPT_DIRTY );
    20112031        }
    20122032    }
     
    21702190// @ vseg   : local pointer on vseg.
    21712191// @ vpn    : unmapped vpn.
    2172 // @ return an extended pointer on the allocated page
     2192// @ return an extended pointer on the allocated page descriptor.
    21732193//////////////////////////////////////////////////////////////////////////////////////
    21742194static xptr_t vmm_page_allocate( vseg_t * vseg,
     
    21862206    xptr_t       page_xp;
    21872207    cxy_t        page_cxy;
    2188     page_t     * page_ptr;
    21892208    uint32_t     index;
    21902209
     
    21972216assert( ( type != VSEG_TYPE_FILE ) , "illegal vseg type\n" );
    21982217
     2218    // compute target cluster identifier
    21992219    if( flags & VSEG_DISTRIB )    // distributed => cxy depends on vpn LSB
    22002220    {
     
    22142234
    22152235    // allocate one small physical page from target cluster
    2216     page_ptr = ppm_remote_alloc_pages( page_cxy , 0 );
    2217 
    2218     page_xp = XPTR( page_cxy , page_ptr );
     2236    kmem_req_t req;
     2237    req.type  = KMEM_PPM;
     2238    req.order = 0;
     2239    req.flags = AF_ZERO;
     2240
     2241    // get local pointer on page base
     2242    void * ptr = kmem_remote_alloc( page_cxy , &req );
     2243
     2244    // get extended pointer on page descriptor
     2245    page_xp = ppm_base2page( XPTR( page_cxy , ptr ) );
    22192246
    22202247#if DEBUG_VMM_PAGE_ALLOCATE
     
    22452272uint32_t   cycle = (uint32_t)hal_get_cycles();
    22462273thread_t * this  = CURRENT_THREAD;
    2247 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
    2248 printk("\n[%s] thread[%x,%x] enter for vpn %x / type %s / page_id  %d / cycle %d\n",
     2274if( DEBUG_VMM_GET_ONE_PPN < cycle )
     2275printk("\n[%s] thread[%x,%x] enter for vpn %x / vseg %s / page_id  %d / cycle %d\n",
    22492276__FUNCTION__, this->process->pid, this->trdid, vpn, vseg_type_str(type), page_id, cycle );
     2277#endif
     2278
     2279#if (DEBUG_VMM_GET_ONE_PPN & 2)
     2280if( DEBUG_VMM_GET_ONE_PPN < cycle )
     2281hal_vmm_display( XPTR( local_cxy , this->process ) , true );
    22502282#endif
    22512283
     
    22912323
    22922324#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    2293 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
     2325if( DEBUG_VMM_GET_ONE_PPN < cycle )
    22942326printk("\n[%s] thread[%x,%x] for vpn = %x / elf_offset = %x\n",
    22952327__FUNCTION__, this->process->pid, this->trdid, vpn, elf_offset );
     
    23052337
    23062338#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    2307 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
     2339if( DEBUG_VMM_GET_ONE_PPN < cycle )
    23082340printk("\n[%s] thread[%x,%x] for vpn  %x / fully in BSS\n",
    23092341__FUNCTION__, this->process->pid, this->trdid, vpn );
     
    23222354
    23232355#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    2324 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
     2356if( DEBUG_VMM_GET_ONE_PPN < cycle )
    23252357printk("\n[%s] thread[%x,%x] for vpn  %x / fully in mapper\n",
    23262358__FUNCTION__, this->process->pid, this->trdid, vpn );
     
    23392371
    23402372#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    2341 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
     2373if( DEBUG_VMM_GET_ONE_PPN < cycle )
    23422374printk("\n[%s] thread[%x,%x] for vpn  %x / both mapper & BSS\n"
    23432375"      %d bytes from mapper / %d bytes from BSS\n",
     
    23652397                }
    23662398            }   
    2367         }  // end initialisation for CODE or DATA types   
     2399
     2400        }  // end if CODE or DATA types   
    23682401    }
    23692402
     
    23722405
    23732406#if DEBUG_VMM_GET_ONE_PPN
    2374 cycle = (uint32_t)hal_get_cycles();
    2375 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
     2407if( DEBUG_VMM_GET_ONE_PPN < cycle )
    23762408printk("\n[%s] thread[%x,%x] exit for vpn %x / ppn %x / cycle %d\n",
    23772409__FUNCTION__ , this->process->pid, this->trdid , vpn , *ppn, cycle );
     2410#endif
     2411
     2412#if (DEBUG_VMM_GET_ONE_PPN & 2)
     2413if( DEBUG_VMM_GET_ONE_PPN < cycle )
     2414hal_vmm_display( XPTR( local_cxy , this->process ) , true );
    23782415#endif
    23792416
     
    24042441
    24052442#if DEBUG_VMM_HANDLE_PAGE_FAULT
    2406 if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
     2443if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) & (vpn > 0) )
    24072444printk("\n[%s] thread[%x,%x] enter for vpn %x / cycle %d\n",
    24082445__FUNCTION__, this->process->pid, this->trdid, vpn, start_cycle );
    24092446#endif
    24102447
    2411 #if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
     2448#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 2)
    24122449if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
    2413 hal_vmm_display( this->process , true );
     2450hal_vmm_display( XPTR( local_cxy , this->process ) , true );
    24142451#endif
    24152452
     
    25042541#if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT)
    25052542uint32_t end_cycle = (uint32_t)hal_get_cycles();
    2506 uint32_t cost      = end_cycle - start_cycle;
    25072543#endif
    25082544
     
    25132549#endif
    25142550
     2551#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 2)
     2552if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
     2553hal_vmm_display( XPTR( local_cxy , this->process ) , true );
     2554#endif
     2555
    25152556#if CONFIG_INSTRUMENTATION_PGFAULTS
     2557uint32_t cost      = end_cycle - start_cycle;
    25162558this->info.local_pgfault_nr++;
    25172559this->info.local_pgfault_cost += cost;
     
    25842626#if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT)
    25852627uint32_t end_cycle = (uint32_t)hal_get_cycles();
    2586 uint32_t cost      = end_cycle - start_cycle;
    25872628#endif
    25882629
     
    25932634#endif
    25942635
     2636#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 2)
     2637if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
     2638hal_vmm_display( XPTR( local_cxy , this->process ) , true );
     2639#endif
     2640
    25952641#if CONFIG_INSTRUMENTATION_PGFAULTS
     2642uint32_t cost      = end_cycle - start_cycle;
    25962643this->info.false_pgfault_nr++;
    25972644this->info.false_pgfault_cost += cost;
     
    26512698#if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT)
    26522699uint32_t end_cycle = (uint32_t)hal_get_cycles();
    2653 uint32_t cost      = end_cycle - start_cycle;
    26542700#endif
    26552701
     
    26602706#endif
    26612707
     2708#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 2)
     2709if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
     2710hal_vmm_display( XPTR( local_cxy , this->process ) , true );
     2711#endif
     2712
    26622713#if CONFIG_INSTRUMENTATION_PGFAULTS
     2714uint32_t cost      = end_cycle - start_cycle;
    26632715this->info.global_pgfault_nr++;
    26642716this->info.global_pgfault_cost += cost;
     
    26762728#if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT)
    26772729uint32_t end_cycle = (uint32_t)hal_get_cycles();
    2678 uint32_t cost      = end_cycle - start_cycle;
    26792730#endif
    26802731
     
    26862737
    26872738#if CONFIG_INSTRUMENTATION_PGFAULTS
     2739uint32_t cost      = end_cycle - start_cycle;
    26882740this->info.false_pgfault_nr++;
    26892741this->info.false_pgfault_cost += cost;
     
    27202772#endif
    27212773
    2722 #if ((DEBUG_VMM_HANDLE_COW & 3) == 3 )
     2774#if (DEBUG_VMM_HANDLE_COW & 2)
    27232775hal_vmm_display( XPTR( local_cxy , process ) , true );
    27242776#endif
     
    29022954#endif
    29032955
    2904 #if ((DEBUG_VMM_HANDLE_COW & 3) == 3)
     2956#if (DEBUG_VMM_HANDLE_COW & 2)
    29052957hal_vmm_display( XPTR( local_cxy , process ) , true );
    29062958#endif
Note: See TracChangeset for help on using the changeset viewer.