Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dfa834e1 authored by Dasaratharaman Chandramouli's avatar Dasaratharaman Chandramouli Committed by Doug Ledford
Browse files

IB/SA: Introduce path record specific types



struct sa_path_rec has a gid_type field. This patch introduces a more
generic path record specific type 'rec_type' which is either IB, ROCE v1
or ROCE v2. The patch also provides conversion functions to get
a gid type from a path record type and vice versa

Reviewed-by: default avatarDon Hiatt <don.hiatt@intel.com>
Reviewed-by: default avatarIra Weiny <ira.weiny@intel.com>
Signed-off-by: default avatarDasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent c2f8fc4e
Loading
Loading
Loading
Loading
+12 −3
Original line number Original line Diff line number Diff line
@@ -453,7 +453,8 @@ static int cm_init_av_by_path(struct sa_path_rec *path, struct cm_av *av,
	read_lock_irqsave(&cm.device_lock, flags);
	read_lock_irqsave(&cm.device_lock, flags);
	list_for_each_entry(cm_dev, &cm.device_list, list) {
	list_for_each_entry(cm_dev, &cm.device_list, list) {
		if (!ib_find_cached_gid(cm_dev->ib_device, &path->sgid,
		if (!ib_find_cached_gid(cm_dev->ib_device, &path->sgid,
					path->gid_type, ndev, &p, NULL)) {
					sa_conv_pathrec_to_gid_type(path),
					ndev, &p, NULL)) {
			port = cm_dev->port[p-1];
			port = cm_dev->port[p-1];
			break;
			break;
		}
		}
@@ -1775,8 +1776,11 @@ static int cm_req_handler(struct cm_work *work)
			work->path[0].ifindex = gid_attr.ndev->ifindex;
			work->path[0].ifindex = gid_attr.ndev->ifindex;
			work->path[0].net = dev_net(gid_attr.ndev);
			work->path[0].net = dev_net(gid_attr.ndev);
			dev_put(gid_attr.ndev);
			dev_put(gid_attr.ndev);
			work->path[0].rec_type =
				sa_conv_gid_to_pathrec_type(gid_attr.gid_type);
		} else {
			work->path[0].rec_type = SA_PATH_REC_TYPE_IB;
		}
		}
		work->path[0].gid_type = gid_attr.gid_type;
		ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av,
		ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av,
					 cm_id_priv);
					 cm_id_priv);
	}
	}
@@ -1789,8 +1793,13 @@ static int cm_req_handler(struct cm_work *work)
			work->path[0].ifindex = gid_attr.ndev->ifindex;
			work->path[0].ifindex = gid_attr.ndev->ifindex;
			work->path[0].net = dev_net(gid_attr.ndev);
			work->path[0].net = dev_net(gid_attr.ndev);
			dev_put(gid_attr.ndev);
			dev_put(gid_attr.ndev);
			work->path[0].rec_type =
				sa_conv_gid_to_pathrec_type(gid_attr.gid_type);
		} else {
			work->path[0].rec_type = SA_PATH_REC_TYPE_IB;
		}
		}
		work->path[0].gid_type = gid_attr.gid_type;
		if (req_msg->alt_local_lid)
			work->path[1].rec_type = work->path[0].rec_type;
		ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID,
		ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID,
			       &work->path[0].sgid, sizeof work->path[0].sgid,
			       &work->path[0].sgid, sizeof work->path[0].sgid,
			       NULL, 0);
			       NULL, 0);
+10 −6
Original line number Original line Diff line number Diff line
@@ -2532,6 +2532,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
	struct cma_work *work;
	struct cma_work *work;
	int ret;
	int ret;
	struct net_device *ndev = NULL;
	struct net_device *ndev = NULL;
	enum ib_gid_type gid_type = IB_GID_TYPE_IB;
	u8 default_roce_tos = id_priv->cma_dev->default_roce_tos[id_priv->id.port_num -
	u8 default_roce_tos = id_priv->cma_dev->default_roce_tos[id_priv->id.port_num -
					rdma_start_port(id_priv->cma_dev->device)];
					rdma_start_port(id_priv->cma_dev->device)];
	u8 tos = id_priv->tos_set ? id_priv->tos : default_roce_tos;
	u8 tos = id_priv->tos_set ? id_priv->tos : default_roce_tos;
