Пример #1
0
static int open_device(char *ib_devname)
{
	struct ibv_device **dev_list;
	int i = 0;

	dev_list = ibv_get_device_list(NULL);
	if (!dev_list) {
		fprintf(stderr, "Failed to get IB devices list");
		return -1;
	}

	if (ib_devname) {
		for (; dev_list[i]; ++i) {
			if (!strcmp(ibv_get_device_name(dev_list[i]), ib_devname))
				break;
		}
	}
	if (!dev_list[i]) {
		fprintf(stderr, "IB device %s not found\n",
			ib_devname ? ib_devname : "");
		return -1;
	}

	ctx.context = ibv_open_device(dev_list[i]);
	if (!ctx.context) {
		fprintf(stderr, "Couldn't get context for %s\n",
			ibv_get_device_name(dev_list[i]));
		return -1;
	}

	ibv_free_device_list(dev_list);
	return 0;
}
Пример #2
0
static struct ibv_context *get_device_context(const char *device_name)
{
	struct ibv_device **device_list;
	struct ibv_context *ctx = NULL;
	int num_devices;
	int i;

	device_list = ibv_get_device_list(&num_devices);
	if (!device_list) {
		fprintf(stderr, "Error, ibv_get_device_list() failed\n");
		return NULL;
	}

	for (i = 0; i < num_devices; ++ i) {
		/* if this isn't the requested device */
		if (strcmp(ibv_get_device_name(device_list[i]), device_name))
			continue;

		ctx = ibv_open_device(device_list[i]);
		if (!ctx) {
			fprintf(stderr, "Error, failed to open the device '%s'\n",
				ibv_get_device_name(device_list[i]));
			goto out;
		}

		printf("The device '%s' was detected\n", device_name);
		break;
	}

out:
	ibv_free_device_list(device_list);

