diff mbox series

[ibacm,v2,2/2] ibacm: acme supports only one port

Message ID 3c979b69a5f654b6ae2c43b90a87e70bb16c92ea.1546850468.git.haakon.bugge@oracle.com (mailing list archive)
State Not Applicable
Headers show
Series ibacm: acme supports only one port | expand

Commit Message

Haakon Bugge Jan. 7, 2019, 8:45 a.m. UTC
acme can display end-point information. This is implemented in acm by
iterating through all end-points and their ports, until the end-point
indexes match.

This implies, considering a multi-ported device, that the address
information associated with the first port is the only one displayed.

Before this commit:

 # ibstat | grep ports
	Number of ports: 2
 # ib_acme -e
svc,guid,port,pkey,ep_index,prov,addr_0,addresses
ibacm-unix.sock,0x0021280001a17c96,1,0xffff,1,ibacmp,lab36,lab36-1,192.168.2.2

Fixed by adding port_num to the equation, and the above command will
yield:

 # ib_acme -e
svc,guid,port,pkey,ep_index,prov,addr_0,addresses
ibacm-unix.sock,0x0021280001a17c96,1,0xffff,1,ibacmp,192.168.2.2,lab36,lab36-1
ibacm-unix.sock,0x0021280001a17c96,2,0xffff,1,ibacmp,192.168.2.3,lab36-2

Signed-off-by: HÃ¥kon Bugge <haakon.bugge@oracle.com>

---

v1 -> v2:
   * Incorporated review comments from Doug
   * Fixed a memory leak in enumerate_ep() introduced by v1
   * Hardened enumerate_ep() related to the first EP being unavailable
---
 ibacm/include/infiniband/acm.h |  6 ++--
 ibacm/src/acm.c                | 11 +++++--
 ibacm/src/acme.c               | 36 ++++++++++++++---------
 ibacm/src/libacm.c             | 53 +++++++++++++++++++++++-----------
 ibacm/src/libacm.h             |  2 +-
 5 files changed, 71 insertions(+), 37 deletions(-)
diff mbox series

Patch

diff --git a/ibacm/include/infiniband/acm.h b/ibacm/include/infiniband/acm.h
index f6efee18..90f3d431 100644
--- a/ibacm/include/infiniband/acm.h
+++ b/ibacm/include/infiniband/acm.h
@@ -73,7 +73,8 @@  struct acm_hdr {
 	uint8_t                 version;
 	uint8_t                 opcode;
 	uint8_t                 status;
-	uint8_t		        data[3];
+	uint8_t			port_num;
+	uint8_t		        data[2];
 	uint16_t                length;
 	uint64_t                tid;
 };
