Skip to content

Commit 7e8b1bb

Browse files
pakluiPak Nin Lui
andauthored
add NIC_TRAFFIC_CLASS and NIC_SERVICE_LEVEL env vars for DSCP marking (#315)
Adds support for marking RoCE/IB traffic with specific DSCP/QoS values. - NIC_TRAFFIC_CLASS (default=0): sets the DSCP/traffic class byte in the RoCE GRH (grh.traffic_class) when transitioning QPs to RTR state. - NIC_SERVICE_LEVEL (default=0): sets the IB service level (ah_attr.sl) on QPs. This applies to IB and RoCE connections. - NicOptions: I added uint8_t serviceLevel and uint8_t trafficClass fields - TransitionQpToRtr(): accepts trafficClass and serviceLevel as parameters; sets grh.traffic_class (RoCE only) and ah_attr.sl (all QP types) --------- Co-authored-by: Pak Nin Lui <paklui@smc300x-ccs-aus-gpuf2c9.prov.aus.ccs.cpe.ice.amd.com>
1 parent e923e24 commit 7e8b1bb

3 files changed

Lines changed: 35 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Documentation for TransferBench is available at
55

66
## v1.67.00
77
### Added
8+
- Added NIC_TRAFFIC_CLASS to set the DSCP/traffic class byte in the RoCE GRH for QPs (RoCE only)
9+
- Added NIC_SERVICE_LEVEL to set the IB service level (sl) for QPs (IB and RoCE)
810
- Initial support for pod communication. Requires compatible hardware / ROCm version and subject to further testing
911
- This potentially enables GFX/DMA executors to access SRC/DST memory locations on GPUs within the same pod
1012
- Pod membership requires amd-smi however can be skipped by setting TB_FORCE_SINGLE_POD=1

src/client/EnvVars.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ class EnvVars
120120
int nicChunkBytes; // Number of bytes to send per chunk for RDMA operations
121121
int nicCqPollBatch; // Number of CQ entries to poll per ibv_poll_cq call
122122
int nicRelaxedOrder; // Use relaxed ordering for RDMA
123+
int nicServiceLevel; // IB service level (sl) for InfiniBand QPs
124+
int nicTrafficClass; // DSCP/traffic class byte for RoCE GRH
123125
int roceVersion; // RoCE version number
124126

125127
// Developer features
@@ -185,6 +187,18 @@ class EnvVars
185187
nicChunkBytes = GetEnvVar("NIC_CHUNK_BYTES" , 1073741824);
186188
nicCqPollBatch = GetEnvVar("NIC_CQ_POLL_BATCH" , 4);
187189
nicRelaxedOrder = GetEnvVar("NIC_RELAX_ORDER" , 1);
190+
nicServiceLevel = GetEnvVar("NIC_SERVICE_LEVEL" , 0);
191+
nicTrafficClass = GetEnvVar("NIC_TRAFFIC_CLASS" , 0);
192+
193+
// Check that NIC service level and traffic class are in valid ranges
194+
if (nicServiceLevel < 0 || nicServiceLevel > 15) {
195+
printf("[ERROR] NIC_SERVICE_LEVEL must be in range 0..15 (got %d)\n", nicServiceLevel);
196+
exit(1);
197+
}
198+
if (nicTrafficClass < 0 || nicTrafficClass > 255) {
199+
printf("[ERROR] NIC_TRAFFIC_CLASS must be in range 0..255 (got %d)\n", nicTrafficClass);
200+
exit(1);
201+
}
188202

189203
gpuMaxHwQueues = GetEnvVar("GPU_MAX_HW_QUEUES" , 4);
190204

@@ -366,6 +380,8 @@ class EnvVars
366380
printf(" NIC_CHUNK_BYTES - Number of bytes to send at a time using NIC (default = 1GB)\n");
367381
printf(" NIC_CQ_POLL_BATCH - Number of CQ entries to poll per ibv_poll_cq call (default = 4)\n");
368382
printf(" NIC_RELAX_ORDER - Set to non-zero to use relaxed ordering\n");
383+
printf(" NIC_SERVICE_LEVEL - IB service level (sl) for InfiniBand QPs (default=0)\n");
384+
printf(" NIC_TRAFFIC_CLASS - DSCP/traffic class byte for RoCE GRH (default=0)\n");
369385
#endif
370386
printf(" NUM_ITERATIONS - # of timed iterations per test. If negative, run for this many seconds instead\n");
371387
printf(" NUM_SUBITERATIONS - # of sub-iterations to run per iteration. Must be non-negative\n");
@@ -504,6 +520,10 @@ class EnvVars
504520
"Polling %d CQ entries per ibv_poll_cq call", nicCqPollBatch);
505521
Print("NIC_RELAX_ORDER", nicRelaxedOrder,
506522
"Using %s ordering for NIC RDMA", nicRelaxedOrder ? "relaxed" : "strict");
523+
Print("NIC_SERVICE_LEVEL", nicServiceLevel,
524+
"IB service level (sl) set to %d", nicServiceLevel);
525+
Print("NIC_TRAFFIC_CLASS", nicTrafficClass,
526+
"RoCE traffic class (DSCP) set to %d", nicTrafficClass);
507527
#endif
508528
Print("NUM_ITERATIONS", numIterations,
509529
(numIterations == 0) ? "Running infinitely" :
@@ -725,6 +745,8 @@ class EnvVars
725745
cfg.nic.ibPort = ibPort;
726746
cfg.nic.ipAddressFamily = ipAddressFamily;
727747
cfg.nic.useRelaxedOrder = nicRelaxedOrder;
748+
cfg.nic.serviceLevel = nicServiceLevel;
749+
cfg.nic.trafficClass = nicTrafficClass;
728750
cfg.nic.roceVersion = roceVersion;
729751

730752
return cfg;

src/header/TransferBench.hpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ namespace TransferBench
270270
int queueSize = 100; ///< Completion queue size
271271
int roceVersion = 2; ///< RoCE version (used for auto GID detection)
272272
int useRelaxedOrder = 1; ///< Use relaxed ordering
273+
uint8_t serviceLevel = 0; ///< IB service level (sl) for InfiniBand QPs
274+
uint8_t trafficClass = 0; ///< DSCP/traffic class byte for RoCE GRH
273275
int useNuma = 0; ///< Switch to closest numa thread for execution
274276
};
275277