	return ctx;
}
Пример #3
0
static int fi_ibv_open_device_by_name(struct fi_ibv_domain *domain, const char *name)
{
	struct ibv_context **dev_list;
	int i, ret = -FI_ENODEV;

	if (!name)
		return -FI_EINVAL;

	dev_list = rdma_get_devices(NULL);
	if (!dev_list)
		return -errno;

	for (i = 0; dev_list[i] && ret; i++) {
		if (domain->rdm) {
			ret = strncmp(name, ibv_get_device_name(dev_list[i]->device),
				      strlen(name) - strlen(verbs_rdm_domain.suffix));

		} else {
			ret = strcmp(name, ibv_get_device_name(dev_list[i]->device));
		}

		if (!ret)
			domain->verbs = dev_list[i];
	}
	rdma_free_devices(dev_list);
	return ret;
}
Пример #4
0
int main(void)
{
  hwloc_topology_t topology;
  struct ibv_device **dev_list, *dev;
  int count, i;
  int err;

  dev_list = ibv_get_device_list(&count);
  if (!dev_list) {
    fprintf(stderr, "ibv_get_device_list failed\n");
    return 0;
  }
  printf("ibv_get_device_list found %d devices\n", count);

  hwloc_topology_init(&topology);
  hwloc_topology_set_type_filter(topology, HWLOC_OBJ_PCI_DEVICE, HWLOC_TYPE_FILTER_KEEP_IMPORTANT);
  hwloc_topology_set_type_filter(topology, HWLOC_OBJ_OS_DEVICE, HWLOC_TYPE_FILTER_KEEP_IMPORTANT);
  hwloc_topology_load(topology);

  for(i=0; i<count; i++) {
    hwloc_bitmap_t set;
    dev = dev_list[i];

    set = hwloc_bitmap_alloc();
    err = hwloc_ibv_get_device_cpuset(topology, dev, set);
    if (err < 0) {
      printf("failed to get cpuset for device %d (%s)\n",
	     i, ibv_get_device_name(dev));
    } else {
      char *cpuset_string = NULL;
      hwloc_obj_t os;

      hwloc_bitmap_asprintf(&cpuset_string, set);
      printf("got cpuset %s for device %d (%s)\n",
	     cpuset_string, i, ibv_get_device_name(dev));
      free(cpuset_string);

      os = hwloc_ibv_get_device_osdev(topology, dev);
      if (os) {
	assert(os->type == HWLOC_OBJ_OS_DEVICE);
	printf("found OS object subtype %u lindex %u name %s\n",
	       (unsigned) os->attr->osdev.type, os->logical_index, os->name);
	assert(os->attr->osdev.type == HWLOC_OBJ_OSDEV_OPENFABRICS);
	if (strcmp(ibv_get_device_name(dev), os->name))
	  assert(0);
      }
    }
    hwloc_bitmap_free(set);
  }

  hwloc_topology_destroy(topology);

  ibv_free_device_list(dev_list);

  return 0;
}
/* Quere for the XOOB priority - will be highest in XRC case */
static int xoob_component_query(mca_btl_openib_module_t *openib_btl, 
        ompi_btl_openib_connect_base_module_t **cpc)
{
    int rc;

    if (mca_btl_openib_component.num_xrc_qps <= 0) {
        opal_output_verbose(5, mca_btl_base_output,
                            "openib BTL: xoob CPC only supported with XRC receive queues; skipped on %s:%d",
                            ibv_get_device_name(openib_btl->device->ib_dev),
                            openib_btl->port_num);
        return OMPI_ERR_NOT_SUPPORTED;
    }

    *cpc = malloc(sizeof(ompi_btl_openib_connect_base_module_t));
    if (NULL == *cpc) {
        opal_output_verbose(5, mca_btl_base_output,
                            "openib BTL: xoob CPC system error (malloc failed)");
        return OMPI_ERR_OUT_OF_RESOURCE;
    }

    /* If this btl supports XOOB, then post the RML message.  But
       ensure to only post it *once*, because another btl may have
       come in before this and already posted it. */
    if (!rml_recv_posted) {
        rc = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, 
                                     OMPI_RML_TAG_XOPENIB,
                                     ORTE_RML_PERSISTENT,
                                     xoob_rml_recv_cb,
                                     NULL);
        if (ORTE_SUCCESS != rc) {
            opal_output_verbose(5, mca_btl_base_output,
                                "openib BTL: xoob CPC system error %d (%s)",
                                rc, opal_strerror(rc));
            return rc;
        }
        rml_recv_posted = true;
    }
        
    (*cpc)->data.cbm_component = &ompi_btl_openib_connect_xoob;
    (*cpc)->data.cbm_priority = xoob_priority;
    (*cpc)->data.cbm_modex_message = NULL;
    (*cpc)->data.cbm_modex_message_len = 0;

    (*cpc)->cbm_endpoint_init = NULL;
    (*cpc)->cbm_start_connect = xoob_module_start_connect;
    (*cpc)->cbm_endpoint_finalize = NULL;
    (*cpc)->cbm_finalize = NULL;
    (*cpc)->cbm_uses_cts = false;

    opal_output_verbose(5, mca_btl_base_output,
                        "openib BTL: xoob CPC available for use on %s:%d",
                        ibv_get_device_name(openib_btl->device->ib_dev),
                        openib_btl->port_num);
    return OMPI_SUCCESS;
}
/* Unload devices */
static int iboffload_release_devices(void)
{
    int i;
    mca_bcol_iboffload_device_t *device = NULL;

    mca_bcol_iboffload_component_t *cm = &mca_bcol_iboffload_component;
    opal_pointer_array_t *devs = &cm->devices;

    IBOFFLOAD_VERBOSE(10, ("Destroy all devices.\n"));

    for (i = 0; i < cm->num_devs; i++) {
        device = opal_pointer_array_get_item(devs, i);

        IBOFFLOAD_VERBOSE(10, ("Device %s with index %d will be destroyed.\n",
                               ibv_get_device_name(device->dev.ib_dev), i));
        if (NULL != device) {
            OBJ_RELEASE(device);
        }
    }

    IBOFFLOAD_VERBOSE(10, ("All devices were destroyed.\n"));

    opal_pointer_array_remove_all(devs);
    OBJ_DESTRUCT(devs);

    /* release device list */
    /*ibv_free_device_list_compat(cm->ib_devs);*/
    ompi_ibv_free_device_list(cm->ib_devs);
    cm->ib_devs = NULL;

    IBOFFLOAD_VERBOSE(10, ("All devices destroyed.\n"));

    return OMPI_SUCCESS;
}
Пример #7
0
/*
 * Function: rdma_find_active_port
 *
 * Description:
 *      Finds if the given device has any active ports.
 *
 * Input:
 *      context -   Pointer to the device context obtained by opening device.
 *      ib_dev  -   Pointer to the device from ibv_get_device_list.
 *
 * Return:
 *      Success:    Port number of the active port.
 *      Failure:    ERROR (-1).
 */
static int rdma_find_active_port(struct ibv_context *context,struct ibv_device *ib_dev)
{
    int j = 0;
    const char *dev_name = NULL;
    struct ibv_port_attr port_attr;

    if (NULL == ib_dev) {
        return -1;
    } else {
        dev_name = ibv_get_device_name(ib_dev);
    }

    for (j = 1; j <= RDMA_DEFAULT_MAX_PORTS; ++ j) {
        if ((! ibv_query_port(context, j, &port_attr)) &&
             port_attr.state == IBV_PORT_ACTIVE) {
            if (!strncmp(dev_name, "cxgb3", 5) || !strncmp(dev_name, "cxgb4", 5)
                || port_attr.lid) {
                /* Chelsio RNIC's don't get LID's as they're not IB devices.
                 * So dont do this check for them.
                 */
                DEBUG_PRINT("Active port number = %d, state = %s, lid = %d\r\n",
                    j, (port_attr.state==IBV_PORT_ACTIVE)?"Active":"Not Active",
                    port_attr.lid);
                return j;
            }
        }
    }

    return -1;
}
Пример #8
0
static int fi_ibv_add_rai(struct dlist_entry *verbs_devs, struct rdma_cm_id *id,
		struct rdma_addrinfo *rai)
{
	struct verbs_dev_info *dev;
	struct verbs_addr *addr;
	const char *dev_name;

	if (!(addr = malloc(sizeof(*addr))))
		return -FI_ENOMEM;

	addr->rai = rai;

