uint32_t ib_ctx_time_converter::get_device_convertor_status(struct ibv_context* ctx) {
	uint32_t dev_status = 0;
#ifdef DEFINED_IBV_EXP_CQ_TIMESTAMP
	int rval;

	// Checking if ibv_exp_query_device() is valid
	struct ibv_exp_device_attr device_attr;
	memset(&device_attr, 0, sizeof(device_attr));
	device_attr.comp_mask = IBV_EXP_DEVICE_ATTR_WITH_HCA_CORE_CLOCK;

	if ((rval = ibv_exp_query_device(ctx ,&device_attr)) || !device_attr.hca_core_clock) {
		vlog_printf(VLOG_DEBUG, "ib_ctx_time_converter::get_device_convertor_status :Error in querying hca core clock "
				"(ibv_exp_query_device() return value=%d ) (ibv context %p) (errno=%d %m)\n", rval, ctx, errno);
	} else {
		dev_status |= IBV_EXP_QUERY_DEVICE_SUPPORTED;
	}

	// Checking if ibv_exp_query_values() is valid
	struct ibv_exp_values queried_values;
	memset(&queried_values, 0, sizeof(queried_values));
	queried_values.comp_mask = IBV_EXP_VALUES_HW_CLOCK;

	if ((rval = ibv_exp_query_values(ctx,IBV_EXP_VALUES_HW_CLOCK, &queried_values)) || !queried_values.hwclock) {
		vlog_printf(VLOG_DEBUG, "ib_ctx_time_converter::get_device_convertor_status :Error in querying hw clock, can't convert"
				" hw time to system time (ibv_exp_query_values() return value=%d ) (ibv context %p) (errno=%d %m)\n", rval, ctx, errno);
	} else {
		dev_status |= IBV_EXP_QUERY_VALUES_SUPPORTED;
	}
#else
	NOT_IN_USE(ctx);
#endif
	return dev_status;
}
bool ib_ctx_time_converter::sync_clocks(struct timespec* st, uint64_t* hw_clock){
	struct timespec st1, st2, diff, st_min = TIMESPEC_INITIALIZER;
	struct ibv_exp_values queried_values;
	int64_t interval, best_interval = 0;
	uint64_t hw_clock_min = 0;

	memset(&queried_values, 0, sizeof(queried_values));
	queried_values.comp_mask = IBV_EXP_VALUES_HW_CLOCK;
	for (int i = 0 ; i < 10 ; i++) {
		clock_gettime(CLOCK_REALTIME, &st1);
		if (ibv_exp_query_values(m_p_ibv_context,IBV_EXP_VALUES_HW_CLOCK, &queried_values) || !queried_values.hwclock) {
			return false;
		}

		clock_gettime(CLOCK_REALTIME, &st2);
		interval = (st2.tv_sec - st1.tv_sec) * NSEC_PER_SEC + (st2.tv_nsec - st1.tv_nsec);

		if (!best_interval || interval < best_interval) {
			best_interval = interval;
			hw_clock_min = queried_values.hwclock;

			interval /= 2;
			diff.tv_sec = interval / NSEC_PER_SEC;
			diff.tv_nsec = interval - (diff.tv_sec * NSEC_PER_SEC);
			ts_add(&st1, &diff, &st_min);
		}
	}
	*st = st_min;
	*hw_clock = hw_clock_min;
	return true;
}
Exemple #3
0
static int poll_cqs(enum CQ_INDEX index)
{
	struct ibv_wc wc[8];
	struct ibv_exp_wc exp_wc[8];
	int done, i, ret, j;
	struct ibv_wc *p_wc;

	for (i = 0; i < connections; i++) {
		if (!test.nodes[i].connected)
			continue;

		for (done = 0; done < message_count; done += ret) {
			if (set_ts) {
				ret = ibv_exp_poll_cq(test.nodes[i].cq[index], 8,
						      exp_wc, sizeof(exp_wc[0]));
				p_wc = (struct ibv_wc *)exp_wc;
			} else {
				ret = ibv_poll_cq(test.nodes[i].cq[index], 8,
						  wc);
				p_wc = (struct ibv_wc *)wc;
			}
			if (ret < 0) {
				printf("cmatose: failed polling CQ: %d\n", ret);
				return ret;
			}
			for (j = 0; j < ret; ++j) {
				if (GET_WC(p_wc, j)->status != IBV_WC_SUCCESS) {
					printf("wc[%d]: bad status %d\n",
					       j, GET_WC(p_wc, j)->status);
					return -1;
				}
			}
			if (set_ts && ret > 0) {
				struct ibv_exp_values queried_values;
				queried_values.comp_mask = IBV_EXP_VALUES_HW_CLOCK;
				if (ibv_exp_query_values(test.nodes[i].cq[index]
							 ->context,
							 IBV_EXP_VALUES_HW_CLOCK,
							 &queried_values) &&
							 (queried_values.comp_mask &
							  IBV_EXP_VALUES_HW_CLOCK)) {
					printf("Error in querying hw clock\n");
					queried_values.hwclock = 0;
				}
				for (j = 0; j < ret; j++)
					printf("connection %d, batch %d, "
					       "packet %d/%d %s, "
					       "queried: %lu, timestamp: %lu\n",
					       i, done, j + 1, ret,
					       p_wc->opcode == IBV_WC_SEND ?
							"tx" : "rx",
					       queried_values.hwclock,
					       exp_wc[j].timestamp);
			}
		}
	}
	return 0;
}
Exemple #4
0
static int post_sends(struct cmatest_node *node)
{
	struct ibv_send_wr send_wr, *bad_send_wr;
	struct ibv_sge sge;
	int i, ret = 0;

	if (!node->connected || !message_count)
		return 0;

	send_wr.next = NULL;
	send_wr.sg_list = &sge;
	send_wr.num_sge = 1;
	send_wr.opcode = IBV_WR_SEND;
	send_wr.send_flags = 0;
	send_wr.wr_id = (unsigned long)node;

	sge.length = message_size;
	sge.lkey = node->mr->lkey;
	sge.addr = (uintptr_t) node->mem;

	for (i = 0; i < message_count && !ret; i++) {
		ret = ibv_post_send(node->cma_id->qp, &send_wr, &bad_send_wr);
		if (ret) {
			printf("failed to post sends: %d\n", ret);
		} else if (set_ts) {
			struct ibv_exp_values queried_values;
			queried_values.comp_mask = IBV_EXP_VALUES_HW_CLOCK;
			if (!ibv_exp_query_values(node->cma_id->verbs,
						  IBV_EXP_VALUES_HW_CLOCK,
						  &queried_values) &&
						  (queried_values.comp_mask &
						   IBV_EXP_VALUES_HW_CLOCK)) {
				printf("Event: Post send was called in %lu\n",
				       queried_values.hwclock);
			}
		}
	}
	return ret;
}