From 6edf653df44ba38f729580ed5732a5751849533b Mon Sep 17 00:00:00 2001 From: Arlin Davis Date: Wed, 12 Feb 2014 14:55:25 -0800 Subject: [PATCH] new lightweight open_query/close_query IB extension for fast attribute query Consumers that need provider attributes must do a full device open in order to get any provider/device information. With so many static device entries in /etc/dat.conf consumers are building classification mechanisms to identify provider type, locality, name, device mode, and decide which device is appropriate. The existing DAT interface doesn't provide a lightweight mechanism for queries. The following fast query functions have been added to dat_ib_extensions.h: dat_ib_open_query(name, ia_handle, ia_mask, ia_attr, prov_mask, prov_attr) dat_ib_close_query(ia_handle) In addition, DAT extension interface, dat_extension_op, has been expanded to include new internal calls to handle quick provider load and function linkage via udat_extension_open, and udat_extension_close functions. Extended operations needing DAT open/close services need to be defined from a DAT_OPEN_EXTENSION_BASE or DAT_CLOSE_EXTENSION_BASE respectively. NOTE: The ia_handle returned with open query must be closed with subsequent close_query and not used with any other dat_ia_ operations. Attribute storage from query_open is not valid after close_query call. The IB extensions have been rolled to version 2.0.8 with this new API. The changes are backward compatible. Signed-off-by: Arlin Davis --- dapl/common/dapl_adapter_util.h | 9 +- dapl/common/dapl_ia_open.c | 2 +- dapl/common/dapl_ia_query.c | 4 +- dapl/common/dapl_ia_util.c | 3 +- dapl/ibal/dapl_ibal_util.c | 3 +- dapl/openib_cma/dapl_ib_util.h | 1 + dapl/openib_cma/device.c | 41 +++++--- dapl/openib_common/ib_extensions.c | 150 ++++++++++++++++++++++++++- dapl/openib_common/mem.c | 4 + dapl/openib_common/util.c | 51 +++++++-- dapl/openib_mcm/dapl_ib_util.h | 3 +- dapl/openib_mcm/device.c | 46 +++++--- dapl/openib_mcm/mix.c | 4 +- dapl/openib_scm/dapl_ib_util.h | 1 + dapl/openib_scm/device.c | 61 ++++++----- dapl/openib_ucm/dapl_ib_util.h | 1 + dapl/openib_ucm/device.c | 57 ++++++---- dat/common/dat_api.c | 56 +++++++--- dat/common/dat_dr.c | 24 +++++ dat/common/dat_dr.h | 11 +- dat/include/dat2/dat.h | 2 + dat/include/dat2/dat_ib_extensions.h | 40 ++++++- dat/udat/udat.c | 136 +++++++++++++++++++++++- test/dtest/dtest.c | 76 ++++++++++++-- 24 files changed, 660 insertions(+), 126 deletions(-) diff --git a/dapl/common/dapl_adapter_util.h b/dapl/common/dapl_adapter_util.h index 92cb9b7..9b12b2d 100755 --- a/dapl/common/dapl_adapter_util.h +++ b/dapl/common/dapl_adapter_util.h @@ -50,6 +50,12 @@ typedef enum async_handler_type DAPL_ASYNC_QP_ERROR } DAPL_ASYNC_HANDLER_TYPE; +typedef enum dapl_open_flags +{ + DAPL_OPEN_NORMAL, + DAPL_OPEN_QUERY +} DAPL_OPEN_FLAGS; + int dapls_ib_init (void); @@ -66,7 +72,8 @@ DAT_RETURN dapls_ib_get_instance_data( DAT_RETURN dapls_ib_open_hca ( IN char *namestr, - IN DAPL_HCA *hca_ptr); + IN DAPL_HCA *hca_ptr, + IN DAPL_OPEN_FLAGS flags); DAT_RETURN dapls_ib_close_hca ( IN DAPL_HCA *hca_ptr); diff --git a/dapl/common/dapl_ia_open.c b/dapl/common/dapl_ia_open.c index 10c48d4..50c43d8 100644 --- a/dapl/common/dapl_ia_open.c +++ b/dapl/common/dapl_ia_open.c @@ -132,7 +132,7 @@ dapl_ia_open(IN const DAT_NAME_PTR name, dapl_os_lock(&hca_ptr->lock); if (hca_ptr->ib_hca_handle == IB_INVALID_HANDLE) { /* register with the HW */ - dat_status = dapls_ib_open_hca(hca_ptr->name, hca_ptr); + dat_status = dapls_ib_open_hca(hca_ptr->name, hca_ptr, DAPL_OPEN_NORMAL); if (dat_status != DAT_SUCCESS) { dapl_dbg_log(DAPL_DBG_TYPE_ERR, diff --git a/dapl/common/dapl_ia_query.c b/dapl/common/dapl_ia_query.c index d530d72..5470ccb 100755 --- a/dapl/common/dapl_ia_query.c +++ b/dapl/common/dapl_ia_query.c @@ -108,8 +108,8 @@ dapl_ia_query(IN DAT_IA_HANDLE ia_handle, * Obtain parameters from the HCA. Protect against multiple * IAs beating on the HCA at the same time. */ - dat_status = - dapls_ib_query_hca(ia_ptr->hca_ptr, ia_attr, NULL, NULL); + dat_status = dapls_ib_query_hca(ia_ptr->hca_ptr, + ia_attr, NULL, NULL); if (dat_status != DAT_SUCCESS) { goto bail; } diff --git a/dapl/common/dapl_ia_util.c b/dapl/common/dapl_ia_util.c index 6d1b5a8..940c048 100755 --- a/dapl/common/dapl_ia_util.c +++ b/dapl/common/dapl_ia_util.c @@ -528,7 +528,8 @@ void dapli_ia_release_hca(DAPL_HCA * hca_ptr) #ifdef DAPL_COUNTERS { DAPL_IA *ia = (DAPL_IA *)dapl_llist_peek_head(&hca_ptr->ia_list_head); - dapli_stop_counters(ia); + if (hca_ptr->ib_hca_handle) + dapli_stop_counters(ia); dapl_os_free(ia->cntrs, sizeof(DAT_UINT64) * DCNT_IA_ALL_COUNTERS); } #endif diff --git a/dapl/ibal/dapl_ibal_util.c b/dapl/ibal/dapl_ibal_util.c index 0852df2..9fb8c4a 100644 --- a/dapl/ibal/dapl_ibal_util.c +++ b/dapl/ibal/dapl_ibal_util.c @@ -811,7 +811,8 @@ dapl_ib_convert_name( * */ DAT_RETURN dapls_ib_open_hca ( IN char *hca_name, - IN DAPL_HCA *p_hca ) + IN DAPL_HCA *p_hca, + IN DAPL_OPEN_FLAGS flags) { dapl_ibal_ca_t *p_ca; IB_HCA_NAME ca_guid; diff --git a/dapl/openib_cma/dapl_ib_util.h b/dapl/openib_cma/dapl_ib_util.h index 7994679..dcfbb3e 100755 --- a/dapl/openib_cma/dapl_ib_util.h +++ b/dapl/openib_cma/dapl_ib_util.h @@ -130,6 +130,7 @@ typedef struct _ib_hca_transport char *mtu_str; char *mode_str; char *read_str; + char *port_state_str; #ifdef DAT_IB_COLLECTIVES /* Collective member device and address information */ ib_thread_state_t coll_thread_state; diff --git a/dapl/openib_cma/device.c b/dapl/openib_cma/device.c index 6fd12f9..e5e2c6e 100644 --- a/dapl/openib_cma/device.c +++ b/dapl/openib_cma/device.c @@ -262,15 +262,28 @@ int32_t dapls_ib_release(void) * dapl_convert_errno * */ -DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr) +DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, + IN DAPL_HCA * hca_ptr, + IN DAPL_OPEN_FLAGS flags) { struct rdma_cm_id *cm_id = NULL; union ibv_gid *gid; int ret; - DAT_RETURN dat_status; + DAT_RETURN dat_status = DAT_SUCCESS; - dapl_dbg_log(DAPL_DBG_TYPE_UTIL, - " open_hca: %s - %p\n", hca_name, hca_ptr); + /* HCA name will be hostname or IP address */ + if (getipaddr((char *)hca_name, + (char *)&hca_ptr->hca_address, + sizeof(DAT_SOCK_ADDR6))) + return DAT_INVALID_ADDRESS; + + if (flags & DAPL_OPEN_QUERY) { + dapl_log(DAPL_DBG_TYPE_WARN, + " WARNING! open_hca: %s %s - %p in %s\n", + PROVIDER_NAME, hca_name, hca_ptr, + flags & DAPL_OPEN_QUERY ? "QUERY MODE":""); + goto done; + } /* Setup the global cm event channel */ dapl_os_lock(&g_hca_lock); @@ -289,12 +302,6 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr) dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " open_hca: RDMA channel created (%p)\n", g_cm_events); - /* HCA name will be hostname or IP address */ - if (getipaddr((char *)hca_name, - (char *)&hca_ptr->hca_address, - sizeof(DAT_SOCK_ADDR6))) - return DAT_INVALID_ADDRESS; - /* cm_id will bind local device/GID based on IP address */ if (rdma_create_id(g_cm_events, &cm_id, (void *)hca_ptr, RDMA_PS_TCP)) { @@ -341,8 +348,7 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr) } /* set inline max with env or default, get local lid and gid 0 */ - if (hca_ptr->ib_hca_handle->device->transport_type - == IBV_TRANSPORT_IWARP) + if (hca_ptr->ib_hca_handle->device->transport_type == IBV_TRANSPORT_IWARP) hca_ptr->ib_trans.max_inline_send = dapl_os_get_env_val("DAPL_MAX_INLINE", INLINE_SEND_IWARP_DEFAULT); @@ -358,9 +364,6 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr) hca_ptr->ib_trans.max_cm_retries = dapl_os_get_env_val("DAPL_MAX_CM_RETRIES", IB_CM_RETRIES); - /* set default IB MTU */ - hca_ptr->ib_trans.mtu = dapl_ib_mtu(2048); - dat_status = dapli_ib_thread_init(); if (dat_status != DAT_SUCCESS) return dat_status; @@ -399,6 +402,10 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr) return DAT_INTERNAL_ERROR; #endif +done: + /* set default IB MTU */ + hca_ptr->ib_trans.mtu = dapl_ib_mtu(2048); + return DAT_SUCCESS; } @@ -423,6 +430,9 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr) dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p->%p\n", hca_ptr, hca_ptr->ib_hca_handle); + if (!g_ib_thread_state) /* thread never started */ + goto bail; + #ifdef DAT_IB_COLLECTIVES dapli_free_collective_service(hca_ptr); #endif @@ -455,7 +465,6 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr) dapl_os_sleep_usec(1000); } bail: - if (hca_ptr->ib_trans.ib_cq) ibv_destroy_comp_channel(hca_ptr->ib_trans.ib_cq); diff --git a/dapl/openib_common/ib_extensions.c b/dapl/openib_common/ib_extensions.c index 0952bd5..339dae7 100644 --- a/dapl/openib_common/ib_extensions.c +++ b/dapl/openib_common/ib_extensions.c @@ -29,7 +29,10 @@ #include "dapl_evd_util.h" #include "dapl_ib_util.h" #include "dapl_ep_util.h" +#include "dapl_ia_util.h" #include "dapl_cookie.h" +#include "dapl_provider.h" + #include #ifdef DAT_IB_COLLECTIVES @@ -48,6 +51,14 @@ dapli_post_ext(IN DAT_EP_HANDLE ep_handle, IN int op_type, IN DAT_COMPLETION_FLAGS flags, IN DAT_IB_ADDR_HANDLE * ah); +DAT_RETURN +dapli_open_query_ext(IN const DAT_NAME_PTR name, + OUT DAT_IA_HANDLE * ia_handle, + IN DAT_IA_ATTR_MASK ia_mask, + OUT DAT_IA_ATTR * ia_attr, + IN DAT_PROVIDER_ATTR_MASK pr_mask, + OUT DAT_PROVIDER_ATTR * pr_attr); + /* * dapl_extensions * @@ -68,7 +79,8 @@ dapli_post_ext(IN DAT_EP_HANDLE ep_handle, */ DAT_RETURN dapl_extensions(IN DAT_HANDLE dat_handle, - IN DAT_EXTENDED_OP ext_op, IN va_list args) + IN DAT_EXTENDED_OP ext_op, + IN va_list args) { DAT_EP_HANDLE ep; DAT_IB_ADDR_HANDLE *ah = NULL; @@ -87,6 +99,29 @@ dapl_extensions(IN DAT_HANDLE dat_handle, switch ((int)ext_op) { + case DAT_IB_OPEN_QUERY_OP: + { + dapl_dbg_log(DAPL_DBG_TYPE_RTN, + " OPEN_QUERY extension call\n"); + + DAT_IA_HANDLE *ia_handle = va_arg(args, DAT_IA_HANDLE *); + DAT_IA_ATTR_MASK ia_mask = va_arg(args, DAT_IA_ATTR_MASK); + DAT_IA_ATTR *ia_attr = va_arg(args, DAT_IA_ATTR *); + DAT_PROVIDER_ATTR_MASK pr_mask = va_arg(args, DAT_PROVIDER_ATTR_MASK); + DAT_PROVIDER_ATTR *pr_attr = va_arg(args, DAT_PROVIDER_ATTR *); + DAT_NAME_PTR name = (DAT_NAME_PTR) dat_handle; + + status = dapli_open_query_ext(name, ia_handle, ia_mask, + ia_attr, pr_mask, pr_attr); + break; + } + case DAT_IB_CLOSE_QUERY_OP: + dapl_dbg_log(DAPL_DBG_TYPE_RTN, + " CLOSE_QUERY extension call\n"); + + status = dapl_ia_close(dat_handle, DAT_CLOSE_ABRUPT_FLAG); + break; + case DAT_IB_RDMA_WRITE_IMMED_OP: dapl_dbg_log(DAPL_DBG_TYPE_RTN, " WRITE_IMMED_DATA extension call\n"); @@ -574,3 +609,116 @@ dapls_cqe_to_event_extension(IN DAPL_EP * ep_ptr, break; } } + +/* + * dapli_open_query_ext + * + * + * Direct link to provider for quick provider query without full IA device open + * + * Input: + * provider name + * ia_attr + * provider_attr + * + * Output: + * ia_attr + * provider_attr + * + * Return Values: + * DAT_SUCCESS + * DAT_INSUFFICIENT_RESOURCES + * DAT_INVALID_PARAMETER + * DAT_INVALID_HANDLE + * DAT_PROVIDER_NOT_FOUND (returned by dat registry if necessary) + */ +DAT_RETURN +dapli_open_query_ext(IN const DAT_NAME_PTR name, + OUT DAT_IA_HANDLE * ia_handle_ptr, + IN DAT_IA_ATTR_MASK ia_mask, + OUT DAT_IA_ATTR * ia_attr, + IN DAT_PROVIDER_ATTR_MASK pr_mask, + OUT DAT_PROVIDER_ATTR * pr_attr) +{ + DAT_RETURN dat_status = DAT_SUCCESS; + DAT_PROVIDER *provider; + DAPL_HCA *hca_ptr = NULL; + DAT_IA_HANDLE ia_ptr = NULL; + + dapl_log(DAPL_DBG_TYPE_EXTENSION, + "dapli_open_query_ext (%s, 0x%llx, %p, 0x%x, %p)\n", + name, ia_mask, ia_attr, pr_mask, pr_attr); + + dat_status = dapl_provider_list_search(name, &provider); + if (DAT_SUCCESS != dat_status) { + dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1); + goto bail; + } + + /* ia_handle_ptr and async_evd_handle_ptr cannot be NULL */ + if ((ia_attr == NULL) && (pr_attr == NULL)) { + return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG5); + } + + /* initialize the caller's OUT param */ + *ia_handle_ptr = DAT_HANDLE_NULL; + + /* get the hca_ptr */ + hca_ptr = (DAPL_HCA *) provider->extension; + + /* log levels could be reset and set between open_query calls */ + if (dapl_os_get_env_val("DAPL_DBG_TYPE", 0)) + g_dapl_dbg_type = dapl_os_get_env_val("DAPL_DBG_TYPE", 0); + + /* + * Open the HCA if it has not been done before. + */ + dapl_os_lock(&hca_ptr->lock); + if (hca_ptr->ib_hca_handle == IB_INVALID_HANDLE) { + /* open in query mode */ + dat_status = dapls_ib_open_hca(hca_ptr->name, + hca_ptr, DAPL_OPEN_QUERY); + if (dat_status != DAT_SUCCESS) { + dapl_dbg_log(DAPL_DBG_TYPE_ERR, + "dapls_ib_open_hca failed %x\n", + dat_status); + dapl_os_unlock(&hca_ptr->lock); + goto bail; + } + } + /* Take a reference on the hca_handle */ + dapl_os_atomic_inc(&hca_ptr->handle_ref_count); + dapl_os_unlock(&hca_ptr->lock); + + /* Allocate and initialize ia structure */ + ia_ptr = (DAT_IA_HANDLE) dapl_ia_alloc(provider, hca_ptr); + if (!ia_ptr) { + dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, DAT_RESOURCE_MEMORY); + goto cleanup; + } + + dat_status = dapl_ia_query(ia_ptr, NULL, ia_mask, ia_attr, pr_mask, pr_attr); + if (dat_status != DAT_SUCCESS) { + dapl_dbg_log(DAPL_DBG_TYPE_ERR, + "dapls_ib_query_hca failed %x\n", dat_status); + goto cleanup; + } + + *ia_handle_ptr = ia_ptr; + return DAT_SUCCESS; + +cleanup: + /* close device and release HCA reference */ + if (ia_ptr) { + dapl_ia_close(ia_ptr, DAT_CLOSE_ABRUPT_FLAG); + } else { + dapl_os_lock(&hca_ptr->lock); + dapls_ib_close_hca(hca_ptr); + hca_ptr->ib_hca_handle = IB_INVALID_HANDLE; + dapl_os_atomic_dec(&hca_ptr->handle_ref_count); + dapl_os_unlock(&hca_ptr->lock); + } +bail: + return dat_status; +} + diff --git a/dapl/openib_common/mem.c b/dapl/openib_common/mem.c index a0ebf6f..8028048 100644 --- a/dapl/openib_common/mem.c +++ b/dapl/openib_common/mem.c @@ -222,6 +222,10 @@ dapls_ib_mr_register(IN DAPL_IA * ia_ptr, } } #endif + dapl_dbg_log(DAPL_DBG_TYPE_UTIL, + " mr_register: ia=%p, lmr=%p va=%p ln=%d return\n", + ia_ptr, lmr, virt_addr, length, privileges); + return DAT_SUCCESS; } diff --git a/dapl/openib_common/util.c b/dapl/openib_common/util.c index 9bea66e..f2a9385 100644 --- a/dapl/openib_common/util.c +++ b/dapl/openib_common/util.c @@ -265,7 +265,25 @@ char *dapl_ib_mtu_str(enum ibv_mtu mtu) } } - +char *dapl_ib_port_str(enum ibv_port_state state) +{ + switch (state) { + case IBV_PORT_NOP: + return "NOP"; + case IBV_PORT_DOWN: + return "DOWN"; + case IBV_PORT_INIT: + return "INIT"; + case IBV_PORT_ARMED: + return "ARMED"; + case IBV_PORT_ACTIVE: + return "ACTIVE"; + case IBV_PORT_ACTIVE_DEFER: + return "DEFER"; + default: + return "UNKNOWN"; + } +} /* * dapls_ib_query_hca @@ -294,18 +312,19 @@ DAT_RETURN dapls_ib_query_hca(IN DAPL_HCA * hca_ptr, struct ibv_device_attr dev_attr; struct ibv_port_attr port_attr; - if (hca_ptr->ib_hca_handle == NULL) { - dapl_dbg_log(DAPL_DBG_TYPE_ERR, " query_hca: BAD handle\n"); - return (DAT_INVALID_HANDLE); - } - /* local IP address of device, set during ia_open */ - if (ip_addr != NULL) + if (ip_addr) memcpy(ip_addr, &hca_ptr->hca_address, sizeof(DAT_SOCK_ADDR6)); if (ia_attr == NULL && ep_attr == NULL) return DAT_SUCCESS; + if (ia_attr != NULL) /* setup address ptr, even with no device */ + ia_attr->ia_address_ptr = (DAT_IA_ADDRESS_PTR) &hca_ptr->hca_address; + + if (hca_ptr->ib_hca_handle == NULL) /* no open device, query mode */ + return DAT_SUCCESS; + /* query verbs for this device and port attributes */ if (ibv_query_device(hca_ptr->ib_hca_handle, &dev_attr) || ibv_query_port(hca_ptr->ib_hca_handle, @@ -325,6 +344,7 @@ DAT_RETURN dapls_ib_query_hca(IN DAPL_HCA * hca_ptr, dapl_os_get_env_val("DAPL_MCM_MSG_MAX", DAT_MIX_RDMA_MAX)); } #endif + if (ia_attr != NULL) { (void)dapl_os_memzero(ia_attr, sizeof(*ia_attr)); strncpy(ia_attr->adapter_name, @@ -390,6 +410,7 @@ DAT_RETURN dapls_ib_query_hca(IN DAPL_HCA * hca_ptr, /* set provider/transport specific named attributes */ hca_ptr->ib_trans.dev_str = ia_attr->adapter_name; hca_ptr->ib_trans.mtu_str = dapl_ib_mtu_str(hca_ptr->ib_trans.mtu); + hca_ptr->ib_trans.port_state_str = dapl_ib_port_str(port_attr.state); hca_ptr->ib_trans.guid = ntohll(ibv_get_device_guid(hca_ptr->ib_trans.ib_dev)); sprintf(hca_ptr->ib_trans.guid_str, "%04x:%04x:%04x:%04x", (unsigned) (hca_ptr->ib_trans.guid >> 48) & 0xffff, @@ -398,7 +419,7 @@ DAT_RETURN dapls_ib_query_hca(IN DAPL_HCA * hca_ptr, (unsigned) (hca_ptr->ib_trans.guid >> 0) & 0xffff); #ifdef _OPENIB_MCM_ hca_ptr->ib_trans.sys_guid = dev_attr.sys_image_guid; /* network order */ - if (hca_ptr->ib_trans.scif_ep) + if (hca_ptr->ib_trans.self.node) hca_ptr->ib_trans.mode_str = "PROXY"; else hca_ptr->ib_trans.mode_str = "DIRECT"; @@ -474,12 +495,13 @@ skip_ib: dapl_log(DAPL_DBG_TYPE_UTIL, " query_hca: msg %llu rdma %llu iov %d lmr %d rmr %d" - " ack_time %d mr %u\n", + " ack_time %d mr %u ia_addr_ptr %p\n", ia_attr->max_message_size, ia_attr->max_rdma_size, ia_attr->max_iov_segments_per_dto, ia_attr->max_lmrs, ia_attr->max_rmrs, hca_ptr->ib_trans.ack_timer, - ia_attr->max_lmr_block_size); + ia_attr->max_lmr_block_size, + ia_attr->ia_address_ptr); } if (ep_attr != NULL) { @@ -692,6 +714,9 @@ DAT_NAMED_ATTR ib_attrs[] = { { "DAT_IB_TRANSPORT_MTU", "2048"} , + { + "DAT_IB_PORT_STATUS", "UNKNOWN"} + , #ifdef DAT_EXTENSIONS { "DAT_EXTENSION_INTERFACE", "TRUE"} @@ -745,15 +770,21 @@ DAT_NAMED_ATTR ib_attrs[] = { void dapls_query_provider_specific_attr(IN DAPL_IA * ia_ptr, IN DAT_PROVIDER_ATTR * attr_ptr) { + attr_ptr->num_provider_specific_attr = SPEC_ATTR_SIZE(ib_attrs); attr_ptr->provider_specific_attr = ib_attrs; + dapl_log(DAPL_DBG_TYPE_UTIL, + " prov_attr: %p sz %d\n", ib_attrs, SPEC_ATTR_SIZE(ib_attrs)); + /* update common attributes from providers */ ib_attrs[1].value = ia_ptr->hca_ptr->ib_trans.dev_str; ib_attrs[2].value = ia_ptr->hca_ptr->ib_trans.mode_str; ib_attrs[3].value = ia_ptr->hca_ptr->ib_trans.read_str; ib_attrs[4].value = ia_ptr->hca_ptr->ib_trans.guid_str; ib_attrs[5].value = ia_ptr->hca_ptr->ib_trans.mtu_str; + ib_attrs[6].value = ia_ptr->hca_ptr->ib_trans.port_state_str; + } /* diff --git a/dapl/openib_mcm/dapl_ib_util.h b/dapl/openib_mcm/dapl_ib_util.h index 21f2112..5f6d77b 100644 --- a/dapl/openib_mcm/dapl_ib_util.h +++ b/dapl/openib_mcm/dapl_ib_util.h @@ -146,6 +146,7 @@ typedef struct _ib_hca_transport char *mtu_str; char *mode_str; char *read_str; + char *port_state_str; } ib_hca_transport_t; @@ -163,7 +164,7 @@ dp_ib_cm_handle_t dapls_cm_create(DAPL_HCA *hca, DAPL_EP *ep); DAT_RETURN dapls_modify_qp_rtu(struct ibv_qp *qp, uint32_t qpn, uint16_t lid, ib_gid_handle_t gid); /* MIC eXchange (MIX) operations */ -int dapli_mix_open(ib_hca_transport_t *tp, char *name, int port); +int dapli_mix_open(ib_hca_transport_t *tp, char *name, int port, int query); void dapli_mix_close(ib_hca_transport_t *tp); int dapli_mix_listen(dp_ib_cm_handle_t cm, uint16_t sid); int dapli_mix_listen_free(dp_ib_cm_handle_t cm); diff --git a/dapl/openib_mcm/device.c b/dapl/openib_mcm/device.c index 544b5e6..309145a 100644 --- a/dapl/openib_mcm/device.c +++ b/dapl/openib_mcm/device.c @@ -157,13 +157,22 @@ int32_t dapls_ib_release(void) * dapl_convert_errno * */ -DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr) +DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, + IN DAPL_HCA * hca_ptr, + IN DAPL_OPEN_FLAGS flags) { struct ibv_device **dev_list; - struct dat_mcm_addr *mcm_ia = &hca_ptr->hca_address; + struct dat_mcm_addr *mcm_ia = (struct dat_mcm_addr *) &hca_ptr->hca_address; struct ibv_port_attr port_attr; int i; - DAT_RETURN dat_status; + DAT_RETURN dat_status = DAT_SUCCESS; + + if (flags & DAPL_OPEN_QUERY) { + dapl_log(DAPL_DBG_TYPE_WARN, + " WARNING! open_hca: %s %s - %p in %s\n", + PROVIDER_NAME, hca_name, hca_ptr, + flags & DAPL_OPEN_QUERY ? "QUERY MODE":""); + } /* Get list of all IB devices, find match, open */ dev_list = ibv_get_device_list(NULL); @@ -240,13 +249,17 @@ found: hca_ptr->ib_trans.mtu = dapl_ib_mtu(dapl_os_get_env_val("DAPL_IB_MTU", DCM_IB_MTU)); - if (dapli_mix_open(&hca_ptr->ib_trans, hca_name, hca_ptr->port_num)) { + if (dapli_mix_open(&hca_ptr->ib_trans, hca_name, + hca_ptr->port_num, flags & DAPL_OPEN_QUERY)) { dapl_log(DAPL_DBG_TYPE_ERR, " open_hca: SCIF init ERR for %s\n", ibv_get_device_name(hca_ptr->ib_trans.ib_dev)); goto err; } + if (flags & DAPL_OPEN_QUERY) + goto done; + /* initialize CM list, LISTEN, SND queue, PSP array, locks */ if ((dapl_os_lock_init(&hca_ptr->ib_trans.lock)) != DAT_SUCCESS) goto err; @@ -305,6 +318,11 @@ found: &hca_ptr->hca_address)->sin_addr), mcm_map_str(hca_ptr->ib_trans.addr.ep_map)); + /* wait for cm_thread */ + while (hca_ptr->ib_trans.cm_state != IB_THREAD_RUN) + dapl_os_sleep_usec(1000); + +done: /* save LID, GID, QPN, PORT address information, for ia_queries */ /* Set AF_INET6 to insure callee address storage of 28 bytes */ hca_ptr->ib_trans.hca = hca_ptr; @@ -316,24 +334,18 @@ found: dapl_log(DAPL_DBG_TYPE_CM, " MCM IA: AF %d LID 0x%x QPN 0x%x GID" " 0x" F64x ":" F64x " port %d ep_map %s sl %d qt %d\n", - mcm_ia->family, ntohl(mcm_ia->qpn), ntohs(mcm_ia->lid), + mcm_ia->family, ntohs(mcm_ia->lid), ntohl(mcm_ia->qpn), (unsigned long long)ntohll(*(uint64_t*)&mcm_ia->gid[0]), (unsigned long long)ntohll(*(uint64_t*)&mcm_ia->gid[8]), - mcm_ia->port, mcm_map_str(mcm_ia->ep_map), mcm_ia->sl, mcm_ia->qp_type); + mcm_ia->port, mcm_map_str(mcm_ia->ep_map), + mcm_ia->sl, mcm_ia->qp_type); ibv_free_device_list(dev_list); - - /* wait for cm_thread */ - while (hca_ptr->ib_trans.cm_state != IB_THREAD_RUN) - dapl_os_sleep_usec(1000); - return dat_status; - bail: mcm_service_destroy(hca_ptr); ibv_close_device(hca_ptr->ib_hca_handle); hca_ptr->ib_hca_handle = IB_INVALID_HANDLE; - err: ibv_free_device_list(dev_list); return DAT_INTERNAL_ERROR; @@ -359,6 +371,9 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr) { dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p\n", hca_ptr); + if (!hca_ptr->ib_trans.cm_state) /* thread never started */ + goto done; + if (hca_ptr->ib_trans.cm_state == IB_THREAD_RUN) { hca_ptr->ib_trans.cm_state = IB_THREAD_CANCEL; dapls_thread_signal(&hca_ptr->ib_trans.signal); @@ -371,12 +386,11 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr) } dapli_mix_close(&hca_ptr->ib_trans); - dapl_os_lock_destroy(&hca_ptr->ib_trans.lock); dapl_os_lock_destroy(&hca_ptr->ib_trans.llock); destroy_os_signal(hca_ptr); mcm_service_destroy(hca_ptr); - +done: if (hca_ptr->ib_trans.ib_cq) ibv_destroy_comp_channel(hca_ptr->ib_trans.ib_cq); @@ -545,7 +559,7 @@ static int mcm_service_create(IN DAPL_HCA *hca) recv_wr.num_sge = 1; sge.length = mlen + hlen; sge.lkey = tp->mr_rbuf->lkey; - rbuf = tp->rbuf; + rbuf = (char *) tp->rbuf; for (i = 0; i < tp->qpe; i++) { recv_wr.wr_id = (uintptr_t) (rbuf + hlen); diff --git a/dapl/openib_mcm/mix.c b/dapl/openib_mcm/mix.c index 97e2e67..da453a7 100644 --- a/dapl/openib_mcm/mix.c +++ b/dapl/openib_mcm/mix.c @@ -75,7 +75,7 @@ static inline void const_ib_wc(struct ibv_wc *iwc, struct dat_mix_wc *mwc, int e * * MIX_IA_OPEN */ -int dapli_mix_open(ib_hca_transport_t *tp, char *name, int port) +int dapli_mix_open(ib_hca_transport_t *tp, char *name, int port, int query_only) { int ret, len; dat_mix_open_t msg; @@ -95,7 +95,7 @@ int dapli_mix_open(ib_hca_transport_t *tp, char *name, int port) } dapl_log(DAPL_DBG_TYPE_EXTENSION," SCIF node_id: %d\n", (uint16_t)tp->self.node); - if (tp->self.node == 0 && !always_proxy) { + if (query_only || (tp->self.node == 0 && !always_proxy)){ dapl_log(DAPL_DBG_TYPE_EXTENSION," Not running on MIC, no MPXY connect required\n"); tp->scif_ep = 0; return 0; diff --git a/dapl/openib_scm/dapl_ib_util.h b/dapl/openib_scm/dapl_ib_util.h index 5ecbb90..80e5f9d 100644 --- a/dapl/openib_scm/dapl_ib_util.h +++ b/dapl/openib_scm/dapl_ib_util.h @@ -117,6 +117,7 @@ typedef struct _ib_hca_transport char *mtu_str; char *mode_str; char *read_str; + char *port_state_str; #ifdef DAT_IB_COLLECTIVES /* Collective member device and address information */ ib_thread_state_t coll_thread_state; diff --git a/dapl/openib_scm/device.c b/dapl/openib_scm/device.c index 1b7e970..ce38eb7 100644 --- a/dapl/openib_scm/device.c +++ b/dapl/openib_scm/device.c @@ -262,27 +262,22 @@ int32_t dapls_ib_release(void) * dapl_convert_errno * */ -DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr) +DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, + IN DAPL_HCA * hca_ptr, + IN DAPL_OPEN_FLAGS flags) { struct ibv_device **dev_list; struct ibv_port_attr port_attr; int i; - DAT_RETURN dat_status; - - dapl_dbg_log(DAPL_DBG_TYPE_UTIL, - " open_hca: %s - %p\n", hca_name, hca_ptr); + DAT_RETURN dat_status = DAT_SUCCESS; - /* get the IP address of the device */ - dat_status = getlocalipaddr((char *)&hca_ptr->hca_address, - sizeof(DAT_SOCK_ADDR6)); - if (dat_status != DAT_SUCCESS) - return dat_status; + if (flags & DAPL_OPEN_QUERY) { + dapl_log(DAPL_DBG_TYPE_WARN, + " WARNING! open_hca: %s %s - %p in %s\n", + PROVIDER_NAME, hca_name, hca_ptr, + flags & DAPL_OPEN_QUERY ? "QUERY MODE":""); + } -#ifdef DAPL_DBG - /* DBG: unused port, set process id, lower 16 bits of pid */ - ((struct sockaddr_in *)&hca_ptr->hca_address)->sin_port = - htons((uint16_t)dapl_os_getpid()); -#endif /* Get list of all IB devices, find match, open */ dev_list = ibv_get_device_list(NULL); if (!dev_list) { @@ -298,7 +293,6 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr) hca_name)) goto found; } - dapl_log(DAPL_DBG_TYPE_ERR, " open_hca: device %s not found\n", hca_name); goto err; @@ -364,6 +358,20 @@ found: hca_ptr->ib_trans.mtu = dapl_ib_mtu(dapl_os_get_env_val("DAPL_IB_MTU", SCM_IB_MTU)); + if (flags & DAPL_OPEN_QUERY) + goto done; + + /* get the IP address of the device */ + dat_status = getlocalipaddr((char *)&hca_ptr->hca_address, + sizeof(DAT_SOCK_ADDR6)); + if (dat_status != DAT_SUCCESS) + return dat_status; + +#ifdef DAPL_DBG + /* DBG: unused port, set process id, lower 16 bits of pid */ + ((struct sockaddr_in *)&hca_ptr->hca_address)->sin_port = + htons((uint16_t)dapl_os_getpid()); +#endif /* EVD events without direct CQ channels, CNO support */ hca_ptr->ib_trans.ib_cq = @@ -432,12 +440,6 @@ found: dapl_os_sleep_usec(1000); } - dapl_log(DAPL_DBG_TYPE_CM, - " SCM IA: devname %s, IB port %d, hostname_IP %s\n", - ibv_get_device_name(hca_ptr->ib_trans.ib_dev), - hca_ptr->port_num, - inet_ntoa(((struct sockaddr_in *) - &hca_ptr->hca_address)->sin_addr)); dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " open_hca: LID 0x%x GID Subnet 0x" F64x " ID 0x" F64x "\n", ntohs(hca_ptr->ib_trans.lid), (unsigned long long) @@ -450,13 +452,20 @@ found: goto bail; #endif +done: + dapl_log(DAPL_DBG_TYPE_CM, + " SCM IA: devname %s, IB port %d, hostname_IP %s\n", + ibv_get_device_name(hca_ptr->ib_trans.ib_dev), + hca_ptr->port_num, + inet_ntoa(((struct sockaddr_in *) + &hca_ptr->hca_address)->sin_addr)); ibv_free_device_list(dev_list); return dat_status; - bail: +bail: ibv_close_device(hca_ptr->ib_hca_handle); hca_ptr->ib_hca_handle = IB_INVALID_HANDLE; - err: +err: ibv_free_device_list(dev_list); return DAT_INTERNAL_ERROR; } @@ -481,10 +490,12 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr) { dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p\n", hca_ptr); + if (!g_ib_thread_state) /* thread never started */ + goto out; + #ifdef DAT_IB_COLLECTIVES dapli_free_collective_service(hca_ptr); #endif - dapl_os_lock(&g_hca_lock); if (g_ib_thread_state != IB_THREAD_RUN) { dapl_os_unlock(&g_hca_lock); diff --git a/dapl/openib_ucm/dapl_ib_util.h b/dapl/openib_ucm/dapl_ib_util.h index dccf7d5..681fd15 100644 --- a/dapl/openib_ucm/dapl_ib_util.h +++ b/dapl/openib_ucm/dapl_ib_util.h @@ -127,6 +127,7 @@ typedef struct _ib_hca_transport char *mtu_str; char *mode_str; char *read_str; + char *port_state_str; #ifdef DAT_IB_COLLECTIVES /* Collective member device and address information */ ib_thread_state_t coll_thread_state; diff --git a/dapl/openib_ucm/device.c b/dapl/openib_ucm/device.c index 477d760..6fd62c8 100644 --- a/dapl/openib_ucm/device.c +++ b/dapl/openib_ucm/device.c @@ -192,15 +192,24 @@ int32_t dapls_ib_release(void) * dapl_convert_errno * */ -DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr) +DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, + IN DAPL_HCA * hca_ptr, + IN DAPL_OPEN_FLAGS flags) { struct ibv_device **dev_list; - union dcm_addr *ucm_ia = &hca_ptr->hca_address; + union dcm_addr *ucm_ia = (union dcm_addr *) &hca_ptr->hca_address; struct ibv_port_attr port_attr; int i; - DAT_RETURN dat_status; + DAT_RETURN dat_status = DAT_SUCCESS; char gid_str[INET6_ADDRSTRLEN]; + if (flags & DAPL_OPEN_QUERY) { + dapl_log(DAPL_DBG_TYPE_WARN, + " WARNING! open_hca: %s %s - %p in %s\n", + PROVIDER_NAME, hca_name, hca_ptr, + flags & DAPL_OPEN_QUERY ? "QUERY MODE":""); + } + /* Get list of all IB devices, find match, open */ dev_list = ibv_get_device_list(NULL); if (!dev_list) { @@ -216,13 +225,11 @@ DAT_RETURN dapls_ib_open_hca(IN IB_HCA_NAME hca_name, IN DAPL_HCA * hca_ptr) hca_name)) goto found; } - dapl_log(DAPL_DBG_TYPE_ERR, " open_hca: device %s not found\n", hca_name); goto err; found: - hca_ptr->ib_hca_handle = ibv_open_device(hca_ptr->ib_trans.ib_dev); if (!hca_ptr->ib_hca_handle) { dapl_log(DAPL_DBG_TYPE_ERR, @@ -278,6 +285,9 @@ found: hca_ptr->ib_trans.mtu = dapl_ib_mtu(dapl_os_get_env_val("DAPL_IB_MTU", DCM_IB_MTU)); + if (flags & DAPL_OPEN_QUERY) + goto done; + /* initialize CM list, LISTEN, SND queue, PSP array, locks */ if ((dapl_os_lock_init(&hca_ptr->ib_trans.lock)) != DAT_SUCCESS) goto err; @@ -336,40 +346,38 @@ found: inet_ntoa(((struct sockaddr_in *) &hca_ptr->hca_address)->sin_addr)); +#ifdef DAT_IB_COLLECTIVES + if (dapli_create_collective_service(hca_ptr)) + goto bail; +#endif + + /* wait for cm_thread */ + while (hca_ptr->ib_trans.cm_state != IB_THREAD_RUN) + dapl_os_sleep_usec(1000); + +done: /* save LID, GID, QPN, PORT address information, for ia_queries */ /* Set AF_INET6 to insure callee address storage of 28 bytes */ hca_ptr->ib_trans.hca = hca_ptr; - hca_ptr->ib_trans.addr.ib.family = AF_INET6; + hca_ptr->ib_trans.addr.ib.family = AF_INET6; hca_ptr->ib_trans.addr.ib.qp_type = IBV_QPT_UD; - memcpy(&hca_ptr->hca_address, - &hca_ptr->ib_trans.addr, + memcpy(&hca_ptr->hca_address, + &hca_ptr->ib_trans.addr, sizeof(union dcm_addr)); dapl_log(DAPL_DBG_TYPE_CM, " UCM IA: AF %d LID 0x%x QPN 0x%x GID" " 0x" F64x ":" F64x " port %d sl %d qt %d\n", - ucm_ia->ib.family, ntohl(ucm_ia->ib.qpn), ntohs(ucm_ia->ib.lid), + ucm_ia->ib.family, ntohs(ucm_ia->ib.lid), ntohl(ucm_ia->ib.qpn), (unsigned long long)ntohll(*(uint64_t*)&ucm_ia->ib.gid[0]), (unsigned long long)ntohll(*(uint64_t*)&ucm_ia->ib.gid[8]), ucm_ia->ib.port, ucm_ia->ib.sl, ucm_ia->ib.qp_type); -#ifdef DAT_IB_COLLECTIVES - if (dapli_create_collective_service(hca_ptr)) - goto bail; -#endif - ibv_free_device_list(dev_list); - - /* wait for cm_thread */ - while (hca_ptr->ib_trans.cm_state != IB_THREAD_RUN) - dapl_os_sleep_usec(1000); - return dat_status; - bail: ucm_service_destroy(hca_ptr); ibv_close_device(hca_ptr->ib_hca_handle); hca_ptr->ib_hca_handle = IB_INVALID_HANDLE; - err: ibv_free_device_list(dev_list); return DAT_INTERNAL_ERROR; @@ -395,6 +403,9 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr) { dapl_dbg_log(DAPL_DBG_TYPE_UTIL, " close_hca: %p\n", hca_ptr); + if (!hca_ptr->ib_trans.cm_state) /* thread never started */ + goto done; + #ifdef DAT_IB_COLLECTIVES dapli_free_collective_service(hca_ptr); #endif @@ -414,7 +425,7 @@ DAT_RETURN dapls_ib_close_hca(IN DAPL_HCA * hca_ptr) dapl_os_lock_destroy(&hca_ptr->ib_trans.llock); destroy_os_signal(hca_ptr); ucm_service_destroy(hca_ptr); - +done: if (hca_ptr->ib_trans.ib_cq) ibv_destroy_comp_channel(hca_ptr->ib_trans.ib_cq); @@ -575,7 +586,7 @@ static int ucm_service_create(IN DAPL_HCA *hca) recv_wr.num_sge = 1; sge.length = mlen + hlen; sge.lkey = tp->mr_rbuf->lkey; - rbuf = tp->rbuf; + rbuf = (char *) tp->rbuf; for (i = 0; i < tp->qpe; i++) { recv_wr.wr_id = (uintptr_t) (rbuf + hlen); diff --git a/dat/common/dat_api.c b/dat/common/dat_api.c index 50ffa2c..a4d77d2 100755 --- a/dat/common/dat_api.c +++ b/dat/common/dat_api.c @@ -1073,7 +1073,20 @@ DAT_RETURN DAT_API dat_srq_set_lw(IN DAT_SRQ_HANDLE srq_handle, #ifdef DAT_EXTENSIONS extern int g_dat_extensions; - +extern DAT_RETURN udat_extension_open(IN const DAT_NAME_PTR name, + IN DAT_EXTENDED_OP ext_op, + IN va_list args); +extern DAT_RETURN udat_extension_close(IN const DAT_NAME_PTR name, + IN DAT_EXTENDED_OP ext_op, + IN va_list args); + +/* Consumer API - dat_extension_op() + * + * Handle == IA, EP, EVD, etc + * !Handle == direct extension operation to provider without device open + * provider name supplied for linkage to library + * + */ DAT_RETURN DAT_API dat_extension_op(IN DAT_HANDLE handle, IN DAT_EXTENDED_OP ext_op, IN ...) { @@ -1081,26 +1094,45 @@ DAT_RETURN DAT_API dat_extension_op(IN DAT_HANDLE handle, DAT_IA_HANDLE dapl_handle; va_list args; - if (handle == NULL) { - return DAT_ERROR(DAT_INVALID_HANDLE, - DAT_INVALID_HANDLE1); - } + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " dat_extension_op: (handle %p, op %d) called\n", + handle, ext_op); /* If not IA handle then just passthrough */ - if (dats_get_ia_handle(handle, &dapl_handle) != DAT_SUCCESS) { + if (dats_get_ia_handle(handle, &dapl_handle) != DAT_SUCCESS) dapl_handle = handle; - } - /* verify provider extension support */ - if (!g_dat_extensions) { + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " dat_extension_op: dapl_handle %p \n", handle); + + /* verify provider extension support, if open */ + if (dapl_handle && !g_dat_extensions) return DAT_ERROR(DAT_NOT_IMPLEMENTED, 0); - } /* extension will validate the handle based on op */ va_start(args, ext_op); - status = DAT_HANDLE_EXTENDEDOP(dapl_handle, ext_op, args); - va_end(args); + if (ext_op & DAT_OPEN_EXTENSION_BASE) { + const DAT_NAME_PTR name = va_arg(args, const DAT_NAME_PTR); + + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " call udat_ext_open: (name %p, %s op %d) called\n", + name, name, handle, ext_op); + if (name == NULL) + status = DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_ARG3); + else + status = udat_extension_open(name, ext_op, args); + + } else if (ext_op & DAT_CLOSE_EXTENSION_BASE) { + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " call udat_ext_close: handle %p\n", handle); + status = udat_extension_close(handle, ext_op, args); + } else { + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " call dat_ext_op: handle %p\n", dapl_handle); + status = DAT_HANDLE_EXTENDEDOP(dapl_handle, ext_op, args); + } + va_end(args); return status; } #endif diff --git a/dat/common/dat_dr.c b/dat/common/dat_dr.c index 0460e81..91a9497 100644 --- a/dat/common/dat_dr.c +++ b/dat/common/dat_dr.c @@ -212,6 +212,30 @@ dat_dr_provider_open(IN const DAT_PROVIDER_INFO * info, return status; } +//*********************************************************************** +// Function: dat_dr_provider_open_ext +//*********************************************************************** +#ifdef DAT_EXTENSIONS +DAT_RETURN +dat_dr_provider_open_ext(IN const DAT_PROVIDER_INFO *info, + OUT DAT_HANDLE_EXTENDEDOP_FUNC *p_ext_func) +{ + DAT_RETURN status; + DAT_DICTIONARY_DATA data; + + dat_os_lock(&g_dr_lock); + status = dat_dictionary_search(g_dr_dictionary, info, &data); + dat_os_unlock(&g_dr_lock); + + if (DAT_SUCCESS == status) { + ((DAT_DR_ENTRY *) data)->ref_count++; + *p_ext_func = ((DAT_DR_ENTRY *)data)->ia_ext_func; + } + + return status; +} +#endif + //*********************************************************************** // Function: dat_dr_provider_close //*********************************************************************** diff --git a/dat/common/dat_dr.h b/dat/common/dat_dr.h index 3012252..2a03e5b 100644 --- a/dat/common/dat_dr.h +++ b/dat/common/dat_dr.h @@ -56,6 +56,9 @@ typedef struct DAT_COUNT ref_count; DAT_IA_OPEN_FUNC ia_open_func; DAT_PROVIDER_INFO info; +#ifdef DAT_EXTENSIONS + DAT_HANDLE_EXTENDEDOP_FUNC ia_ext_func; +#endif /* DAT_EXTENSIONS */ } DAT_DR_ENTRY; @@ -80,12 +83,18 @@ extern DAT_RETURN dat_dr_remove ( IN const DAT_PROVIDER_INFO *info ); - extern DAT_RETURN dat_dr_provider_open ( IN const DAT_PROVIDER_INFO *info, OUT DAT_IA_OPEN_FUNC *p_ia_open_func ); +#ifdef DAT_EXTENSIONS +extern DAT_RETURN +dat_dr_provider_open_ext ( + IN const DAT_PROVIDER_INFO *info, + OUT DAT_HANDLE_EXTENDEDOP_FUNC *p_ext_func ); +#endif + extern DAT_RETURN dat_dr_provider_close ( IN const DAT_PROVIDER_INFO *info); diff --git a/dat/include/dat2/dat.h b/dat/include/dat2/dat.h index cf0b7ec..261c56a 100755 --- a/dat/include/dat2/dat.h +++ b/dat/include/dat2/dat.h @@ -1345,6 +1345,8 @@ extern DAT_RETURN DAT_API dat_srq_set_lw ( IN DAT_COUNT); /* low_watermark */ #ifdef DAT_EXTENSIONS +#define DAT_OPEN_EXTENSION_BASE 0x1000 +#define DAT_CLOSE_EXTENSION_BASE 0x2000 typedef int DAT_EXTENDED_OP; extern DAT_RETURN DAT_API dat_extension_op( IN DAT_HANDLE, /* handle */ diff --git a/dat/include/dat2/dat_ib_extensions.h b/dat/include/dat2/dat_ib_extensions.h index 6e3cb9e..31e7f48 100755 --- a/dat/include/dat2/dat_ib_extensions.h +++ b/dat/include/dat2/dat_ib_extensions.h @@ -74,9 +74,10 @@ * 2.0.5 - Add DAT_IB_UD extended UD connection error events * 2.0.6 - Add MPI over IB collective extensions * 2.0.7 - Add new IA counters for dapl CM, device LINK, device DIAG + * 2.0.8 - Add DAT_IB_OPEN_QUERY_OP, DAT_IB_CLOSE_QUERY_OP, fast provider query interface * */ -#define DAT_IB_EXTENSION_VERSION 207 /* 2.0.7 */ +#define DAT_IB_EXTENSION_VERSION 208 /* 2.0.8 */ #define DAT_IB_ATTR_COUNTERS "DAT_COUNTERS" #define DAT_IB_ATTR_FETCH_AND_ADD "DAT_IB_FETCH_AND_ADD" #define DAT_IB_ATTR_CMP_AND_SWAP "DAT_IB_CMP_AND_SWAP" @@ -154,6 +155,9 @@ typedef enum dat_ib_op DAT_IB_COLLECTIVE_BARRIER_OP, DAT_IB_START_COUNTERS_OP, DAT_IB_STOP_COUNTERS_OP, + /* OPEN and CLOSE extensions require DAT support, set proper range */ + DAT_IB_OPEN_QUERY_OP = DAT_OPEN_EXTENSION_BASE, + DAT_IB_CLOSE_QUERY_OP = DAT_CLOSE_EXTENSION_BASE, } DAT_IB_OP; @@ -747,6 +751,40 @@ dat_strerror_ext_status ( IN (DAT_IB_OP) DAT_IB_STOP_COUNTERS_OP, \ IN (DAT_COUNTER_TYPE) (type)) +/* + * dat_ib_open_query: + * dat_ib_close_query: + * + * Given IA name, open appropriate provider for fast attribute query + * + * OUT: + * ia_handle + * ia_attr + * pr_attr + * + * RETURN VALUE: + * + * DAT_SUCCESS + * DAT_INVALID_HANDLE + * DAT_NOT_IMPLEMENTED + * + */ +#define dat_ib_open_query(name, ia_handle, ia_mask, ia_attr, prov_mask, prov_attr) \ + dat_extension_op(\ + IN (DAT_HANDLE) (NULL), \ + IN (DAT_IB_OP) DAT_IB_OPEN_QUERY_OP, \ + IN (const DAT_NAME_PTR) (name), \ + OUT (DAT_HANDLE *) (ia_handle), \ + IN (DAT_IA_ATTR_MASK) (ia_mask), \ + OUT (DAT_IA_ATTR *) (ia_attr), \ + IN (DAT_PROVIDER_ATTR_MASK) (prov_mask), \ + OUT (DAT_PROVIDER_ATTR *) (prov_attr)) + +#define dat_ib_close_query(ia_handle) \ + dat_extension_op(\ + IN (DAT_HANDLE) (ia_handle), \ + IN (DAT_IB_OP) DAT_IB_CLOSE_QUERY_OP) + /* ************************ MPI IB Collective Functions *********************** */ diff --git a/dat/udat/udat.c b/dat/udat/udat.c index 03edcf9..1b3eee9 100755 --- a/dat/udat/udat.c +++ b/dat/udat/udat.c @@ -106,7 +106,9 @@ dat_registry_add_provider(IN const DAT_PROVIDER * provider, entry.ref_count = 0; entry.ia_open_func = provider->ia_open_func; entry.info = *provider_info; - +#ifdef DAT_EXTENSIONS + entry.ia_ext_func = provider->handle_extendedop_func; +#endif return dat_dr_insert(provider_info, &entry); } @@ -400,6 +402,138 @@ DAT_BOOLEAN udat_check_state(void) return status; } +#ifdef DAT_EXTENSIONS + +/*********************************************************************** + * Function: udat_extension_open - provider name supplied + ***********************************************************************/ +DAT_RETURN DAT_API +udat_extension_open(IN const DAT_NAME_PTR name, + IN DAT_EXTENDED_OP ext_op, + IN va_list args) +{ + DAT_HANDLE_EXTENDEDOP_FUNC prov_ext_func; + DAT_PROVIDER_INFO info; + DAT_OS_SIZE len; + DAT_RETURN dat_status; + + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " udat_extenstion_op(%s,%x:%x,%x,%d) called\n", + name, ext_op, DAT_VERSION_MAJOR, DAT_VERSION_MINOR, DAT_THREADSAFE); + + if (UDAT_IS_BAD_POINTER(name)) { + return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1); + } + + len = dat_os_strlen(name); + + if (DAT_NAME_MAX_LENGTH <= len) { + return DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG1); + } + + if (DAT_FALSE == udat_check_state()) { + return DAT_ERROR(DAT_INVALID_STATE, 0); + } + + dat_os_strncpy(info.ia_name, name, len + 1); + + info.dapl_version_major = DAT_VERSION_MAJOR; + info.dapl_version_minor = DAT_VERSION_MINOR; + info.is_thread_safe = DAT_THREADSAFE; + +#ifndef DAT_NO_STATIC_REGISTRY + (void)dat_sr_provider_open(&info); +#endif + dat_status = dat_dr_provider_open_ext(&info, &prov_ext_func); + if (dat_status != DAT_SUCCESS) { + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " DAT Registry: udat_ext_op () provider information " + "for IA name %s not found in dynamic registry\n", + name); + return dat_status; + } + g_dat_extensions = 1; + dat_status = (*prov_ext_func) (name, ext_op, args); + + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " udat_extension_op () return = 0x%x for IA name %s\n", + dat_status, name); + + if (dat_status != DAT_SUCCESS) { + (void)dat_dr_provider_close(&info); +#ifndef DAT_NO_STATIC_REGISTRY + (void)dat_sr_provider_close(&info); +#endif + } + + return dat_status; +} +/*********************************************************************** + * Function: udat_extension_close - provider handle supplied + ***********************************************************************/ +DAT_RETURN DAT_API +udat_extension_close(IN DAT_IA_HANDLE ia_handle, + IN DAT_EXTENDED_OP ext_op, + IN va_list args) +{ + DAT_PROVIDER *provider; + DAT_PROVIDER_INFO info; + DAT_OS_SIZE len; + DAT_RETURN dat_status; + const char* ia_name; + + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " udat_ext_close_op(ia=%p,op=%x) called\n", + ia_handle, ext_op); + + if (ia_handle == NULL) + return DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA); + + if (DAT_FALSE == udat_check_state()) + return DAT_ERROR(DAT_INVALID_STATE, 0); + + provider = DAT_HANDLE_TO_PROVIDER(ia_handle); + ia_name = provider->device_name; + + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " udat_ext_close_op(ia=%p,op=%x,name=%s) called\n", + ia_handle, ext_op, ia_name); + + dat_status = (*provider->handle_extendedop_func) (ia_handle, ext_op, args); + + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + " udat_extension_op () return = 0x%x for IA name %s\n", + dat_status, ia_name); + + if (dat_status != DAT_SUCCESS) + return dat_status; + + len = dat_os_strlen(ia_name); + dat_os_assert(len < DAT_NAME_MAX_LENGTH); + dat_os_strncpy(info.ia_name, ia_name, len + 1); + info.dapl_version_major = DAT_VERSION_MAJOR; + info.dapl_version_minor = DAT_VERSION_MINOR; + info.is_thread_safe = DAT_THREADSAFE; + + dat_status = dat_dr_provider_close(&info); + if (DAT_SUCCESS != dat_status) { + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + "udat_ext_close_op: dynamic registry unable to close " + "provider for IA name %s\n", ia_name); + } + +#ifndef DAT_NO_STATIC_REGISTRY + dat_status = dat_sr_provider_close(&info); + if (DAT_SUCCESS != dat_status) { + dat_os_dbg_print(DAT_OS_DBG_TYPE_CONSUMER_API, + "udat_ext_close_op: static registry unable to close " + "provider for IA name %s\n", ia_name); + } +#endif + return dat_status; +} +#endif + /* * Local variables: * c-indent-level: 4 diff --git a/test/dtest/dtest.c b/test/dtest/dtest.c index 7bb1488..4b63dfc 100755 --- a/test/dtest/dtest.c +++ b/test/dtest/dtest.c @@ -114,6 +114,7 @@ #define RDMA_BUFFER_SIZE (4*1024*1024) /* Global DAT vars */ +static DAT_IA_HANDLE h_ia_query = DAT_HANDLE_NULL; static DAT_IA_HANDLE h_ia = DAT_HANDLE_NULL; static DAT_PZ_HANDLE h_pz = DAT_HANDLE_NULL; static DAT_EP_HANDLE h_ep = DAT_HANDLE_NULL; @@ -218,6 +219,7 @@ static int burst_msg_posted = 0; static int burst_msg_index = 0; static int ucm = 0; static int write_only = 1; /* only test rdma_writes by default */ +static int query_only = 0; static int rq_cnt, sq_cnt; static DAT_SOCK_ADDR6 remote; @@ -328,6 +330,11 @@ static void print_ia_address(struct sockaddr *sa) { char str[INET6_ADDRSTRLEN] = {" ??? "}; + if (!sa) { + printf("%d Local Address not provided - port %d\n", getpid(), SERVER_CONN_QUAL); + return; + } + switch(sa->sa_family) { case AF_INET: inet_ntop(AF_INET, &((struct sockaddr_in *)sa)->sin_addr, str, INET6_ADDRSTRLEN); @@ -354,11 +361,14 @@ int main(int argc, char **argv) DAT_PROVIDER_ATTR pr_attr; /* parse arguments */ - while ((c = getopt(argc, argv, "Aautscvpq:l:b:d:B:h:P:S:e:")) != -1) { + while ((c = getopt(argc, argv, "AQautscvpq:l:b:d:B:h:P:S:e:")) != -1) { switch (c) { case 'A': /* all tests, msg, rdma read and write */ write_only = 0; break; + case 'Q': /* query only */ + query_only = 1; + break; case 'a': align_data = 1; fflush(stdout); @@ -496,6 +506,42 @@ int main(int argc, char **argv) LOGPRINTF("%d Allocated RMR buffers (r:%p,s:%p) len %d \n", getpid(), p_rmr_rcv, p_rmr_snd, 4096); + /* query_by_name */ + start = get_time(); + ret = dat_ib_open_query(provider, + &h_ia_query, + DAT_IA_FIELD_ALL, &ia_attr, + DAT_PROVIDER_FIELD_PROVIDER_SPECIFIC_ATTR, + &pr_attr); + stop = get_time(); + ts.open += ((stop - start) * 1.0e6); + if (ret != DAT_SUCCESS) { + fprintf(stderr, "%d: Error open_query: %s\n", + getpid(), DT_RetToStr(ret)); + exit(1); + } else + LOGPRINTF("%d Query_by_name \n", getpid()); + + print_ia_address(ia_attr.ia_address_ptr); + + /* Provider specific attributes */ + for (i=0; i