	dev_name = ibv_get_device_name(id->verbs->device);
	dlist_foreach_container(verbs_devs, struct verbs_dev_info, dev, entry)
		if (!strcmp(dev_name, dev->name))
			goto add_rai;

	if (!(dev = malloc(sizeof(*dev))))
		goto err1;

	if (!(dev->name = strdup(dev_name)))
		goto err2;

	dlist_init(&dev->addrs);
	dlist_insert_tail(&dev->entry, verbs_devs);
add_rai:
	dlist_insert_tail(&addr->entry, &dev->addrs);
	return 0;
err2:
	free(dev);
err1:
	free(addr);
	return -FI_ENOMEM;
}
Пример #9
0
int fi_ibv_getinfo(uint32_t version, const char *node, const char *service,
		   uint64_t flags, struct fi_info *hints, struct fi_info **info)
{
	struct rdma_cm_id *id = NULL;
	struct rdma_addrinfo *rai;
	int ret;

	ret = fi_ibv_init_info();
	if (ret)
		goto out;

	ret = fi_ibv_create_ep(node, service, flags, hints, &rai, &id);
	if (ret)
		goto out;

	if (id->verbs) {
		ret = fi_ibv_get_matching_info(ibv_get_device_name(id->verbs->device),
					       hints, rai, info);
	} else {
		ret = fi_ibv_get_matching_info(NULL, hints, rai, info);
	}

	ofi_alter_info(*info, hints);

	fi_ibv_destroy_ep(rai, &id);

out:
	if (!ret || ret == -FI_ENOMEM || ret == -FI_ENODEV)
		return ret;
	else
		return -FI_ENODATA;
}
Пример #10
0
static int print_device_info(void) {
  struct ibv_device ** ibv_devs;
  int i = 0;
  /*TODO: get num_devs automatically*/
  int num_devs = 1;
  /*NULL => get all devices*/

  ibv_devs = ibv_get_device_list(NULL);

  for (i = 0; i < num_devs; i++) {
    struct ibv_context *ibv_contxt;
    struct ibv_device_attr device_attr;
    char *dev_name;
    uint64_t dev_guid;

    ibv_contxt = ibv_open_device (ibv_devs[i]);

    dev_name = ibv_get_device_name(ibv_devs[i]);
    dev_guid = ibv_get_device_guid(ibv_devs[i]);
    printf("%s (%d):\n", dev_name, dev_guid);
    ibv_query_device (ibv_contxt, &device_attr);
    printf("      Record           : %d\n", i);
    printf("         max_mr_size   : %llu\n", device_attr.max_mr_size);
    printf("         max_mr        : %llu\n", device_attr.max_mr);

    ibv_close_device (ibv_contxt);
  }

  ibv_free_device_list(ibv_devs);
  return 0;
}
Пример #11
0
static void mlx4_check_numa_enabled(struct ibv_context *context)
{
	char fname[MAXPATHLEN];
	char buf[128];
	FILE *fp;
	int numa_enabled;
	char env[VERBS_MAX_ENV_VAL];

	snprintf(fname, MAXPATHLEN, "/sys/class/infiniband/%s/device/numa_node",
		 ibv_get_device_name(context->device));

	fp = fopen(fname, "r");
	if (!fp) {
		fprintf(stderr, PFX "Warning: can not check if NUMA is enabled "
			"on node: failed to open %s\n", fname);
		return;
	}

	if (!fgets(buf, sizeof(buf), fp)) {
		fprintf(stderr, PFX "Warning: can not check if NUMA is enabled "
			"on node: failed to read numa node value\n");
		goto out;
	}

	numa_enabled = (strtol(buf, 0, 10) >= 0);
	if (numa_enabled)
		printf(PFX "Device NUMA node detection is supported\n");
	else if (ibv_exp_cmd_getenv(context, "MLX4_LOCAL_CPUS", env, sizeof(env)))
		printf(PFX "Warning: Device NUMA node detection is not supported. "
		       "Please consider setting the environment variable "
			"'MLX4_LOCAL_CPUS' or enable ACPI SLIT\n");
out:
	fclose(fp);
}
Пример #12
0
ucs_status_t uct_ud_ep_connect_to_ep(uct_ud_ep_t *ep,
                                     const struct sockaddr *addr)
{
    uct_ud_iface_t *iface = ucs_derived_of(ep->super.super.iface, uct_ud_iface_t);
    uct_ib_device_t *dev = uct_ib_iface_device(&iface->super);
    const uct_sockaddr_ib_t *ib_addr = (uct_sockaddr_ib_t *)addr;

    ucs_assert_always(ep->dest_ep_id == UCT_UD_EP_NULL_ID);
    ucs_trace_func("");

    ep->dest_ep_id = ib_addr->id;
    ep->dest_qpn   = ib_addr->qp_num;

    uct_ud_ep_reset(ep);

    ucs_debug("%s:%d slid=%d qpn=%d ep=%u connected to dlid=%d qpn=%d ep=%u", 
              ibv_get_device_name(dev->ibv_context->device),
              iface->super.port_num,
              dev->port_attr[iface->super.port_num-dev->first_port].lid,
              iface->qp->qp_num,
              ep->ep_id, 
              ib_addr->lid, ep->dest_qpn, ep->dest_ep_id);

    return UCS_OK;
}
Пример #13
0
static void
update_read_info_hwnames()
{
	struct ibv_device **dev_list;
	int num_devices, i;
	uint64_t	dev_guid;
	char		*dev_name;
	size_t		dev_name_len;

	dev_list = ibv_get_device_list(&num_devices);
	if (!dev_list) {
		fprintf(stderr, "No IB devices found\n");
		return;
	}

	for (i = 0; i < num_devices; ++i) {
		int	j;

		dev_guid = (uint64_t)ntohll(ibv_get_device_guid(dev_list[i]));
		dev_name = (char *)ibv_get_device_name(dev_list[i]);
		dev_name_len = strlen(dev_name) + 1;
		for (j = 0; j < nd_read_info_cnt; j++) {
			if (nd_read_info_arr[j].info_valid == B_TRUE &&
			    nd_read_info_arr[j].guid == dev_guid) {
				memcpy(nd_read_info_arr[j].ofuv_name,
				    dev_name, dev_name_len);
				nd_read_info_arr[j].ofuv_name_valid = B_TRUE;
				break;
			}
		}
	}

	ibv_free_device_list(dev_list);
}
Пример #14
0
/*
man cpuset

  This format displays each 32-bit word in hexadecimal (using ASCII characters "0" - "9" and "a" - "f"); words
  are filled with leading zeros, if required. For masks longer than one word, a comma separator is used between
  words. Words are displayed in big-endian order, which has the most significant bit first. The hex digits
  within a word are also in big-endian order.

  The number of 32-bit words displayed is the minimum number needed to display all bits of the bitmask, based on
  the size of the bitmask.

  Examples of the Mask Format:

     00000001                        # just bit 0 set
     40000000,00000000,00000000      # just bit 94 set
     000000ff,00000000               # bits 32-39 set
     00000000,000E3862               # 1,5,6,11-13,17-19 set

  A mask with bits 0, 1, 2, 4, 8, 16, 32, and 64 set displays as:

     00000001,00000001,00010117

  The first "1" is for bit 64, the second for bit 32, the third for bit 16, the fourth for bit 8, the fifth for
  bit 4, and the "7" is for bits 2, 1, and 0.
*/
static void mlx5_local_cpu_set(struct mlx5_context *ctx, cpu_set_t *cpu_set)
{
	char *p, buf[1024];
	char env_value[VERBS_MAX_ENV_VAL];
	uint32_t word;
	int i, k;
	struct ibv_context *context = &ctx->ibv_ctx;

	if (!ibv_exp_cmd_getenv(context, "MLX5_LOCAL_CPUS", env_value, sizeof(env_value)))
		strncpy(buf, env_value, sizeof(buf));
	else {
		char fname[MAXPATHLEN];
		FILE *fp;

		snprintf(fname, MAXPATHLEN, "/sys/class/infiniband/%s/device/local_cpus",
			 ibv_get_device_name(context->device));

		fp = fopen(fname, "r");
		if (!fp) {
			fprintf(stderr, PFX "Warning: can not get local cpu set: failed to open %s\n", fname);
			return;
		}
		if (!fgets(buf, sizeof(buf), fp)) {
			fprintf(stderr, PFX "Warning: can not get local cpu set: failed to read cpu mask\n");
			fclose(fp);
			return;
		}
		fclose(fp);
	}

	p = strrchr(buf, ',');
	if (!p)
		p = buf;

	i = 0;
	do {
		if (*p == ',') {
			*p = 0;
			p ++;
		}

		word = strtoul(p, 0, 16);

		for (k = 0; word; ++k, word >>= 1)
			if (word & 1)
				CPU_SET(k+i, cpu_set);

		if (p == buf)
			break;

		p = strrchr(buf, ',');
		if (!p)
			p = buf;

		i += 32;
	} while (i < CPU_SETSIZE);
}
Пример #15
0
static struct fi_info *
fi_ibv_eq_cm_getinfo(struct fi_ibv_fabric *fab, struct rdma_cm_event *event,
		struct fi_info *pep_info)
{
	struct fi_info *info, *fi;
	struct fi_ibv_connreq *connreq;
	const char *devname = ibv_get_device_name(event->id->verbs->device);