@@ -2580,10 +2581,11 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
		route->path_rec->ifindex = ndev->ifindex;
		route->path_rec->ifindex = ndev->ifindex;
		supported_gids = roce_gid_type_mask_support(id_priv->id.device,
		supported_gids = roce_gid_type_mask_support(id_priv->id.device,
							    id_priv->id.port_num);
							    id_priv->id.port_num);
		route->path_rec->gid_type =
		gid_type = cma_route_gid_type(addr->dev_addr.network,
			cma_route_gid_type(addr->dev_addr.network,
					      supported_gids,
					      supported_gids,
					      id_priv->gid_type);
					      id_priv->gid_type);
		route->path_rec->rec_type =
			sa_conv_gid_to_pathrec_type(gid_type);
	}
	}
	if (!ndev) {
	if (!ndev) {
		ret = -ENODEV;
		ret = -ENODEV;
@@ -2598,8 +2600,10 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
		    &route->path_rec->dgid);
		    &route->path_rec->dgid);


	/* Use the hint from IP Stack to select GID Type */
	/* Use the hint from IP Stack to select GID Type */
	if (route->path_rec->gid_type < ib_network_to_gid_type(addr->dev_addr.network))
	if (gid_type < ib_network_to_gid_type(addr->dev_addr.network))
		route->path_rec->gid_type = ib_network_to_gid_type(addr->dev_addr.network);
		gid_type = ib_network_to_gid_type(addr->dev_addr.network);
	route->path_rec->rec_type = sa_conv_gid_to_pathrec_type(gid_type);

	if (((struct sockaddr *)&id_priv->id.route.addr.dst_addr)->sa_family != AF_IB)
	if (((struct sockaddr *)&id_priv->id.route.addr.dst_addr)->sa_family != AF_IB)
		/* TODO: get the hoplimit from the inet/inet6 device */
		/* TODO: get the hoplimit from the inet/inet6 device */
		route->path_rec->hop_limit = addr->dev_addr.hoplimit;
		route->path_rec->hop_limit = addr->dev_addr.hoplimit;
+9 −5
Original line number Original line Diff line number Diff line
@@ -1144,7 +1144,7 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,


		if ((dev_addr.network == RDMA_NETWORK_IPV4 ||
		if ((dev_addr.network == RDMA_NETWORK_IPV4 ||
		     dev_addr.network == RDMA_NETWORK_IPV6) &&
		     dev_addr.network == RDMA_NETWORK_IPV6) &&
		    rec->gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
		    rec->rec_type != SA_PATH_REC_TYPE_ROCE_V2)
			return -EINVAL;
			return -EINVAL;


		idev = device->get_netdev(device, port_num);
		idev = device->get_netdev(device, port_num);
@@ -1175,9 +1175,10 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
	}
	}


	if (rec->hop_limit > 0 || use_roce) {
	if (rec->hop_limit > 0 || use_roce) {
		ret = ib_find_cached_gid_by_port(device, &rec->sgid,
		enum ib_gid_type type = sa_conv_pathrec_to_gid_type(rec);
						 rec->gid_type, port_num, ndev,

						 &gid_index);
		ret = ib_find_cached_gid_by_port(device, &rec->sgid, type,
						 port_num, ndev, &gid_index);
		if (ret) {
		if (ret) {
			if (ndev)
			if (ndev)
				dev_put(ndev);
				dev_put(ndev);
@@ -1327,7 +1328,7 @@ static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
			  mad->data, &rec);
			  mad->data, &rec);
		rec.net = NULL;
		rec.net = NULL;
		rec.ifindex = 0;
		rec.ifindex = 0;
		rec.gid_type = IB_GID_TYPE_IB;
		rec.rec_type = SA_PATH_REC_TYPE_IB;
		eth_zero_addr(rec.dmac);
		eth_zero_addr(rec.dmac);
		query->callback(status, &rec, query->context);
		query->callback(status, &rec, query->context);
	} else
	} else
