Esempio n. 1
0
static int
usdf_usnic_getinfo(uint32_t version, struct fid_fabric *fabric,
			struct fi_usnic_info *uip)
{
	struct usdf_fabric *fp;
	struct usd_device_attrs *dap;

	USDF_TRACE("\n");

	fp = fab_ftou(fabric);
	dap = fp->fab_dev_attrs;

	if (version > FI_EXT_USNIC_INFO_VERSION) {
		return -FI_EINVAL;
	}

	/* this assignment was missing in libfabric v1.1.1 and earlier */
	uip->ui_version = FI_EXT_USNIC_INFO_VERSION;

	uip->ui.v1.ui_link_speed = dap->uda_bandwidth;
	uip->ui.v1.ui_netmask_be = dap->uda_netmask_be;
	strcpy(uip->ui.v1.ui_ifname, dap->uda_ifname);
	uip->ui.v1.ui_num_vf = dap->uda_num_vf;
	uip->ui.v1.ui_qp_per_vf = dap->uda_qp_per_vf;
	uip->ui.v1.ui_cq_per_vf = dap->uda_cq_per_vf;

	return 0;
}
Esempio n. 2
0
static int
usdf_usnic_getinfo(struct fid_fabric *fabric, struct fi_usnic_info *uip)
{
	struct usdf_fabric *fp;
	struct usd_device_attrs *dap;

	fp = fab_ftou(fabric);
	dap = fp->fab_dev_attrs;

	uip->ui.v1.ui_link_speed = dap->uda_bandwidth;
	uip->ui.v1.ui_netmask_be = dap->uda_netmask_be;
	strcpy(uip->ui.v1.ui_ifname, dap->uda_ifname);
	uip->ui.v1.ui_num_vf = dap->uda_num_vf;
	uip->ui.v1.ui_qp_per_vf = dap->uda_qp_per_vf;
	uip->ui.v1.ui_cq_per_vf = dap->uda_cq_per_vf;

	return 0;
}
Esempio n. 3
0
static int
usdf_usnic_getinfo(uint32_t version, struct fid_fabric *fabric,
			struct fi_usnic_info *uip)
{
	struct usdf_fabric *fp;
	struct usd_device_attrs *dap;

	fp = fab_ftou(fabric);
	dap = fp->fab_dev_attrs;

	if (version > FI_EXT_USNIC_INFO_VERSION) {
		return -FI_EINVAL;
	}

	uip->ui.v1.ui_link_speed = dap->uda_bandwidth;
	uip->ui.v1.ui_netmask_be = dap->uda_netmask_be;
	strcpy(uip->ui.v1.ui_ifname, dap->uda_ifname);
	uip->ui.v1.ui_num_vf = dap->uda_num_vf;
	uip->ui.v1.ui_qp_per_vf = dap->uda_qp_per_vf;
	uip->ui.v1.ui_cq_per_vf = dap->uda_cq_per_vf;

	return 0;
}
Esempio n. 4
0
int
usdf_pep_open(struct fid_fabric *fabric, struct fi_info *info,
              struct fid_pep **pep_o, void *context)
{
    struct usdf_pep *pep;
    struct usdf_fabric *fp;
    struct sockaddr_in *sin;
    int ret;
    int optval;

    USDF_TRACE_SYS(EP_CTRL, "\n");

    if (!info) {
        USDF_DBG_SYS(EP_CTRL, "null fi_info struct is invalid\n");
        return -FI_EINVAL;
    }

    if (info->ep_attr->type != FI_EP_MSG) {
        return -FI_ENODEV;
    }

    if ((info->caps & ~USDF_MSG_CAPS) != 0) {
        return -FI_EBADF;
    }

    switch (info->addr_format) {
    case FI_SOCKADDR:
        if (((struct sockaddr *)info->src_addr)->sa_family != AF_INET) {
            USDF_WARN_SYS(EP_CTRL, "non-AF_INET src_addr specified\n");
            return -FI_EINVAL;
        }
        break;
    case FI_SOCKADDR_IN:
        break;
    default:
        USDF_WARN_SYS(EP_CTRL, "unknown/unsupported addr_format\n");
        return -FI_EINVAL;
    }

    if (info->src_addrlen &&
            info->src_addrlen != sizeof(struct sockaddr_in)) {
        USDF_WARN_SYS(EP_CTRL, "unexpected src_addrlen\n");
        return -FI_EINVAL;
    }

    fp = fab_ftou(fabric);

    pep = calloc(1, sizeof(*pep));
    if (pep == NULL) {
        return -FI_ENOMEM;
    }

