Ignore:
Timestamp:
May 21, 2019, 6:00:06 PM (5 years ago)
Author:
alain
Message:

1) Fix a bug in the vfs_add_special_dentries() function:
The <.> and <..> dentries must not be created on IOC and on the mapper
for the VFS root directory.
2) Fix a bug in the hal_gpt_allocate_pt2 function, related to the
use of the TSAR_LOCKED attribute to avoid concurrent mapping of the PTD1.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/tsar_mips32/core/hal_gpt.c

    r629 r630  
    318318
    319319/////////////////////////////////////////////////////////////////////////////////////////
    320 // This static function check that a PTE1 entry, in the PT1 of a possibly remote GPT,
    321 // identified by the <pte1_xp> argument is mapped. If this entry is not mapped,
    322 // it allocates a - local or remote - PT2, updates the PTE1 value in PT1, and
    323 // returns the PTE1 value in the <pte1> buffer.
    324 // It uses the TSR_MMU_LOCKED attribute in PTE1 to handle possible concurrent
    325 // mappings of the missing PTE1:
    326 // - If the PTE1 is unmapped and unlocked => it tries to atomically lock this PTE1,
    327 //   and map it if lock is successful.
    328 // - If the PTE1 is unmapped but locked => it poll the PTE1 value, unti the mapping
    329 //   is done by the other thread.
    330 // - If the PTE1 is already mapped => it does nothing
    331 // It returns an error if it cannot allocate memory fot a new PT2.
     320// This static function returns in the <ptd1_value> buffer the current value of
     321// the PT1 entry identified by the <pte1_xp> argument, that must contain a PTD1
     322// (i.e. a pointer on a PT2). If this PT1 entry is not mapped yet, it allocates a
     323// new PT2 and updates the PT1 entry, using the TSAR_MMU_LOCKED attribute in PT1
     324// entry, to handle possible concurrent mappings of the missing PTD1:
     325// 1) If the PT1 entry is unmapped, it tries to atomically lock this PTD1.
     326//    - if the atomic lock is successful it allocates a new PT1, and updates the PTD1.
     327//    - else, it simply waits, in a polling loop, the mapping done by another thread.
     328//    In both cases, returns the PTD1 value, when the mapping is completed.
     329// 2) If the PT1 entry is already mapped, it returns the PTD1 value, and does
     330//    nothing else.
    332331/////////////////////////////////////////////////////////////////////////////////////////
    333 static error_t hal_gpt_allocate_pt2( xptr_t     pte1_xp,
    334                                    uint32_t * pte1_value )
    335 {
    336     cxy_t      gpt_cxy;     // target GPT cluster = GET_CXY( pte1_xp );
    337     uint32_t   pte1;        // PTE1 value
     332static error_t hal_gpt_allocate_pt2( xptr_t     ptd1_xp,
     333                                     uint32_t * ptd1_value )
     334{
     335    cxy_t      gpt_cxy;     // target GPT cluster = GET_CXY( ptd1_xp );
     336    uint32_t   ptd1;        // PTD1 value
    338337    ppn_t      pt2_ppn;     // PPN of page containing the new PT2
    339338    bool_t     atomic;
     
    342341
    343342    // get GPT cluster identifier
    344     gpt_cxy = GET_CXY( pte1_xp );
    345 
    346     // get current pte1 value
    347     pte1 = hal_remote_l32( pte1_xp );
    348 
    349     if( ((pte1 & TSAR_PTE_MAPPED) == 0) &&   // PTE1 unmapped and unlocked
    350         ((pte1 & TSAR_PTE_LOCKED) == 0) )    // try to allocate a new PT2
     343    gpt_cxy = GET_CXY( ptd1_xp );
     344
     345    // get current ptd1 value
     346    ptd1 = hal_remote_l32( ptd1_xp );
     347
     348    if( (ptd1 & TSAR_PTE_MAPPED) == 0)    // PTD1 unmapped and unlocked
    351349        {
    352         // atomically lock the PTE1 to prevent concurrent PTE1 mappings
    353         atomic = hal_remote_atomic_cas( pte1_xp,
    354                                         pte1,
    355                                         pte1 | TSAR_PTE_LOCKED );
    356 
    357         if( atomic )  // PTE1 successfully locked
     350        // atomically lock the PTD1 to prevent concurrent PTD1 mappings
     351        atomic = hal_remote_atomic_cas( ptd1_xp,
     352                                        ptd1,
     353                                        ptd1 | TSAR_PTE_LOCKED );
     354
     355        if( atomic )  // PTD1 successfully locked
    358356                {
    359357            // allocate one physical page for PT2
     
    377375            pt2_ppn = ppm_page2ppn( page_xp );
    378376
    379             // build  PTE1 value
    380             pte1 = TSAR_PTE_MAPPED | TSAR_PTE_SMALL | pt2_ppn;
     377            // build  PTD1
     378            ptd1 = TSAR_PTE_MAPPED | TSAR_PTE_SMALL | pt2_ppn;
    381379
    382380            // set the PTD1 value in PT1
    383             hal_remote_s32( pte1_xp , pte1 );
     381            hal_remote_s32( ptd1_xp , ptd1 );
    384382            hal_fence();
    385383
     
    388386uint32_t   cycle = (uint32_t)hal_get_cycles();
    389387if( DEBUG_HAL_GPT_ALLOCATE_PT2 < cycle )
    390 printk("\n[%s] : thread[%x,%x] map PTE1 / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n",
    391 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, pte1 );
     388printk("\n[%s] : thread[%x,%x] map PTD1 / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n",
     389__FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, ptd1 );
    392390#endif
    393391        }
    394         else
     392        else         // PTD1 modified by another thread
    395393        {
    396             // poll PTE1 until mapped by another thread
    397             while( (pte1 & TSAR_PTE_MAPPED) == 0 )  pte1 = hal_remote_l32( pte1_xp );
     394            // poll PTD1 until mapped by another thread
     395            while( (ptd1 & TSAR_PTE_MAPPED) == 0 )  ptd1 = hal_remote_l32( ptd1_xp );
    398396        }
    399397    }
    400     else if( ((pte1 & TSAR_PTE_MAPPED) == 0) &&
    401              ((pte1 & TSAR_PTE_LOCKED) != 0) ) 
    402     {
    403         // poll PTE1 until mapped by another thread
    404         while( (pte1 & TSAR_PTE_MAPPED) == 0 )  pte1 = hal_remote_l32( pte1_xp );
    405         }
    406     else                                   // PTE1 mapped => just use it
     398    else                                   // PTD1 mapped => just use it
    407399    {
    408400
     
    411403uint32_t   cycle = (uint32_t)hal_get_cycles();
    412404if( DEBUG_HAL_GPT_ALLOCATE_PT2 < cycle )
    413 printk("\n[%s] : thread[%x,%x] PTE1 mapped / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n",
    414 __FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, pte1 );
     405printk("\n[%s] : thread[%x,%x] PTD1 mapped / cxy %x / ix1 %d / pt1 %x / ptd1 %x\n",
     406__FUNCTION__, this->process->pid, this->trdid, gpt_cxy, ix1, pt1_ptr, ptd1 );
    415407#endif
    416408
    417409    }
    418410
    419     *pte1_value = pte1;
     411    *ptd1_value = ptd1;
    420412    return 0;
    421413
Note: See TracChangeset for help on using the changeset viewer.