	if (strcmp(devname, fab->info->domain_attr->name)) {
		fi = fi_ibv_get_verbs_info(fab->all_infos, devname);
		if (!fi)
			return NULL;
	} else {
		fi = fab->info;
	}

	info = fi_dupinfo(fi);
	if (!info)
		return NULL;

	info->fabric_attr->fabric = &fab->util_fabric.fabric_fid;
	if (!(info->fabric_attr->prov_name = strdup(VERBS_PROV_NAME)))
		goto err;

	ofi_alter_info(info, pep_info, fab->util_fabric.fabric_fid.api_version);

	info->src_addrlen = fi_ibv_sockaddr_len(rdma_get_local_addr(event->id));
	if (!(info->src_addr = malloc(info->src_addrlen)))
		goto err;
	memcpy(info->src_addr, rdma_get_local_addr(event->id), info->src_addrlen);

	info->dest_addrlen = fi_ibv_sockaddr_len(rdma_get_peer_addr(event->id));
	if (!(info->dest_addr = malloc(info->dest_addrlen)))
		goto err;
	memcpy(info->dest_addr, rdma_get_peer_addr(event->id), info->dest_addrlen);

	VERBS_INFO(FI_LOG_CORE, "src_addr: %s:%d\n",
		   inet_ntoa(((struct sockaddr_in *)info->src_addr)->sin_addr),
		   ntohs(((struct sockaddr_in *)info->src_addr)->sin_port));