@@ -2000,6 +2002,8 @@ namespace {
20002002
if (nic.maxSendWorkReq != cfg.nic.maxSendWorkReq) ADD_ERROR("cfg.nic.maxSendWorkReq");
20012003
// nic.queueSize is permitted to be different across ranks
20022004
if (nic.roceVersion != cfg.nic.roceVersion) ADD_ERROR("cfg.nic.roceVersion");
2005+
if (nic.serviceLevel != cfg.nic.serviceLevel) ADD_ERROR("cfg.nic.serviceLevel");
2006+
if (nic.trafficClass != cfg.nic.trafficClass) ADD_ERROR("cfg.nic.trafficClass");
20032007
if (nic.useRelaxedOrder != cfg.nic.useRelaxedOrder) ADD_ERROR("cfg.nic.useRelaxedOrder");
20042008
if (nic.useNuma != cfg.nic.useNuma) ADD_ERROR("cfg.nic.useNuma");
20052009
}
@@ -3284,7 +3288,9 @@ static bool IsConfiguredGid(union ibv_gid const& gid)
32843288
ConnInfo const& connInfo,
32853289
uint8_t const& port,
32863290
bool const& isRoCE,
3287-
ibv_mtu const& mtu)
3291+
ibv_mtu const& mtu,
3292+
uint8_t const& trafficClass,
3293+
uint8_t const& serviceLevel)
32883294
{
32893295
// Prepare QP attributes
32903296
struct ibv_qp_attr attr = {};
@@ -3300,11 +3306,12 @@ static bool IsConfiguredGid(union ibv_gid const& gid)
33003306
attr.ah_attr.grh.flow_label = 0;
33013307
attr.ah_attr.grh.sgid_index = connInfo.gidIdx;
33023308
attr.ah_attr.grh.hop_limit = 255;
3309+
attr.ah_attr.grh.traffic_class = trafficClass;
33033310
} else {
33043311
attr.ah_attr.is_global = 0;
33053312
attr.ah_attr.dlid = connInfo.lid;
33063313
}
3307-
attr.ah_attr.sl = 0;
3314+
attr.ah_attr.sl = serviceLevel;
33083315
attr.ah_attr.src_path_bits = 0;
33093316
attr.ah_attr.port_num = port;
33103317
attr.dest_qp_num = connInfo.qpn;
@@ -3588,7 +3595,7 @@ static bool IsConfiguredGid(union ibv_gid const& gid)
35883595
static_assert(std::is_trivially_copyable<QpTransitionResult>::value, "QpTransitionResult must be trivially copyable for MPI broadcast");
35893596
QpTransitionResult srcQpResult = {ERR_NONE, false};
35903597
if (GetRank() == srcMemRank) {
3591-
ErrResult err = TransitionQpToRtr(rss.srcQueuePairs[i], dstConnInfo, port, srcIsRoCE, rss.srcPortAttr.active_mtu);
3598+
ErrResult err = TransitionQpToRtr(rss.srcQueuePairs[i], dstConnInfo, port, srcIsRoCE, rss.srcPortAttr.active_mtu, cfg.nic.trafficClass, cfg.nic.serviceLevel);
35923599
srcQpResult.rtrFailed = (err.errType != ERR_NONE);
35933600
if (err.errType == ERR_NONE) {
35943601
err = TransitionQpToRts(rss.srcQueuePairs[i]);
@@ -3603,7 +3610,7 @@ static bool IsConfiguredGid(union ibv_gid const& gid)
36033610

36043611
QpTransitionResult dstQpResult = {ERR_NONE, false};
36053612
if (GetRank() == dstMemRank) {
3606-
ErrResult err = TransitionQpToRtr(rss.dstQueuePairs[i], srcConnInfo, port, dstIsRoCE, rss.dstPortAttr.active_mtu);
3613+
ErrResult err = TransitionQpToRtr(rss.dstQueuePairs[i], srcConnInfo, port, dstIsRoCE, rss.dstPortAttr.active_mtu, cfg.nic.trafficClass, cfg.nic.serviceLevel);
36073614
dstQpResult.rtrFailed = (err.errType != ERR_NONE);
36083615
if (err.errType == ERR_NONE) {
36093616
err = TransitionQpToRts(rss.dstQueuePairs[i]);

0 commit comments

Comments
 (0)