예제 #1
0
파일: rxd_av.c 프로젝트: ParaStation/psmpi2
int rxd_av_insert_dg_addr(struct rxd_av *av, uint64_t hint_index,
			  const void *addr, fi_addr_t *dg_fiaddr)
{
	int ret;

	fastlock_acquire(&av->util_av.lock);
	if (!av->dg_addrlen) {
		ret = rxd_av_set_addrlen(av, addr);
		if (ret)
			goto out;
		ret = -FI_ENODATA;
	} else {
		ret = rxd_av_dg_reverse_lookup(av, hint_index, addr, dg_fiaddr);
	}

	if (ret == -FI_ENODATA) {
		ret = fi_av_insert(av->dg_av, addr, 1, dg_fiaddr, 0, NULL);
		if (ret == 1) {
			av->dg_av_used++;
			ret = 0;
		}
	}
out:
	fastlock_release(&av->util_av.lock);
	return ret;
}
예제 #2
0
파일: rxd_av.c 프로젝트: ParaStation/psmpi2
static int rxd_av_insert(struct fid_av *av_fid, const void *addr, size_t count,
			fi_addr_t *fi_addr, uint64_t flags, void *context)
{
	struct rxd_av *av;
	int i = 0, index, ret = 0, success_cnt = 0, lookup = 1;
	uint64_t dg_fiaddr;

	av = container_of(av_fid, struct rxd_av, util_av.av_fid);
	fastlock_acquire(&av->util_av.lock);
	if (!av->dg_addrlen) {
		ret = rxd_av_set_addrlen(av, addr);
		if (ret)
			goto out;
		/* Skip lookups if this is the first insertion call.  */
		lookup = 0;
	}

	for (; i < count; i++, addr = (uint8_t *) addr + av->dg_addrlen) {
		ret = lookup ? rxd_av_dg_reverse_lookup(av, i, addr, &dg_fiaddr) :
				-FI_ENODATA;
		if (ret) {
			ret = fi_av_insert(av->dg_av, addr, 1, &dg_fiaddr,
					   flags, context);
			if (ret != 1)
				break;
		}

		ret = ofi_av_insert_addr(&av->util_av, &dg_fiaddr, dg_fiaddr, &index);
		if (ret)
			break;

		success_cnt++;
		if (fi_addr)
			fi_addr[i] = index;
	}

	if (ret) {
		FI_WARN(&rxd_prov, FI_LOG_AV,
			"failed to insert address %d: %d (%s)\n",
			i, -ret, fi_strerror(-ret));
		if (av->util_av.eq)
			ofi_av_write_event(&av->util_av, i, -ret, context);
		if (fi_addr)
			fi_addr[i] = FI_ADDR_NOTAVAIL;
		i++;
	}
out:
	av->dg_av_used += success_cnt;
	fastlock_release(&av->util_av.lock);

	for (; i < count; i++) {
		if (av->util_av.eq)
			ofi_av_write_event(&av->util_av, i, FI_ECANCELED, context);
		if (fi_addr)
			fi_addr[i] = FI_ADDR_NOTAVAIL;
	}

	if (av->util_av.eq) {
		ofi_av_write_event(&av->util_av, success_cnt, 0, context);
		return 0;
	}

	return success_cnt;
}
예제 #3
0
파일: rxd_av.c 프로젝트: gbtitus/libfabric
static int rxd_av_insert(struct fid_av *av_fid, const void *addr, size_t count,
			fi_addr_t *fi_addr, uint64_t flags, void *context)
{
	struct rxd_av *av;
	int i = 0, ret = 0, success_cnt = 0;
	fi_addr_t rxd_addr, util_addr;
	struct ofi_rbnode *node;

	av = container_of(av_fid, struct rxd_av, util_av.av_fid);
	fastlock_acquire(&av->util_av.lock);
	if (!av->dg_addrlen) {
		ret = rxd_av_set_addrlen(av, addr);
		if (ret)
			goto out;
	}

	for (; i < count; i++, addr = (uint8_t *) addr + av->dg_addrlen) {
		node = ofi_rbmap_find(&av->rbmap, (void *) addr);
		if (node) {
			rxd_addr = (fi_addr_t) node->data;
		} else {
			ret = rxd_av_insert_dg_addr(av, addr, &rxd_addr,
						    flags, context);
			if (ret)
				break;
		}

		util_addr = av->rxd_addr_table[rxd_addr].fi_addr == FI_ADDR_UNSPEC ?
			    rxd_set_fi_addr(av, rxd_addr) :
			    av->rxd_addr_table[rxd_addr].fi_addr;
		if (fi_addr)
			fi_addr[i] = util_addr;

		success_cnt++;
	}

	if (ret) {
		FI_WARN(&rxd_prov, FI_LOG_AV,
			"failed to insert address %d: %d (%s)\n",
			i, -ret, fi_strerror(-ret));
		if (av->util_av.eq)
			ofi_av_write_event(&av->util_av, i, -ret, context);
		if (fi_addr)
			fi_addr[i] = FI_ADDR_NOTAVAIL;
		i++;
	}
out:
	av->dg_av_used += success_cnt;
	fastlock_release(&av->util_av.lock);

	for (; i < count; i++) {
		if (av->util_av.eq)
			ofi_av_write_event(&av->util_av, i, FI_ECANCELED, context);
		if (fi_addr)
			fi_addr[i] = FI_ADDR_NOTAVAIL;
	}

	if (av->util_av.eq) {
		ofi_av_write_event(&av->util_av, success_cnt, 0, context);
		return 0;
	}

	return success_cnt;
}