aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>2017-04-28 19:20:26 -0400
committerDoug Ledford <dledford@redhat.com>2017-04-28 19:29:42 -0400
commit2196f2716292c39b35c86f5238ed16a8978f9ad4 (patch)
treeafceebb9d0069d86f2d2f0f194c3f885c60e3d13
parentaa4656d9a4292018c9746dbad1dad5488e575232 (diff)
IB/SA: Add support to query opa classport info.
For OPA devices, SA will query the OPA classport info instead of the IB defined classport info. opa classport info exposes additional information and capabilities that are specific to OPA devices. Reviewed-by: Ira Weiny <ira.weiny@intel.com> Reviewed-by: Don Hiatt <don.hiatt@intel.com> Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/core/sa_query.c182
-rw-r--r--include/rdma/ib_sa.h1
2 files changed, 158 insertions, 25 deletions
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 8a4b1f030e52..b57bdc257fcf 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -67,10 +67,23 @@ struct ib_sa_sm_ah {
67 u8 src_path_mask; 67 u8 src_path_mask;
68}; 68};
69 69
70enum rdma_class_port_info_type {
71 RDMA_CLASS_PORT_INFO_IB,
72 RDMA_CLASS_PORT_INFO_OPA
73};
74
75struct rdma_class_port_info {
76 enum rdma_class_port_info_type type;
77 union {
78 struct ib_class_port_info ib;
79 struct opa_class_port_info opa;
80 };
81};
82
70struct ib_sa_classport_cache { 83struct ib_sa_classport_cache {
71 bool valid; 84 bool valid;
72 int retry_cnt; 85 int retry_cnt;
73 struct ib_class_port_info data; 86 struct rdma_class_port_info data;
74}; 87};
75 88
76struct ib_sa_port { 89struct ib_sa_port {
@@ -107,6 +120,7 @@ struct ib_sa_query {
107 120
108#define IB_SA_ENABLE_LOCAL_SERVICE 0x00000001 121#define IB_SA_ENABLE_LOCAL_SERVICE 0x00000001
109#define IB_SA_CANCEL 0x00000002 122#define IB_SA_CANCEL 0x00000002
123#define IB_SA_QUERY_OPA 0x00000004
110 124
111struct ib_sa_service_query { 125struct ib_sa_service_query {
112 void (*callback)(int, struct ib_sa_service_rec *, void *); 126 void (*callback)(int, struct ib_sa_service_rec *, void *);
@@ -410,7 +424,7 @@ static const struct ib_field service_rec_table[] = {
410 .struct_size_bytes = sizeof((struct ib_class_port_info *)0)->field, \ 424 .struct_size_bytes = sizeof((struct ib_class_port_info *)0)->field, \
411 .field_name = "ib_class_port_info:" #field 425 .field_name = "ib_class_port_info:" #field
412 426
413static const struct ib_field classport_info_rec_table[] = { 427static const struct ib_field ib_classport_info_rec_table[] = {
414 { CLASSPORTINFO_REC_FIELD(base_version), 428 { CLASSPORTINFO_REC_FIELD(base_version),
415 .offset_words = 0, 429 .offset_words = 0,
416 .offset_bits = 0, 430 .offset_bits = 0,
@@ -481,6 +495,88 @@ static const struct ib_field classport_info_rec_table[] = {
481 .size_bits = 32 }, 495 .size_bits = 32 },
482}; 496};
483 497
498#define OPA_CLASSPORTINFO_REC_FIELD(field) \
499 .struct_offset_bytes =\
500 offsetof(struct opa_class_port_info, field), \
501 .struct_size_bytes = \
502 sizeof((struct opa_class_port_info *)0)->field, \
503 .field_name = "opa_class_port_info:" #field
504
505static const struct ib_field opa_classport_info_rec_table[] = {
506 { OPA_CLASSPORTINFO_REC_FIELD(base_version),
507 .offset_words = 0,
508 .offset_bits = 0,
509 .size_bits = 8 },
510 { OPA_CLASSPORTINFO_REC_FIELD(class_version),
511 .offset_words = 0,
512 .offset_bits = 8,
513 .size_bits = 8 },
514 { OPA_CLASSPORTINFO_REC_FIELD(cap_mask),
515 .offset_words = 0,
516 .offset_bits = 16,
517 .size_bits = 16 },
518 { OPA_CLASSPORTINFO_REC_FIELD(cap_mask2_resp_time),
519 .offset_words = 1,
520 .offset_bits = 0,
521 .size_bits = 32 },
522 { OPA_CLASSPORTINFO_REC_FIELD(redirect_gid),
523 .offset_words = 2,
524 .offset_bits = 0,
525 .size_bits = 128 },
526 { OPA_CLASSPORTINFO_REC_FIELD(redirect_tc_fl),
527 .offset_words = 6,
528 .offset_bits = 0,
529 .size_bits = 32 },
530 { OPA_CLASSPORTINFO_REC_FIELD(redirect_lid),
531 .offset_words = 7,
532 .offset_bits = 0,
533 .size_bits = 32 },
534 { OPA_CLASSPORTINFO_REC_FIELD(redirect_sl_qp),
535 .offset_words = 8,
536 .offset_bits = 0,
537 .size_bits = 32 },
538 { OPA_CLASSPORTINFO_REC_FIELD(redirect_qkey),
539 .offset_words = 9,
540 .offset_bits = 0,
541 .size_bits = 32 },
542 { OPA_CLASSPORTINFO_REC_FIELD(trap_gid),
543 .offset_words = 10,
544 .offset_bits = 0,
545 .size_bits = 128 },
546 { OPA_CLASSPORTINFO_REC_FIELD(trap_tc_fl),
547 .offset_words = 14,
548 .offset_bits = 0,
549 .size_bits = 32 },
550 { OPA_CLASSPORTINFO_REC_FIELD(trap_lid),
551 .offset_words = 15,
552 .offset_bits = 0,
553 .size_bits = 32 },
554 { OPA_CLASSPORTINFO_REC_FIELD(trap_hl_qp),
555 .offset_words = 16,
556 .offset_bits = 0,
557 .size_bits = 32 },
558 { OPA_CLASSPORTINFO_REC_FIELD(trap_qkey),
559 .offset_words = 17,
560 .offset_bits = 0,
561 .size_bits = 32 },
562 { OPA_CLASSPORTINFO_REC_FIELD(trap_pkey),
563 .offset_words = 18,
564 .offset_bits = 0,
565 .size_bits = 16 },
566 { OPA_CLASSPORTINFO_REC_FIELD(redirect_pkey),
567 .offset_words = 18,
568 .offset_bits = 16,
569 .size_bits = 16 },
570 { OPA_CLASSPORTINFO_REC_FIELD(trap_sl_rsvd),
571 .offset_words = 19,
572 .offset_bits = 0,
573 .size_bits = 8 },
574 { RESERVED,
575 .offset_words = 19,
576 .offset_bits = 8,
577 .size_bits = 24 },
578};
579
484#define GUIDINFO_REC_FIELD(field) \ 580#define GUIDINFO_REC_FIELD(field) \
485 .struct_offset_bytes = offsetof(struct ib_sa_guidinfo_rec, field), \ 581 .struct_offset_bytes = offsetof(struct ib_sa_guidinfo_rec, field), \
486 .struct_size_bytes = sizeof((struct ib_sa_guidinfo_rec *) 0)->field, \ 582 .struct_size_bytes = sizeof((struct ib_sa_guidinfo_rec *) 0)->field, \
@@ -1121,7 +1217,9 @@ static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask)
1121 query->sm_ah->pkey_index, 1217 query->sm_ah->pkey_index,
1122 0, IB_MGMT_SA_HDR, IB_MGMT_SA_DATA, 1218 0, IB_MGMT_SA_HDR, IB_MGMT_SA_DATA,
1123 gfp_mask, 1219 gfp_mask,
1124 IB_MGMT_BASE_VERSION); 1220 ((query->flags & IB_SA_QUERY_OPA) ?
1221 OPA_MGMT_BASE_VERSION :
1222 IB_MGMT_BASE_VERSION));
1125 if (IS_ERR(query->mad_buf)) { 1223 if (IS_ERR(query->mad_buf)) {
1126 kref_put(&query->sm_ah->ref, free_sm_ah); 1224 kref_put(&query->sm_ah->ref, free_sm_ah);
1127 return -ENOMEM; 1225 return -ENOMEM;
@@ -1138,16 +1236,21 @@ static void free_mad(struct ib_sa_query *query)
1138 kref_put(&query->sm_ah->ref, free_sm_ah); 1236 kref_put(&query->sm_ah->ref, free_sm_ah);
1139} 1237}
1140 1238
1141static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent) 1239static void init_mad(struct ib_sa_query *query, struct ib_mad_agent *agent)
1142{ 1240{
1241 struct ib_sa_mad *mad = query->mad_buf->mad;
1143 unsigned long flags; 1242 unsigned long flags;
1144 1243
1145 memset(mad, 0, sizeof *mad); 1244 memset(mad, 0, sizeof *mad);
1146 1245
1147 mad->mad_hdr.base_version = IB_MGMT_BASE_VERSION; 1246 if (query->flags & IB_SA_QUERY_OPA) {
1247 mad->mad_hdr.base_version = OPA_MGMT_BASE_VERSION;
1248 mad->mad_hdr.class_version = OPA_SA_CLASS_VERSION;
1249 } else {
1250 mad->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
1251 mad->mad_hdr.class_version = IB_SA_CLASS_VERSION;
1252 }
1148 mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM; 1253 mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
1149 mad->mad_hdr.class_version = IB_SA_CLASS_VERSION;
1150
1151 spin_lock_irqsave(&tid_lock, flags); 1254 spin_lock_irqsave(&tid_lock, flags);
1152 mad->mad_hdr.tid = 1255 mad->mad_hdr.tid =
1153 cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++); 1256 cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++);
@@ -1301,7 +1404,7 @@ int ib_sa_path_rec_get(struct ib_sa_client *client,
1301 query->context = context; 1404 query->context = context;
1302 1405
1303 mad = query->sa_query.mad_buf->mad; 1406 mad = query->sa_query.mad_buf->mad;
1304 init_mad(mad, agent); 1407 init_mad(&query->sa_query, agent);
1305 1408
1306 query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL; 1409 query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL;
1307 query->sa_query.release = ib_sa_path_rec_release; 1410 query->sa_query.release = ib_sa_path_rec_release;
@@ -1426,7 +1529,7 @@ int ib_sa_service_rec_query(struct ib_sa_client *client,
1426 query->context = context; 1529 query->context = context;
1427 1530
1428 mad = query->sa_query.mad_buf->mad; 1531 mad = query->sa_query.mad_buf->mad;
1429 init_mad(mad, agent); 1532 init_mad(&query->sa_query, agent);
1430 1533
1431 query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL; 1534 query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
1432 query->sa_query.release = ib_sa_service_rec_release; 1535 query->sa_query.release = ib_sa_service_rec_release;
@@ -1518,7 +1621,7 @@ int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
1518 query->context = context; 1621 query->context = context;
1519 1622
1520 mad = query->sa_query.mad_buf->mad; 1623 mad = query->sa_query.mad_buf->mad;
1521 init_mad(mad, agent); 1624 init_mad(&query->sa_query, agent);
1522 1625
1523 query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL; 1626 query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL;
1524 query->sa_query.release = ib_sa_mcmember_rec_release; 1627 query->sa_query.release = ib_sa_mcmember_rec_release;
@@ -1615,7 +1718,7 @@ int ib_sa_guid_info_rec_query(struct ib_sa_client *client,
1615 query->context = context; 1718 query->context = context;
1616 1719
1617 mad = query->sa_query.mad_buf->mad; 1720 mad = query->sa_query.mad_buf->mad;
1618 init_mad(mad, agent); 1721 init_mad(&query->sa_query, agent);
1619 1722
1620 query->sa_query.callback = callback ? ib_sa_guidinfo_rec_callback : NULL; 1723 query->sa_query.callback = callback ? ib_sa_guidinfo_rec_callback : NULL;
1621 query->sa_query.release = ib_sa_guidinfo_rec_release; 1724 query->sa_query.release = ib_sa_guidinfo_rec_release;
@@ -1661,9 +1764,10 @@ bool ib_sa_sendonly_fullmem_support(struct ib_sa_client *client,
1661 port = &sa_dev->port[port_num - sa_dev->start_port]; 1764 port = &sa_dev->port[port_num - sa_dev->start_port];
1662 1765
1663 spin_lock_irqsave(&port->classport_lock, flags); 1766 spin_lock_irqsave(&port->classport_lock, flags);
1664 if (port->classport_info.valid) 1767 if ((port->classport_info.valid) &&
1665 ret = ib_get_cpi_capmask2(&port->classport_info.data) & 1768 (port->classport_info.data.type == RDMA_CLASS_PORT_INFO_IB))
1666 IB_SA_CAP_MASK2_SENDONLY_FULL_MEM_SUPPORT; 1769 ret = ib_get_cpi_capmask2(&port->classport_info.data.ib)
1770 & IB_SA_CAP_MASK2_SENDONLY_FULL_MEM_SUPPORT;
1667 spin_unlock_irqrestore(&port->classport_lock, flags); 1771 spin_unlock_irqrestore(&port->classport_lock, flags);
1668 return ret; 1772 return ret;
1669} 1773}
@@ -1688,22 +1792,47 @@ static void ib_sa_classport_info_rec_callback(struct ib_sa_query *sa_query,
1688 unsigned long flags; 1792 unsigned long flags;
1689 struct ib_sa_classport_info_query *query = 1793 struct ib_sa_classport_info_query *query =
1690 container_of(sa_query, struct ib_sa_classport_info_query, sa_query); 1794 container_of(sa_query, struct ib_sa_classport_info_query, sa_query);
1795 struct ib_sa_classport_cache *info = &sa_query->port->classport_info;
1691 1796
1692 if (mad) { 1797 if (mad) {
1693 struct ib_class_port_info rec; 1798 if (sa_query->flags & IB_SA_QUERY_OPA) {
1799 struct opa_class_port_info rec;
1694 1800
1695 ib_unpack(classport_info_rec_table, 1801 ib_unpack(opa_classport_info_rec_table,
1696 ARRAY_SIZE(classport_info_rec_table), 1802 ARRAY_SIZE(opa_classport_info_rec_table),
1697 mad->data, &rec); 1803 mad->data, &rec);
1804
1805 spin_lock_irqsave(&sa_query->port->classport_lock,
1806 flags);
1807 if (!status && !info->valid) {
1808 memcpy(&info->data.opa, &rec,
1809 sizeof(info->data.opa));
1810
1811 info->valid = true;
1812 info->data.type = RDMA_CLASS_PORT_INFO_OPA;
1813 }
1814 spin_unlock_irqrestore(&sa_query->port->classport_lock,
1815 flags);
1816
1817 } else {
1818 struct ib_class_port_info rec;
1698 1819
1699 spin_lock_irqsave(&sa_query->port->classport_lock, flags); 1820 ib_unpack(ib_classport_info_rec_table,
1700 if (!status && !sa_query->port->classport_info.valid) { 1821 ARRAY_SIZE(ib_classport_info_rec_table),
1701 memcpy(&sa_query->port->classport_info.data, &rec, 1822 mad->data, &rec);
1702 sizeof(sa_query->port->classport_info.data));
1703 1823
1704 sa_query->port->classport_info.valid = true; 1824 spin_lock_irqsave(&sa_query->port->classport_lock,
1825 flags);
1826 if (!status && !info->valid) {
1827 memcpy(&info->data.ib, &rec,
1828 sizeof(info->data.ib));
1829
1830 info->valid = true;
1831 info->data.type = RDMA_CLASS_PORT_INFO_IB;
1832 }
1833 spin_unlock_irqrestore(&sa_query->port->classport_lock,
1834 flags);
1705 } 1835 }
1706 spin_unlock_irqrestore(&sa_query->port->classport_lock, flags);
1707 } 1836 }
1708 query->callback(query->context); 1837 query->callback(query->context);
1709} 1838}
@@ -1733,6 +1862,9 @@ static int ib_sa_classport_info_rec_query(struct ib_sa_port *port,
1733 return -ENOMEM; 1862 return -ENOMEM;
1734 1863
1735 query->sa_query.port = port; 1864 query->sa_query.port = port;
1865 query->sa_query.flags |= rdma_cap_opa_ah(port->agent->device,
1866 port->port_num) ?
1867 IB_SA_QUERY_OPA : 0;
1736 ret = alloc_mad(&query->sa_query, gfp_mask); 1868 ret = alloc_mad(&query->sa_query, gfp_mask);
1737 if (ret) 1869 if (ret)
1738 goto err_free; 1870 goto err_free;
@@ -1741,7 +1873,7 @@ static int ib_sa_classport_info_rec_query(struct ib_sa_port *port,
1741 query->context = context; 1873 query->context = context;
1742 1874
1743 mad = query->sa_query.mad_buf->mad; 1875 mad = query->sa_query.mad_buf->mad;
1744 init_mad(mad, agent); 1876 init_mad(&query->sa_query, agent);
1745 1877
1746 query->sa_query.callback = ib_sa_classport_info_rec_callback; 1878 query->sa_query.callback = ib_sa_classport_info_rec_callback;
1747 query->sa_query.release = ib_sa_classport_info_rec_release; 1879 query->sa_query.release = ib_sa_classport_info_rec_release;
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
index 46838c8abb51..843b56288ecf 100644
--- a/include/rdma/ib_sa.h
+++ b/include/rdma/ib_sa.h
@@ -56,6 +56,7 @@ enum {
56 IB_SA_METHOD_GET_TRACE_TBL = 0x13 56 IB_SA_METHOD_GET_TRACE_TBL = 0x13
57}; 57};
58 58
59#define OPA_SA_CLASS_VERSION 0x80
59enum { 60enum {
60 IB_SA_ATTR_CLASS_PORTINFO = 0x01, 61 IB_SA_ATTR_CLASS_PORTINFO = 0x01,
61 IB_SA_ATTR_NOTICE = 0x02, 62 IB_SA_ATTR_NOTICE = 0x02,