	VERBS_INFO(FI_LOG_CORE, "dst_addr: %s:%d\n",
		   inet_ntoa(((struct sockaddr_in *)info->dest_addr)->sin_addr),
		   ntohs(((struct sockaddr_in *)info->dest_addr)->sin_port));

	connreq = calloc(1, sizeof *connreq);
	if (!connreq)
		goto err;

	connreq->handle.fclass = FI_CLASS_CONNREQ;
	connreq->id = event->id;
	info->handle = &connreq->handle;
	return info;
err:
	fi_freeinfo(info);
	return NULL;
}
Пример #16
0
static
struct ibv_device *psofed_get_dev_by_hca_name(const char *in_hca_name)
{
	/* new method with ibv_get_device_list() */
	struct ibv_device **dev_list;
	struct ibv_device *ib_dev = NULL;
	int dev_list_count;

	dev_list = ibv_get_device_list(&dev_list_count);
	if (!dev_list) goto err_no_dev;
	if (!in_hca_name) {
		// const char *tmp;
		ib_dev = dev_list[0];

		// tmp = ibv_get_device_name(ib_dev);

		// psofed_dprint(2, "Got IB device \"%s\"", tmp);

		if (!ib_dev) goto err_no_dev2;
	} else {
		int i;
		for (i = 0; i < dev_list_count; i++) {
			ib_dev = dev_list[i];
			if (!ib_dev) break;
			const char *tmp = ibv_get_device_name(ib_dev);
			if (!strcmp(tmp, in_hca_name)) {
				// psofed_dprint(2, "Got IB device \"%s\"", tmp);
				break;
			}
			ib_dev = NULL;
		}
		if (!ib_dev) goto err_no_dev_name;
	}
	ibv_free_device_list(dev_list);

	return ib_dev;
	/* --- */
err_no_dev:
	psofed_err_errno("ibv_get_devices() failed : No IB dev found", errno);
	return 0;
	/* --- */
err_no_dev2:
	psofed_err_errno("ibv_get_devices() failed : IB dev list empty", errno);
	ibv_free_device_list(dev_list);
	return 0;
	/* --- */
err_no_dev_name:
	{
		static char err_str[50];
		snprintf(err_str, sizeof(err_str), "IB device \"%s\"", in_hca_name);
		psofed_err_errno(err_str, ENODEV);
		ibv_free_device_list(dev_list);
		return 0;
	}
}
Пример #17
0
ibv_context* open_default_device() {
  ibv_device** dev_list;
  ibv_device* ib_dev;
  dev_list = ibv_get_device_list(NULL);
  CHECK(dev_list) << "No InfiniBand device found";
  ib_dev = dev_list[0];
  CHECK(ib_dev) << "No InfiniBand device found";
  ibv_context* context = ibv_open_device(ib_dev);
  CHECK(context) << "Open context failed for " << ibv_get_device_name(ib_dev);
  return context;
}
Пример #18
0
static int get_pathrecord_sl(struct ibv_context *context_arg,
                      uint32_t port_num,
                      uint16_t lid,
                      uint16_t rem_lid)
{
    struct ibv_send_wr swr;
    ib_sa_mad_t *req_mad, *resp_mad;
    struct ibv_sge ssge;
    struct mca_btl_openib_sa_qp_cache *cache;
    long page_size = sysconf(_SC_PAGESIZE);
    int rc;

    /* search for a cached item */
    for (cache = sa_qp_cache; cache; cache = cache->next) {
        if (0 == strcmp(cache->device_name,
                    ibv_get_device_name(context_arg->device))
                && cache->port_num == port_num) {
            break;
        }
    }

    if (NULL == cache) {
        /* init new cache */
        if (posix_memalign((void **)(&cache), page_size,
                    sizeof(struct mca_btl_openib_sa_qp_cache))) {
            BTL_ERROR(("error in posix_memalign SA cache"));
            return OPAL_ERROR;
        }
        /* one time setup for each device/port combination */
        rc = init_device(context_arg, cache, port_num);
        if (0 != rc) {
            return rc;
        }
    }

    /* if the destination lid SL value is not in the cache, go get it */
    if (SL_NOT_PRESENT == cache->sl_values[rem_lid]) {
        /* sa_mad is first buffer, where we build the SA Get request to send */
        req_mad = (ib_sa_mad_t *)(cache->send_recv_buffer);

        init_sa_mad(cache, req_mad, &swr, &ssge, lid, rem_lid);

        /* resp_mad is the receive buffer (40 byte offset is for GRH) */
        resp_mad = (ib_sa_mad_t *)(cache->send_recv_buffer + MAD_BLOCK_SIZE + 40);

        rc = get_pathrecord_info(cache, req_mad, resp_mad, &swr, lid, rem_lid);
        if (0 != rc) {
            return rc;
        }
    }

    /* now all we do is send back the value laying around */
    return cache->sl_values[rem_lid];
}
Пример #19
0
static
void psofed_scan_hca_ports(struct ibv_device *ib_dev)
{
	struct ibv_context *ctx;
	struct ibv_device_attr device_attr;
	int rc;
	unsigned port_cnt;
	unsigned port;
	const char *dev_name;

	dev_name =ibv_get_device_name(ib_dev);
	if (!dev_name) dev_name = "unknown";

	ctx = ibv_open_device(ib_dev);
	if (!ctx) goto err_open_dev;

	rc = ibv_query_device(ctx, &device_attr);
	if (!rc) {
		port_cnt = device_attr.phys_port_cnt;
		if (port_cnt > 128) port_cnt = 128;
	} else {
		// Query failed. Assume 2 ports.
		port_cnt = 2;
	}

	for (port = 1; port <= port_cnt; port++) {
		struct ibv_port_attr port_attr;
		enum ibv_port_state port_state;
		const char *marker;

		rc = ibv_query_port(ctx, port, &port_attr);
		port_state = !rc ? port_attr.state : 999 /* unknown */;

		marker = "";
		if (port_state == IBV_PORT_ACTIVE &&
		    (!psofed_hca || !strcmp(dev_name, psofed_hca)) &&
		    (!psofed_port || psofed_port == port)) {
			// use this port for the communication:

			if (!psofed_hca) psofed_hca = strdup(dev_name);
			if (!psofed_port) psofed_port = port;
			marker = "*";
		}

		psofed_dprint(3, "IB port <%s:%u>: %s%s",
			      dev_name, port, port_state_str(port_state), marker);
	}

	if (ctx) ibv_close_device(ctx);

err_open_dev:
	return;
}
Пример #20
0
/*
 * Convenience function. Given the name of an HFI,
 * returns the ibv_device structure associated with it.
 * Returns NULL if the HFI could not be found.
 *
 * HFI can be identified by name ("mthfi0") or by number
 * "1", "2", et cetera.
 *
 * OPENS THE HFI! Use ibv_close_device() to release it.
 */ 
