diff options
author | Sean Hefty <sean.hefty@intel.com> | 2007-08-08 18:51:06 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-10-09 22:59:12 -0400 |
commit | a81c994d5eef87ed77cb30d8343d6be296528b3f (patch) | |
tree | 2d5be6dcb6283ab32cbc434b43f04df3034de5d8 | |
parent | 733d65fe33b3002a6f2694c0fd8bd760dc13141f (diff) |
RDMA/cma: Add ability to specify type of service
Provide support to specify a type of service for a communication
identifier. A new function call is used when dealing with IPv4
addresses. For IPv6 addresses, the ToS is specified through the
traffic class field in the sockaddr_in6 structure.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
[ The comments Eitan Zahavi and myself have made over the v1 post at
<http://lists.openfabrics.org/pipermail/general/2007-August/039247.html>
were fully addressed. ]
Reviewed-by: Or Gerlitz <ogerlitz@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | drivers/infiniband/core/cma.c | 44 | ||||
-rw-r--r-- | include/rdma/rdma_cm.h | 14 |
2 files changed, 48 insertions, 10 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 9ffb9987450a..19c9172f0cdc 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -138,6 +138,7 @@ struct rdma_id_private { | |||
138 | u32 qkey; | 138 | u32 qkey; |
139 | u32 qp_num; | 139 | u32 qp_num; |
140 | u8 srq; | 140 | u8 srq; |
141 | u8 tos; | ||
141 | }; | 142 | }; |
142 | 143 | ||
143 | struct cma_multicast { | 144 | struct cma_multicast { |
@@ -1474,6 +1475,15 @@ err: | |||
1474 | } | 1475 | } |
1475 | EXPORT_SYMBOL(rdma_listen); | 1476 | EXPORT_SYMBOL(rdma_listen); |
1476 | 1477 | ||
1478 | void rdma_set_service_type(struct rdma_cm_id *id, int tos) | ||
1479 | { | ||
1480 | struct rdma_id_private *id_priv; | ||
1481 | |||
1482 | id_priv = container_of(id, struct rdma_id_private, id); | ||
1483 | id_priv->tos = (u8) tos; | ||
1484 | } | ||
1485 | EXPORT_SYMBOL(rdma_set_service_type); | ||
1486 | |||
1477 | static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, | 1487 | static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, |
1478 | void *context) | 1488 | void *context) |
1479 | { | 1489 | { |
@@ -1498,23 +1508,37 @@ static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, | |||
1498 | static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, | 1508 | static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, |
1499 | struct cma_work *work) | 1509 | struct cma_work *work) |
1500 | { | 1510 | { |
1501 | struct rdma_dev_addr *addr = &id_priv->id.route.addr.dev_addr; | 1511 | struct rdma_addr *addr = &id_priv->id.route.addr; |
1502 | struct ib_sa_path_rec path_rec; | 1512 | struct ib_sa_path_rec path_rec; |
1513 | ib_sa_comp_mask comp_mask; | ||
1514 | struct sockaddr_in6 *sin6; | ||
1503 | 1515 | ||
1504 | memset(&path_rec, 0, sizeof path_rec); | 1516 | memset(&path_rec, 0, sizeof path_rec); |
1505 | ib_addr_get_sgid(addr, &path_rec.sgid); | 1517 | ib_addr_get_sgid(&addr->dev_addr, &path_rec.sgid); |
1506 | ib_addr_get_dgid(addr, &path_rec.dgid); | 1518 | ib_addr_get_dgid(&addr->dev_addr, &path_rec.dgid); |
1507 | path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr)); | 1519 | path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr)); |
1508 | path_rec.numb_path = 1; | 1520 | path_rec.numb_path = 1; |
1509 | path_rec.reversible = 1; | 1521 | path_rec.reversible = 1; |
1522 | path_rec.service_id = cma_get_service_id(id_priv->id.ps, &addr->dst_addr); | ||
1523 | |||
1524 | comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | | ||
1525 | IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | | ||
1526 | IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID; | ||
1527 | |||
1528 | if (addr->src_addr.sa_family == AF_INET) { | ||
1529 | path_rec.qos_class = cpu_to_be16((u16) id_priv->tos); | ||
1530 | comp_mask |= IB_SA_PATH_REC_QOS_CLASS; | ||
1531 | } else { | ||
1532 | sin6 = (struct sockaddr_in6 *) &addr->src_addr; | ||
1533 | path_rec.traffic_class = (u8) (be32_to_cpu(sin6->sin6_flowinfo) >> 20); | ||
1534 | comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS; | ||
1535 | } | ||
1510 | 1536 | ||
1511 | id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device, | 1537 | id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device, |
1512 | id_priv->id.port_num, &path_rec, | 1538 | id_priv->id.port_num, &path_rec, |
1513 | IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | | 1539 | comp_mask, timeout_ms, |
1514 | IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | | 1540 | GFP_KERNEL, cma_query_handler, |
1515 | IB_SA_PATH_REC_REVERSIBLE, | 1541 | work, &id_priv->query); |
1516 | timeout_ms, GFP_KERNEL, | ||
1517 | cma_query_handler, work, &id_priv->query); | ||
1518 | 1542 | ||
1519 | return (id_priv->query_id < 0) ? id_priv->query_id : 0; | 1543 | return (id_priv->query_id < 0) ? id_priv->query_id : 0; |
1520 | } | 1544 | } |
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h index 2d6a7705eae7..010f876f41d8 100644 --- a/include/rdma/rdma_cm.h +++ b/include/rdma/rdma_cm.h | |||
@@ -314,4 +314,18 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr, | |||
314 | */ | 314 | */ |
315 | void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr); | 315 | void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr); |
316 | 316 | ||
317 | /** | ||
318 | * rdma_set_service_type - Set the type of service associated with a | ||
319 | * connection identifier. | ||
320 | * @id: Communication identifier to associated with service type. | ||
321 | * @tos: Type of service. | ||
322 | * | ||
323 | * The type of service is interpretted as a differentiated service | ||
324 | * field (RFC 2474). The service type should be specified before | ||
325 | * performing route resolution, as existing communication on the | ||
326 | * connection identifier may be unaffected. The type of service | ||
327 | * requested may not be supported by the network to all destinations. | ||
328 | */ | ||
329 | void rdma_set_service_type(struct rdma_cm_id *id, int tos); | ||
330 | |||
317 | #endif /* RDMA_CM_H */ | 331 | #endif /* RDMA_CM_H */ |