@@ -1385,6 +1386,9 @@ int ib_sa_path_rec_get(struct ib_sa_client *client,
	if (!sa_dev)
	if (!sa_dev)
		return -ENODEV;
		return -ENODEV;


	if (rec->rec_type != SA_PATH_REC_TYPE_IB)
		return -EINVAL;

	port  = &sa_dev->port[port_num - sa_dev->start_port];
	port  = &sa_dev->port[port_num - sa_dev->start_port];
	agent = port->agent;
	agent = port->agent;


+1 −1
Original line number Original line Diff line number Diff line
@@ -149,6 +149,6 @@ void ib_copy_path_rec_from_user(struct sa_path_rec *dst,
	memset(dst->dmac, 0, sizeof(dst->dmac));
	memset(dst->dmac, 0, sizeof(dst->dmac));
	dst->net = NULL;
	dst->net = NULL;
	dst->ifindex = 0;
	dst->ifindex = 0;
	dst->gid_type = IB_GID_TYPE_IB;
	dst->rec_type = SA_PATH_REC_TYPE_IB;
}
}
EXPORT_SYMBOL(ib_copy_path_rec_from_user);
EXPORT_SYMBOL(ib_copy_path_rec_from_user);
+32 −1
Original line number Original line Diff line number Diff line
@@ -147,6 +147,11 @@ enum ib_sa_mc_join_states {
#define IB_SA_PATH_REC_PACKET_LIFE_TIME_SELECTOR	IB_SA_COMP_MASK(20)
#define IB_SA_PATH_REC_PACKET_LIFE_TIME_SELECTOR	IB_SA_COMP_MASK(20)
#define IB_SA_PATH_REC_PACKET_LIFE_TIME			IB_SA_COMP_MASK(21)
#define IB_SA_PATH_REC_PACKET_LIFE_TIME			IB_SA_COMP_MASK(21)
#define IB_SA_PATH_REC_PREFERENCE			IB_SA_COMP_MASK(22)
#define IB_SA_PATH_REC_PREFERENCE			IB_SA_COMP_MASK(22)
enum sa_path_rec_type {
	SA_PATH_REC_TYPE_IB,
	SA_PATH_REC_TYPE_ROCE_V1,
	SA_PATH_REC_TYPE_ROCE_V2
};


struct sa_path_rec {
struct sa_path_rec {
	__be64       service_id;
	__be64       service_id;
@@ -176,7 +181,7 @@ struct sa_path_rec {
	int	     ifindex;
	int	     ifindex;
	/* ignored in IB */
	/* ignored in IB */
	struct net  *net;
	struct net  *net;
	enum ib_gid_type gid_type;
	enum sa_path_rec_type rec_type;
};
};


static inline struct net_device *ib_get_ndev_from_path(struct sa_path_rec *rec)
static inline struct net_device *ib_get_ndev_from_path(struct sa_path_rec *rec)
@@ -184,6 +189,32 @@ static inline struct net_device *ib_get_ndev_from_path(struct sa_path_rec *rec)
	return rec->net ? dev_get_by_index(rec->net, rec->ifindex) : NULL;
	return rec->net ? dev_get_by_index(rec->net, rec->ifindex) : NULL;
}
}


static inline enum ib_gid_type
		sa_conv_pathrec_to_gid_type(struct sa_path_rec *rec)
{
	switch (rec->rec_type) {
	case SA_PATH_REC_TYPE_ROCE_V1:
		return IB_GID_TYPE_ROCE;
	case SA_PATH_REC_TYPE_ROCE_V2:
		return IB_GID_TYPE_ROCE_UDP_ENCAP;
	default:
		return IB_GID_TYPE_IB;
	}
}

static inline enum sa_path_rec_type
		sa_conv_gid_to_pathrec_type(enum ib_gid_type type)
{
	switch (type) {
	case IB_GID_TYPE_ROCE:
		return SA_PATH_REC_TYPE_ROCE_V1;
	case IB_GID_TYPE_ROCE_UDP_ENCAP:
		return SA_PATH_REC_TYPE_ROCE_V2;
	default:
		return SA_PATH_REC_TYPE_IB;
	}
}

#define IB_SA_MCMEMBER_REC_MGID				IB_SA_COMP_MASK( 0)
#define IB_SA_MCMEMBER_REC_MGID				IB_SA_COMP_MASK( 0)
#define IB_SA_MCMEMBER_REC_PORT_GID			IB_SA_COMP_MASK( 1)
#define IB_SA_MCMEMBER_REC_PORT_GID			IB_SA_COMP_MASK( 1)
#define IB_SA_MCMEMBER_REC_QKEY				IB_SA_COMP_MASK( 2)
#define IB_SA_MCMEMBER_REC_QKEY				IB_SA_COMP_MASK( 2)