struct ibv_context *
op_path_find_hfi(const char *name, 
			    struct ibv_device **device)
{
	struct ibv_device	*ibv_dev = NULL;
	struct ibv_context	*context = NULL;
	int i;

	if (!dev_list) {
		dev_list = ibv_get_device_list(&num_devices);
	}
	if (!dev_list) {
		errno = EFAULT;
		return NULL;
	}
	
	if (name == NULL || name[0]=='\0') {
		i=0;
	} else if (isdigit(name[0])) {
		i = strtoul(name,NULL,0) - 1;
		if (i<0 || i > num_devices) i=0;
	} else {
		for (i=0; i < num_devices; i++) {
			if (!strcmp(ibv_get_device_name(dev_list[i]), name))
				break;
		}
		if (i >= num_devices) {
			errno = EFAULT;
			return NULL;
		}
	}
	ibv_dev = dev_list[i];

	/*
	 * Opens the verbs interface to the HFI.
	 * Note that this will increment the usage counter for that
	 * HFI. This needs to be done before we release the device list.
	 */
	if(ibv_dev) {
		context = ibv_open_device(ibv_dev);
		if (!context) {
			errno = EFAULT;
			*device = NULL;
		} else {
			*device = ibv_dev;
		}
	} else {
		*device = NULL;
		errno = ENODEV;
	}

