X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=engines%2Frdma.c;h=4d81c7da65004f0b0eb2afa00ec5087eb103221f;hp=79d72d20c844d7f8a393c6e1e7873a3f5bbde99c;hb=ee88d05666760999be7428beda20f3b24d571d5b;hpb=a05d62b28f18e37256f2698106169b1177708cc1 diff --git a/engines/rdma.c b/engines/rdma.c index 79d72d20..4d81c7da 100644 --- a/engines/rdma.c +++ b/engines/rdma.c @@ -7,14 +7,25 @@ * * This I/O engine is disabled by default. To enable it, execute: * - * $ export EXTFLAGS="-DFIO_HAVE_RDMA" - * $ export EXTLIBS="-libverbs -lrdmacm" + * $ export EXTFLAGS+=" -DFIO_HAVE_RDMA " + * $ export EXTLIBS+=" -libverbs -lrdmacm " * * before running make. You will need the Linux RDMA software as well, either * from your Linux distributor or directly from openfabrics.org: * * http://www.openfabrics.org/downloads/OFED/ * + * Exchanging steps of RDMA ioengine control messages: + * 1. client side sends test mode (RDMA_WRITE/RDMA_READ/SEND) + * to server side. + * 2. server side parses test mode, and sends back confirmation + * to client side. In RDMA WRITE/READ test, this confirmation + * includes memory information, such as rkey, address. + * 3. client side initiates test loop. + * 4. In RDMA WRITE/READ test, client side sends a completion + * notification to server side. Server side updates its + * td->done as true. + * */ #include #include @@ -35,13 +46,14 @@ #include #include "../fio.h" +#include "../hash.h" #ifdef FIO_HAVE_RDMA #include #include -#define FIO_RDMA_MAX_IO_DEPTH 128 +#define FIO_RDMA_MAX_IO_DEPTH 512 enum rdma_io_mode { FIO_RDMA_UNKNOWN = 0, @@ -108,6 +120,8 @@ struct rdmaio_data { int io_u_flight_nr; struct io_u **io_us_completed; int io_u_completed_nr; + + struct frand_state rand_state; }; static int client_recv(struct thread_data *td, struct ibv_wc *wc) @@ -591,7 +605,8 @@ static int fio_rdmaio_send(struct thread_data *td, struct io_u **io_us, enum ibv_wc_opcode comp_opcode; comp_opcode = IBV_WC_RDMA_WRITE; #endif - int i, index; + int i; + long index; struct rdma_io_u_data *r_io_u_d; r_io_u_d = NULL; @@ -602,7 +617,10 @@ static int fio_rdmaio_send(struct thread_data *td, struct io_u **io_us, case FIO_RDMA_MEM_WRITE: /* compose work request */ r_io_u_d = io_us[i]->engine_data; - index = rand() % rd->rmt_nr; + if (td->o.use_os_rand) + index = os_random_long(&td->random_state) % rd->rmt_nr; + else + index = __rand(&rd->rand_state) % rd->rmt_nr; r_io_u_d->sq_wr.opcode = IBV_WR_RDMA_WRITE; r_io_u_d->sq_wr.wr.rdma.rkey = rd->rmt_us[index].rkey; r_io_u_d->sq_wr.wr.rdma.remote_addr = \ @@ -612,7 +630,10 @@ static int fio_rdmaio_send(struct thread_data *td, struct io_u **io_us, case FIO_RDMA_MEM_READ: /* compose work request */ r_io_u_d = io_us[i]->engine_data; - index = rand() % rd->rmt_nr; + if (td->o.use_os_rand) + index = os_random_long(&td->random_state) % rd->rmt_nr; + else + index = __rand(&rd->rand_state) % rd->rmt_nr; r_io_u_d->sq_wr.opcode = IBV_WR_RDMA_READ; r_io_u_d->sq_wr.wr.rdma.rkey = rd->rmt_us[index].rkey; r_io_u_d->sq_wr.wr.rdma.remote_addr = \ @@ -790,6 +811,16 @@ static int fio_rdmaio_connect(struct thread_data *td, struct fio_file *f) /* wait for remote MR info from server side */ rdma_poll_wait(td, IBV_WC_RECV); + /* In SEND/RECV test, it's a good practice to setup the iodepth of + * of the RECV side deeper than that of the SEND side to + * avoid RNR (receiver not ready) error. The + * SEND side may send so many unsolicited message before + * RECV side commits sufficient recv buffers into recv queue. + * This may lead to RNR error. Here, SEND side pauses for a while + * during which RECV side commits sufficient recv buffers. + */ + usleep(500000); + return 0; } @@ -872,8 +903,8 @@ static int fio_rdmaio_close_file(struct thread_data *td, struct fio_file *f) return 1; }*/ - ibv_destroy_qp(rd->qp); ibv_destroy_cq(rd->cq); + ibv_destroy_qp(rd->qp); if (rd->is_client == 1) rdma_destroy_id(rd->cm_id); @@ -1182,6 +1213,7 @@ static int fio_rdmaio_setup(struct thread_data *td) rd = malloc(sizeof(*rd));; memset(rd, 0, sizeof(*rd)); + init_rand_seed(&rd->rand_state, (unsigned int) GOLDEN_RATIO_PRIME); td->io_ops->data = rd; } @@ -1229,8 +1261,8 @@ static int fio_rdmaio_init(struct thread_data fio_unused * td) log_err(" make sure OFED is installed,\n"); log_err(" $ ofed_info\n"); log_err(" then try to make fio as follows:\n"); - log_err(" $ export EXTFLAGS=\"-DFIO_HAVE_RDMA\"\n"); - log_err(" $ export EXTLIBS=\"-libverbs -lrdmacm\"\n"); + log_err(" $ export EXTFLAGS+=\" -DFIO_HAVE_RDMA \"\n"); + log_err(" $ export EXTLIBS+=\" -libverbs -lrdmacm \"\n"); log_err(" $ make clean && make\n"); return 1; }