aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2007-08-08 18:51:06 -0400
committerRoland Dreier <rolandd@cisco.com>2007-10-09 22:59:12 -0400
commita81c994d5eef87ed77cb30d8343d6be296528b3f (patch)
tree2d5be6dcb6283ab32cbc434b43f04df3034de5d8
parent733d65fe33b3002a6f2694c0fd8bd760dc13141f (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.c44
-rw-r--r--include/rdma/rdma_cm.h14
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
143struct cma_multicast { 144struct cma_multicast {
@@ -1474,6 +1475,15 @@ err:
1474} 1475}
1475EXPORT_SYMBOL(rdma_listen); 1476EXPORT_SYMBOL(rdma_listen);
1476 1477
1478void 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}
1485EXPORT_SYMBOL(rdma_set_service_type);
1486
1477static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, 1487static 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,
1498static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, 1508static 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 */
315void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr); 315void 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 */
329void rdma_set_service_type(struct rdma_cm_id *id, int tos);
330
317#endif /* RDMA_CM_H */ 331#endif /* RDMA_CM_H */