	return context;
}
Пример #21
0
static void start_comp_thread(RdmaBackendDev *backend_dev)
{
    char thread_name[THR_NAME_LEN] = {};

    stop_backend_thread(&backend_dev->comp_thread);

    snprintf(thread_name, sizeof(thread_name), "rdma_comp_%s",
             ibv_get_device_name(backend_dev->ib_dev));
    backend_dev->comp_thread.run = true;
    qemu_thread_create(&backend_dev->comp_thread.thread, thread_name,
                       comp_handler_thread, backend_dev, QEMU_THREAD_DETACHED);
}
Пример #22
0
void release_resources(void)
{
    int i;
   
    // Destroy the registration cache

    reg_cache_destroy(nprocs);

    for(i = 0; i < nprocs ; i++) {
        if (me != i) {
            if(ibv_destroy_qp(conn.qp[i])) {
                printf("Exiting\n");
                exit(1);
            }
        }
    }
#if 0
    if(ibv_destroy_cq(hca.cq)) {
        fprintf(stderr,"Couldn't destroy cq %s\n",
                ibv_get_device_name(hca.ib_dev));
    }
    if(ibv_dealloc_pd(hca.pd)) {
        fprintf(stderr,"Couldn't free pd %s\n",
                ibv_get_device_name(hca.ib_dev));
    }
#endif

    free(conn.qp);
    free(conn.lid);
    free(conn.qp_num);

    free(rbuf.qp_num);
    free(rbuf.lid);
#if 0
    free(rbuf.rkey); 
    free(rbuf.buf);
#endif
}
Пример #23
0
/* TODO: This should copy the listening fi_info as the base */
static struct fi_info *
fi_ibv_eq_cm_getinfo(struct fi_ibv_fabric *fab, struct rdma_cm_event *event)
{
	struct fi_info *info, *fi;
	struct fi_ibv_connreq *connreq;

	fi = fi_ibv_get_verbs_info(ibv_get_device_name(event->id->verbs->device));
	if (!fi)
		return NULL;

	info = fi_dupinfo(fi);
	if (!info)
		return NULL;

	info->fabric_attr->fabric = &fab->fabric_fid;
	if (!(info->fabric_attr->prov_name = strdup(VERBS_PROV_NAME)))
		goto err;

	fi_ibv_update_info(NULL, info);

	info->src_addrlen = fi_ibv_sockaddr_len(rdma_get_local_addr(event->id));
	if (!(info->src_addr = malloc(info->src_addrlen)))
		goto err;
	memcpy(info->src_addr, rdma_get_local_addr(event->id), info->src_addrlen);

	info->dest_addrlen = fi_ibv_sockaddr_len(rdma_get_peer_addr(event->id));
	if (!(info->dest_addr = malloc(info->dest_addrlen)))
		goto err;
	memcpy(info->dest_addr, rdma_get_peer_addr(event->id), info->dest_addrlen);

	FI_INFO(&fi_ibv_prov, FI_LOG_CORE, "src_addr: %s:%d\n",
		inet_ntoa(((struct sockaddr_in *)info->src_addr)->sin_addr),
		ntohs(((struct sockaddr_in *)info->src_addr)->sin_port));

	FI_INFO(&fi_ibv_prov, FI_LOG_CORE, "dst_addr: %s:%d\n",
		inet_ntoa(((struct sockaddr_in *)info->dest_addr)->sin_addr),
		ntohs(((struct sockaddr_in *)info->dest_addr)->sin_port));

	connreq = calloc(1, sizeof *connreq);
	if (!connreq)
		goto err;

	connreq->handle.fclass = FI_CLASS_CONNREQ;
	connreq->id = event->id;
	info->handle = &connreq->handle;
	return info;
err:
	fi_freeinfo(info);
	return NULL;
}
Пример #24
0
/*
 * Retrieves an IB Path Record given a particular query.
 *
 * context		Pointer to the HFI and port to query on.
 *
 * query		The path record to use for asking the query.
 *				All fields should be zero'ed out except for
 *				those being used to query! For example,
 *				a simple query might specify the source lid,
 *				the destination lid and a pkey. All fields should
 *				be in network byte order.
 * 
 * response		The path record where the completed path will
 *				be written. All fields are in network byte order.
 *
 * RETURN VAL:	This function will return a 0 on success,
 *				or non-zero on error.
 */
