/*---------------------------------------------------------------------------*/ static int xio_server_main(void *data) { struct xio_server *server; struct xio_context_params ctx_params; init_xio_rdma_common_test(); memset(&ctx_params, 0, sizeof(ctx_params)); ctx_params.flags = XIO_LOOP_GIVEN_THREAD; ctx_params.worker = current; test_params.ctx = xio_context_create(&ctx_params, 0, 0); xio_assert(test_params.ctx); session_ops.on_session_event = on_session_event; server = xio_bind(test_params.ctx, &session_ops, url, NULL, 0, NULL); xio_assert(server); pr_info("listen to %s\n", url); xio_context_run_loop(test_params.ctx); /* normal exit phase */ pr_info("exit signaled\n"); /* free the server */ xio_unbind(server); xio_context_destroy(test_params.ctx); fini_xio_rdma_common_test(); complete_and_exit(&cleanup_complete, 0); return 0; }
/*---------------------------------------------------------------------------*/ static int on_msg_error(struct xio_session *session, enum xio_status error, enum xio_msg_direction direction, struct xio_msg *msg, void *cb_user_context) { struct thread_data *tdata = (struct thread_data *)cb_user_context; printf("**** [%p] message [%lu] failed. reason: %s\n", session, msg->request->sn, xio_strerror(error)); msg_pool_put(tdata->pool, msg); switch (error) { case XIO_E_MSG_DISCARDED: case XIO_E_MSG_FLUSHED: break; default: /* need to send response here */ xio_assert(0); break; }; return 0; }
/*---------------------------------------------------------------------------*/ static int on_request(struct xio_session *session, struct xio_msg *req, int last_in_rxq, void *cb_prv_data) { struct xio_msg *rsp; struct thread_data *tdata = (struct thread_data *)cb_prv_data; /* process request */ process_request(tdata, req); /* alloc transaction */ rsp = msg_pool_get(tdata->pool); rsp->request = req; /* fill response */ msg_build_out_sgl(&msg_prms, rsp, test_config.hdr_len, 1, test_config.data_len); if (xio_send_response(rsp) == -1) { printf("**** [%p] Error - xio_send_msg failed. %s\n", session, xio_strerror(xio_errno())); msg_pool_put(tdata->pool, req); /* better to do disconnect */ /*xio_disconnect(tdata->conn);*/ xio_assert(0); } tdata->nsent++; return 0; }
/*---------------------------------------------------------------------------*/ static int on_request(struct xio_session *session, struct xio_msg *req, int last_in_rxq, void *cb_prv_data) { struct xio_msg *rsp; /* process request */ process_request(req); /* alloc transaction */ rsp = msg_pool_get(pool); rsp->request = req; /* fill response */ msg_build_out_sgl(&msg_params, rsp, test_config.hdr_len, 1, test_config.data_len); if (xio_send_response(rsp) == -1) { printf("**** [%p] Error - xio_send_msg failed. %s\n", session, xio_strerror(xio_errno())); msg_pool_put(pool, req); xio_assert(0); } return 0; }
/*---------------------------------------------------------------------------*/ static int on_message_delivered(struct xio_session *session, struct xio_msg *msg, int last_in_rxq, void *cb_user_context) { struct ow_test_params *ow_params = (struct ow_test_params *)cb_user_context; struct xio_msg *new_msg; process_tx_message(ow_params, msg); ow_params->ndelivered++; /* can be safely returned to pool */ msg_pool_put(ow_params->pool, msg); if (ow_params->finite_run) { if (ow_params->ndelivered == ow_params->disconnect_nr) { xio_disconnect(ow_params->conn); return 0; } if (ow_params->nsent == ow_params->disconnect_nr) return 0; } /* peek message from the pool */ new_msg = msg_pool_get(ow_params->pool); if (new_msg == NULL) { printf("pool is empty\n"); return 0; } /* assign buffers to the message */ msg_write(&ow_params->msg_params, new_msg, test_config.hdr_len, 1, test_config.data_len); /* * ask for receipt since we need to put the message back * to pool */ new_msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT; /* send it */ if (xio_send_msg(ow_params->conn, new_msg) == -1) { if (xio_errno() != EAGAIN) printf("**** [%p] Error - xio_send_msg " \ "failed. %s\n", session, xio_strerror(xio_errno())); msg_pool_put(ow_params->pool, new_msg); xio_assert(0); } ow_params->nsent++; return 0; }
/*---------------------------------------------------------------------------*/ int on_msg_error(struct xio_session *session, enum xio_status error, struct xio_msg *msg, void *cb_private_data) { switch (msg->type) { case XIO_MSG_TYPE_REQ: printf("**** [%p] message [%lu] failed. reason: %s\n", session, msg->sn, xio_strerror(error)); msg_pool_put(pool, msg); switch (error) { case XIO_E_MSG_FLUSHED: case XIO_E_MSG_DISCARDED: break; default: xio_assert(0); break; }; break; case XIO_MSG_TYPE_RSP: printf("**** [%p] message [%lu] failed. reason: %s\n", session, msg->request->sn, xio_strerror(error)); /* message is no longer needed */ switch (error) { case XIO_E_MSG_FLUSHED: xio_release_response(msg); msg_pool_put(pool, msg); break; default: msg_pool_put(pool, msg); xio_assert(0); break; }; break; default: printf("unknown message type : %d\n", msg->type); msg_pool_put(pool, msg); xio_assert(0); break; } return 0; }
/*---------------------------------------------------------------------------*/ static int on_response(struct xio_session *session, struct xio_msg *rsp, int more_in_batch, void *cb_user_context) { struct xio_iovec_ex *sglist; process_response(rsp); /* message is no longer needed */ xio_release_response(rsp); nrecv++; if (test_config.finite_run) { if (nrecv == disconnect_nr) { xio_disconnect(conn); return 0; } if (nrecv > disconnect_nr || nsent == disconnect_nr) return 0; } /* reset message */ rsp->in.header.iov_base = NULL; rsp->in.header.iov_len = 0; sglist = vmsg_sglist(&rsp->in); vmsg_sglist_set_nents(&rsp->in, 1); sglist[0].iov_base = NULL; sglist[0].iov_len = ONE_MB; sglist[0].mr = NULL; rsp->sn = 0; rsp->more_in_batch = 0; do { /* recycle the message and fill new request */ msg_write(&msg_params, rsp, test_config.hdr_len, 1, test_config.data_len); /* try to send it */ if (xio_send_request(conn, rsp) == -1) { if (xio_errno() != EAGAIN) printf("**** [%p] Error - xio_send_msg " \ "failed %s\n", session, xio_strerror(xio_errno())); msg_pool_put(pool, rsp); xio_assert(0); } nsent++; } while (0); return 0; }
/*---------------------------------------------------------------------------*/ static int on_connection_established(struct xio_connection *conn) { struct xio_msg *msg; pr_info("**** starting ...\n"); /* create transaction */ msg = msg_pool_get(pool); if (!msg) return 0; /* get pointers to internal buffers */ msg->in.header.iov_base = NULL; msg->in.header.iov_len = 0; msg->in.data_tbl.nents = 0; /* sglist = vmsg_sglist(&msg->in); sglist[0].iov_base = NULL; sglist[0].iov_len = ONE_MB; sglist[0].mr = NULL; vmsg_sglist_set_nents(&msg->in, 1); */ /* recycle the message and fill new request */ msg_build_out_sgl(&msg_params, msg, test_config.hdr_len, 1, test_config.data_len); /* try to send it */ if (xio_send_request(conn, msg) == -1) { pr_info("**** sent %d messages\n", 1); if (xio_errno() != EAGAIN) pr_info("**** [%p] Error - xio_send_msg " \ "failed. %s\n", conn, xio_strerror(xio_errno())); msg_pool_put(pool, msg); xio_assert(0); } return 0; }
/*---------------------------------------------------------------------------*/ static int on_response(struct xio_session *session, struct xio_msg *msg, int last_in_rxq, void *cb_user_context) { struct test_params *test_params = (struct test_params *)cb_user_context; struct xio_iovec_ex *sglist; static int chain_messages = CHAIN_MESSAGES; size_t j; test_params->nrecv++; process_response(test_params, msg); /* message is no longer needed */ xio_release_response(msg); msg_pool_put(test_params->pool, msg); if (test_params->finite_run) { if (test_params->nrecv == test_params->disconnect_nr) { xio_disconnect(test_params->connection); return 0; } if (test_params->nsent == test_params->disconnect_nr) return 0; } /* peek message from the pool */ msg = msg_pool_get(test_params->pool); if (msg == NULL) { printf("pool is empty\n"); return 0; } msg->in.header.iov_base = NULL; msg->in.header.iov_len = 0; sglist = vmsg_sglist(&msg->in); vmsg_sglist_set_nents(&msg->in, test_config.in_iov_len); /* tell accelio to use 1MB buffer from its internal pool */ for (j = 0; j < test_config.in_iov_len; j++) { sglist[j].iov_base = NULL; sglist[j].iov_len = ONE_MB; sglist[j].mr = NULL; } msg->sn = 0; /* assign buffers to the message */ msg_build_out_sgl(&test_params->msg_params, msg, test_config.hdr_len, test_config.out_iov_len, test_config.data_len); if (chain_messages) { msg->next = NULL; if (test_params->chain.head == NULL) { test_params->chain.head = msg; test_params->chain.tail = test_params->chain.head; } else { test_params->chain.tail->next = msg; test_params->chain.tail = test_params->chain.tail->next; } if (++test_params->chain.sz == MAX_OUTSTANDING_REQS) { if (xio_send_request(test_params->connection, test_params->chain.head) == -1) { if (xio_errno() != EAGAIN) printf("**** [%p] Error - xio_send_request " \ "failed %s\n", session, xio_strerror(xio_errno())); msg_pool_put(test_params->pool, msg); xio_assert(xio_errno() == EAGAIN); } test_params->nsent += test_params->chain.sz; test_params->chain.head = NULL; test_params->chain.sz = 0; } } else { /* try to send it */ /*msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT; */ /*msg->flags = XIO_MSG_FLAG_PEER_READ_REQ;*/ if (xio_send_request(test_params->connection, msg) == -1) { if (xio_errno() != EAGAIN) printf("**** [%p] Error - xio_send_request " \ "failed %s\n", session, xio_strerror(xio_errno())); msg_pool_put(test_params->pool, msg); xio_assert(xio_errno() == EAGAIN); } test_params->nsent++; } return 0; }
/*---------------------------------------------------------------------------*/ static int xio_client_main(void *data) { char url[256]; struct xio_session_params params; struct xio_context_params ctx_params; struct xio_connection_params cparams; int error; int retval = 0; atomic_add(2, &module_state); print_counter = PRINT_COUNTER; print_test_config(&test_config); memset(¶ms, 0, sizeof(params)); memset(&cparams, 0, sizeof(cparams)); /* prepare buffers for this test */ if (msg_api_init(&msg_params, test_config.hdr_len, test_config.data_len, 0) != 0) { pr_err("msg_api_init failed\n"); return -1; } pool = msg_pool_alloc(MAX_POOL_SIZE, 1, 1); if (!pool) { pr_err("msg_pool_alloc failed\n"); goto cleanup; } /* create thread context for the server */ memset(&ctx_params, 0, sizeof(ctx_params)); ctx_params.flags = XIO_LOOP_GIVEN_THREAD; ctx_params.worker = current; ctx = xio_context_create(&ctx_params, POLLING_TIMEOUT, cpu); if (!ctx) { pr_err("context open failed\n"); goto cleanup; } sprintf(url, "%s://%s:%d", test_config.transport, test_config.server_addr, test_config.server_port); params.type = XIO_SESSION_CLIENT; params.ses_ops = &ses_ops; params.uri = url; g_session = xio_session_create(¶ms); if (!g_session) pr_err("session creation failed\n"); cparams.session = g_session; cparams.ctx = ctx; cparams.conn_idx = test_config.conn_idx; /* connect the session */ g_connection = xio_connect(&cparams); /* the default xio supplied main loop */ if (atomic_add_unless(&module_state, 4, 0x83)) retval = xio_context_run_loop(ctx); atomic_sub(4, &module_state); if (retval != 0) { error = xio_errno(); pr_err("running event loop failed. reason %d - (%s)\n", error, xio_strerror(error)); xio_assert(retval == 0); } /* normal exit phase */ pr_info("exit signaled\n"); xio_context_destroy(ctx); msg_pool_free(pool); cleanup: msg_api_free(&msg_params); pr_info("exit complete\n"); complete_and_exit(&cleanup_complete, 0); return 0; }
/*---------------------------------------------------------------------------*/ static int on_msg_send_complete(struct xio_session *session, struct xio_msg *msg, void *cb_user_context) { struct test_params *test_params = cb_user_context; process_message(test_params, msg); test_params->ncomp++; /* can be safely freed */ msg_pool_put(test_params->pool, msg); if (test_params->finite_run) { if ((test_params->ncomp+test_params->ndelivered) > test_params->disconnect_nr) return 0; if ((test_params->ncomp + test_params->ndelivered) == test_params->disconnect_nr) { xio_disconnect(test_params->connection); return 0; } } if (test_params->closed) return 0; /* peek message from the pool */ msg = msg_pool_get(test_params->pool); if (msg == NULL) { printf("pool is empty\n"); return 0; } /* reset message */ msg->in.header.iov_base = NULL; msg->in.header.iov_len = 0; msg->in.data_iov.nents = 0; msg->more_in_batch = 0; /* assign buffers to the message */ msg_write(&test_params->msg_params, msg, test_config.hdr_len, 1, test_config.data_len); /* try to send it */ if (test_params->ask_for_receipt) msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT; else msg->flags = 0; if (xio_send_msg(test_params->connection, msg) == -1) { if (xio_errno() != EAGAIN) printf("**** [%p] Error - xio_send_request " \ "failed %s\n", session, xio_strerror(xio_errno())); msg_pool_put(test_params->pool, msg); xio_assert(0); } test_params->nsent++; return 0; }