@@ -135,7 +136,8 @@  struct acm_perf_msg {
 struct acm_ep_config_data {
 	uint64_t                dev_guid;
 	uint8_t                 port_num;
-	uint8_t                 rsvd[3];
+	uint8_t			phys_port_cnt;
+	uint8_t                 rsvd[2];
 	uint16_t                pkey;
 	uint16_t                addr_cnt;
 	uint8_t                 prov_name[ACM_MAX_PROV_NAME];
diff --git a/ibacm/src/acm.c b/ibacm/src/acm.c
index 6453c5f0..8f25f34b 100644
--- a/ibacm/src/acm.c
+++ b/ibacm/src/acm.c
@@ -876,7 +876,9 @@  static struct acmc_addr *acm_get_ep_address(struct acm_ep_addr_data *data)
 	return NULL;
 }
 
-static struct acmc_ep *acm_get_ep(int index)
+/* If port_num is zero, iterate through all ports, otherwise consider
+ * only the specific port_num */
+static struct acmc_ep *acm_get_ep(int index, uint8_t port_num)
 {
 	struct acmc_device *dev;
 	struct acmc_ep *ep;
@@ -885,6 +887,8 @@  static struct acmc_ep *acm_get_ep(int index)
 	acm_log(2, "ep index %d\n", index);
 	list_for_each(&dev_list, dev, entry) {
 		for (i = 0; i < dev->port_cnt; i++) {
+			if (port_num && port_num != (i + 1))
+				continue;
 			if (dev->port[i].state != IBV_PORT_ACTIVE)
 				continue;
 			list_for_each(&dev->port[i].ep_list, ep, entry) {
@@ -1156,7 +1160,7 @@  static int acm_svr_perf_query(struct acmc_client *client, struct acm_msg *msg)
 		len = ACM_MSG_HDR_LENGTH + (ACM_MAX_COUNTER * sizeof(uint64_t));
 	} else {
 		if (index >= 1) {
-			ep = acm_get_ep(index - 1);
+			ep = acm_get_ep(index - 1, msg->hdr.port_num);
 		} else {
 			addr = acm_get_ep_address(&msg->resolve_data[0]);
 			if (addr)
@@ -1193,11 +1197,12 @@  static int acm_svr_ep_query(struct acmc_client *client, struct acm_msg *msg)
 
 	acm_log(2, "client %d\n", client->index);
 	index = msg->hdr.data[0];
-	ep = acm_get_ep(index - 1);
+	ep = acm_get_ep(index - 1, msg->hdr.port_num);
 	if (ep) {
 		msg->hdr.status = ACM_STATUS_SUCCESS;
 		msg->ep_data[0].dev_guid = ep->port->dev->device.dev_guid;
 		msg->ep_data[0].port_num = ep->port->port.port_num;
+		msg->ep_data[0].phys_port_cnt = ep->port->dev->port_cnt;
 		msg->ep_data[0].pkey = htobe16(ep->endpoint.pkey);
 		strncpy((char *)msg->ep_data[0].prov_name, ep->port->prov->name,
 			ACM_MAX_PROV_NAME - 1);
diff --git a/ibacm/src/acme.c b/ibacm/src/acme.c
index b592b977..1289fa36 100644
--- a/ibacm/src/acme.c
+++ b/ibacm/src/acme.c
@@ -926,24 +926,32 @@  static int enumerate_ep(char *svc, int index)
 	static int labels;
 	int ret, i;
 	struct acm_ep_config_data *ep_data;
+	int phys_port_cnt = 255;
+	int found = 0;
+	int port;
 
-	ret = ib_acm_enum_ep(index, &ep_data);
-	if (ret)
-		return ret;
+	for (port = 1; port <= phys_port_cnt; ++port)  {
+		ret = ib_acm_enum_ep(index, &ep_data, port);
+		if (ret)
+			continue;
 
-	if (!labels) {
-		printf("svc,guid,port,pkey,ep_index,prov,addr_0,addresses\n");
-		labels = 1;
-	}
+		found = 1;
 
-	printf("%s,0x%016" PRIx64 ",%d,0x%04x,%d,%s", svc, ep_data->dev_guid,
-	       ep_data->port_num, ep_data->pkey, index, ep_data->prov_name);
-	for (i = 0; i < ep_data->addr_cnt; i++)
-		printf(",%s", ep_data->addrs[i].name);
-	printf("\n");
-	ib_acm_free_ep_data(ep_data);
+		if (!labels) {
+			printf("svc,guid,port,pkey,ep_index,prov,addr_0,addresses\n");
+			labels = 1;
+		}
 
-	return 0;
+		printf("%s,0x%016" PRIx64 ",%d,0x%04x,%d,%s", svc, ep_data->dev_guid,
+			ep_data->port_num, ep_data->pkey, index, ep_data->prov_name);
+		for (i = 0; i < ep_data->addr_cnt; i++)
+			printf(",%s", ep_data->addrs[i].name);
+		printf("\n");
+		phys_port_cnt = ep_data->phys_port_cnt;
+		ib_acm_free_ep_data(ep_data);
+	}
+
+	return !found;
 }
 
 static void enumerate_eps(char *svc)
diff --git a/ibacm/src/libacm.c b/ibacm/src/libacm.c
index 1d9d7145..92f5baf9 100644
--- a/ibacm/src/libacm.c
+++ b/ibacm/src/libacm.c
@@ -382,18 +382,21 @@  out:
 	return ret;
 }
 
-int ib_acm_enum_ep(int index, struct acm_ep_config_data **data)
+int ib_acm_enum_ep(int index, struct acm_ep_config_data **data, uint8_t port)
 {
+	struct acm_ep_config_data *netw_edata = NULL;
+	struct acm_ep_config_data *host_edata = NULL;
+	struct acm_hdr hdr;
 	struct acm_msg msg;
 	int ret;
 	int len;
-	int cnt;
-	struct acm_ep_config_data *edata;
+	int i;
 
 	pthread_mutex_lock(&acm_lock);
 	memset(&msg, 0, sizeof msg);
 	msg.hdr.version = ACM_VERSION;
 	msg.hdr.opcode = ACM_OP_EP_QUERY;
+	msg.hdr.port_num = port;
 	msg.hdr.data[0] = index;
 	msg.hdr.length = htobe16(ACM_MSG_HDR_LENGTH);
 
@@ -401,33 +404,49 @@  int ib_acm_enum_ep(int index, struct acm_ep_config_data **data)
 	if (ret != ACM_MSG_HDR_LENGTH)
 		goto out;
 
-	ret = recv(sock, (char *) &msg, sizeof msg, 0);
-	if (ret < ACM_MSG_HDR_LENGTH || ret != be16toh(msg.hdr.length)) {
+	ret = recv(sock, (char *) &hdr, sizeof(hdr), 0);
+	if (ret != sizeof(hdr)) {
 		ret = ACM_STATUS_EINVAL;
 		goto out;
 	}
 
-	if (msg.hdr.status) {
-		ret = acm_error(msg.hdr.status);
+	if (hdr.status) {
+		ret = acm_error(hdr.status);
 		goto out;
 	}
 
-	cnt = be16toh(msg.ep_data[0].addr_cnt);
-	len = sizeof(struct acm_ep_config_data) +
-		ACM_MAX_ADDRESS * cnt;
-	edata = malloc(len);
-	if (!edata) {
+	len = be16toh(hdr.length) - sizeof(hdr);
+	netw_edata = (struct acm_ep_config_data *)malloc(len);
+	host_edata = (struct acm_ep_config_data *)malloc(len);
+	if (!netw_edata || !host_edata) {
 		ret = ACM_STATUS_ENOMEM;
 		goto out;
 	}
 
-	memcpy(edata, &msg.ep_data[0], len);
-	edata->dev_guid = be64toh(msg.ep_data[0].dev_guid);
-	edata->pkey = be16toh(msg.ep_data[0].pkey);
-	edata->addr_cnt = cnt;
-	*data = edata;
+	ret = recv(sock, (char *)netw_edata, len, 0);
+	if (ret != len) {
+		ret = ACM_STATUS_EINVAL;
+		goto out;
+	}
+
+	host_edata->dev_guid = be64toh(netw_edata->dev_guid);
+	host_edata->port_num = netw_edata->port_num;
+	host_edata->phys_port_cnt = netw_edata->phys_port_cnt;
+	host_edata->pkey = be16toh(netw_edata->pkey);
+	host_edata->addr_cnt = be16toh(netw_edata->addr_cnt);
+
+	memcpy(host_edata->prov_name, netw_edata->prov_name,
+	       sizeof(host_edata->prov_name));
+
+	for (i = 0; i < host_edata->addr_cnt; ++i)
+		host_edata->addrs[i] = netw_edata->addrs[i];
+
+	*data = host_edata;
 	ret = 0;
 out:
+	free(netw_edata);
+	if (ret)
+		free(host_edata);
 	pthread_mutex_unlock(&acm_lock);
 	return ret;
 }
diff --git a/ibacm/src/libacm.h b/ibacm/src/libacm.h
index bf8cb79b..fb81b417 100644
--- a/ibacm/src/libacm.h
+++ b/ibacm/src/libacm.h
@@ -54,7 +54,7 @@  int ib_acm_query_perf_ep_addr(uint8_t *src, uint8_t type,
 
 const char *ib_acm_cntr_name(int index);
 
-int ib_acm_enum_ep(int index, struct acm_ep_config_data **data);
+int ib_acm_enum_ep(int index, struct acm_ep_config_data **data, uint8_t port);
 #define ib_acm_free_ep_data(data) free(data)
 
 #endif /* LIBACM_H */