Files
mckernel/test/rusage/verbs/cas.c
Dominique Martinet 7f1c17fc4c tests: add 'postk_master' branch tests
Change-Id: Ie0d4cfd0921aed89d2db6083c9eb068b1cfc1984
2019-02-01 15:15:00 +09:00

190 lines
7.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/mman.h>
#include <unistd.h>
#include "ibcomm.h"
#include "debug.h"
#include "mtype.h"
#include "mcons.h"
#include "mm_ib_test.h"
//#define DEBUG_CAS
#ifdef DEBUG_CAS
#define dprintf printf
#else
#define dprintf(...)
#endif
#define NTRIAL 10
#define NSKIPS 0
#define NSKIPR 0
#define ERR_CHKANDJUMP(cond, errno, stmt) if(cond) { stmt; main_errno = errno; goto fn_fail; }
static unsigned long rdtsc() {
unsigned long x;
__asm__ __volatile__("xorl %%eax, %%eax; cpuid;" : : : "%rax", "%rbx", "%rcx", "%rdx"); /* rdtsc cannot be executed earlier than this */
__asm__ __volatile__("rdtsc; shl $32, %%rdx; or %%rdx, %%rax" : "=a"(x) : : "memory"); /* rdtsc cannot be executed earlier than here */
__asm__ __volatile__("xorl %%eax, %%eax; cpuid;" : : : "%rax", "%rbx", "%rcx", "%rdx"); /* following instructions cannot be executed earlier than this */
return x;
}
volatile int k;
int main(int argc, char **argv) {
config_t config;
int i;
int j;
int main_errno = 0;
char sync_res;
unsigned long tscs, tsce;
resource_t res;
pdinfo_t pdinfo;
qpinfo_t qpinfo;
mrinfo_t *mr_local = NULL;
int entry;
int ib_errno;
if (read_config(&config, argc, argv)) {
goto fn_exit;
}
config.use_rdma = 1;
if(config.buf_size != 8) {
printf("set buf_size to 8\n");
config.buf_size = 8;
}
if(resource_create(config, &res) || pd_create(&res, &pdinfo) || qp_create(&res, &pdinfo, &qpinfo)) { printf("qp_create failed\n"); goto fn_fail; }
/* rdma-write-to buffer */
void *buf_rdma = mmap(0, 8/*IBCOM_RDMABUF_SZSEG*/, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
//void *buf_rdma = calloc(8, 1);
ERR_CHKANDJUMP(!buf_rdma, -1, printf("mmap failed\n"));
memset(buf_rdma, 0, 8/*IBCOM_RDMABUF_SZSEG*/);
//ib_errno = mr_create(&res, &pdinfo, 8/*IBCOM_RDMABUF_SZSEG*/, buf_rdma, &res.rdma_mr);
//ERR_CHKANDJUMP(ib_errno, -1, printf("mr_create failed\n"));
memset(&res.rdma_mr, 0, sizeof(mrinfo_t));
res.rdma_mr.buf = buf_rdma;
res.rdma_mr.buf_size = 8;
res.rdma_mr.mr = ibv_reg_mr(pdinfo.pd, buf_rdma, 8, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ | IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_ATOMIC);
ERR_CHKANDJUMP(!res.rdma_mr.mr, -1, printf("ibv_reg_mr failed\n"));
mr_local = calloc(sizeof(mrinfo_t), sizeof(char));
ERR_CHKANDJUMP(!mr_local, -1, printf("calloc failed\n"));
void *buf_local = mmap(0, config.buf_size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
ERR_CHKANDJUMP(!buf_local, -1, printf("mmap failed\n"));
memset(buf_local, config.server_flg ? 0x55 : 0xaa, config.buf_size);
//ib_errno = mr_create(&res, &pdinfo, config.buf_size, buf_local, mr_local);
//ERR_CHKANDJUMP(ib_errno, -1, printf("mr_create fail\n"));
memset(mr_local, 0, sizeof(mrinfo_t));
mr_local->buf = buf_local;
mr_local->buf_size = 8;
mr_local->mr = ibv_reg_mr(pdinfo.pd, buf_local, 8, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ | IBV_ACCESS_REMOTE_WRITE | IBV_ACCESS_REMOTE_ATOMIC);
ERR_CHKANDJUMP(!mr_local->mr, -1, printf("ibv_reg_mr failed\n"));
/* exchange gid, lid, qpn, raddr, rkey */
if(connect_qp(config, &res, &qpinfo)) { printf("connect_qp failed\n"); goto fn_fail; }
debug_print_qp_conn_info(res, qpinfo, &config);
printf("connect_qp done\n"); fflush(stdout);
/* make qp RTS */
if(init_qp(config, &qpinfo) || rtr_qp(config, &qpinfo) || rts_qp(config, &qpinfo)) { printf("rts failed\n"); goto fn_fail; }
printf("rts done\n"); fflush(stdout);
/* barrier */
for(i = 0; i < (config.server_flg ? config.nremote : 1); i++) {
if(sock_sync_data(qpinfo.sock[i], 1, "R", &sync_res)) { perror("sock_sync_data"); }
}
printf("barrier done\n"); fflush(stdout);
if(config.server_flg) { /* sender side */
for (i = 0; i < NTRIAL; i++) {
if(i == NSKIPS) { tscs = rdtsc(); }
struct ibv_send_wr sr;
memset(&sr, 0, sizeof(struct ibv_send_wr));
struct ibv_send_wr *bad_wr = NULL;
struct ibv_sge sge[1];
memset(&sge[0], 0, sizeof(struct ibv_sge));
sr.next = NULL;
sr.wr_id = 0;
sr.sg_list = sge;
//sr.imm_data = imm_data;
sr.send_flags = IBV_SEND_SIGNALED;
sge[0].addr = (uintptr_t)mr_local->buf;
printf("local_addr=%08lx\n", sge[0].addr);
sge[0].length = mr_local->buf_size;
printf("length=%d\n", sge[0].length);
sge[0].lkey = mr_local->mr->lkey;
sr.num_sge = 1;
#if 1
sr.opcode = IBV_WR_ATOMIC_CMP_AND_SWP;
//sr.opcode = IBV_WR_ATOMIC_FETCH_AND_ADD;
sr.wr.atomic.compare_add = (uint64_t)i;
sr.wr.atomic.swap = (uint64_t)i+1;
sr.wr.atomic.remote_addr = /*255*/qpinfo.remote_conn_info[0].addr;
printf("remote_addr=%08lx\n", sr.wr.atomic.remote_addr);
sr.wr.atomic.rkey = /*123*/qpinfo.remote_conn_info[0].rkey;
printf("rkey=%08lx\n", sr.wr.atomic.rkey);
#else
sr.opcode = IBV_WR_RDMA_WRITE;
sr.wr.rdma.remote_addr = qpinfo.remote_conn_info[0].addr;
sr.wr.rdma.rkey = qpinfo.remote_conn_info[0].rkey;
#endif
dprintf("ibv_post_send,raddr=%lx\n", sr.wr.rdma.remote_addr);
ib_errno = ibv_post_send(qpinfo.qp, &sr, &bad_wr);
ERR_CHKANDJUMP(ib_errno, -1, printf("ibv_post_send return %d\n", ib_errno));
while(1) {
int result;
struct ibv_wc cqe[1];
result = ibv_poll_cq(qpinfo.scq, 1, &cqe[0]);
ERR_CHKANDJUMP(result < 0, -1, printf("ibv_poll_cq"));
if(result > 0) {
for(j = 0; j < result; j++) {
printf("cqe.imm_data=%08x\n", cqe[j].imm_data);
printf("buf_local=%lx\n", *((uint64_t*)buf_local));
ERR_CHKANDJUMP(cqe[j].status != IBV_WC_SUCCESS, -1, printf("cqe status,%s\n", ibv_wc_status_str(cqe[j].status)));
}
break;
}
}
}
tsce = rdtsc(); printf("send,%.0f\n", (tsce-tscs)/(double)(NTRIAL-NSKIPS));
} else { /* receiver side */
for (i = 0; i < NTRIAL; i++) {
if(i == NSKIPR) { tscs = rdtsc(); }
printf("res.rdma_mr.buf=%lx\n", (unsigned long)res.rdma_mr.buf);
printf("poll addr=%lx\n", (unsigned long)(buf_rdma));
volatile uint64_t *ptr = (volatile uint64_t *)buf_rdma;
while(*ptr == i) {
__asm__ __volatile__("pause");
}
printf("*ptr=%08lx\n", *ptr);
}
tsce = rdtsc(); printf("recv,%.0f\n", (tsce-tscs)/(double)(NTRIAL-NSKIPR));
}
fn_exit:
return main_errno;
fn_fail:
goto fn_exit;
}