@@ -1353,28 +1353,69 @@ static void ucp_wireup_discard_uct_eps(ucp_ep_h ep, uct_ep_h *uct_eps,
1353
1353
}
1354
1354
}
1355
1355
1356
+ static int
1357
+ ucp_wireup_is_am_lane_replaced (ucp_ep_h ep ,
1358
+ const ucp_lane_index_t * reuse_lane_map )
1359
+ {
1360
+ return !ucp_ep_has_cm_lane (ep ) && (ep -> am_lane != UCP_NULL_LANE ) &&
1361
+ (reuse_lane_map [ep -> am_lane ] == UCP_NULL_LANE );
1362
+ }
1363
+
1356
1364
static int
1357
1365
ucp_wireup_check_is_reconfigurable (ucp_ep_h ep ,
1358
1366
const ucp_ep_config_key_t * new_key ,
1359
1367
const ucp_unpacked_address_t * remote_address ,
1360
1368
const unsigned * addr_indices )
1361
1369
{
1362
- ucp_lane_index_t lane ;
1370
+ ucp_lane_index_t lane , wireup_lane , reuse_lane_map [UCP_MAX_LANES ];
1371
+ const ucp_ep_config_key_t * old_key ;
1363
1372
1364
1373
if ((ep -> cfg_index == UCP_WORKER_CFG_INDEX_NULL ) ||
1365
1374
ucp_ep_has_cm_lane (ep )) {
1366
1375
return 1 ;
1367
1376
}
1368
1377
1369
- /* TODO: Support reconfiguration when lanes are created without a wireup_ep
1370
- * wrapper */
1371
- for (lane = 0 ; lane < ucp_ep_num_lanes (ep ); ++ lane ) {
1372
- if (!ucp_wireup_ep_test (ucp_ep_get_lane (ep , lane ))) {
1378
+ old_key = & ucp_ep_config (ep )-> key ;
1379
+
1380
+ /* TODO: 1) Support lanes which are connected to the same remote MD, but
1381
+ * different remote sys_dev (eg. TCP). */
1382
+ for (lane = 0 ; lane < old_key -> num_lanes ; ++ lane ) {
1383
+ if ((ucp_ep_config_find_match_lane (old_key , lane , new_key ) !=
1384
+ UCP_NULL_LANE ) &&
1385
+ !ucp_ep_config_lane_is_equal (old_key , new_key , lane )) {
1373
1386
return 0 ;
1374
1387
}
1375
1388
}
1376
1389
1377
- return 1 ;
1390
+ ucp_ep_config_lanes_intersect (old_key , new_key , ep , remote_address ,
1391
+ addr_indices , reuse_lane_map );
1392
+ wireup_lane = ucp_wireup_get_msg_lane (ep , UCP_WIREUP_MSG_REQUEST );
1393
+
1394
+ /* TODO: 2) Support reconfiguration for separated wireup and AM lanes
1395
+ * during wireup process (request sent). */
1396
+ return !(ep -> flags & UCP_EP_FLAG_CONNECT_REQ_QUEUED ) ||
1397
+ (ep -> am_lane == wireup_lane ) ||
1398
+ !ucp_wireup_is_am_lane_replaced (ep , reuse_lane_map );
1399
+ }
1400
+
1401
+ static int ucp_wireup_should_reconfigure (ucp_ep_h ep ,
1402
+ const ucp_lane_index_t * reuse_lane_map ,
1403
+ ucp_lane_index_t num_lanes )
1404
+ {
1405
+ ucp_lane_index_t lane ;
1406
+
1407
+ if (ucp_ep_has_cm_lane (ep )) {
1408
+ return 1 ;
1409
+ }
1410
+
1411
+ /* Check whether all lanes are reused */
1412
+ for (lane = 0 ; lane < ucp_ep_num_lanes (ep ); ++ lane ) {
1413
+ if (reuse_lane_map [lane ] == UCP_NULL_LANE ) {
1414
+ return 1 ;
1415
+ }
1416
+ }
1417
+
1418
+ return ucp_ep_num_lanes (ep ) != num_lanes ;
1378
1419
}
1379
1420
1380
1421
static ucs_status_t
@@ -1384,15 +1425,16 @@ ucp_wireup_replace_wireup_msg_lane(ucp_ep_h ep, ucp_ep_config_key_t *key,
1384
1425
{
1385
1426
uct_ep_h uct_ep = NULL ;
1386
1427
ucp_lane_index_t old_lane , new_wireup_lane ;
1387
- ucp_wireup_ep_t * old_wireup_ep , * new_wireup_ep ;
1428
+ ucp_wireup_ep_t * new_wireup_ep ;
1429
+ uct_ep_h old_wireup_ep , msg_ep ;
1388
1430
ucp_rsc_index_t aux_rsc_index ;
1389
- int is_p2p ;
1431
+ int is_p2p , is_wireup_ep , is_next ;
1390
1432
ucs_status_t status ;
1391
1433
1392
1434
/* Get old wireup lane */
1393
1435
old_lane = ucp_wireup_get_msg_lane (ep , UCP_WIREUP_MSG_REQUEST );
1394
- old_wireup_ep = ucp_wireup_ep ( ucp_ep_get_lane (ep , old_lane ) );
1395
- ucs_assert_always ( old_wireup_ep != NULL );
1436
+ old_wireup_ep = ucp_ep_get_lane (ep , old_lane );
1437
+ is_wireup_ep = ucp_wireup_ep_test ( old_wireup_ep );
1396
1438
1397
1439
/* Select CM/non-reused lane as new wireup lane */
1398
1440
new_wireup_lane = ucp_ep_find_non_reused_lane (ep , key , reuse_lane_map );
@@ -1417,32 +1459,31 @@ ucp_wireup_replace_wireup_msg_lane(ucp_ep_h ep, ucp_ep_config_key_t *key,
1417
1459
}
1418
1460
1419
1461
ucs_assert (new_wireup_ep != NULL );
1462
+ is_next = ucp_wireup_ep_is_next_ep_active (ucp_wireup_ep (old_wireup_ep ));
1420
1463
1421
1464
/* Get correct aux_rsc_index either from next_ep or aux_ep */
1422
- aux_rsc_index = ucp_wireup_ep_is_next_ep_active ( old_wireup_ep ) ?
1465
+ aux_rsc_index = (! is_wireup_ep || is_next ) ?
1423
1466
ucp_ep_get_rsc_index (ep , old_lane ) :
1424
- ucp_wireup_ep_get_aux_rsc_index (
1425
- & old_wireup_ep -> super .super );
1467
+ ucp_wireup_ep_get_aux_rsc_index (old_wireup_ep );
1426
1468
1427
1469
ucs_assert (aux_rsc_index != UCP_NULL_RESOURCE );
1428
1470
is_p2p = ucp_ep_config_connect_p2p (ep -> worker , & ucp_ep_config (ep )-> key ,
1429
1471
aux_rsc_index );
1430
1472
1431
1473
/* Move aux EP to new wireup lane */
1432
- ucp_wireup_ep_set_aux ( new_wireup_ep ,
1433
- ucp_wireup_ep_extract_msg_ep ( old_wireup_ep ) ,
1474
+ msg_ep = ucp_wireup_ep_extract_msg_ep ( ucp_wireup_ep ( old_wireup_ep ));
1475
+ ucp_wireup_ep_set_aux ( new_wireup_ep , is_wireup_ep ? msg_ep : old_wireup_ep ,
1434
1476
aux_rsc_index , is_p2p );
1435
1477
1436
- /* Remove old wireup_ep as it's not needed anymore.
1437
- * NOTICE: Next two lines are intentionally not merged with the lane
1438
- * removal loop in ucp_wireup_check_config_intersect, because of future
1439
- * support for non-wireup EPs reconfiguration (which will modify this
1440
- * code). */
1441
- uct_ep_destroy (& old_wireup_ep -> super .super );
1442
- ucp_ep_set_lane (ep , old_lane , NULL );
1478
+ if (is_wireup_ep ) {
1479
+ /* Remove old wireup_ep as it's not needed anymore. */
1480
+ uct_ep_destroy (old_wireup_ep );
1481
+ }
1443
1482
1483
+ ucp_ep_set_lane (ep , old_lane , NULL );
1444
1484
new_uct_eps [new_wireup_lane ] = & new_wireup_ep -> super .super ;
1445
1485
key -> wireup_msg_lane = new_wireup_lane ;
1486
+
1446
1487
return UCS_OK ;
1447
1488
}
1448
1489
@@ -1479,6 +1520,11 @@ ucp_wireup_check_config_intersect(ucp_ep_h ep, ucp_ep_config_key_t *new_key,
1479
1520
ucp_ep_config_lanes_intersect (old_key , new_key , ep , remote_address ,
1480
1521
addr_indices , reuse_lane_map );
1481
1522
1523
+ if (!ucp_wireup_should_reconfigure (ep , reuse_lane_map ,
1524
+ new_key -> num_lanes )) {
1525
+ return UCS_OK ;
1526
+ }
1527
+
1482
1528
if (ucp_ep_has_cm_lane (ep )) {
1483
1529
/* CM lane has to be reused by the new EP configuration */
1484
1530
ucs_assert (reuse_lane_map [ucp_ep_get_cm_lane (ep )] != UCP_NULL_LANE );
@@ -1585,16 +1631,36 @@ ucp_wireup_gather_pending_reqs(ucp_ep_h ep,
1585
1631
ucs_queue_head_t * replay_pending_queue )
1586
1632
{
1587
1633
ucp_request_t * req ;
1634
+ ucp_lane_index_t lane ;
1588
1635
1636
+ ucs_queue_head_init (replay_pending_queue );
1637
+
1638
+ if (ep -> cfg_index == UCP_WORKER_CFG_INDEX_NULL ) {
1639
+ return ;
1640
+ }
1641
+
1642
+ /* Handle wireup EPs */
1589
1643
ucp_wireup_eps_pending_extract (ep , replay_pending_queue );
1590
1644
1645
+ /* rkey ptr requests */
1591
1646
ucs_queue_for_each (req , & ep -> worker -> rkey_ptr_reqs ,
1592
1647
send .rndv .rkey_ptr .queue_elem ) {
1593
1648
if (req -> send .ep == ep ) {
1594
1649
ucs_queue_push (replay_pending_queue ,
1595
1650
(ucs_queue_elem_t * )& req -> send .uct .priv );
1596
1651
}
1597
1652
}
1653
+
1654
+ /* Fully connected lanes */
1655
+ for (lane = 0 ; lane < ucp_ep_num_lanes (ep ); ++ lane ) {
1656
+ if (ucp_wireup_ep_test (ucp_ep_get_lane (ep , lane ))) {
1657
+ continue ;
1658
+ }
1659
+
1660
+ uct_ep_pending_purge (ucp_ep_get_lane (ep , lane ),
1661
+ ucp_request_purge_enqueue_cb ,
1662
+ replay_pending_queue );
1663
+ }
1598
1664
}
1599
1665
1600
1666
ucs_status_t ucp_wireup_init_lanes (ucp_ep_h ep , unsigned ep_init_flags ,
0 commit comments