Message ID | 1464202927-14979-3-git-send-email-erezsh@mellanox.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
On 5/25/2016 3:02 PM, Erez Shitrit wrote: > New SA query function to return the ClassPortInfo struct from the SA. > If the SM supports FullMemberSendOnly mode for MCG's, it sets a > capability bit in the capability_mask2 field of the response. > > Signed-off-by: Erez Shitrit <erezsh@mellanox.com> > Reviewed-by: Leon Romanovsky <leonro@mellanox.com> Just a nit below: > --- > drivers/infiniband/core/sa_query.c | 173 +++++++++++++++++++++++++++++++++++++ > include/rdma/ib_sa.h | 12 +++ > 2 files changed, 185 insertions(+) > > diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c > index 3ebd108..5c37f2f 100644 > --- a/drivers/infiniband/core/sa_query.c > +++ b/drivers/infiniband/core/sa_query.c > @@ -119,6 +119,12 @@ struct ib_sa_guidinfo_query { > struct ib_sa_query sa_query; > }; > > +struct ib_sa_classport_info_query { > + void (*callback)(int, struct ib_class_port_info *, void *); > + void *context; > + struct ib_sa_query sa_query; > +}; > + > struct ib_sa_mcmember_query { > void (*callback)(int, struct ib_sa_mcmember_rec *, void *); > void *context; > @@ -392,6 +398,82 @@ static const struct ib_field service_rec_table[] = { > .size_bits = 2*64 }, > }; > > +#define CLASSPORTINFO_REC_FIELD(field) \ > + .struct_offset_bytes = offsetof(struct ib_class_port_info, field), \ > + .struct_size_bytes = sizeof((struct ib_class_port_info *)0)->field, \ > + .field_name = "ib_class_port_info:" #field > + > +static const struct ib_field classport_info_rec_table[] = { > + { CLASSPORTINFO_REC_FIELD(base_version), > + .offset_words = 0, > + .offset_bits = 0, > + .size_bits = 8 }, > + { CLASSPORTINFO_REC_FIELD(class_version), > + .offset_words = 0, > + .offset_bits = 8, > + .size_bits = 8 }, > + { CLASSPORTINFO_REC_FIELD(capability_mask), > + .offset_words = 0, > + .offset_bits = 16, > + .size_bits = 16 }, > + { CLASSPORTINFO_REC_FIELD(cap_mask2_resp_time), > + .offset_words = 1, > + .offset_bits = 0, > + .size_bits = 32 }, > + { CLASSPORTINFO_REC_FIELD(redirect_gid), > + .offset_words = 2, > + .offset_bits = 0, > + .size_bits = 128 }, > + { CLASSPORTINFO_REC_FIELD(redirect_tcslfl), > + .offset_words = 6, > + .offset_bits = 0, > + .size_bits = 32 }, > + { CLASSPORTINFO_REC_FIELD(redirect_lid), > + .offset_words = 7, > + .offset_bits = 0, > + .size_bits = 16 }, > + { CLASSPORTINFO_REC_FIELD(redirect_pkey), > + .offset_words = 7, > + .offset_bits = 16, > + .size_bits = 16 }, > + > + { CLASSPORTINFO_REC_FIELD(redirect_qp), > + .offset_words = 8, > + .offset_bits = 0, > + .size_bits = 32 }, > + { CLASSPORTINFO_REC_FIELD(redirect_qkey), > + .offset_words = 9, > + .offset_bits = 0, > + .size_bits = 32 }, > + > + { CLASSPORTINFO_REC_FIELD(trap_gid), > + .offset_words = 10, > + .offset_bits = 0, > + .size_bits = 128 }, > + { CLASSPORTINFO_REC_FIELD(trap_tcslfl), > + .offset_words = 14, > + .offset_bits = 0, > + .size_bits = 32 }, > + > + { CLASSPORTINFO_REC_FIELD(trap_lid), > + .offset_words = 15, > + .offset_bits = 0, > + .size_bits = 16 }, > + { CLASSPORTINFO_REC_FIELD(trap_pkey), > + .offset_words = 15, > + .offset_bits = 16, > + .size_bits = 16 }, > + > + { CLASSPORTINFO_REC_FIELD(trap_hlqp), > + .offset_words = 16, > + .offset_bits = 0, > + .size_bits = 32 }, > + { CLASSPORTINFO_REC_FIELD(trap_qkey), > + .offset_words = 17, > + .offset_bits = 0, > + .size_bits = 32 }, > +}; > + > #define GUIDINFO_REC_FIELD(field) \ > .struct_offset_bytes = offsetof(struct ib_sa_guidinfo_rec, field), \ > .struct_size_bytes = sizeof((struct ib_sa_guidinfo_rec *) 0)->field, \ > @@ -1645,6 +1727,97 @@ err1: > } > EXPORT_SYMBOL(ib_sa_guid_info_rec_query); > > +/* Support get SA ClassPortInfo */ > +static void ib_sa_classport_info_rec_callback(struct ib_sa_query *sa_query, > + int status, > + struct ib_sa_mad *mad) > +{ > + struct ib_sa_classport_info_query *query = > + container_of(sa_query, struct ib_sa_classport_info_query, sa_query); > + > + if (mad) { > + struct ib_class_port_info rec; > + > + ib_unpack(classport_info_rec_table, > + ARRAY_SIZE(classport_info_rec_table), > + mad->data, &rec); > + query->callback(status, &rec, query->context); > + } else { > + query->callback(status, NULL, query->context); > + } > +} > + > +static void ib_sa_portclass_info_rec_release(struct ib_sa_query *sa_query) > +{ > + kfree(container_of(sa_query, struct ib_sa_classport_info_query, > + sa_query)); > +} > + Should there be comment block here describing the added routine below like the other query routines have ? Other than that: Reviewed-by: Hal Rosenstock <hal@mellanox.com> > +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, > + struct ib_device *device, u8 port_num, > + int timeout_ms, gfp_t gfp_mask, > + void (*callback)(int status, > + struct ib_class_port_info *resp, > + void *context), > + void *context, > + struct ib_sa_query **sa_query) > +{ > + struct ib_sa_classport_info_query *query; > + struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); > + struct ib_sa_port *port; > + struct ib_mad_agent *agent; > + struct ib_sa_mad *mad; > + int ret; > + > + if (!sa_dev) > + return -ENODEV; > + > + port = &sa_dev->port[port_num - sa_dev->start_port]; > + agent = port->agent; > + > + query = kzalloc(sizeof(*query), gfp_mask); > + if (!query) > + return -ENOMEM; > + > + query->sa_query.port = port; > + ret = alloc_mad(&query->sa_query, gfp_mask); > + if (ret) > + goto err1; > + > + ib_sa_client_get(client); > + query->sa_query.client = client; > + query->callback = callback; > + query->context = context; > + > + mad = query->sa_query.mad_buf->mad; > + init_mad(mad, agent); > + > + query->sa_query.callback = callback ? ib_sa_classport_info_rec_callback : NULL; > + > + query->sa_query.release = ib_sa_portclass_info_rec_release; > + /* support GET only */ > + mad->mad_hdr.method = IB_MGMT_METHOD_GET; > + mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_CLASS_PORTINFO); > + mad->sa_hdr.comp_mask = 0; > + *sa_query = &query->sa_query; > + > + ret = send_mad(&query->sa_query, timeout_ms, gfp_mask); > + if (ret < 0) > + goto err2; > + > + return ret; > + > +err2: > + *sa_query = NULL; > + ib_sa_client_put(query->sa_query.client); > + free_mad(&query->sa_query); > + > +err1: > + kfree(query); > + return ret; > +} > +EXPORT_SYMBOL(ib_sa_classport_info_rec_query); > + > static void send_handler(struct ib_mad_agent *agent, > struct ib_mad_send_wc *mad_send_wc) > { > diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h > index cdc1c81..3840416 100644 > --- a/include/rdma/ib_sa.h > +++ b/include/rdma/ib_sa.h > @@ -94,6 +94,8 @@ enum ib_sa_selector { > IB_SA_BEST = 3 > }; > > +#define IB_SA_CAP_MASK2_SENDONLY_FULL_MEM_SUPPORT BIT(12) > + > /* > * Structures for SA records are named "struct ib_sa_xxx_rec." No > * attempt is made to pack structures to match the physical layout of > @@ -439,4 +441,14 @@ int ib_sa_guid_info_rec_query(struct ib_sa_client *client, > void *context, > struct ib_sa_query **sa_query); > > +/* Support get SA ClassPortInfo */ > +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, > + struct ib_device *device, u8 port_num, > + int timeout_ms, gfp_t gfp_mask, > + void (*callback)(int status, > + struct ib_class_port_info *resp, > + void *context), > + void *context, > + struct ib_sa_query **sa_query); > + > #endif /* IB_SA_H */ > -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 3ebd108..5c37f2f 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -119,6 +119,12 @@ struct ib_sa_guidinfo_query { struct ib_sa_query sa_query; }; +struct ib_sa_classport_info_query { + void (*callback)(int, struct ib_class_port_info *, void *); + void *context; + struct ib_sa_query sa_query; +}; + struct ib_sa_mcmember_query { void (*callback)(int, struct ib_sa_mcmember_rec *, void *); void *context; @@ -392,6 +398,82 @@ static const struct ib_field service_rec_table[] = { .size_bits = 2*64 }, }; +#define CLASSPORTINFO_REC_FIELD(field) \ + .struct_offset_bytes = offsetof(struct ib_class_port_info, field), \ + .struct_size_bytes = sizeof((struct ib_class_port_info *)0)->field, \ + .field_name = "ib_class_port_info:" #field + +static const struct ib_field classport_info_rec_table[] = { + { CLASSPORTINFO_REC_FIELD(base_version), + .offset_words = 0, + .offset_bits = 0, + .size_bits = 8 }, + { CLASSPORTINFO_REC_FIELD(class_version), + .offset_words = 0, + .offset_bits = 8, + .size_bits = 8 }, + { CLASSPORTINFO_REC_FIELD(capability_mask), + .offset_words = 0, + .offset_bits = 16, + .size_bits = 16 }, + { CLASSPORTINFO_REC_FIELD(cap_mask2_resp_time), + .offset_words = 1, + .offset_bits = 0, + .size_bits = 32 }, + { CLASSPORTINFO_REC_FIELD(redirect_gid), + .offset_words = 2, + .offset_bits = 0, + .size_bits = 128 }, + { CLASSPORTINFO_REC_FIELD(redirect_tcslfl), + .offset_words = 6, + .offset_bits = 0, + .size_bits = 32 }, + { CLASSPORTINFO_REC_FIELD(redirect_lid), + .offset_words = 7, + .offset_bits = 0, + .size_bits = 16 }, + { CLASSPORTINFO_REC_FIELD(redirect_pkey), + .offset_words = 7, + .offset_bits = 16, + .size_bits = 16 }, + + { CLASSPORTINFO_REC_FIELD(redirect_qp), + .offset_words = 8, + .offset_bits = 0, + .size_bits = 32 }, + { CLASSPORTINFO_REC_FIELD(redirect_qkey), + .offset_words = 9, + .offset_bits = 0, + .size_bits = 32 }, + + { CLASSPORTINFO_REC_FIELD(trap_gid), + .offset_words = 10, + .offset_bits = 0, + .size_bits = 128 }, + { CLASSPORTINFO_REC_FIELD(trap_tcslfl), + .offset_words = 14, + .offset_bits = 0, + .size_bits = 32 }, + + { CLASSPORTINFO_REC_FIELD(trap_lid), + .offset_words = 15, + .offset_bits = 0, + .size_bits = 16 }, + { CLASSPORTINFO_REC_FIELD(trap_pkey), + .offset_words = 15, + .offset_bits = 16, + .size_bits = 16 }, + + { CLASSPORTINFO_REC_FIELD(trap_hlqp), + .offset_words = 16, + .offset_bits = 0, + .size_bits = 32 }, + { CLASSPORTINFO_REC_FIELD(trap_qkey), + .offset_words = 17, + .offset_bits = 0, + .size_bits = 32 }, +}; + #define GUIDINFO_REC_FIELD(field) \ .struct_offset_bytes = offsetof(struct ib_sa_guidinfo_rec, field), \ .struct_size_bytes = sizeof((struct ib_sa_guidinfo_rec *) 0)->field, \ @@ -1645,6 +1727,97 @@ err1: } EXPORT_SYMBOL(ib_sa_guid_info_rec_query); +/* Support get SA ClassPortInfo */ +static void ib_sa_classport_info_rec_callback(struct ib_sa_query *sa_query, + int status, + struct ib_sa_mad *mad) +{ + struct ib_sa_classport_info_query *query = + container_of(sa_query, struct ib_sa_classport_info_query, sa_query); + + if (mad) { + struct ib_class_port_info rec; + + ib_unpack(classport_info_rec_table, + ARRAY_SIZE(classport_info_rec_table), + mad->data, &rec); + query->callback(status, &rec, query->context); + } else { + query->callback(status, NULL, query->context); + } +} + +static void ib_sa_portclass_info_rec_release(struct ib_sa_query *sa_query) +{ + kfree(container_of(sa_query, struct ib_sa_classport_info_query, + sa_query)); +} + +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, + struct ib_device *device, u8 port_num, + int timeout_ms, gfp_t gfp_mask, + void (*callback)(int status, + struct ib_class_port_info *resp, + void *context), + void *context, + struct ib_sa_query **sa_query) +{ + struct ib_sa_classport_info_query *query; + struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); + struct ib_sa_port *port; + struct ib_mad_agent *agent; + struct ib_sa_mad *mad; + int ret; + + if (!sa_dev) + return -ENODEV; + + port = &sa_dev->port[port_num - sa_dev->start_port]; + agent = port->agent; + + query = kzalloc(sizeof(*query), gfp_mask); + if (!query) + return -ENOMEM; + + query->sa_query.port = port; + ret = alloc_mad(&query->sa_query, gfp_mask); + if (ret) + goto err1; + + ib_sa_client_get(client); + query->sa_query.client = client; + query->callback = callback; + query->context = context; + + mad = query->sa_query.mad_buf->mad; + init_mad(mad, agent); + + query->sa_query.callback = callback ? ib_sa_classport_info_rec_callback : NULL; + + query->sa_query.release = ib_sa_portclass_info_rec_release; + /* support GET only */ + mad->mad_hdr.method = IB_MGMT_METHOD_GET; + mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_CLASS_PORTINFO); + mad->sa_hdr.comp_mask = 0; + *sa_query = &query->sa_query; + + ret = send_mad(&query->sa_query, timeout_ms, gfp_mask); + if (ret < 0) + goto err2; + + return ret; + +err2: + *sa_query = NULL; + ib_sa_client_put(query->sa_query.client); + free_mad(&query->sa_query); + +err1: + kfree(query); + return ret; +} +EXPORT_SYMBOL(ib_sa_classport_info_rec_query); + static void send_handler(struct ib_mad_agent *agent, struct ib_mad_send_wc *mad_send_wc) { diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h index cdc1c81..3840416 100644 --- a/include/rdma/ib_sa.h +++ b/include/rdma/ib_sa.h @@ -94,6 +94,8 @@ enum ib_sa_selector { IB_SA_BEST = 3 }; +#define IB_SA_CAP_MASK2_SENDONLY_FULL_MEM_SUPPORT BIT(12) + /* * Structures for SA records are named "struct ib_sa_xxx_rec." No * attempt is made to pack structures to match the physical layout of @@ -439,4 +441,14 @@ int ib_sa_guid_info_rec_query(struct ib_sa_client *client, void *context, struct ib_sa_query **sa_query); +/* Support get SA ClassPortInfo */ +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, + struct ib_device *device, u8 port_num, + int timeout_ms, gfp_t gfp_mask, + void (*callback)(int status, + struct ib_class_port_info *resp, + void *context), + void *context, + struct ib_sa_query **sa_query); + #endif /* IB_SA_H */