Ignore:
Timestamp:
Dec 5, 2017, 4:20:07 PM (4 years ago)
Author:
alain
Message:

Fix several bugs in the fork() syscall.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/rpc.c

    r407 r408  
    4949{
    5050    &rpc_pmem_get_pages_server,         // 0
    51     &rpc_process_pid_alloc_server,      // 1
    52     &rpc_process_exec_server,           // 2
     51    &rpc_process_make_exec_server,      // 1
     52    &rpc_process_make_fork_server,      // 2
    5353    &rpc_process_kill_server,           // 3
    5454    &rpc_thread_user_create_server,     // 4
     
    7878    &rpc_vmm_create_vseg_server,        // 26
    7979    &rpc_sched_display_server,          // 27
    80     &rpc_undefined,                     // 28
     80    &rpc_vmm_set_cow_server,            // 28
    8181    &rpc_undefined,                     // 29
    8282};
     
    148148
    149149/////////////////////////////////////////////////////////////////////////////////////////
    150 // [1]           Marshaling functions attached to RPC_PROCESS_PID_ALLOC
    151 /////////////////////////////////////////////////////////////////////////////////////////
    152 
    153 //////////////////////////////////////////////////
    154 void rpc_process_pid_alloc_client( cxy_t       cxy,
    155                                    process_t * process,  // in
    156                                    error_t   * error,    // out
    157                                    pid_t     * pid )     // out
    158 {
    159     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    160     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    161     CURRENT_THREAD->core->lid , hal_time_stamp() );
    162 
    163     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    164 
    165     // initialise RPC descriptor header
    166     rpc_desc_t  rpc;
    167     rpc.index    = RPC_PROCESS_PID_ALLOC;
    168     rpc.response = 1;
    169 
    170     // set input arguments in RPC descriptor
    171     rpc.args[0] = (uint64_t)(intptr_t)process;
    172 
    173     // register RPC request in remote RPC fifo (blocking function)
    174     rpc_send_sync( cxy , &rpc );
    175 
    176     // get output arguments RPC descriptor
    177     *pid    = (pid_t)rpc.args[1];
    178     *error  = (error_t)rpc.args[2];     
    179 
    180     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    181     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    182     CURRENT_THREAD->core->lid , hal_time_stamp() );
    183 }
    184 
    185 //////////////////////////////////////////////
    186 void rpc_process_pid_alloc_server( xptr_t xp )
    187 {
    188     process_t * process;   // input  : client process descriptor
    189     error_t     error;     // output : error status
    190     pid_t       pid;       // output : process identifier
    191 
    192     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    193     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    194     CURRENT_THREAD->core->lid , hal_time_stamp() );
    195 
    196     // get client cluster identifier and pointer on RPC descriptor
    197     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
    198     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
    199 
    200     // get input argument from client RPC descriptor
    201     process = (process_t*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    202    
    203     // call local pid allocator
    204     xptr_t xp_process = XPTR( client_cxy , process );
    205     error = cluster_pid_alloc( xp_process , &pid );
    206 
    207     // set output arguments into client RPC descriptor
    208     hal_remote_sw( XPTR( client_cxy , &desc->args[0] ) , (uint64_t)error );
    209     hal_remote_sw( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)pid );
    210 
    211     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    212     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    213     CURRENT_THREAD->core->lid , hal_time_stamp() );
    214 }
    215 
    216 
    217 /////////////////////////////////////////////////////////////////////////////////////////
    218 // [2]           Marshaling functions attached to RPC_PROCESS_EXEC
    219 /////////////////////////////////////////////////////////////////////////////////////////
    220 
    221 ////////////////////////////////////////////////
    222 void rpc_process_exec_client( cxy_t         cxy,
    223                               exec_info_t * info,     // in
    224                               error_t     * error )   // out
    225 {
    226     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    227     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    228     CURRENT_THREAD->core->lid , hal_time_stamp() );
    229 
    230     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    231 
    232     // initialise RPC descriptor header
    233     rpc_desc_t  rpc;
    234     rpc.index    = RPC_PROCESS_EXEC;
     150// [1]           Marshaling functions attached to RPC_PROCESS_MAKE_EXEC
     151/////////////////////////////////////////////////////////////////////////////////////////
     152
     153/////////////////////////////////////////////////////
     154void rpc_process_make_exec_client( cxy_t         cxy,
     155                                   exec_info_t * info,     // in
     156                                   error_t     * error )   // out
     157{
     158    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     159    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     160    CURRENT_THREAD->core->lid , hal_time_stamp() );
     161
     162    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     163
     164    // initialise RPC descriptor header
     165    rpc_desc_t  rpc;
     166    rpc.index    = RPC_PROCESS_MAKE_EXEC;
    235167    rpc.response = 1;
    236168
     
    249181}
    250182
    251 /////////////////////////////////////////
    252 void rpc_process_exec_server( xptr_t xp )
     183//////////////////////////////////////////////
     184void rpc_process_make_exec_server( xptr_t xp )
    253185{
    254186    exec_info_t * ptr;       // local pointer on remote exec_info structure
     
    283215}
    284216
     217/////////////////////////////////////////////////////////////////////////////////////////
     218// [2]           Marshaling functions attached to RPC_PROCESS_MAKE_FORK
     219/////////////////////////////////////////////////////////////////////////////////////////
     220
     221///////////////////////////////////////////////////
     222void rpc_process_make_fork_client( cxy_t       cxy,
     223                                   xptr_t      ref_process_xp,      // in
     224                                   xptr_t      parent_thread_xp,    // in
     225                                   pid_t     * child_pid,           // out
     226                                   thread_t ** child_thread_ptr,    // out     
     227                                   error_t   * error )              // out
     228{
     229    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     230    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     231    CURRENT_THREAD->core->lid , hal_time_stamp() );
     232
     233    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     234
     235    // initialise RPC descriptor header
     236    rpc_desc_t  rpc;
     237    rpc.index    = RPC_PROCESS_MAKE_FORK;
     238    rpc.response = 1;
     239
     240    // set input arguments in RPC descriptor 
     241    rpc.args[0] = (uint64_t)(intptr_t)ref_process_xp;
     242    rpc.args[1] = (uint64_t)(intptr_t)parent_thread_xp;
     243
     244    // register RPC request in remote RPC fifo (blocking function)
     245    rpc_send_sync( cxy , &rpc );
     246
     247    // get output arguments from RPC descriptor
     248    *child_pid         = (pid_t)rpc.args[2];
     249    *child_thread_ptr  = (thread_t *)(intptr_t)rpc.args[3];
     250    *error             = (error_t)rpc.args[4];     
     251
     252    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     253    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     254    CURRENT_THREAD->core->lid , hal_time_stamp() );
     255}
     256
     257//////////////////////////////////////////////
     258void rpc_process_make_fork_server( xptr_t xp )
     259{
     260    xptr_t     ref_process_xp;     // extended pointer on reference parent process
     261    xptr_t     parent_thread_xp;   // extended pointer on parent thread
     262    pid_t      child_pid;          // child process identifier
     263    thread_t * child_thread_ptr;   // local copy of exec_info structure
     264    error_t    error;              // local error status
     265
     266    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     267    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     268    CURRENT_THREAD->core->lid , hal_time_stamp() );
     269
     270    // get client cluster identifier and pointer on RPC descriptor
     271    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     272    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
     273
     274    // get input arguments from cient RPC descriptor
     275    ref_process_xp   = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     276    parent_thread_xp = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     277
     278    // call local kernel function
     279    error = process_make_fork( ref_process_xp,
     280                               parent_thread_xp,
     281                               &child_pid,
     282                               &child_thread_ptr );
     283
     284    // set output argument into client RPC descriptor
     285    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)child_pid );
     286    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)(intptr_t)child_thread_ptr );
     287    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
     288
     289    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     290    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     291    CURRENT_THREAD->core->lid , hal_time_stamp() );
     292}
    285293
    286294/////////////////////////////////////////////////////////////////////////////////////////
     
    18001808}
    18011809
     1810/////////////////////////////////////////////////////////////////////////////////////////
     1811// [28]          Marshaling functions attached to RPC_VMM_SET_COW
     1812/////////////////////////////////////////////////////////////////////////////////////////
     1813
     1814/////////////////////////////////////////////
     1815void rpc_vmm_set_cow_client( cxy_t       cxy,
     1816                             process_t * process )
     1817{
     1818    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1819    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1820    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1821
     1822    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     1823
     1824    // initialise RPC descriptor header
     1825    rpc_desc_t  rpc;
     1826    rpc.index    = RPC_VMM_SET_COW;
     1827    rpc.response = 1;
     1828
     1829    // set input arguments in RPC descriptor
     1830    rpc.args[0] = (uint64_t)(intptr_t)process;
     1831
     1832    // register RPC request in remote RPC fifo (blocking function)
     1833    rpc_send_sync( cxy , &rpc );
     1834
     1835    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1836    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1837    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1838}
     1839
     1840////////////////////////////////////////
     1841void rpc_vmm_set_cow_server( xptr_t xp )
     1842{
     1843    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     1844    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1845    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1846
     1847    process_t * process;
     1848
     1849    // get client cluster identifier and pointer on RPC descriptor
     1850    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
     1851    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
     1852
     1853    // get input arguments from client RPC descriptor
     1854    process = (process_t *)(intptr_t)hal_remote_lpt( XPTR(cxy , &desc->args[0]));
     1855   
     1856    // call local kernel function
     1857    vmm_set_cow( process );
     1858
     1859    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     1860    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     1861    CURRENT_THREAD->core->lid , hal_time_stamp() );
     1862}
     1863
    18021864/***************************************************************************************/
    18031865/************ Generic functions supporting RPCs : client side **************************/
     
    18351897            __FUNCTION__ , local_cxy , server_cxy );
    18361898
    1837             if( thread_can_yield() ) sched_yield();
     1899            if( thread_can_yield() ) sched_yield("RPC fifo full");
    18381900        }
    18391901    }
     
    18721934
    18731935        thread_block( this , THREAD_BLOCKED_RPC );
    1874         sched_yield();
     1936        sched_yield("client blocked on RPC");
    18751937
    18761938grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s resumes after RPC completion\n",
     
    19592021
    19602022    // interrupted thread deschedule always           
    1961         sched_yield();
     2023        sched_yield("IPI received");
    19622024
    19632025grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s resume / cycle %d\n",
     
    20792141
    20802142        // deschedule without blocking
    2081         sched_yield();
     2143        sched_yield("RPC fifo empty or too much work");
    20822144
    20832145grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) resumes / cycle %d\n",
     
    20892151
    20902152
    2091 
    2092 
    2093 
    2094 
    2095 
    2096 
    2097 
    2098 /* deprecated [AG] 29/09/2017
    2099 
    2100 ////////////////////////////////////////////////////
    2101 error_t rpc_activate_thread( remote_fifo_t * rpc_fifo )
    2102 {
    2103         core_t      * core;
    2104         thread_t    * thread;
    2105         thread_t    * this;
    2106     scheduler_t * sched;
    2107         error_t       error;
    2108     bool_t        found;
    2109     reg_t         sr_save;
    2110 
    2111    
    2112         this   = CURRENT_THREAD;
    2113     core   = this->core;
    2114     sched  = &core->scheduler;
    2115     found  = false;
    2116 
    2117     assert( (this->trdid == rpc_fifo->owner) , __FUNCTION__ ,
    2118     "calling thread is not RPC_FIFO owner\n" );
    2119 
    2120     // makes the calling thread not preemptable
    2121     // during activation / creation of the RPC thread
    2122         hal_disable_irq( &sr_save );
    2123 
    2124 grpc_dmsg("\n[DBG] %s : core[%x,%d] enter at cycle %d\n",
    2125 __FUNCTION__ , local_cxy , core->lid , hal_time_stamp() );
    2126 
    2127     // search one non blocked RPC thread   
    2128     list_entry_t * iter;
    2129     LIST_FOREACH( &sched->k_root , iter )
    2130     {
    2131         thread = LIST_ELEMENT( iter , thread_t , sched_list );
    2132         if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) )
    2133         {
    2134             found = true;
    2135             break;
    2136         }
    2137     }
    2138 
    2139     if( found == false )                    // create new RPC thread     
    2140     {
    2141         error = thread_kernel_create( &thread,
    2142                                       THREAD_RPC,
    2143                                                   &rpc_thread_func,
    2144                                       NULL,
    2145                                                   core->lid );
    2146             if( error )
    2147         {
    2148                 hal_restore_irq( sr_save );
    2149             printk("\n[ERROR] in %s : no memory for new RPC thread in cluster %x\n",
    2150                    __FUNCTION__ , local_cxy );
    2151             return ENOMEM;
    2152         }
    2153 
    2154         // unblock thread
    2155         thread->blocked = 0;
    2156 
    2157         // update core descriptor counter 
    2158             hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 );
    2159 
    2160 grpc_dmsg("\n[DBG] %s : core [%x,%d] creates RPC thread %x at cycle %d\n",
    2161 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );
    2162 
    2163     }
    2164     else                           // create a new RPC thread
    2165     {
    2166 
    2167 grpc_dmsg("\n[DBG] %s : core[%x,%d] activates RPC thread %x at cycle %d\n",
    2168 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );
    2169 
    2170     }
    2171 
    2172     // update rpc_fifo owner
    2173     rpc_fifo->owner = thread->trdid;
    2174 
    2175     // current thread deschedule           
    2176         sched_yield();
    2177 
    2178     // restore IRQs for the calling thread
    2179         hal_restore_irq( sr_save );
    2180 
    2181     // return success
    2182         return 0;
    2183 
    2184 }  // end rpc_activate_thread()
    2185 
    2186 ////////////////
    2187 void rpc_check()
    2188 {
    2189         thread_t   * this     = CURRENT_THREAD;
    2190         remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
    2191     error_t      error;
    2192 
    2193 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / enter at cycle %d\n",
    2194 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() );
    2195 
    2196     // calling thread does nothing if light lock already taken or FIFO empty 
    2197         if( (rpc_fifo->owner != 0) || (local_fifo_is_empty( &rpc_fifo->fifo )) )
    2198     {
    2199 
    2200 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / exit do nothing at cycle %d\n",
    2201 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() );
    2202 
    2203         return;
    2204     }
    2205 
    2206         // try to take the light lock, and activates an RPC thread if success
    2207     if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) )
    2208         {
    2209         error = rpc_activate_thread( rpc_fifo );
    2210 
    2211         if( error )    // cannot activate an RPC_THREAD
    2212         {
    2213             rpc_fifo->owner = 0;
    2214 
    2215             printk("\n[ERROR] in %s : no memory to create a RPC thread for core %d"
    2216             " in cluster %x => do nothing\n",
    2217             __FUNCTION__ , CURRENT_CORE->lid , local_cxy );
    2218         }
    2219 
    2220         return;
    2221     }
    2222     else  // light lock taken by another thread
    2223     {
    2224 
    2225 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / exit do nothing at cycle %d\n",
    2226 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , hal_time_stamp() );
    2227 
    2228         return;
    2229     }
    2230 } // end rpc_check()
    2231 
    2232 
    2233 //////////////////////
    2234 void rpc_thread_func()
    2235 {
    2236     // makes the RPC thread not preemptable
    2237         hal_disable_irq( NULL );
    2238  
    2239         thread_t   * this     = CURRENT_THREAD;
    2240         remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
    2241 
    2242         while(1)
    2243         {
    2244         // check fifo ownership (ownership should be given by rpc_activate()
    2245         assert( (this->trdid == rpc_fifo->owner) , __FUNCTION__ ,
    2246         "thread %x on core[%x,%d] not owner of RPC_FIFO / owner = %x\n",
    2247         this->trdid, local_cxy, this->core->lid , rpc_fifo->owner );
    2248  
    2249         // executes pending RPC(s)
    2250         rpc_execute_all( rpc_fifo );
    2251 
    2252         // release rpc_fifo ownership if required
    2253         // (this ownership can be lost during RPC execution)
    2254         if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0;
    2255 
    2256         //  deschedule or sucide
    2257                 if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX )  // suicide
    2258                 {
    2259 
    2260 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / suicide at cycle %d\n",
    2261 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
    2262 
    2263             // update core descriptor counter
    2264                 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 );
    2265 
    2266             // suicide
    2267                         thread_exit();
    2268                 }
    2269         else                                                       // deschedule
    2270         {
    2271 
    2272 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / deschedule at cycle %d\n",
    2273 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
    2274 
    2275             sched_yield();
    2276 
    2277 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / wake up at cycle %d\n",
    2278 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
    2279 
    2280         }
    2281         } // end while
    2282 } // end rpc_thread_func()
    2283 
    2284 */
    2285 
    2286 
Note: See TracChangeset for help on using the changeset viewer.