Commit a81c994d authored by Sean Hefty's avatar Sean Hefty Committed by Roland Dreier

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: default avatarSean 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: default avatarRoland Dreier <rolandd@cisco.com>
parent 733d65fe
...@@ -138,6 +138,7 @@ struct rdma_id_private { ...@@ -138,6 +138,7 @@ struct rdma_id_private {
u32 qkey; u32 qkey;
u32 qp_num; u32 qp_num;
u8 srq; u8 srq;
u8 tos;
}; };
struct cma_multicast { struct cma_multicast {
...@@ -1474,6 +1475,15 @@ int rdma_listen(struct rdma_cm_id *id, int backlog) ...@@ -1474,6 +1475,15 @@ int rdma_listen(struct rdma_cm_id *id, int backlog)
} }
EXPORT_SYMBOL(rdma_listen); EXPORT_SYMBOL(rdma_listen);
void rdma_set_service_type(struct rdma_cm_id *id, int tos)
{
struct rdma_id_private *id_priv;
id_priv = container_of(id, struct rdma_id_private, id);
id_priv->tos = (u8) tos;
}
EXPORT_SYMBOL(rdma_set_service_type);
static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec,
void *context) void *context)
{ {
...@@ -1498,23 +1508,37 @@ static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, ...@@ -1498,23 +1508,37 @@ static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec,
static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
struct cma_work *work) struct cma_work *work)
{ {
struct rdma_dev_addr *addr = &id_priv->id.route.addr.dev_addr; struct rdma_addr *addr = &id_priv->id.route.addr;
struct ib_sa_path_rec path_rec; struct ib_sa_path_rec path_rec;
ib_sa_comp_mask comp_mask;
struct sockaddr_in6 *sin6;
memset(&path_rec, 0, sizeof path_rec); memset(&path_rec, 0, sizeof path_rec);
ib_addr_get_sgid(addr, &path_rec.sgid); ib_addr_get_sgid(&addr->dev_addr, &path_rec.sgid);
ib_addr_get_dgid(addr, &path_rec.dgid); ib_addr_get_dgid(&addr->dev_addr, &path_rec.dgid);
path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(addr)); path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr));
path_rec.numb_path = 1; path_rec.numb_path = 1;
path_rec.reversible = 1; path_rec.reversible = 1;
path_rec.service_id = cma_get_service_id(id_priv->id.ps, &addr->dst_addr);
comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH |
IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID;
if (addr->src_addr.sa_family == AF_INET) {
path_rec.qos_class = cpu_to_be16((u16) id_priv->tos);
comp_mask |= IB_SA_PATH_REC_QOS_CLASS;
} else {
sin6 = (struct sockaddr_in6 *) &addr->src_addr;
path_rec.traffic_class = (u8) (be32_to_cpu(sin6->sin6_flowinfo) >> 20);
comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS;
}
id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device, id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device,
id_priv->id.port_num, &path_rec, id_priv->id.port_num, &path_rec,
IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | comp_mask, timeout_ms,
IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | GFP_KERNEL, cma_query_handler,
IB_SA_PATH_REC_REVERSIBLE, work, &id_priv->query);
timeout_ms, GFP_KERNEL,
cma_query_handler, work, &id_priv->query);
return (id_priv->query_id < 0) ? id_priv->query_id : 0; return (id_priv->query_id < 0) ? id_priv->query_id : 0;
} }
......
...@@ -314,4 +314,18 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr, ...@@ -314,4 +314,18 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
*/ */
void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr); void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr);
/**
* rdma_set_service_type - Set the type of service associated with a
* connection identifier.
* @id: Communication identifier to associated with service type.
* @tos: Type of service.
*
* The type of service is interpretted as a differentiated service
* field (RFC 2474). The service type should be specified before
* performing route resolution, as existing communication on the
* connection identifier may be unaffected. The type of service
* requested may not be supported by the network to all destinations.
*/
void rdma_set_service_type(struct rdma_cm_id *id, int tos);
#endif /* RDMA_CM_H */ #endif /* RDMA_CM_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment