[PATCH rdma-next 11/13] IB/{core, cm, cma, ipoib}: Resolve route only while sending CM requests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Parav Pandit <parav@xxxxxxxxxxxx>

Currently CM request for RoCE follows following flow.
rdma_create_id()
rdma_resolve_addr()
rdma_resolve_route()
For RC QPs:
rdma_connect()
->cma_connect_ib()
  ->ib_send_cm_req()
    ->cm_init_av_by_path()
      ->ib_init_ah_attr_from_path()
For UD QPs:
rdma_connect()
->cma_resolve_ib_udp()
  ->ib_send_cm_sidr_req()
    ->cm_init_av_by_path()
      ->ib_init_ah_attr_from_path()

In both the flows, route is already resolved before sending CM requests.
Therefore, code is refactored to avoid resolving route second time in
ib_cm layer.
ib_init_ah_attr_from_path() is extended to resolve route when it is not
yet resolved for RoCE link layer. This is achieved by caller setting
route_resolved field in path record whenever it has route already
resolved.

Reviewed-by: Daniel Jurgens <danielj@xxxxxxxxxxxx>
Reviewed-by: Mark Bloch <markb@xxxxxxxxxxxx>
Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx>
Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx>
---
 drivers/infiniband/core/cm.c       |  7 ++++++-
 drivers/infiniband/core/cma.c      |  1 +
 drivers/infiniband/core/sa_query.c |  9 ++++++---
 include/rdma/ib_sa.h               | 26 ++++++++++++++++++++++++++
 4 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index c9b325040df3..46303a7a2164 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -1934,9 +1934,11 @@ static int cm_req_handler(struct cm_work *work)
 		work->path[1].rec_type = work->path[0].rec_type;
 	cm_format_paths_from_req(req_msg, &work->path[0],
 				 &work->path[1]);
-	if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE)
+	if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE) {
 		sa_path_set_dmac(&work->path[0],
 				 cm_id_priv->av.ah_attr.roce.dmac);
+		sa_path_set_roce_route_resolved(&work->path[0], false);
+	}
 	work->path[0].hop_limit = grh->hop_limit;
 	ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av,
 				 cm_id_priv);
@@ -1958,6 +1960,9 @@ static int cm_req_handler(struct cm_work *work)
 		goto rejected;
 	}
 	if (cm_req_has_alt_path(req_msg)) {
+		if (sa_path_is_roce(&work->path[1]))
+			sa_path_set_roce_route_resolved(&work->path[1], false);
+
 		ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av,
 					 cm_id_priv);
 		if (ret) {
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index a62a5b0ad0dd..dcf8d22ef352 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -2506,6 +2506,7 @@ cma_iboe_set_path_rec_l2_fields(struct rdma_id_private *id_priv)
 		gid_type = ib_network_to_gid_type(addr->dev_addr.network);
 	route->path_rec->rec_type = sa_conv_gid_to_pathrec_type(gid_type);
 
+	sa_path_set_roce_route_resolved(route->path_rec, true);
 	sa_path_set_ndev(route->path_rec, addr->dev_addr.net);
 	sa_path_set_ifindex(route->path_rec, ndev->ifindex);
 	sa_path_set_dmac(route->path_rec, addr->dev_addr.dst_dev_addr);
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 1cfec68c7911..e3ee1bb08c42 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -1327,9 +1327,12 @@ int ib_init_ah_attr_from_path(struct ib_device *device, u8 port_num,
 	rdma_ah_set_static_rate(ah_attr, rec->rate);
 
 	if (sa_path_is_roce(rec)) {
-		ret = roce_resolve_route_from_path(device, port_num, rec);
-		if (ret)
-			return ret;
+		if (!sa_path_roce_is_route_resolved(rec)) {
+			ret = roce_resolve_route_from_path(device, port_num,
+							   rec);
+			if (ret)
+				return ret;
+		}
 
 		memcpy(ah_attr->roce.dmac, sa_path_get_dmac(rec), ETH_ALEN);
 	} else {
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
index 82b8e59af14a..66b20d28e01d 100644
--- a/include/rdma/ib_sa.h
+++ b/include/rdma/ib_sa.h
@@ -163,7 +163,17 @@ struct sa_path_rec_ib {
 	u8           raw_traffic;
 };
 
+/**
+ * struct sa_path_rec_roce - RoCE specific portion of the path record entry
+ * @route_resolved:	When set, it indicates that this route is already
+ *			resolved for this path record entry.
+ * @dmac:		Destination mac address for the given DGID entry
+ *			of the path record entry.
+ */
 struct sa_path_rec_roce {
+	bool	route_resolved;	/* Indicates that route is resolved for this
+				 * path record entry.
+				 */
 	u8           dmac[ETH_ALEN];
 	/* ignored in IB */
 	int	     ifindex;
@@ -551,6 +561,10 @@ int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num,
 /**
  * ib_init_ah_attr_from_path - Initialize address handle attributes based on
  *   an SA path record.
+ * @device: Device associated ah attributes initialization.
+ * @port_num: Port on the specified device.
+ * @rec: path record entry to use for ah attributes initialization.
+ * @ah_attr: address handle attributes to initialization from path record.
  */
 int ib_init_ah_attr_from_path(struct ib_device *device, u8 port_num,
 			      struct sa_path_rec *rec,
@@ -647,6 +661,18 @@ static inline u8 sa_path_get_raw_traffic(struct sa_path_rec *rec)
 	return 0;
 }
 
+static inline void
+sa_path_set_roce_route_resolved(struct sa_path_rec *rec, bool resolved)
+{
+	rec->roce.route_resolved = resolved;
+}
+
+static inline bool
+sa_path_roce_is_route_resolved(const struct sa_path_rec *rec)
+{
+	return rec->roce.route_resolved;
+}
+
 static inline void sa_path_set_dmac(struct sa_path_rec *rec, u8 *dmac)
 {
 	if (sa_path_is_roce(rec))
-- 
2.16.2

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux