aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/cm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/core/cm.c')
-rw-r--r--drivers/infiniband/core/cm.c267
1 files changed, 267 insertions, 0 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index d396b987b0f2..7f609979e4de 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -4253,10 +4253,277 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data)
kfree(cm_dev);
}
+/*
+ * Check at compile time that the byte offset and length of field old_name in
+ * the struct matches the byte offset and length in the new macro.
+ */
+#define _IBA_CHECK_OFF(old_name, field_struct, field_offset, mask, bits) \
+ static_assert(offsetof(field_struct, old_name) == (field_offset)); \
+ static_assert(bits == sizeof(((field_struct *)0)->old_name) * 8)
+#define IBA_CHECK_OFF(field, old_name) _IBA_CHECK_OFF(old_name, field)
+
+IBA_CHECK_OFF(CM_REQ_LOCAL_COMM_ID, local_comm_id);
+IBA_CHECK_OFF(CM_REQ_SERVICE_ID, service_id);
+IBA_CHECK_OFF(CM_REQ_LOCAL_CA_GUID, local_ca_guid);
+IBA_CHECK_OFF(CM_REQ_LOCAL_Q_KEY, local_qkey);
+IBA_CHECK_OFF(CM_REQ_PARTITION_KEY, pkey);
+IBA_CHECK_OFF(CM_REQ_PRIMARY_LOCAL_PORT_LID, primary_local_lid);
+IBA_CHECK_OFF(CM_REQ_PRIMARY_REMOTE_PORT_LID, primary_remote_lid);
+IBA_CHECK_OFF(CM_REQ_PRIMARY_LOCAL_PORT_GID, primary_local_gid);
+IBA_CHECK_OFF(CM_REQ_PRIMARY_REMOTE_PORT_GID, primary_remote_gid);
+IBA_CHECK_OFF(CM_REQ_PRIMARY_TRAFFIC_CLASS, primary_traffic_class);
+IBA_CHECK_OFF(CM_REQ_PRIMARY_HOP_LIMIT, primary_hop_limit);
+IBA_CHECK_OFF(CM_REQ_ALTERNATE_LOCAL_PORT_LID, alt_local_lid);
+IBA_CHECK_OFF(CM_REQ_ALTERNATE_REMOTE_PORT_LID, alt_remote_lid);
+IBA_CHECK_OFF(CM_REQ_ALTERNATE_LOCAL_PORT_GID, alt_local_gid);
+IBA_CHECK_OFF(CM_REQ_ALTERNATE_REMOTE_PORT_GID, alt_remote_gid);
+IBA_CHECK_OFF(CM_REQ_ALTERNATE_TRAFFIC_CLASS, alt_traffic_class);
+IBA_CHECK_OFF(CM_REQ_ALTERNATE_HOP_LIMIT, alt_hop_limit);
+IBA_CHECK_OFF(CM_REQ_PRIVATE_DATA, private_data);
+IBA_CHECK_OFF(CM_MRA_LOCAL_COMM_ID, local_comm_id);
+IBA_CHECK_OFF(CM_MRA_REMOTE_COMM_ID, remote_comm_id);
+IBA_CHECK_OFF(CM_MRA_PRIVATE_DATA, private_data);
+IBA_CHECK_OFF(CM_REJ_LOCAL_COMM_ID, local_comm_id);
+IBA_CHECK_OFF(CM_REJ_REMOTE_COMM_ID, remote_comm_id);
+IBA_CHECK_OFF(CM_REJ_REASON, reason);
+IBA_CHECK_OFF(CM_REJ_ARI, ari);
+IBA_CHECK_OFF(CM_REJ_PRIVATE_DATA, private_data);
+IBA_CHECK_OFF(CM_REP_LOCAL_COMM_ID, local_comm_id);
+IBA_CHECK_OFF(CM_REP_REMOTE_COMM_ID, remote_comm_id);
+IBA_CHECK_OFF(CM_REP_LOCAL_Q_KEY, local_qkey);
+IBA_CHECK_OFF(CM_REP_RESPONDER_RESOURCES, resp_resources);
+IBA_CHECK_OFF(CM_REP_INITIATOR_DEPTH, initiator_depth);
+IBA_CHECK_OFF(CM_REP_LOCAL_CA_GUID, local_ca_guid);
+IBA_CHECK_OFF(CM_REP_PRIVATE_DATA, private_data);
+IBA_CHECK_OFF(CM_RTU_LOCAL_COMM_ID, local_comm_id);
+IBA_CHECK_OFF(CM_RTU_REMOTE_COMM_ID, remote_comm_id);
+IBA_CHECK_OFF(CM_RTU_PRIVATE_DATA, private_data);
+IBA_CHECK_OFF(CM_DREQ_LOCAL_COMM_ID, local_comm_id);
+IBA_CHECK_OFF(CM_DREQ_REMOTE_COMM_ID, remote_comm_id);
+IBA_CHECK_OFF(CM_DREQ_PRIVATE_DATA, private_data);
+IBA_CHECK_OFF(CM_DREP_LOCAL_COMM_ID, local_comm_id);
+IBA_CHECK_OFF(CM_DREP_REMOTE_COMM_ID, remote_comm_id);
+IBA_CHECK_OFF(CM_DREP_PRIVATE_DATA, private_data);
+IBA_CHECK_OFF(CM_LAP_LOCAL_COMM_ID, local_comm_id);
+IBA_CHECK_OFF(CM_LAP_REMOTE_COMM_ID, remote_comm_id);
+IBA_CHECK_OFF(CM_LAP_ALTERNATE_LOCAL_PORT_LID, alt_local_lid);
+IBA_CHECK_OFF(CM_LAP_ALTERNATE_REMOTE_PORT_LID, alt_remote_lid);
+IBA_CHECK_OFF(CM_LAP_ALTERNATE_LOCAL_PORT_GID, alt_local_gid);
+IBA_CHECK_OFF(CM_LAP_ALTERNATE_REMOTE_PORT_GID, alt_remote_gid);
+IBA_CHECK_OFF(CM_LAP_ALTERNATE_HOP_LIMIT, alt_hop_limit);
+IBA_CHECK_OFF(CM_LAP_PRIVATE_DATA, private_data);
+IBA_CHECK_OFF(CM_APR_LOCAL_COMM_ID, local_comm_id);
+IBA_CHECK_OFF(CM_APR_REMOTE_COMM_ID, remote_comm_id);
+IBA_CHECK_OFF(CM_APR_ADDITIONAL_INFORMATION_LENGTH, info_length);
+IBA_CHECK_OFF(CM_APR_AR_STATUS, ap_status);
+IBA_CHECK_OFF(CM_APR_ADDITIONAL_INFORMATION, info);
+IBA_CHECK_OFF(CM_APR_PRIVATE_DATA, private_data);
+IBA_CHECK_OFF(CM_SIDR_REQ_REQUESTID, request_id);
+IBA_CHECK_OFF(CM_SIDR_REQ_PARTITION_KEY, pkey);
+IBA_CHECK_OFF(CM_SIDR_REQ_SERVICEID, service_id);
+IBA_CHECK_OFF(CM_SIDR_REQ_PRIVATE_DATA, private_data);
+IBA_CHECK_OFF(CM_SIDR_REP_REQUESTID, request_id);
+IBA_CHECK_OFF(CM_SIDR_REP_STATUS, status);
+IBA_CHECK_OFF(CM_SIDR_REP_ADDITIONAL_INFORMATION_LENGTH, info_length);
+IBA_CHECK_OFF(CM_SIDR_REP_SERVICEID, service_id);
+IBA_CHECK_OFF(CM_SIDR_REP_Q_KEY, qkey);
+IBA_CHECK_OFF(CM_SIDR_REP_ADDITIONAL_INFORMATION, info);
+IBA_CHECK_OFF(CM_SIDR_REP_PRIVATE_DATA, private_data);
+
+/*
+ * Check that the new macro gets the same bits as the old get function.
+ * - IBA_SET() IBA_GET and old get_fn all agree on the field width.
+ * The field width should match what IBA_SET truncates to
+ * - Reading from an all ones data should not return extra bits
+ * - Setting '1' should be the same (ie no endian problems)
+ */
+/* defeat builtin_constant checks */
+u64 cm_global_all_ones = 0xffffffffffffffffULL;
+#define _IBA_CHECK_GET(fn, field_struct, field_offset, mask, bits) \
+ ({ \
+ field_struct *lmsg = (field_struct *)msg; \
+ unsigned long long all_ones; \
+ static_assert(sizeof(*lmsg) <= sizeof(msg)); \
+ \
+ bitmap_zero(msg, nbits); \
+ _IBA_SET(field_struct, field_offset, mask, bits, lmsg, \
+ cm_global_all_ones); \
+ all_ones = (1ULL << bitmap_weight(msg, nbits)) - 1; \
+ if (_IBA_GET(field_struct, field_offset, mask, bits, lmsg) != \
+ all_ones) { \
+ printk("Failed #1 line=%u\n", __LINE__); \
+ return; \
+ } \
+ if (fn != all_ones) { \
+ printk("Failed #2 line=%u\n", __LINE__); \
+ return; \
+ } \
+ \
+ bitmap_fill(msg, nbits); \
+ if (_IBA_GET(field_struct, field_offset, mask, bits, lmsg) != \
+ all_ones) { \
+ printk("Failed #3 line=%u\n", __LINE__); \
+ return; \
+ } \
+ if (fn != all_ones) { \
+ printk("Failed #4 line=%u\n", __LINE__); \
+ return; \
+ } \
+ \
+ _IBA_SET(field_struct, field_offset, mask, bits, lmsg, 0); \
+ if (_IBA_GET(field_struct, field_offset, mask, bits, lmsg) != \
+ 0) { \
+ printk("Failed #5 line=%u\n", __LINE__); \
+ return; \
+ } \
+ if (fn != 0) { \
+ printk("Failed #6 line=%u\n", __LINE__); \
+ return; \
+ } \
+ _IBA_SET(field_struct, field_offset, mask, bits, lmsg, 1); \
+ if (_IBA_GET(field_struct, field_offset, mask, bits, lmsg) != \
+ 1) { \
+ printk("Failed #7 line=%u\n", __LINE__); \
+ return; \
+ } \
+ if (fn != 1) { \
+ printk("Failed #8 line=%u\n", __LINE__); \
+ return; \
+ } \
+ })
+#define IBA_CHECK_GET(field, fn_name) _IBA_CHECK_GET(fn_name(lmsg), field)
+#define IBA_CHECK_GET_BE(field, fn_name) _IBA_CHECK_GET(be32_to_cpu(fn_name(lmsg)), field)
+
+/*
+ * Write the all ones value using the old setter and check that the new getter
+ * reads it back.
+ */
+#define _IBA_CHECK_SET(fn, field_struct, field_offset, mask, bits) \
+ ({ \
+ field_struct *lmsg = (field_struct *)msg; \
+ unsigned long long all_ones; \
+ static_assert(sizeof(*lmsg) <= sizeof(msg)); \
+ \
+ bitmap_zero(msg, nbits); \
+ _IBA_SET(field_struct, field_offset, mask, bits, lmsg, \
+ cm_global_all_ones); \
+ all_ones = (1ULL << bitmap_weight(msg, nbits)) - 1; \
+ bitmap_zero(msg, nbits); \
+ fn; \
+ if (_IBA_GET(field_struct, field_offset, mask, bits, lmsg) != \
+ all_ones) { \
+ printk("Failed #9 line=%u\n", __LINE__); \
+ return; \
+ } \
+ all_ones = 1; \
+ fn; \
+ if (_IBA_GET(field_struct, field_offset, mask, bits, lmsg) != \
+ 1) { \
+ printk("Failed #10 line=%u\n", __LINE__); \
+ return; \
+ } \
+ })
+
+#define IBA_CHECK_SET(field, fn_name) _IBA_CHECK_SET(fn_name(lmsg, all_ones), field)
+#define IBA_CHECK_SET_BE(field, fn_name) \
+ _IBA_CHECK_SET(fn_name(lmsg, cpu_to_be32(all_ones)), field)
+
+static void self_test(void)
+{
+ unsigned long msg[256/4];
+ const unsigned int nbits = sizeof(msg) * 8;
+
+ printk("Running CM extractor self test\n");
+ IBA_CHECK_GET_BE(CM_REQ_LOCAL_QPN, cm_req_get_local_qpn);
+ IBA_CHECK_SET_BE(CM_REQ_LOCAL_QPN, cm_req_set_local_qpn);
+ IBA_CHECK_GET(CM_REQ_RESPONDER_RESOURCES, cm_req_get_resp_res);
+ IBA_CHECK_SET(CM_REQ_RESPONDER_RESOURCES, cm_req_set_resp_res);
+ IBA_CHECK_GET(CM_REQ_INITIATOR_DEPTH, cm_req_get_init_depth);
+ IBA_CHECK_SET(CM_REQ_INITIATOR_DEPTH, cm_req_set_init_depth);
+ IBA_CHECK_GET(CM_REQ_REMOTE_CM_RESPONSE_TIMEOUT, cm_req_get_remote_resp_timeout);
+ IBA_CHECK_SET(CM_REQ_REMOTE_CM_RESPONSE_TIMEOUT, cm_req_set_remote_resp_timeout);
+ IBA_CHECK_GET(CM_REQ_TRANSPORT_SERVICE_TYPE, cm_req_get_transport_type);
+ IBA_CHECK_SET(CM_REQ_TRANSPORT_SERVICE_TYPE, cm_req_set_transport_type);
+ IBA_CHECK_GET(CM_REQ_END_TO_END_FLOW_CONTROL, cm_req_get_flow_ctrl);
+ IBA_CHECK_SET(CM_REQ_END_TO_END_FLOW_CONTROL, cm_req_set_flow_ctrl);
+ IBA_CHECK_GET_BE(CM_REQ_STARTING_PSN, cm_req_get_starting_psn);
+ IBA_CHECK_SET_BE(CM_REQ_STARTING_PSN, cm_req_set_starting_psn);
+ IBA_CHECK_GET(CM_REQ_LOCAL_CM_RESPONSE_TIMEOUT, cm_req_get_local_resp_timeout);
+ IBA_CHECK_SET(CM_REQ_LOCAL_CM_RESPONSE_TIMEOUT, cm_req_set_local_resp_timeout);
+ IBA_CHECK_GET(CM_REQ_RETRY_COUNT, cm_req_get_retry_count);
+ IBA_CHECK_SET(CM_REQ_RETRY_COUNT, cm_req_set_retry_count);
+ IBA_CHECK_GET(CM_REQ_PATH_PACKET_PAYLOAD_MTU, cm_req_get_path_mtu);
+ IBA_CHECK_SET(CM_REQ_PATH_PACKET_PAYLOAD_MTU, cm_req_set_path_mtu);
+ IBA_CHECK_GET(CM_REQ_RNR_RETRY_COUNT, cm_req_get_rnr_retry_count);
+ IBA_CHECK_SET(CM_REQ_RNR_RETRY_COUNT, cm_req_set_rnr_retry_count);
+ IBA_CHECK_GET(CM_REQ_MAX_CM_RETRIES, cm_req_get_max_cm_retries);
+ IBA_CHECK_SET(CM_REQ_MAX_CM_RETRIES, cm_req_set_max_cm_retries);
+ IBA_CHECK_GET(CM_REQ_SRQ, cm_req_get_srq);
+ IBA_CHECK_SET(CM_REQ_SRQ, cm_req_set_srq);
+ IBA_CHECK_GET(CM_REQ_EXTENDED_TRANSPORT_TYPE, cm_req_get_transport_type_ex);
+ IBA_CHECK_SET(CM_REQ_EXTENDED_TRANSPORT_TYPE, cm_req_set_transport_type_ex);
+ IBA_CHECK_GET_BE(CM_REQ_PRIMARY_FLOW_LABEL, cm_req_get_primary_flow_label);
+ IBA_CHECK_SET_BE(CM_REQ_PRIMARY_FLOW_LABEL, cm_req_set_primary_flow_label);
+ IBA_CHECK_GET(CM_REQ_PRIMARY_PACKET_RATE, cm_req_get_primary_packet_rate);
+ IBA_CHECK_SET(CM_REQ_PRIMARY_PACKET_RATE, cm_req_set_primary_packet_rate);
+ IBA_CHECK_GET(CM_REQ_PRIMARY_SL, cm_req_get_primary_sl);
+ IBA_CHECK_SET(CM_REQ_PRIMARY_SL, cm_req_set_primary_sl);
+ IBA_CHECK_GET(CM_REQ_PRIMARY_SUBNET_LOCAL, cm_req_get_primary_subnet_local);
+ IBA_CHECK_SET(CM_REQ_PRIMARY_SUBNET_LOCAL, cm_req_set_primary_subnet_local);
+ IBA_CHECK_GET(CM_REQ_PRIMARY_LOCAL_ACK_TIMEOUT, cm_req_get_primary_local_ack_timeout);
+ IBA_CHECK_SET(CM_REQ_PRIMARY_LOCAL_ACK_TIMEOUT, cm_req_set_primary_local_ack_timeout);
+ IBA_CHECK_GET_BE(CM_REQ_ALTERNATE_FLOW_LABEL, cm_req_get_alt_flow_label);
+ IBA_CHECK_SET_BE(CM_REQ_ALTERNATE_FLOW_LABEL, cm_req_set_alt_flow_label);
+ IBA_CHECK_GET(CM_REQ_ALTERNATE_PACKET_RATE, cm_req_get_alt_packet_rate);
+ IBA_CHECK_SET(CM_REQ_ALTERNATE_PACKET_RATE, cm_req_set_alt_packet_rate);
+ IBA_CHECK_GET(CM_REQ_ALTERNATE_SL, cm_req_get_alt_sl);
+ IBA_CHECK_SET(CM_REQ_ALTERNATE_SL, cm_req_set_alt_sl);
+ IBA_CHECK_GET(CM_REQ_ALTERNATE_SUBNET_LOCAL, cm_req_get_alt_subnet_local);
+ IBA_CHECK_SET(CM_REQ_ALTERNATE_SUBNET_LOCAL, cm_req_set_alt_subnet_local);
+ IBA_CHECK_GET(CM_REQ_ALTERNATE_LOCAL_ACK_TIMEOUT, cm_req_get_alt_local_ack_timeout);
+ IBA_CHECK_SET(CM_REQ_ALTERNATE_LOCAL_ACK_TIMEOUT, cm_req_set_alt_local_ack_timeout);
+ IBA_CHECK_GET(CM_MRA_MESSAGE_MRAED, cm_mra_get_msg_mraed);
+ IBA_CHECK_SET(CM_MRA_MESSAGE_MRAED, cm_mra_set_msg_mraed);
+ IBA_CHECK_GET(CM_MRA_SERVICE_TIMEOUT, cm_mra_get_service_timeout);
+ IBA_CHECK_SET(CM_MRA_SERVICE_TIMEOUT, cm_mra_set_service_timeout);
+ IBA_CHECK_GET(CM_REJ_MESSAGE_REJECTED, cm_rej_get_msg_rejected);
+ IBA_CHECK_SET(CM_REJ_MESSAGE_REJECTED, cm_rej_set_msg_rejected);
+ IBA_CHECK_GET(CM_REJ_REJECTED_INFO_LENGTH, cm_rej_get_reject_info_len);
+ IBA_CHECK_SET(CM_REJ_REJECTED_INFO_LENGTH, cm_rej_set_reject_info_len);
+ IBA_CHECK_GET_BE(CM_REP_LOCAL_QPN, cm_rep_get_local_qpn);
+ IBA_CHECK_SET_BE(CM_REP_LOCAL_QPN, cm_rep_set_local_qpn);
+ IBA_CHECK_GET_BE(CM_REP_LOCAL_EE_CONTEXT_NUMBER, cm_rep_get_local_eecn);
+ IBA_CHECK_SET_BE(CM_REP_LOCAL_EE_CONTEXT_NUMBER, cm_rep_set_local_eecn);
+ IBA_CHECK_GET_BE(CM_REP_STARTING_PSN, cm_rep_get_starting_psn);
+ IBA_CHECK_SET_BE(CM_REP_STARTING_PSN, cm_rep_set_starting_psn);
+ IBA_CHECK_GET(CM_REP_TARGET_ACK_DELAY, cm_rep_get_target_ack_delay);
+ IBA_CHECK_SET(CM_REP_TARGET_ACK_DELAY, cm_rep_set_target_ack_delay);
+ IBA_CHECK_GET(CM_REP_FAILOVER_ACCEPTED, cm_rep_get_failover);
+ IBA_CHECK_SET(CM_REP_FAILOVER_ACCEPTED, cm_rep_set_failover);
+ IBA_CHECK_GET(CM_REP_END_TO_END_FLOW_CONTROL, cm_rep_get_flow_ctrl);
+ IBA_CHECK_SET(CM_REP_END_TO_END_FLOW_CONTROL, cm_rep_set_flow_ctrl);
+ IBA_CHECK_GET(CM_REP_RNR_RETRY_COUNT, cm_rep_get_rnr_retry_count);
+ IBA_CHECK_SET(CM_REP_RNR_RETRY_COUNT, cm_rep_set_rnr_retry_count);
+ IBA_CHECK_GET(CM_REP_SRQ, cm_rep_get_srq);
+ IBA_CHECK_SET(CM_REP_SRQ, cm_rep_set_srq);
+ IBA_CHECK_GET_BE(CM_DREQ_REMOTE_QPN_EECN, cm_dreq_get_remote_qpn);
+ IBA_CHECK_SET_BE(CM_DREQ_REMOTE_QPN_EECN, cm_dreq_set_remote_qpn);
+ IBA_CHECK_GET_BE(CM_LAP_ALTERNATE_FLOW_LABEL, cm_lap_get_flow_label);
+ IBA_CHECK_GET(CM_LAP_ALTERNATE_TRAFFIC_CLASS, cm_lap_get_traffic_class);
+ IBA_CHECK_GET(CM_LAP_ALTERNATE_PACKET_RATE, cm_lap_get_packet_rate);
+ IBA_CHECK_GET(CM_LAP_ALTERNATE_SL, cm_lap_get_sl);
+ IBA_CHECK_GET(CM_LAP_ALTERNATE_LOCAL_ACK_TIMEOUT, cm_lap_get_local_ack_timeout);
+ IBA_CHECK_GET_BE(CM_SIDR_REP_QPN, cm_sidr_rep_get_qpn);
+ IBA_CHECK_SET_BE(CM_SIDR_REP_QPN, cm_sidr_rep_set_qpn);
+ printk("Success!\n");
+}
+
static int __init ib_cm_init(void)
{
int ret;
+ self_test();
+
INIT_LIST_HEAD(&cm.device_list);
rwlock_init(&cm.device_lock);
spin_lock_init(&cm.lock);