From: Arlin Davis Date: Fri, 11 Jul 2014 15:39:01 +0000 (-0700) Subject: new lightweight open_query/close_query IB extension for fast attribute query X-Git-Tag: dapl-2.1.0-1~18 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=3d5d3cc10a3f1181835a9c0ca227651649e923ff;p=~ardavis%2Fdapl.git 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 --- 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 e43d78d..b6aa814 100644 --- a/dapl/common/dapl_ia_open.c +++ b/dapl/common/dapl_ia_open.c @@ -128,7 +128,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/device.c b/dapl/openib_cma/device.c index a4fc7ff..c64a052 100644 --- a/dapl/openib_cma/device.c +++ b/dapl/openib_cma/device.c @@ -261,15 +261,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); @@ -288,12 +301,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/util.c b/dapl/openib_common/util.c index 258d172..2a612e1 100644 --- a/dapl/openib_common/util.c +++ b/dapl/openib_common/util.c @@ -291,11 +291,6 @@ 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) memcpy(ip_addr, &hca_ptr->hca_address, sizeof(DAT_SOCK_ADDR6)); @@ -303,6 +298,12 @@ DAT_RETURN dapls_ib_query_hca(IN DAPL_HCA * hca_ptr, if (ia_attr == NULL && ep_attr == NULL) return DAT_SUCCESS; + if (ia_attr) /* 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, @@ -456,12 +457,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) { diff --git a/dapl/openib_scm/device.c b/dapl/openib_scm/device.c index 77c64e3..229ea69 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 = @@ -450,13 +458,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 +496,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 91c8466..cae25ac 100644 --- a/dapl/openib_ucm/dapl_ib_util.h +++ b/dapl/openib_ucm/dapl_ib_util.h @@ -27,7 +27,7 @@ #ifndef _DAPL_IB_UTIL_H_ #define _DAPL_IB_UTIL_H_ -#define _OPENIB_SCM_ +#define _OPENIB_UCM_ #include #include "openib_osd.h" diff --git a/dapl/openib_ucm/device.c b/dapl/openib_ucm/device.c index a07d886..e21e55d 100644 --- a/dapl/openib_ucm/device.c +++ b/dapl/openib_ucm/device.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Intel Corporation. All rights reserved. + * Copyright (c) 2009-2014 Intel Corporation. All rights reserved. * * This Software is licensed under one of the following licenses: * @@ -32,6 +32,7 @@ #include "dapl_osd.h" #include +#include #ifdef DAT_IB_COLLECTIVES #include @@ -191,35 +192,39 @@ 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 = (union dcm_addr *) &hca_ptr->hca_address; struct ibv_port_attr port_attr; - int i; - DAT_RETURN dat_status; + int i, nd = 0; + DAT_RETURN dat_status = DAT_INTERNAL_ERROR; + + dapl_log(DAPL_DBG_TYPE_UTIL, " open_hca: %s %s - %p in %s\n", + PROVIDER_NAME, hca_name, hca_ptr, + flags & DAPL_OPEN_QUERY ? "QUERY MODE":"STD MODE"); /* Get list of all IB devices, find match, open */ - dev_list = ibv_get_device_list(NULL); + dev_list = ibv_get_device_list(&nd); if (!dev_list) { dapl_dbg_log(DAPL_DBG_TYPE_ERR, " open_hca: ibv_get_device_list() failed\n", hca_name); return DAT_INTERNAL_ERROR; } - - for (i = 0; dev_list[i]; ++i) { - hca_ptr->ib_trans.ib_dev = dev_list[i]; - if (!strcmp(ibv_get_device_name(hca_ptr->ib_trans.ib_dev), - hca_name)) + dapl_log(DAPL_DBG_TYPE_UTIL," open_hca %p: %d found\n", hca_ptr, nd); + for (i = 0; i < nd; ++i) { + if (!strcmp(dev_list[i]->name, hca_name)) { + hca_ptr->ib_trans.ib_dev = dev_list[i]; goto found; + } } - - dapl_log(DAPL_DBG_TYPE_ERR, - " open_hca: device %s not found\n", hca_name); + dapl_log(DAPL_DBG_TYPE_ERR, " open_hca: %s not found\n", hca_name); + dat_status = DAT_PROVIDER_NOT_FOUND; 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, @@ -238,8 +243,13 @@ found: " open_hca: get lid ERR for %s, err=%s\n", ibv_get_device_name(hca_ptr->ib_trans.ib_dev), strerror(errno)); - goto err; + dat_status = DAT_INVALID_ADDRESS; + goto bail; } else { + if (port_attr.state != IBV_PORT_ACTIVE) { + dat_status = DAT_INVALID_ADDRESS; + goto bail; + } hca_ptr->ib_trans.addr.ib.lid = htons(port_attr.lid); hca_ptr->ib_trans.lid = htons(port_attr.lid); } @@ -252,7 +262,8 @@ found: " open_hca: query GID ERR for %s, err=%s\n", ibv_get_device_name(hca_ptr->ib_trans.ib_dev), strerror(errno)); - goto err; + dat_status = DAT_INVALID_ADDRESS; + goto bail; } /* set RC tunables via enviroment or default */ @@ -275,18 +286,21 @@ 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; + goto bail; if ((dapl_os_lock_init(&hca_ptr->ib_trans.llock)) != DAT_SUCCESS) - goto err; + goto bail; if ((dapl_os_lock_init(&hca_ptr->ib_trans.slock)) != DAT_SUCCESS) - goto err; + goto bail; if ((dapl_os_lock_init(&hca_ptr->ib_trans.plock)) != DAT_SUCCESS) - goto err; + goto bail; /* EVD events without direct CQ channels, CNO support */ hca_ptr->ib_trans.ib_cq = @@ -332,46 +346,44 @@ found: hca_ptr->port_num, inet_ntoa(((struct sockaddr_in *) &hca_ptr->hca_address)->sin_addr)); - dapl_dbg_log(DAPL_DBG_TYPE_UTIL, - " open_hca: QPN 0x%x LID 0x%x GID Subnet 0x" F64x "" - " ID 0x" F64x "\n", - ntohl(hca_ptr->ib_trans.addr.ib.qpn), - ntohs(hca_ptr->ib_trans.addr.ib.lid), - (unsigned long long) - ntohll(*(uint64_t*)&hca_ptr->ib_trans.addr.ib.gid[0]), - (unsigned long long) - ntohll(*(uint64_t*)&hca_ptr->ib_trans.addr.ib.gid[8])); - - /* 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.qp_type = IBV_QPT_UD; - memcpy(&hca_ptr->hca_address, - &hca_ptr->ib_trans.addr, - sizeof(union dcm_addr)); #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; +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.qp_type = IBV_QPT_UD; + 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, 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); + + ibv_free_device_list(dev_list); + return DAT_SUCCESS; bail: ucm_service_destroy(hca_ptr); ibv_close_device(hca_ptr->ib_hca_handle); hca_ptr->ib_hca_handle = IB_INVALID_HANDLE; - + hca_ptr->ib_trans.ib_ctx = NULL; + hca_ptr->ib_trans.ib_dev = NULL; err: ibv_free_device_list(dev_list); - return DAT_INTERNAL_ERROR; + return dat_status; } /* @@ -394,6 +406,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 @@ -413,7 +428,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); diff --git a/dat/common/dat_api.c b/dat/common/dat_api.c index 7ca81a9..0c28c11 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,28 +1094,48 @@ DAT_RETURN DAT_API dat_extension_op(IN DAT_HANDLE handle, DAT_IA_HANDLE dapl_handle = 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); /* only convert if ia_handle vector */ - if (dats_is_ia_handle(handle)) { - if (dats_get_ia_handle(handle, &dapl_handle)) - return DAT_ERROR(DAT_INVALID_HANDLE, - DAT_INVALID_HANDLE1); - } - - /* verify provider extension support */ - if (!g_dat_extensions) { - return DAT_ERROR(DAT_NOT_IMPLEMENTED, 0); + if (handle && dats_is_ia_handle(handle)) { + if (dats_get_ia_handle(handle, &dapl_handle)) + return DAT_ERROR(DAT_INVALID_HANDLE, + DAT_INVALID_HANDLE1); } + 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 842b36c..1e4fa57 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); } @@ -406,6 +408,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