    pep->pep_fid.fid.fclass = FI_CLASS_PEP;
    pep->pep_fid.fid.context = context;
    pep->pep_fid.fid.ops = &usdf_pep_ops;
    pep->pep_fid.ops = &usdf_pep_base_ops;
    pep->pep_fid.cm = &usdf_pep_cm_ops;
    pep->pep_fabric = fp;

    pep->pep_state = USDF_PEP_UNBOUND;
    pep->pep_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (pep->pep_sock == -1) {
        ret = -errno;
        goto fail;
    }
    ret = fcntl(pep->pep_sock, F_GETFL, 0);
    if (ret == -1) {
        ret = -errno;
        goto fail;
    }
    ret = fcntl(pep->pep_sock, F_SETFL, ret | O_NONBLOCK);
    if (ret == -1) {
        ret = -errno;
        goto fail;
    }

    /* set SO_REUSEADDR to prevent annoying "Address already in use" errors
     * on successive runs of programs listening on a well known port */
    optval = 1;
    ret = setsockopt(pep->pep_sock, SOL_SOCKET, SO_REUSEADDR, &optval,
                     sizeof(optval));
    if (ret == -1) {
        ret = -errno;
        goto fail;
    }

    pep->pep_info = fi_dupinfo(info);
    if (!pep->pep_info) {
        ret = -FI_ENOMEM;
        goto fail;
    }

    if (info->src_addrlen == 0) {
        /* Copy the source address information from the device
         * attributes.
         */
        pep->pep_info->src_addrlen = sizeof(struct sockaddr_in);
        sin = calloc(1, pep->pep_info->src_addrlen);
        if (!sin) {
            USDF_WARN_SYS(EP_CTRL,
                          "calloc for src address failed\n");
            goto fail;
        }

        sin->sin_family = AF_INET;
        sin->sin_addr.s_addr = fp->fab_dev_attrs->uda_ipaddr_be;
        pep->pep_info->src_addr = sin;
    }

    memcpy(&pep->pep_src_addr, pep->pep_info->src_addr,
           pep->pep_info->src_addrlen);

    /* initialize connreq freelist */
    ret = pthread_spin_init(&pep->pep_cr_lock, PTHREAD_PROCESS_PRIVATE);
    if (ret != 0) {
        ret = -ret;
        goto fail;
    }
    TAILQ_INIT(&pep->pep_cr_free);
    TAILQ_INIT(&pep->pep_cr_pending);
    pep->pep_backlog = 10;
    ret = usdf_pep_grow_backlog(pep);
    if (ret != 0) {
        goto fail;
    }

    atomic_initialize(&pep->pep_refcnt, 0);
    atomic_inc(&fp->fab_refcnt);

    *pep_o = pep_utof(pep);
    return 0;

fail:
    if (pep != NULL) {
        usdf_pep_free_cr_lists(pep);
        if (pep->pep_sock != -1) {
            close(pep->pep_sock);
        }
        fi_freeinfo(pep->pep_info);
        free(pep);
    }
    return ret;
}
Esempio n. 5
0
int
usdf_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
	struct fid_eq **feq, void *context)
{
	struct usdf_eq *eq;
	struct usdf_fabric *fab;
	int ret;

	fab = fab_ftou(fabric);

	eq = calloc(1, sizeof(*eq));
	if (eq == NULL) {
		ret = -errno;
		goto fail;
	}

	/* fill in the EQ struct */
	eq->eq_fid.fid.fclass = FI_CLASS_EQ;
	eq->eq_fid.fid.context = context;
	eq->eq_fid.fid.ops = &usdf_eq_fi_ops;
	eq->eq_fid.ops = &eq->eq_ops_data;
	eq->eq_wait_obj = attr->wait_obj;

	eq->eq_fabric = fab;
	atomic_init(&eq->eq_refcnt, 0);
	ret = pthread_spin_init(&eq->eq_lock, PTHREAD_PROCESS_PRIVATE);
	if (ret != 0) {
		ret = -ret;
		goto fail;
	}

	/* get baseline routines */
	eq->eq_ops_data = usdf_eq_ops;

