Changeset 279 for trunk/kernel/kern/rpc.c
- Timestamp:
- Jul 27, 2017, 12:23:29 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/rpc.c
r265 r279 101 101 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 102 102 103 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 104 103 105 // initialise RPC descriptor header 104 106 rpc_desc_t rpc; … … 115 117 *error = (error_t)rpc.args[0]; 116 118 *ppn = (uint32_t)rpc.args[1]; 119 120 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 117 121 } 118 122 … … 153 157 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 154 158 159 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 160 155 161 // initialise RPC descriptor header 156 162 rpc_desc_t rpc; … … 167 173 *pid = (pid_t)rpc.args[1]; 168 174 *error = (error_t)rpc.args[2]; 175 176 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 169 177 } 170 178 … … 204 212 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 205 213 214 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 215 206 216 // initialise RPC descriptor header 207 217 rpc_desc_t rpc; … … 217 227 // get output arguments from RPC descriptor 218 228 *error = (error_t)rpc.args[1]; 229 230 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 219 231 } 220 232 … … 256 268 assert( (GET_CXY( process->ref_xp ) == local_cxy) , __FUNCTION__ , 257 269 "caller must be reference process cluster\n"); 270 271 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 258 272 259 273 // get local process index in reference cluster … … 282 296 if( target_cxy != local_cxy ) rpc_send_sync( target_cxy , &rpc ); 283 297 } 298 299 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 284 300 } 285 301 … … 327 343 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 328 344 345 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 346 329 347 // initialise RPC descriptor header 330 348 rpc_desc_t rpc; … … 344 362 *thread_xp = (xptr_t)rpc.args[4]; 345 363 *error = (error_t)rpc.args[5]; 364 365 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 346 366 } 347 367 … … 405 425 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 406 426 427 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 428 407 429 // initialise RPC descriptor header 408 430 rpc_desc_t rpc; … … 421 443 *thread_xp = (xptr_t)rpc.args[3]; 422 444 *error = (error_t)rpc.args[4]; 445 446 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 423 447 } 424 448 … … 463 487 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 464 488 489 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 490 465 491 // initialise RPC descriptor header 466 492 rpc_desc_t rpc; … … 474 500 // register RPC request in remote RPC fifo 475 501 rpc_send_sync( cxy , &rpc ); 502 503 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 476 504 } 477 505 … … 513 541 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 514 542 543 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 544 515 545 // initialise RPC descriptor header 516 546 rpc_desc_t rpc; … … 534 564 *inode_xp = (xptr_t)rpc.args[8]; 535 565 *error = (error_t)rpc.args[9]; 566 567 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 536 568 } 537 569 … … 590 622 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 591 623 624 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 625 592 626 // initialise RPC descriptor header 593 627 rpc_desc_t rpc; … … 600 634 // register RPC request in remote RPC fifo (blocking function) 601 635 rpc_send_sync( cxy , &rpc ); 636 637 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 602 638 } 603 639 … … 632 668 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 633 669 670 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 671 634 672 // initialise RPC descriptor header 635 673 rpc_desc_t rpc; … … 648 686 *dentry_xp = (xptr_t)rpc.args[3]; 649 687 *error = (error_t)rpc.args[4]; 688 689 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 650 690 } 651 691 … … 695 735 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 696 736 737 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 738 697 739 // initialise RPC descriptor header 698 740 rpc_desc_t rpc; … … 705 747 // register RPC request in remote RPC fifo (blocking function) 706 748 rpc_send_sync( cxy , &rpc ); 749 750 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 707 751 } 708 752 … … 737 781 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 738 782 783 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 784 739 785 // initialise RPC descriptor header 740 786 rpc_desc_t rpc; … … 752 798 *file_xp = (xptr_t)rpc.args[2]; 753 799 *error = (error_t)rpc.args[3]; 800 801 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 754 802 } 755 803 … … 790 838 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 791 839 840 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 841 792 842 // initialise RPC descriptor header 793 843 rpc_desc_t rpc; … … 800 850 // register RPC request in remote RPC fifo (blocking function) 801 851 rpc_send_sync( cxy , &rpc ); 852 853 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 802 854 } 803 855 … … 831 883 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 832 884 885 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 886 833 887 // initialise RPC descriptor header 834 888 rpc_desc_t rpc; … … 846 900 // get output values from RPC descriptor 847 901 *error = (error_t)rpc.args[3]; 902 903 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 848 904 } 849 905 … … 889 945 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 890 946 947 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 948 891 949 // initialise RPC descriptor header 892 950 rpc_desc_t rpc; … … 902 960 // get output values from RPC descriptor 903 961 *error = (error_t)rpc.args[1]; 962 963 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 904 964 } 905 965 … … 938 998 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 939 999 1000 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 1001 940 1002 // initialise RPC descriptor header 941 1003 rpc_desc_t rpc; … … 954 1016 *cluster = (uint32_t)rpc.args[3]; 955 1017 *error = (error_t)rpc.args[4]; 1018 1019 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 956 1020 } 957 1021 … … 994 1058 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 995 1059 1060 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 1061 996 1062 // initialise RPC descriptor header 997 1063 rpc_desc_t rpc; … … 1008 1074 // get output argument from rpc descriptor 1009 1075 *vseg_xp = rpc.args[2]; 1076 1077 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 1010 1078 } 1011 1079 … … 1050 1118 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1051 1119 1120 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 1121 1052 1122 // initialise RPC descriptor header 1053 1123 rpc_desc_t rpc; … … 1066 1136 *ppn = (ppn_t)rpc.args[3]; 1067 1137 *error = (error_t)rpc.args[4]; 1138 1139 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 1068 1140 } 1069 1141 … … 1105 1177 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1106 1178 1179 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 1180 1107 1181 // initialise RPC descriptor header 1108 1182 rpc_desc_t rpc; … … 1118 1192 // get output arguments from RPC descriptor 1119 1193 *buf_xp = (xptr_t)rpc.args[1]; 1194 1195 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 1120 1196 } 1121 1197 … … 1152 1228 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1153 1229 1230 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 1231 1154 1232 // initialise RPC descriptor header 1155 1233 rpc_desc_t rpc; … … 1163 1241 // register RPC request in remote RPC fifo 1164 1242 rpc_send_sync( cxy , &rpc ); 1243 1244 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 1165 1245 } 1166 1246 … … 1199 1279 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1200 1280 1281 rpc_dmsg("\n[INFO] %s : enter\n", __FUNCTION__ ); 1282 1201 1283 // initialise RPC descriptor header 1202 1284 rpc_desc_t rpc; … … 1217 1299 // get output values from RPC descriptor 1218 1300 *error = (error_t)rpc.args[6]; 1301 1302 rpc_dmsg("\n[INFO] %s : completed\n", __FUNCTION__ ); 1219 1303 } 1220 1304 … … 1262 1346 rpc_desc_t * rpc ) 1263 1347 { 1264 thread_t * this = CURRENT_THREAD;1265 1348 uint32_t cores; 1266 1349 error_t error; … … 1268 1351 reg_t sr_save; 1269 1352 1270 // get client CPU and cluster coordinates 1271 cxy_t client_cxy = local_cxy; 1272 lid_t client_lid = CURRENT_CORE->lid; 1353 thread_t * this = CURRENT_THREAD; 1354 1355 rpc_dmsg("\n[INFO] %s : enter / client_cxy = %x / server_cxy = %x\n", 1356 __FUNCTION__ , local_cxy , server_cxy ); 1273 1357 1274 1358 // allocate and initialise an extended pointer on the RPC descriptor 1275 xptr_t xp = XPTR( client_cxy , rpc );1276 1277 // get local pointer on rpc_fifo in remote cluster with the1278 // assumption that addresses are identical in all clusters1359 xptr_t desc_xp = XPTR( local_cxy , rpc ); 1360 1361 // get local pointer on rpc_fifo in remote cluster, with the 1362 // assumption that rpc_fifo pddresses are identical in all clusters 1279 1363 rpc_fifo_t * rf = &LOCAL_CLUSTER->rpc_fifo; 1280 1364 … … 1284 1368 { 1285 1369 error = remote_fifo_put_item( XPTR( server_cxy , &rf->fifo ), 1286 (uint64_t *)&xp,1370 (uint64_t )desc_xp, 1287 1371 &first ); 1288 1372 1289 1373 if ( error ) 1290 1374 { 1291 printk("\n[WARNING] %s : core %d in cluster %x cannot post RPC to cluster %x\n", 1292 __FUNCTION__ , client_lid , client_cxy , server_cxy ); 1375 printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n", 1376 __FUNCTION__ , local_cxy , server_cxy ); 1377 1293 1378 if( thread_can_yield() ) sched_yield(); 1379 } 1380 else 1381 { 1294 1382 } 1295 1383 } 1296 1384 while( error ); 1297 1385 1298 rpc_dmsg("\n[INFO] %s on core %d in cluster %x sent RPC %p to cluster %x\n",1299 __FUNCTION__ , client_lid , client_cxy , rpc , server_cxy);1386 rpc_dmsg("\n[INFO] %s : RPC registered / client_cxy = %x / server_cxy = %x\n", 1387 __FUNCTION__ , local_cxy , server_cxy , first ); 1300 1388 1301 // send IPI if this is the first RPC in remote FIFO 1302 // and no CPU is in kernel mode in server cluster. 1303 // the selected CPU in server has the same lid as the client CPU. 1389 // send IPI to remote CP0, if this is the first RPC in remote FIFO, 1390 // and there is no CPU is in kernel mode in server cluster. 1304 1391 if( first ) 1305 1392 { … … 1309 1396 if( cores == 0 ) // no core in kernel mode in server 1310 1397 { 1311 dev_pic_send_ipi( server_cxy , client_lid);1312 1313 rpc_dmsg("\n[INFO] %s : core %d in cluster %x send IPI to core %d in cluster%x\n",1314 __FUNCTION__, client_lid , client_cxy , client_lid, server_cxy );1398 dev_pic_send_ipi( server_cxy , 0 ); 1399 1400 rpc_dmsg("\n[INFO] %s : IPI sent / client_cxy = %x / server_cxy = %x\n", 1401 __FUNCTION__, local_cxy , server_cxy ); 1315 1402 } 1316 1403 } 1317 1404 1318 // activate preemptionto allow incoming RPC and avoid deadlock1405 // enable IRQs to allow incoming RPC and avoid deadlock 1319 1406 if( this->type == THREAD_RPC ) hal_enable_irq( &sr_save ); 1320 1407 1321 // the sending thread poll the response slot until RPC completed 1408 // the server thread poll the response slot until RPC completed 1409 // TODO this could be replaced by a descheduling policy... [AG] 1322 1410 while( 1 ) 1323 1411 { … … 1325 1413 } 1326 1414 1327 // restore preemption1415 // restore IRQs 1328 1416 if( this->type == THREAD_RPC ) hal_restore_irq( sr_save ); 1417 1418 rpc_dmsg("\n[INFO] %s : completed / client_cxy = %x / server_cxy = %x\n", 1419 __FUNCTION__ , local_cxy , server_cxy ); 1329 1420 1330 1421 } // end rpc_send_sync() … … 1344 1435 } 1345 1436 1346 ///////////////////////////////////////////// ///1347 error_trpc_execute_all( rpc_fifo_t * rpc_fifo )1437 ///////////////////////////////////////////// 1438 void rpc_execute_all( rpc_fifo_t * rpc_fifo ) 1348 1439 { 1349 1440 xptr_t xp; // extended pointer on RPC descriptor … … 1353 1444 rpc_desc_t * desc; // pointer on RPC descriptor 1354 1445 uint32_t index; // RPC index 1355 uint32_t expected; // number of expected responses1356 1446 cxy_t client_cxy; // client cluster identifier 1357 1447 error_t error; … … 1370 1460 if ( error == 0 ) // One RPC request successfully extracted from RPC_FIFO 1371 1461 { 1372 rpc_dmsg("\n[INFO] %s : RPC_THREAD %x on core %x in cluster %x handles RPC %d\n" 1462 rpc_dmsg("\n[INFO] %s : RPC_THREAD %x on core %x in cluster %x handles RPC %d\n", 1373 1463 __FUNCTION__ , this->trdid , core->lid , local_cxy , count ); 1374 1464 … … 1377 1467 desc = (rpc_desc_t *)GET_PTR( xp ); 1378 1468 1379 // get rpc index and expected responsesfrom RPC descriptor1469 // get rpc index from RPC descriptor 1380 1470 index = hal_remote_lw( XPTR( client_cxy , &desc->index ) ); 1381 expected = hal_remote_lw( XPTR( client_cxy , &desc->response ) );1382 1471 1383 1472 // call the relevant server function … … 1388 1477 1389 1478 // notify RPC completion as required 1390 if( expected == 1 ) hal_remote_sw( XPTR(client_cxy,&desc->response) , 0 ); 1391 if( expected > 1 ) hal_remote_atomic_add( XPTR(client_cxy,&desc->response) , -1 ); 1479 hal_remote_atomic_add( XPTR(client_cxy,&desc->response) , -1 ); 1392 1480 } 1393 1481 … … 1400 1488 (count > CONFIG_RPC_PENDING_MAX) ) break; 1401 1489 } 1402 while( 1 ) 1403 1404 rpc_dmsg("\n[INFO] %s running on core %d in cluster %x exit\n" 1405 __FUNCTION__ , CURRENT_CORE->lid , local_cxy ); 1406 1490 while( 1 ); 1491 1407 1492 // update RPC_FIFO global counter 1408 1493 rpc_fifo->count += count; 1409 1494 1410 return 0;1411 1495 } // end rpc_execute_all() 1412 1496 … … 1422 1506 reg_t sr_save; 1423 1507 1508 1424 1509 this = CURRENT_THREAD; 1425 1510 core = this->core; … … 1427 1512 found = false; 1428 1513 1429 // calling thread must be the RPC_FIFO owner 1430 if( this->trdid != rpc_fifo->owner ) 1431 { 1432 printk("\n[PANIC] in %s : calling thread is not RPC_FIFO owner\n", __FUNCTION__ ); 1433 hal_core_sleep(); 1434 } 1514 assert( (this->trdid == rpc_fifo->owner) , __FUNCTION__ , 1515 "calling thread is not RPC_FIFO owner\n" ); 1435 1516 1436 1517 // makes the calling thread not preemptable … … 1443 1524 { 1444 1525 thread = LIST_ELEMENT( iter , thread_t , sched_list ); 1445 if( (thread->type == THREAD_RPC) && (thread->blocked == 1526 if( (thread->type == THREAD_RPC) && (thread->blocked == THREAD_BLOCKED_IDLE ) ) 1446 1527 { 1447 1528 found = true; … … 1453 1534 { 1454 1535 thread->blocked = 0; 1536 1537 rpc_dmsg("\n[INFO] %s : activate RPC thread %x on core %x in cluster %x at cycle %d\n", 1538 __FUNCTION__ , thread , core->gid , local_cxy , hal_get_cycles() ); 1455 1539 } 1456 1540 else // create a new RPC thread … … 1469 1553 } 1470 1554 1471 rpc_dmsg("\n[INFO] %s createsRPC thread %x on core %x in cluster %x at cycle %d\n",1555 rpc_dmsg("\n[INFO] %s : create RPC thread %x on core %x in cluster %x at cycle %d\n", 1472 1556 __FUNCTION__ , thread , core->gid , local_cxy , hal_get_cycles() ); 1473 1557 1474 1558 // update core descriptor counter 1475 hal_atomic_add( & core->rpc_threads , 1 );1559 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 ); 1476 1560 } 1477 1561 1478 1562 // update owner in rpc_fifo 1479 1563 rpc_fifo->owner = thread->trdid; 1480 1481 rpc_dmsg ("\n[INFO] %s activates RPC thread %x on core %x in cluster %x at cycle %d\n",1482 __FUNCTION__ , thread , core->gid , local_cxy , hal_get_cycles() );1483 1564 1484 1565 // current thread deschedules / RPC thread start execution … … 1506 1587 } 1507 1588 1508 // calling thread tries to take the light lock, 1509 // and activates an RPC thread if success 1589 // try to take the light lock, and activates an RPC thread if success 1510 1590 if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) ) 1511 1591 { … … 1543 1623 1544 1624 // this infinite loop is not preemptable 1545 // the RPC thread deschedule when the RPC_FIFO is empty1625 // the RPC thread deschedule only when the RPC_FIFO is empty 1546 1626 while(1) 1547 1627 { … … 1561 1641 1562 1642 1563 // suicide if too much RPC threads for this core1564 if( this->core->rpc_threads >CONFIG_RPC_THREADS_MAX )1643 // block and deschedule or sucide 1644 if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX ) 1565 1645 { 1566 1646 rpc_dmsg("\n[INFO] RPC thread %x suicide on core %d in cluster %x at cycle %d\n", … … 1568 1648 1569 1649 // update core descriptor counter 1570 hal_atomic_add( & this->core->rpc_threads , -1 );1650 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 ); 1571 1651 1572 1652 // suicide 1573 1653 thread_exit(); 1574 1654 } 1575 1576 // block and deschedule 1577 rpc_dmsg("\n[INFO] RPC thread %x deschedule on core %d in cluster %x at cycle %d\n", 1578 this->trdid , this->core->lid , local_cxy , hal_get_cycles() ); 1579 1580 thread_block( this , THREAD_BLOCKED_IDLE ); 1581 sched_yield(); 1582 1583 rpc_dmsg("\n[INFO] RPC thread %x wake up on core %d in cluster %x at cycle %d\n", 1584 this->trdid , this->core->lid , local_cxy , hal_get_cycles() ); 1585 } 1655 else 1656 { 1657 rpc_dmsg("\n[INFO] RPC thread %x blocks on core %d in cluster %x at cycle %d\n", 1658 this->trdid , this->core->lid , local_cxy , hal_get_cycles() ); 1659 1660 thread_block( this , THREAD_BLOCKED_IDLE ); 1661 sched_yield(); 1662 1663 rpc_dmsg("\n[INFO] RPC thread %x wake up on core %d in cluster %x at cycle %d\n", 1664 this->trdid , this->core->lid , local_cxy , hal_get_cycles() ); 1665 } 1666 } // end while 1586 1667 } // end rpc_thread_func() 1587 1668
Note: See TracChangeset
for help on using the changeset viewer.