int 
op_path_get_path_by_rec(void *uc,
					   op_path_rec_t *query, 
					   op_path_rec_t *response)
{
	uint64_t mask = build_comp_mask(*query);
	struct op_path_context *context = (struct op_path_context *)uc;

	return op_ppath_find_path(context->reader,
							  ibv_get_device_name(context->ibv_context->device),
							  context->port_num,
							  mask,
					  		  query,
							  response);
}
Пример #25
0
int open_hca(void)
{
    struct ibv_device **dev_list=NULL;
    struct ibv_context *cxt = NULL;

    int rc;

    int num_hcas;
    dev_list = ibv_get_device_list(&num_hcas);


    // Assume that the first device has an ACTIVE port
    // if it does not we do not handle this situation for now
    
    hca.ib_dev = dev_list[0];

    hca.context = ibv_open_device(hca.ib_dev);

    if(!hca.context) {
        fprintf(stderr,"Couldn't get context %s\n",
                ibv_get_device_name(hca.ib_dev));
        return 1;
    }

    hca.pd = ibv_alloc_pd(hca.context);

    assert(hca.pd != NULL);
    
    if(!hca.pd) {
        fprintf(stderr,"Couldn't get pd %s\n",
                ibv_get_device_name(hca.ib_dev));
        return 1;
    }

    return 0;
}
Пример #26
0
int fi_ibv_getinfo(uint32_t version, const char *node, const char *service,
		   uint64_t flags, struct fi_info *hints, struct fi_info **info)
{
	struct rdma_cm_id *id = NULL;
	struct rdma_addrinfo *rai;
	int ret;

	ret = fi_ibv_init_info();
	if (ret)
		goto out;

	ret = fi_ibv_create_ep(node, service, flags, hints, &rai, &id);
	if (ret)
		goto out;

	if (id->verbs) {
		ret = fi_ibv_get_matching_info(ibv_get_device_name(id->verbs->device),
					       hints, rai, info);
	} else {
		ret = fi_ibv_get_matching_info(NULL, hints, rai, info);
		if (!ret && !(flags & FI_SOURCE) && !node 
		&& (!hints || (!hints->src_addr && !hints->dest_addr))) {
			ret = fi_ibv_getifaddrs(service, flags, *info);
			if (ret) {
				fi_freeinfo(*info);
				fi_ibv_destroy_ep(rai, &id);
				goto out;
			}
		}
	}

	if (!ret) {
		ret = fi_ibv_rdm_remove_nonaddr_info(info);
	}

	ofi_alter_info(*info, hints);

	fi_ibv_destroy_ep(rai, &id);

out:
	if (!ret || ret == -FI_ENOMEM || ret == -FI_ENODEV)
		return ret;
	else
		return -FI_ENODATA;
}
Пример #27
0
int fi_ibv_getinfo(uint32_t version, const char *node, const char *service,
		   uint64_t flags, struct fi_info *hints, struct fi_info **info)
{
	struct rdma_cm_id *id = NULL;
	struct rdma_addrinfo *rai;
	struct fi_ibv_rdm_cm rdm_cm;
	int ret;

	ret = fi_ibv_init_info();
	if (ret)
		goto out;

	if (FI_IBV_EP_TYPE_IS_RDM(hints)) {
		memset(&rdm_cm, 0, sizeof(struct fi_ibv_rdm_cm));
		ret = fi_ibv_create_ep(node, service, flags, hints, &rai,
				       &(rdm_cm.listener));
		id = rdm_cm.listener;
	} else {
		ret = fi_ibv_create_ep(node, service, flags, hints, &rai, &id);
	}

	if (ret)
		goto out;

	if (id->verbs) {
		ret = fi_ibv_get_matching_info(ibv_get_device_name(id->verbs->device),
					       hints, rai, info);
	} else {
		ret = fi_ibv_get_matching_info(NULL, hints, rai, info);
	}

	ofi_alter_info(*info, hints);

	if (hints && hints->ep_attr)
		fi_ibv_destroy_ep(hints->ep_attr->type, rai,
			FI_IBV_EP_TYPE_IS_RDM(hints) ? &(rdm_cm.listener) : &id);

out:
	if (!ret || ret == -FI_ENOMEM || ret == -FI_ENODEV)
		return ret;
	else
		return -FI_ENODATA;
}
Пример #28
0
ucs_status_t uct_ud_ep_connect_to_iface(uct_ud_ep_t *ep,
                                        const uct_sockaddr_ib_t *if_addr)
{   
    uct_ud_iface_t *iface = ucs_derived_of(ep->super.super.iface, uct_ud_iface_t);
    uct_ib_device_t *dev = uct_ib_iface_device(&iface->super);

    ep->dest_qpn = if_addr->qp_num;
    uct_ud_ep_reset(ep);

    ucs_debug("%s:%d slid=%d qpn=%d ep_id=%u ep=%p connected to IFACE dlid=%d qpn=%d", 
              ibv_get_device_name(dev->ibv_context->device),
              iface->super.port_num,
              dev->port_attr[iface->super.port_num-dev->first_port].lid,
              iface->qp->qp_num,
              ep->ep_id, ep, 
              if_addr->lid, if_addr->qp_num);

    return UCS_OK;
}
Пример #29
0
static struct ibv_device *pp_find_dev(const char *ib_devname) {
	struct ibv_device **dev_list;
	struct ibv_device *ib_dev = NULL;

	dev_list = ibv_get_device_list(NULL);

	if (!ib_devname) {
		ib_dev = dev_list[0];
		if (!ib_dev)
			fprintf(stderr, "No IB devices found\n");
	} else {
		for (; (ib_dev = *dev_list); ++dev_list)
			if (!strcmp(ibv_get_device_name(ib_dev), ib_devname))
				break;
		if (!ib_dev)
			fprintf(stderr, "IB device %s not found\n", ib_devname);
	}
	return ib_dev;
}
/* Create list of IB HCA that have active port */
static int iboffload_load_devices(void)
{
    int num_devs = 0, i;
    mca_bcol_iboffload_device_t *device = NULL;
    mca_bcol_iboffload_component_t *cm = &mca_bcol_iboffload_component;

    IBOFFLOAD_VERBOSE(10, ("Entering to iboffload_load_devices"));

    /* Get list of devices */
    /*cm->ib_devs = ibv_get_device_list_compat(&num_devs);*/
    cm->ib_devs = ompi_ibv_get_device_list(&num_devs);
    if (0 == num_devs || NULL == cm->ib_devs) {
        IBOFFLOAD_ERROR(("No IB devices found"));
        /* No hca error*/
        orte_show_help("help-mpi-btl-openib.txt", "no-nics", true);
        return OMPI_ERROR;
    }

    cm->num_devs = num_devs;

    for (i = 0; i < num_devs; i++) {
        device = OBJ_NEW(mca_bcol_iboffload_device_t);
        if (NULL != device) {
            opal_pointer_array_set_item(&cm->devices, i, (void *) device);
            device->dev.ib_dev = cm->ib_devs[i];

            IBOFFLOAD_VERBOSE(10, ("Device %s with index %d was appended.\n",
                                   ibv_get_device_name(device->dev.ib_dev), i));
        }
    }

    if (0 == opal_pointer_array_get_size(&cm->devices)) {
        /* No relevand devices were found, return error */
        IBOFFLOAD_ERROR(("No active devices found.\n"));

        return OMPI_ERROR;
    }

    return OMPI_SUCCESS;
}