190 lines
7.0 KiB
C
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;
|
|
}
|