	/* fill in sread based on wait type */
	switch (eq->eq_wait_obj) {
	case FI_WAIT_NONE:
		eq->eq_ops_data.read = usdf_eq_read;
		eq->eq_ops_data.sread = fi_no_eq_sread;
		eq->eq_ops_data.write = usdf_eq_write;
		break;
	case FI_WAIT_UNSPEC:	/* default to FD */
		eq->eq_wait_obj = FI_WAIT_FD;
		attr->wait_obj = FI_WAIT_FD;
		/* FALLSTHROUGH */
	case FI_WAIT_FD:
		eq->eq_ops_data.read = usdf_eq_read_fd;
		eq->eq_ops_data.sread = usdf_eq_sread_fd;
		eq->eq_ops_data.write = usdf_eq_write_fd;
		eq->eq_fd = eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE);
		if (eq->eq_fd == -1) {
			ret = -errno;
			goto fail;
		}
		break;
	default:
		ret = -FI_ENOSYS;
		goto fail;
	}

	/*
	 * Dis-allow write if requested
	 */
	if ((attr->flags & FI_WRITE) == 0) {
		eq->eq_ops_data.write = fi_no_eq_write;
	}

	/*
	 * Allocate and initialize event ring
	 */
	if (attr->size == 0) {
		attr->size = 1024;	// XXX
	}
	eq->eq_ev_ring = calloc(attr->size, sizeof(*eq->eq_ev_ring));
	eq->eq_ev_buf = calloc(attr->size, sizeof(*eq->eq_ev_buf));
	if (eq->eq_ev_ring == NULL || eq->eq_ev_buf == NULL) {
		ret = -errno;
		goto fail;
	}
	eq->eq_ev_head = eq->eq_ev_ring;
	eq->eq_ev_tail = eq->eq_ev_ring;
	eq->eq_ev_ring_size = attr->size;
	eq->eq_ev_end = eq->eq_ev_ring + eq->eq_ev_ring_size;
	atomic_init(&eq->eq_num_events, 0);

	atomic_inc(&eq->eq_fabric->fab_refcnt);
	*feq = eq_utof(eq);

	return 0;

fail:
	if (eq != NULL) {
		if (eq->eq_ev_ring != NULL) {
			free(eq->eq_ev_ring);
		}
		free(eq);
	}
	return ret;
}
Esempio n. 6
0
int
usdf_pep_open(struct fid_fabric *fabric, struct fi_info *info,
	    struct fid_pep **pep_o, void *context)
{
	struct usdf_pep *pep;
	struct usdf_fabric *fp;
	int ret;
	int optval;

	USDF_TRACE_SYS(EP_CTRL, "\n");

	if (info->ep_attr->type != FI_EP_MSG) {
		return -FI_ENODEV;
	}

	if ((info->caps & ~USDF_MSG_CAPS) != 0) {
		return -FI_EBADF;
	}

	fp = fab_ftou(fabric);

	pep = calloc(1, sizeof(*pep));
	if (pep == NULL) {
		return -FI_ENOMEM;
	}

	pep->pep_fid.fid.fclass = FI_CLASS_PEP;
	pep->pep_fid.fid.context = context;
	pep->pep_fid.fid.ops = &usdf_pep_ops;
	pep->pep_fid.ops = &usdf_pep_base_ops;
	pep->pep_fid.cm = &usdf_pep_cm_ops;
	pep->pep_fabric = fp;

	pep->pep_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (pep->pep_sock == -1) {
		ret = -errno;
		goto fail;
	}
        ret = fcntl(pep->pep_sock, F_GETFL, 0);
        if (ret == -1) {
                ret = -errno;
                goto fail;
        }
        ret = fcntl(pep->pep_sock, F_SETFL, ret | O_NONBLOCK);
        if (ret == -1) {
                ret = -errno;
                goto fail;
        }

	/* set SO_REUSEADDR to prevent annoying "Address already in use" errors
	 * on successive runs of programs listening on a well known port */
	optval = 1;
	ret = setsockopt(pep->pep_sock, SOL_SOCKET, SO_REUSEADDR, &optval,
				sizeof(optval));
	if (ret == -1) {
		ret = -errno;
		goto fail;
	}

	ret = bind(pep->pep_sock, (struct sockaddr *)info->src_addr,
			info->src_addrlen);
	if (ret == -1) {
		ret = -errno;
		goto fail;
	}

	/* initialize connreq freelist */
	ret = pthread_spin_init(&pep->pep_cr_lock, PTHREAD_PROCESS_PRIVATE);
	if (ret != 0) {
		ret = -ret;
		goto fail;
	}
	TAILQ_INIT(&pep->pep_cr_free);
	TAILQ_INIT(&pep->pep_cr_pending);
	pep->pep_backlog = 10;
	ret = usdf_pep_grow_backlog(pep);
	if (ret != 0) {
		goto fail;
	}

	atomic_initialize(&pep->pep_refcnt, 0);
	atomic_inc(&fp->fab_refcnt);

	*pep_o = pep_utof(pep);
	return 0;

fail:
	if (pep != NULL) {
		usdf_pep_free_cr_lists(pep);
		if (pep->pep_sock != -1) {
			close(pep->pep_sock);
		}
		free(pep);
	}
	return ret;
}