1e68ff398SKip Macy /*
2e68ff398SKip Macy * Copyright (c) 2005 Ammasso, Inc. All rights reserved.
30082e6a5SNavdeep Parhar * Copyright (c) 2006-2009 Open Grid Computing, Inc. All rights reserved.
4e68ff398SKip Macy *
5e68ff398SKip Macy * This software is available to you under a choice of one of two
6e68ff398SKip Macy * licenses. You may choose to be licensed under the terms of the GNU
7e68ff398SKip Macy * General Public License (GPL) Version 2, available from the file
8e68ff398SKip Macy * COPYING in the main directory of this source tree, or the
9e68ff398SKip Macy * OpenIB.org BSD license below:
10e68ff398SKip Macy *
11e68ff398SKip Macy * Redistribution and use in source and binary forms, with or
12e68ff398SKip Macy * without modification, are permitted provided that the following
13e68ff398SKip Macy * conditions are met:
14e68ff398SKip Macy *
15e68ff398SKip Macy * - Redistributions of source code must retain the above
16e68ff398SKip Macy * copyright notice, this list of conditions and the following
17e68ff398SKip Macy * disclaimer.
18e68ff398SKip Macy *
19e68ff398SKip Macy * - Redistributions in binary form must reproduce the above
20e68ff398SKip Macy * copyright notice, this list of conditions and the following
21e68ff398SKip Macy * disclaimer in the documentation and/or other materials
22e68ff398SKip Macy * provided with the distribution.
23e68ff398SKip Macy *
24e68ff398SKip Macy * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25e68ff398SKip Macy * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26e68ff398SKip Macy * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27e68ff398SKip Macy * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28e68ff398SKip Macy * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29e68ff398SKip Macy * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30e68ff398SKip Macy * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31e68ff398SKip Macy * SOFTWARE.
32e68ff398SKip Macy */
33e68ff398SKip Macy
34e68ff398SKip Macy #include <sys/cdefs.h>
35e68ff398SKip Macy __FBSDID("$FreeBSD$");
36e68ff398SKip Macy
370082e6a5SNavdeep Parhar #include <linux/module.h>
380082e6a5SNavdeep Parhar #include <linux/moduleparam.h>
390082e6a5SNavdeep Parhar #include <linux/slab.h>
400082e6a5SNavdeep Parhar #include <linux/err.h>
410082e6a5SNavdeep Parhar #include <linux/string.h>
420082e6a5SNavdeep Parhar #include <linux/list.h>
430082e6a5SNavdeep Parhar #include <linux/in.h>
440082e6a5SNavdeep Parhar #include <linux/device.h>
450082e6a5SNavdeep Parhar #include <linux/pci.h>
460082e6a5SNavdeep Parhar #include <linux/sched.h>
474eb18346SMark Johnston #include <linux/wait.h>
48e68ff398SKip Macy
490082e6a5SNavdeep Parhar #include <asm/atomic.h>
50e68ff398SKip Macy
510082e6a5SNavdeep Parhar #include <rdma/ib_verbs.h>
5209fe6320SNavdeep Parhar #include <rdma/rdma_cm.h>
53e68ff398SKip Macy
54e68ff398SKip Macy #include "krping.h"
550082e6a5SNavdeep Parhar #include "getopt.h"
56e68ff398SKip Macy
57478d3005SHans Petter Selasky #define PFX "krping: "
58478d3005SHans Petter Selasky
590082e6a5SNavdeep Parhar extern int krping_debug;
60478d3005SHans Petter Selasky #define DEBUG_LOG(...) do { if (krping_debug) log(LOG_INFO, __VA_ARGS__); } while (0)
619d31afabSNavdeep Parhar #define BIND_INFO 1
62e68ff398SKip Macy
630082e6a5SNavdeep Parhar MODULE_AUTHOR("Steve Wise");
64478d3005SHans Petter Selasky MODULE_DESCRIPTION("RDMA ping server");
650082e6a5SNavdeep Parhar MODULE_LICENSE("Dual BSD/GPL");
66d39d7c86SHans Petter Selasky MODULE_VERSION(krping, 1);
672da3897dSHans Petter Selasky MODULE_DEPEND(krping, linuxkpi, 1, 1, 1);
680082e6a5SNavdeep Parhar
690082e6a5SNavdeep Parhar static __inline uint64_t
get_cycles(void)700082e6a5SNavdeep Parhar get_cycles(void)
710082e6a5SNavdeep Parhar {
72f4ea84ceSJohn Baldwin return (get_cyclecount());
730082e6a5SNavdeep Parhar }
740082e6a5SNavdeep Parhar
750082e6a5SNavdeep Parhar typedef uint64_t cycles_t;
760082e6a5SNavdeep Parhar
770082e6a5SNavdeep Parhar enum mem_type {
780082e6a5SNavdeep Parhar DMA = 1,
79478d3005SHans Petter Selasky REG = 2,
800082e6a5SNavdeep Parhar };
81e68ff398SKip Macy
82e68ff398SKip Macy static const struct krping_option krping_opts[] = {
83e68ff398SKip Macy {"count", OPT_INT, 'C'},
84e68ff398SKip Macy {"size", OPT_INT, 'S'},
85e68ff398SKip Macy {"addr", OPT_STRING, 'a'},
86478d3005SHans Petter Selasky {"addr6", OPT_STRING, 'A'},
87e68ff398SKip Macy {"port", OPT_INT, 'p'},
88e68ff398SKip Macy {"verbose", OPT_NOPARAM, 'v'},
89e68ff398SKip Macy {"validate", OPT_NOPARAM, 'V'},
90e68ff398SKip Macy {"server", OPT_NOPARAM, 's'},
91e68ff398SKip Macy {"client", OPT_NOPARAM, 'c'},
920082e6a5SNavdeep Parhar {"server_inv", OPT_NOPARAM, 'I'},
93e68ff398SKip Macy {"wlat", OPT_NOPARAM, 'l'},
94e68ff398SKip Macy {"rlat", OPT_NOPARAM, 'L'},
95e68ff398SKip Macy {"bw", OPT_NOPARAM, 'B'},
960082e6a5SNavdeep Parhar {"duplex", OPT_NOPARAM, 'd'},
9798450752SHans Petter Selasky {"tos", OPT_INT, 't'},
980082e6a5SNavdeep Parhar {"txdepth", OPT_INT, 'T'},
99e68ff398SKip Macy {"poll", OPT_NOPARAM, 'P'},
1000082e6a5SNavdeep Parhar {"local_dma_lkey", OPT_NOPARAM, 'Z'},
1010082e6a5SNavdeep Parhar {"read_inv", OPT_NOPARAM, 'R'},
102478d3005SHans Petter Selasky {"fr", OPT_NOPARAM, 'f'},
103e68ff398SKip Macy {NULL, 0, 0}
104e68ff398SKip Macy };
105e68ff398SKip Macy
1060082e6a5SNavdeep Parhar #define htonll(x) cpu_to_be64((x))
1070082e6a5SNavdeep Parhar #define ntohll(x) cpu_to_be64((x))
1080082e6a5SNavdeep Parhar
109478d3005SHans Petter Selasky static DEFINE_MUTEX(krping_mutex);
110e68ff398SKip Macy
111e68ff398SKip Macy /*
112e68ff398SKip Macy * List of running krping threads.
113e68ff398SKip Macy */
1140082e6a5SNavdeep Parhar static LIST_HEAD(krping_cbs);
115e68ff398SKip Macy
116e68ff398SKip Macy /*
117478d3005SHans Petter Selasky * Invoke like this, one on each side, using the server's address on
118478d3005SHans Petter Selasky * the RDMA device (iw%d):
119478d3005SHans Petter Selasky *
120478d3005SHans Petter Selasky * /bin/echo server,port=9999,addr=192.168.69.142,validate > /proc/krping
121478d3005SHans Petter Selasky * /bin/echo client,port=9999,addr=192.168.69.142,validate > /proc/krping
122478d3005SHans Petter Selasky * /bin/echo client,port=9999,addr6=2001:db8:0:f101::1,validate > /proc/krping
123478d3005SHans Petter Selasky *
124e68ff398SKip Macy * krping "ping/pong" loop:
125e68ff398SKip Macy * client sends source rkey/addr/len
126e68ff398SKip Macy * server receives source rkey/add/len
127e68ff398SKip Macy * server rdma reads "ping" data from source
128e68ff398SKip Macy * server sends "go ahead" on rdma read completion
129e68ff398SKip Macy * client sends sink rkey/addr/len
130e68ff398SKip Macy * server receives sink rkey/addr/len
131e68ff398SKip Macy * server rdma writes "pong" data to sink
132e68ff398SKip Macy * server sends "go ahead" on rdma write completion
133e68ff398SKip Macy * <repeat loop>
134e68ff398SKip Macy */
135e68ff398SKip Macy
136e68ff398SKip Macy /*
1370082e6a5SNavdeep Parhar * These states are used to signal events between the completion handler
1380082e6a5SNavdeep Parhar * and the main client or server thread.
1390082e6a5SNavdeep Parhar *
1400082e6a5SNavdeep Parhar * Once CONNECTED, they cycle through RDMA_READ_ADV, RDMA_WRITE_ADV,
1410082e6a5SNavdeep Parhar * and RDMA_WRITE_COMPLETE for each ping.
1420082e6a5SNavdeep Parhar */
1430082e6a5SNavdeep Parhar enum test_state {
1440082e6a5SNavdeep Parhar IDLE = 1,
1450082e6a5SNavdeep Parhar CONNECT_REQUEST,
1460082e6a5SNavdeep Parhar ADDR_RESOLVED,
1470082e6a5SNavdeep Parhar ROUTE_RESOLVED,
1480082e6a5SNavdeep Parhar CONNECTED,
1490082e6a5SNavdeep Parhar RDMA_READ_ADV,
1500082e6a5SNavdeep Parhar RDMA_READ_COMPLETE,
1510082e6a5SNavdeep Parhar RDMA_WRITE_ADV,
1520082e6a5SNavdeep Parhar RDMA_WRITE_COMPLETE,
1530082e6a5SNavdeep Parhar ERROR
1540082e6a5SNavdeep Parhar };
1550082e6a5SNavdeep Parhar
1560082e6a5SNavdeep Parhar struct krping_rdma_info {
1570082e6a5SNavdeep Parhar uint64_t buf;
1580082e6a5SNavdeep Parhar uint32_t rkey;
1590082e6a5SNavdeep Parhar uint32_t size;
1600082e6a5SNavdeep Parhar };
1610082e6a5SNavdeep Parhar
1620082e6a5SNavdeep Parhar /*
163e68ff398SKip Macy * Default max buffer size for IO...
164e68ff398SKip Macy */
165e68ff398SKip Macy #define RPING_BUFSIZE 128*1024
1660082e6a5SNavdeep Parhar #define RPING_SQ_DEPTH 64
167e68ff398SKip Macy
1680082e6a5SNavdeep Parhar /*
1690082e6a5SNavdeep Parhar * Control block struct.
1700082e6a5SNavdeep Parhar */
1710082e6a5SNavdeep Parhar struct krping_cb {
1720082e6a5SNavdeep Parhar int server; /* 0 iff client */
1730082e6a5SNavdeep Parhar struct ib_cq *cq;
1740082e6a5SNavdeep Parhar struct ib_pd *pd;
1750082e6a5SNavdeep Parhar struct ib_qp *qp;
1760082e6a5SNavdeep Parhar
1770082e6a5SNavdeep Parhar struct ib_mr *dma_mr;
1780082e6a5SNavdeep Parhar
1790082e6a5SNavdeep Parhar struct ib_fast_reg_page_list *page_list;
1800082e6a5SNavdeep Parhar int page_list_len;
181478d3005SHans Petter Selasky struct ib_reg_wr reg_mr_wr;
1820082e6a5SNavdeep Parhar struct ib_send_wr invalidate_wr;
183478d3005SHans Petter Selasky struct ib_mr *reg_mr;
1840082e6a5SNavdeep Parhar int server_invalidate;
1850082e6a5SNavdeep Parhar int read_inv;
1860082e6a5SNavdeep Parhar u8 key;
1870082e6a5SNavdeep Parhar
1880082e6a5SNavdeep Parhar struct ib_recv_wr rq_wr; /* recv work request record */
1890082e6a5SNavdeep Parhar struct ib_sge recv_sgl; /* recv single SGE */
190478d3005SHans Petter Selasky struct krping_rdma_info recv_buf __aligned(16); /* malloc'd buffer */
1910082e6a5SNavdeep Parhar u64 recv_dma_addr;
1920082e6a5SNavdeep Parhar DECLARE_PCI_UNMAP_ADDR(recv_mapping)
1930082e6a5SNavdeep Parhar
1940082e6a5SNavdeep Parhar struct ib_send_wr sq_wr; /* send work requrest record */
1950082e6a5SNavdeep Parhar struct ib_sge send_sgl;
196478d3005SHans Petter Selasky struct krping_rdma_info send_buf __aligned(16); /* single send buf */
1970082e6a5SNavdeep Parhar u64 send_dma_addr;
1980082e6a5SNavdeep Parhar DECLARE_PCI_UNMAP_ADDR(send_mapping)
1990082e6a5SNavdeep Parhar
200478d3005SHans Petter Selasky struct ib_rdma_wr rdma_sq_wr; /* rdma work request record */
2010082e6a5SNavdeep Parhar struct ib_sge rdma_sgl; /* rdma single SGE */
2020082e6a5SNavdeep Parhar char *rdma_buf; /* used as rdma sink */
2030082e6a5SNavdeep Parhar u64 rdma_dma_addr;
2040082e6a5SNavdeep Parhar DECLARE_PCI_UNMAP_ADDR(rdma_mapping)
2050082e6a5SNavdeep Parhar struct ib_mr *rdma_mr;
2060082e6a5SNavdeep Parhar
2070082e6a5SNavdeep Parhar uint32_t remote_rkey; /* remote guys RKEY */
2080082e6a5SNavdeep Parhar uint64_t remote_addr; /* remote guys TO */
2090082e6a5SNavdeep Parhar uint32_t remote_len; /* remote guys LEN */
2100082e6a5SNavdeep Parhar
2110082e6a5SNavdeep Parhar char *start_buf; /* rdma read src */
2120082e6a5SNavdeep Parhar u64 start_dma_addr;
2130082e6a5SNavdeep Parhar DECLARE_PCI_UNMAP_ADDR(start_mapping)
2140082e6a5SNavdeep Parhar struct ib_mr *start_mr;
2150082e6a5SNavdeep Parhar
2160082e6a5SNavdeep Parhar enum test_state state; /* used for cond/signalling */
2170082e6a5SNavdeep Parhar wait_queue_head_t sem;
2180082e6a5SNavdeep Parhar struct krping_stats stats;
2190082e6a5SNavdeep Parhar
2200082e6a5SNavdeep Parhar uint16_t port; /* dst port in NBO */
2214f939024SHans Petter Selasky u8 addr[16] __aligned(8); /* dst addr in NBO */
2220082e6a5SNavdeep Parhar char *addr_str; /* dst addr string */
223478d3005SHans Petter Selasky uint8_t addr_type; /* ADDR_FAMILY - IPv4/V6 */
2240082e6a5SNavdeep Parhar int verbose; /* verbose logging */
2250082e6a5SNavdeep Parhar int count; /* ping count */
2260082e6a5SNavdeep Parhar int size; /* ping data size */
2270082e6a5SNavdeep Parhar int validate; /* validate ping data */
2280082e6a5SNavdeep Parhar int wlat; /* run wlat test */
2290082e6a5SNavdeep Parhar int rlat; /* run rlat test */
2300082e6a5SNavdeep Parhar int bw; /* run bw test */
2310082e6a5SNavdeep Parhar int duplex; /* run bw full duplex test */
2320082e6a5SNavdeep Parhar int poll; /* poll or block for rlat test */
2330082e6a5SNavdeep Parhar int txdepth; /* SQ depth */
2340082e6a5SNavdeep Parhar int local_dma_lkey; /* use 0 for lkey */
235478d3005SHans Petter Selasky int frtest; /* reg test */
23698450752SHans Petter Selasky int tos; /* type of service */
2370082e6a5SNavdeep Parhar
2380082e6a5SNavdeep Parhar /* CM stuff */
2390082e6a5SNavdeep Parhar struct rdma_cm_id *cm_id; /* connection on client side,*/
2400082e6a5SNavdeep Parhar /* listener on server side. */
2410082e6a5SNavdeep Parhar struct rdma_cm_id *child_cm_id; /* connection on server side */
2420082e6a5SNavdeep Parhar struct list_head list;
2430082e6a5SNavdeep Parhar };
244e68ff398SKip Macy
krping_cma_event_handler(struct rdma_cm_id * cma_id,struct rdma_cm_event * event)245e68ff398SKip Macy static int krping_cma_event_handler(struct rdma_cm_id *cma_id,
246e68ff398SKip Macy struct rdma_cm_event *event)
247e68ff398SKip Macy {
248e68ff398SKip Macy int ret;
249e68ff398SKip Macy struct krping_cb *cb = cma_id->context;
250e68ff398SKip Macy
251478d3005SHans Petter Selasky DEBUG_LOG("cma_event type %d cma_id %p (%s)\n", event->event, cma_id,
252478d3005SHans Petter Selasky (cma_id == cb->cm_id) ? "parent" : "child");
253e68ff398SKip Macy
254e68ff398SKip Macy switch (event->event) {
255e68ff398SKip Macy case RDMA_CM_EVENT_ADDR_RESOLVED:
256e68ff398SKip Macy cb->state = ADDR_RESOLVED;
257e68ff398SKip Macy ret = rdma_resolve_route(cma_id, 2000);
258e68ff398SKip Macy if (ret) {
259478d3005SHans Petter Selasky printk(KERN_ERR PFX "rdma_resolve_route error %d\n",
260478d3005SHans Petter Selasky ret);
2610082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
262e68ff398SKip Macy }
263e68ff398SKip Macy break;
264e68ff398SKip Macy
265e68ff398SKip Macy case RDMA_CM_EVENT_ROUTE_RESOLVED:
266e68ff398SKip Macy cb->state = ROUTE_RESOLVED;
2670082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
268e68ff398SKip Macy break;
269e68ff398SKip Macy
270e68ff398SKip Macy case RDMA_CM_EVENT_CONNECT_REQUEST:
271e68ff398SKip Macy cb->state = CONNECT_REQUEST;
272e68ff398SKip Macy cb->child_cm_id = cma_id;
273478d3005SHans Petter Selasky DEBUG_LOG("child cma %p\n", cb->child_cm_id);
2740082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
275e68ff398SKip Macy break;
276e68ff398SKip Macy
277e68ff398SKip Macy case RDMA_CM_EVENT_ESTABLISHED:
278478d3005SHans Petter Selasky DEBUG_LOG("ESTABLISHED\n");
279e68ff398SKip Macy if (!cb->server) {
280e68ff398SKip Macy cb->state = CONNECTED;
281e68ff398SKip Macy }
2820082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
283e68ff398SKip Macy break;
284e68ff398SKip Macy
285e68ff398SKip Macy case RDMA_CM_EVENT_ADDR_ERROR:
286e68ff398SKip Macy case RDMA_CM_EVENT_ROUTE_ERROR:
287e68ff398SKip Macy case RDMA_CM_EVENT_CONNECT_ERROR:
288e68ff398SKip Macy case RDMA_CM_EVENT_UNREACHABLE:
289e68ff398SKip Macy case RDMA_CM_EVENT_REJECTED:
290478d3005SHans Petter Selasky printk(KERN_ERR PFX "cma event %d, error %d\n", event->event,
291e68ff398SKip Macy event->status);
292e68ff398SKip Macy cb->state = ERROR;
2930082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
294e68ff398SKip Macy break;
295e68ff398SKip Macy
296e68ff398SKip Macy case RDMA_CM_EVENT_DISCONNECTED:
297478d3005SHans Petter Selasky printk(KERN_ERR PFX "DISCONNECT EVENT...\n");
298e68ff398SKip Macy cb->state = ERROR;
2990082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
300e68ff398SKip Macy break;
301e68ff398SKip Macy
302e68ff398SKip Macy case RDMA_CM_EVENT_DEVICE_REMOVAL:
303478d3005SHans Petter Selasky printk(KERN_ERR PFX "cma detected device removal!!!!\n");
30487fb59a5SHans Petter Selasky cb->state = ERROR;
30587fb59a5SHans Petter Selasky wake_up_interruptible(&cb->sem);
3060082e6a5SNavdeep Parhar break;
307e68ff398SKip Macy
308e68ff398SKip Macy default:
309478d3005SHans Petter Selasky printk(KERN_ERR PFX "oof bad type!\n");
3100082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
311e68ff398SKip Macy break;
312e68ff398SKip Macy }
313e68ff398SKip Macy return 0;
314e68ff398SKip Macy }
315e68ff398SKip Macy
server_recv(struct krping_cb * cb,struct ib_wc * wc)316e68ff398SKip Macy static int server_recv(struct krping_cb *cb, struct ib_wc *wc)
317e68ff398SKip Macy {
318e68ff398SKip Macy if (wc->byte_len != sizeof(cb->recv_buf)) {
319478d3005SHans Petter Selasky printk(KERN_ERR PFX "Received bogus data, size %d\n",
320e68ff398SKip Macy wc->byte_len);
321e68ff398SKip Macy return -1;
322e68ff398SKip Macy }
323e68ff398SKip Macy
324e68ff398SKip Macy cb->remote_rkey = ntohl(cb->recv_buf.rkey);
325e68ff398SKip Macy cb->remote_addr = ntohll(cb->recv_buf.buf);
326e68ff398SKip Macy cb->remote_len = ntohl(cb->recv_buf.size);
327478d3005SHans Petter Selasky DEBUG_LOG("Received rkey %x addr %llx len %d from peer\n",
328e68ff398SKip Macy cb->remote_rkey, (unsigned long long)cb->remote_addr,
329e68ff398SKip Macy cb->remote_len);
330e68ff398SKip Macy
331e68ff398SKip Macy if (cb->state <= CONNECTED || cb->state == RDMA_WRITE_COMPLETE)
332e68ff398SKip Macy cb->state = RDMA_READ_ADV;
333e68ff398SKip Macy else
334e68ff398SKip Macy cb->state = RDMA_WRITE_ADV;
335e68ff398SKip Macy
336e68ff398SKip Macy return 0;
337e68ff398SKip Macy }
338e68ff398SKip Macy
client_recv(struct krping_cb * cb,struct ib_wc * wc)339e68ff398SKip Macy static int client_recv(struct krping_cb *cb, struct ib_wc *wc)
340e68ff398SKip Macy {
341e68ff398SKip Macy if (wc->byte_len != sizeof(cb->recv_buf)) {
342478d3005SHans Petter Selasky printk(KERN_ERR PFX "Received bogus data, size %d\n",
343e68ff398SKip Macy wc->byte_len);
344e68ff398SKip Macy return -1;
345e68ff398SKip Macy }
346e68ff398SKip Macy
347e68ff398SKip Macy if (cb->state == RDMA_READ_ADV)
348e68ff398SKip Macy cb->state = RDMA_WRITE_ADV;
349e68ff398SKip Macy else
350e68ff398SKip Macy cb->state = RDMA_WRITE_COMPLETE;
351e68ff398SKip Macy
352e68ff398SKip Macy return 0;
353e68ff398SKip Macy }
354e68ff398SKip Macy
krping_cq_event_handler(struct ib_cq * cq,void * ctx)355e68ff398SKip Macy static void krping_cq_event_handler(struct ib_cq *cq, void *ctx)
356e68ff398SKip Macy {
357e68ff398SKip Macy struct krping_cb *cb = ctx;
358e68ff398SKip Macy struct ib_wc wc;
359c3987b8eSHans Petter Selasky const struct ib_recv_wr *bad_wr;
360e68ff398SKip Macy int ret;
361e68ff398SKip Macy
3620082e6a5SNavdeep Parhar BUG_ON(cb->cq != cq);
363478d3005SHans Petter Selasky if (cb->frtest) {
364478d3005SHans Petter Selasky printk(KERN_ERR PFX "cq completion event in frtest!\n");
365478d3005SHans Petter Selasky return;
366478d3005SHans Petter Selasky }
367478d3005SHans Petter Selasky if (!cb->wlat && !cb->rlat && !cb->bw)
368e68ff398SKip Macy ib_req_notify_cq(cb->cq, IB_CQ_NEXT_COMP);
369e68ff398SKip Macy while ((ret = ib_poll_cq(cb->cq, 1, &wc)) == 1) {
370e68ff398SKip Macy if (wc.status) {
37109fe6320SNavdeep Parhar if (wc.status == IB_WC_WR_FLUSH_ERR) {
372478d3005SHans Petter Selasky DEBUG_LOG("cq flushed\n");
37309fe6320SNavdeep Parhar continue;
37409fe6320SNavdeep Parhar } else {
375478d3005SHans Petter Selasky printk(KERN_ERR PFX "cq completion failed with "
3762d57dc7eSNavdeep Parhar "wr_id %jx status %d opcode %d vender_err %x\n",
3772d57dc7eSNavdeep Parhar (uintmax_t)wc.wr_id, wc.status, wc.opcode, wc.vendor_err);
378e68ff398SKip Macy goto error;
379e68ff398SKip Macy }
38009fe6320SNavdeep Parhar }
381aca12148SHans Petter Selasky if (cb->state == ERROR) {
382aca12148SHans Petter Selasky printk(KERN_ERR PFX "cq completion in ERROR state\n");
383aca12148SHans Petter Selasky return;
384aca12148SHans Petter Selasky }
385e68ff398SKip Macy switch (wc.opcode) {
386e68ff398SKip Macy case IB_WC_SEND:
387478d3005SHans Petter Selasky DEBUG_LOG("send completion\n");
388e68ff398SKip Macy cb->stats.send_bytes += cb->send_sgl.length;
389e68ff398SKip Macy cb->stats.send_msgs++;
390e68ff398SKip Macy break;
391e68ff398SKip Macy
392e68ff398SKip Macy case IB_WC_RDMA_WRITE:
393478d3005SHans Petter Selasky DEBUG_LOG("rdma write completion\n");
394478d3005SHans Petter Selasky cb->stats.write_bytes += cb->rdma_sq_wr.wr.sg_list->length;
395e68ff398SKip Macy cb->stats.write_msgs++;
396e68ff398SKip Macy cb->state = RDMA_WRITE_COMPLETE;
3970082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
398e68ff398SKip Macy break;
399e68ff398SKip Macy
400e68ff398SKip Macy case IB_WC_RDMA_READ:
401478d3005SHans Petter Selasky DEBUG_LOG("rdma read completion\n");
402478d3005SHans Petter Selasky cb->stats.read_bytes += cb->rdma_sq_wr.wr.sg_list->length;
403e68ff398SKip Macy cb->stats.read_msgs++;
404e68ff398SKip Macy cb->state = RDMA_READ_COMPLETE;
4050082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
406e68ff398SKip Macy break;
407e68ff398SKip Macy
408e68ff398SKip Macy case IB_WC_RECV:
409478d3005SHans Petter Selasky DEBUG_LOG("recv completion\n");
410e68ff398SKip Macy cb->stats.recv_bytes += sizeof(cb->recv_buf);
411e68ff398SKip Macy cb->stats.recv_msgs++;
412478d3005SHans Petter Selasky if (cb->wlat || cb->rlat || cb->bw)
413e68ff398SKip Macy ret = server_recv(cb, &wc);
414e68ff398SKip Macy else
415e68ff398SKip Macy ret = cb->server ? server_recv(cb, &wc) :
416e68ff398SKip Macy client_recv(cb, &wc);
417e68ff398SKip Macy if (ret) {
418478d3005SHans Petter Selasky printk(KERN_ERR PFX "recv wc error: %d\n", ret);
419e68ff398SKip Macy goto error;
420e68ff398SKip Macy }
421e68ff398SKip Macy
422e68ff398SKip Macy ret = ib_post_recv(cb->qp, &cb->rq_wr, &bad_wr);
423e68ff398SKip Macy if (ret) {
424478d3005SHans Petter Selasky printk(KERN_ERR PFX "post recv error: %d\n",
425e68ff398SKip Macy ret);
426e68ff398SKip Macy goto error;
427e68ff398SKip Macy }
4280082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
429e68ff398SKip Macy break;
430e68ff398SKip Macy
431e68ff398SKip Macy default:
432478d3005SHans Petter Selasky printk(KERN_ERR PFX
4330082e6a5SNavdeep Parhar "%s:%d Unexpected opcode %d, Shutting down\n",
4340082e6a5SNavdeep Parhar __func__, __LINE__, wc.opcode);
435e68ff398SKip Macy goto error;
436e68ff398SKip Macy }
437e68ff398SKip Macy }
438e68ff398SKip Macy if (ret) {
439478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll error %d\n", ret);
440e68ff398SKip Macy goto error;
441e68ff398SKip Macy }
442e68ff398SKip Macy return;
443e68ff398SKip Macy error:
444e68ff398SKip Macy cb->state = ERROR;
4450082e6a5SNavdeep Parhar wake_up_interruptible(&cb->sem);
446e68ff398SKip Macy }
447e68ff398SKip Macy
krping_accept(struct krping_cb * cb)448e68ff398SKip Macy static int krping_accept(struct krping_cb *cb)
449e68ff398SKip Macy {
450e68ff398SKip Macy struct rdma_conn_param conn_param;
451e68ff398SKip Macy int ret;
452e68ff398SKip Macy
453478d3005SHans Petter Selasky DEBUG_LOG("accepting client connection request\n");
454e68ff398SKip Macy
455e68ff398SKip Macy memset(&conn_param, 0, sizeof conn_param);
456e68ff398SKip Macy conn_param.responder_resources = 1;
457e68ff398SKip Macy conn_param.initiator_depth = 1;
458e68ff398SKip Macy
459e68ff398SKip Macy ret = rdma_accept(cb->child_cm_id, &conn_param);
460e68ff398SKip Macy if (ret) {
461478d3005SHans Petter Selasky printk(KERN_ERR PFX "rdma_accept error: %d\n", ret);
462e68ff398SKip Macy return ret;
463e68ff398SKip Macy }
464e68ff398SKip Macy
465478d3005SHans Petter Selasky if (!cb->wlat && !cb->rlat && !cb->bw) {
4660082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem, cb->state >= CONNECTED);
467e68ff398SKip Macy if (cb->state == ERROR) {
468478d3005SHans Petter Selasky printk(KERN_ERR PFX "wait for CONNECTED state %d\n",
4690082e6a5SNavdeep Parhar cb->state);
470e68ff398SKip Macy return -1;
471e68ff398SKip Macy }
472e68ff398SKip Macy }
473e68ff398SKip Macy return 0;
474e68ff398SKip Macy }
475e68ff398SKip Macy
krping_setup_wr(struct krping_cb * cb)476e68ff398SKip Macy static void krping_setup_wr(struct krping_cb *cb)
477e68ff398SKip Macy {
4780082e6a5SNavdeep Parhar cb->recv_sgl.addr = cb->recv_dma_addr;
479e68ff398SKip Macy cb->recv_sgl.length = sizeof cb->recv_buf;
480478d3005SHans Petter Selasky cb->recv_sgl.lkey = cb->pd->local_dma_lkey;
481e68ff398SKip Macy cb->rq_wr.sg_list = &cb->recv_sgl;
482e68ff398SKip Macy cb->rq_wr.num_sge = 1;
483e68ff398SKip Macy
4840082e6a5SNavdeep Parhar cb->send_sgl.addr = cb->send_dma_addr;
485e68ff398SKip Macy cb->send_sgl.length = sizeof cb->send_buf;
486478d3005SHans Petter Selasky cb->send_sgl.lkey = cb->pd->local_dma_lkey;
487e68ff398SKip Macy
488e68ff398SKip Macy cb->sq_wr.opcode = IB_WR_SEND;
489e68ff398SKip Macy cb->sq_wr.send_flags = IB_SEND_SIGNALED;
490e68ff398SKip Macy cb->sq_wr.sg_list = &cb->send_sgl;
491e68ff398SKip Macy cb->sq_wr.num_sge = 1;
492e68ff398SKip Macy
493478d3005SHans Petter Selasky if (cb->server || cb->wlat || cb->rlat || cb->bw) {
4940082e6a5SNavdeep Parhar cb->rdma_sgl.addr = cb->rdma_dma_addr;
495478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.send_flags = IB_SEND_SIGNALED;
496478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.sg_list = &cb->rdma_sgl;
497478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.num_sge = 1;
4980082e6a5SNavdeep Parhar }
499e68ff398SKip Macy
5000082e6a5SNavdeep Parhar /*
501478d3005SHans Petter Selasky * A chain of 2 WRs, INVALDATE_MR + REG_MR.
5020082e6a5SNavdeep Parhar * both unsignaled. The client uses them to reregister
5030082e6a5SNavdeep Parhar * the rdma buffers with a new key each iteration.
5040082e6a5SNavdeep Parhar */
505478d3005SHans Petter Selasky cb->reg_mr_wr.wr.opcode = IB_WR_REG_MR;
506478d3005SHans Petter Selasky cb->reg_mr_wr.mr = cb->reg_mr;
5070082e6a5SNavdeep Parhar
508478d3005SHans Petter Selasky cb->invalidate_wr.next = &cb->reg_mr_wr.wr;
5090082e6a5SNavdeep Parhar cb->invalidate_wr.opcode = IB_WR_LOCAL_INV;
510e68ff398SKip Macy }
511e68ff398SKip Macy
krping_setup_buffers(struct krping_cb * cb)512e68ff398SKip Macy static int krping_setup_buffers(struct krping_cb *cb)
513e68ff398SKip Macy {
514e68ff398SKip Macy int ret;
515e68ff398SKip Macy
516478d3005SHans Petter Selasky DEBUG_LOG(PFX "krping_setup_buffers called on cb %p\n", cb);
517e68ff398SKip Macy
5185df976f7SNavdeep Parhar cb->recv_dma_addr = ib_dma_map_single(cb->pd->device,
5190082e6a5SNavdeep Parhar &cb->recv_buf,
5200082e6a5SNavdeep Parhar sizeof(cb->recv_buf), DMA_BIDIRECTIONAL);
5210082e6a5SNavdeep Parhar pci_unmap_addr_set(cb, recv_mapping, cb->recv_dma_addr);
5225df976f7SNavdeep Parhar cb->send_dma_addr = ib_dma_map_single(cb->pd->device,
5230082e6a5SNavdeep Parhar &cb->send_buf, sizeof(cb->send_buf),
5240082e6a5SNavdeep Parhar DMA_BIDIRECTIONAL);
5250082e6a5SNavdeep Parhar pci_unmap_addr_set(cb, send_mapping, cb->send_dma_addr);
5260082e6a5SNavdeep Parhar
527478d3005SHans Petter Selasky cb->rdma_buf = ib_dma_alloc_coherent(cb->pd->device, cb->size,
528478d3005SHans Petter Selasky &cb->rdma_dma_addr,
529478d3005SHans Petter Selasky GFP_KERNEL);
530e68ff398SKip Macy if (!cb->rdma_buf) {
531478d3005SHans Petter Selasky DEBUG_LOG(PFX "rdma_buf allocation failed\n");
5320082e6a5SNavdeep Parhar ret = -ENOMEM;
5330082e6a5SNavdeep Parhar goto bail;
534e68ff398SKip Macy }
5350082e6a5SNavdeep Parhar pci_unmap_addr_set(cb, rdma_mapping, cb->rdma_dma_addr);
536478d3005SHans Petter Selasky cb->page_list_len = (((cb->size - 1) & PAGE_MASK) + PAGE_SIZE)
537478d3005SHans Petter Selasky >> PAGE_SHIFT;
538478d3005SHans Petter Selasky cb->reg_mr = ib_alloc_mr(cb->pd, IB_MR_TYPE_MEM_REG,
5390082e6a5SNavdeep Parhar cb->page_list_len);
540478d3005SHans Petter Selasky if (IS_ERR(cb->reg_mr)) {
541478d3005SHans Petter Selasky ret = PTR_ERR(cb->reg_mr);
542478d3005SHans Petter Selasky DEBUG_LOG(PFX "recv_buf reg_mr failed %d\n", ret);
5430082e6a5SNavdeep Parhar goto bail;
5440082e6a5SNavdeep Parhar }
545478d3005SHans Petter Selasky DEBUG_LOG(PFX "reg rkey 0x%x page_list_len %u\n",
546478d3005SHans Petter Selasky cb->reg_mr->rkey, cb->page_list_len);
547e68ff398SKip Macy
548478d3005SHans Petter Selasky if (!cb->server || cb->wlat || cb->rlat || cb->bw) {
5490082e6a5SNavdeep Parhar
550478d3005SHans Petter Selasky cb->start_buf = ib_dma_alloc_coherent(cb->pd->device, cb->size,
551478d3005SHans Petter Selasky &cb->start_dma_addr,
552478d3005SHans Petter Selasky GFP_KERNEL);
553e68ff398SKip Macy if (!cb->start_buf) {
554478d3005SHans Petter Selasky DEBUG_LOG(PFX "start_buf malloc failed\n");
5550082e6a5SNavdeep Parhar ret = -ENOMEM;
5560082e6a5SNavdeep Parhar goto bail;
557e68ff398SKip Macy }
5580082e6a5SNavdeep Parhar pci_unmap_addr_set(cb, start_mapping, cb->start_dma_addr);
559e68ff398SKip Macy }
560e68ff398SKip Macy
561e68ff398SKip Macy krping_setup_wr(cb);
562478d3005SHans Petter Selasky DEBUG_LOG(PFX "allocated & registered buffers...\n");
563e68ff398SKip Macy return 0;
5640082e6a5SNavdeep Parhar bail:
565478d3005SHans Petter Selasky if (cb->reg_mr && !IS_ERR(cb->reg_mr))
566478d3005SHans Petter Selasky ib_dereg_mr(cb->reg_mr);
5670082e6a5SNavdeep Parhar if (cb->rdma_mr && !IS_ERR(cb->rdma_mr))
568e68ff398SKip Macy ib_dereg_mr(cb->rdma_mr);
5690082e6a5SNavdeep Parhar if (cb->dma_mr && !IS_ERR(cb->dma_mr))
570e68ff398SKip Macy ib_dereg_mr(cb->dma_mr);
571478d3005SHans Petter Selasky if (cb->rdma_buf) {
572478d3005SHans Petter Selasky ib_dma_free_coherent(cb->pd->device, cb->size, cb->rdma_buf,
573478d3005SHans Petter Selasky cb->rdma_dma_addr);
574478d3005SHans Petter Selasky }
575478d3005SHans Petter Selasky if (cb->start_buf) {
576478d3005SHans Petter Selasky ib_dma_free_coherent(cb->pd->device, cb->size, cb->start_buf,
577478d3005SHans Petter Selasky cb->start_dma_addr);
578478d3005SHans Petter Selasky }
579e68ff398SKip Macy return ret;
580e68ff398SKip Macy }
581e68ff398SKip Macy
krping_free_buffers(struct krping_cb * cb)582e68ff398SKip Macy static void krping_free_buffers(struct krping_cb *cb)
583e68ff398SKip Macy {
584478d3005SHans Petter Selasky DEBUG_LOG("krping_free_buffers called on cb %p\n", cb);
585e68ff398SKip Macy
5860082e6a5SNavdeep Parhar if (cb->dma_mr)
5870082e6a5SNavdeep Parhar ib_dereg_mr(cb->dma_mr);
5880082e6a5SNavdeep Parhar if (cb->rdma_mr)
5890082e6a5SNavdeep Parhar ib_dereg_mr(cb->rdma_mr);
5900082e6a5SNavdeep Parhar if (cb->start_mr)
5910082e6a5SNavdeep Parhar ib_dereg_mr(cb->start_mr);
592478d3005SHans Petter Selasky if (cb->reg_mr)
593478d3005SHans Petter Selasky ib_dereg_mr(cb->reg_mr);
5940082e6a5SNavdeep Parhar
595e68ff398SKip Macy dma_unmap_single(cb->pd->device->dma_device,
596e68ff398SKip Macy pci_unmap_addr(cb, recv_mapping),
597e68ff398SKip Macy sizeof(cb->recv_buf), DMA_BIDIRECTIONAL);
598e68ff398SKip Macy dma_unmap_single(cb->pd->device->dma_device,
599e68ff398SKip Macy pci_unmap_addr(cb, send_mapping),
600e68ff398SKip Macy sizeof(cb->send_buf), DMA_BIDIRECTIONAL);
601478d3005SHans Petter Selasky
602478d3005SHans Petter Selasky ib_dma_free_coherent(cb->pd->device, cb->size, cb->rdma_buf,
603478d3005SHans Petter Selasky cb->rdma_dma_addr);
604478d3005SHans Petter Selasky
6050082e6a5SNavdeep Parhar if (cb->start_buf) {
606478d3005SHans Petter Selasky ib_dma_free_coherent(cb->pd->device, cb->size, cb->start_buf,
607478d3005SHans Petter Selasky cb->start_dma_addr);
608e68ff398SKip Macy }
609e68ff398SKip Macy }
610e68ff398SKip Macy
krping_create_qp(struct krping_cb * cb)611e68ff398SKip Macy static int krping_create_qp(struct krping_cb *cb)
612e68ff398SKip Macy {
613e68ff398SKip Macy struct ib_qp_init_attr init_attr;
614e68ff398SKip Macy int ret;
615e68ff398SKip Macy
616e68ff398SKip Macy memset(&init_attr, 0, sizeof(init_attr));
617e68ff398SKip Macy init_attr.cap.max_send_wr = cb->txdepth;
618e68ff398SKip Macy init_attr.cap.max_recv_wr = 2;
619478d3005SHans Petter Selasky
620478d3005SHans Petter Selasky /* For flush_qp() */
621478d3005SHans Petter Selasky init_attr.cap.max_send_wr++;
622478d3005SHans Petter Selasky init_attr.cap.max_recv_wr++;
623478d3005SHans Petter Selasky
624e68ff398SKip Macy init_attr.cap.max_recv_sge = 1;
625e68ff398SKip Macy init_attr.cap.max_send_sge = 1;
626e68ff398SKip Macy init_attr.qp_type = IB_QPT_RC;
627e68ff398SKip Macy init_attr.send_cq = cb->cq;
628e68ff398SKip Macy init_attr.recv_cq = cb->cq;
6290082e6a5SNavdeep Parhar init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
630e68ff398SKip Macy
631e68ff398SKip Macy if (cb->server) {
632e68ff398SKip Macy ret = rdma_create_qp(cb->child_cm_id, cb->pd, &init_attr);
633e68ff398SKip Macy if (!ret)
634e68ff398SKip Macy cb->qp = cb->child_cm_id->qp;
635e68ff398SKip Macy } else {
636e68ff398SKip Macy ret = rdma_create_qp(cb->cm_id, cb->pd, &init_attr);
637e68ff398SKip Macy if (!ret)
638e68ff398SKip Macy cb->qp = cb->cm_id->qp;
639e68ff398SKip Macy }
640e68ff398SKip Macy
641e68ff398SKip Macy return ret;
642e68ff398SKip Macy }
643e68ff398SKip Macy
krping_free_qp(struct krping_cb * cb)644e68ff398SKip Macy static void krping_free_qp(struct krping_cb *cb)
645e68ff398SKip Macy {
646e68ff398SKip Macy ib_destroy_qp(cb->qp);
647e68ff398SKip Macy ib_destroy_cq(cb->cq);
648e68ff398SKip Macy ib_dealloc_pd(cb->pd);
649e68ff398SKip Macy }
650e68ff398SKip Macy
krping_setup_qp(struct krping_cb * cb,struct rdma_cm_id * cm_id)651e68ff398SKip Macy static int krping_setup_qp(struct krping_cb *cb, struct rdma_cm_id *cm_id)
652e68ff398SKip Macy {
653e68ff398SKip Macy int ret;
654478d3005SHans Petter Selasky struct ib_cq_init_attr attr = {0};
655478d3005SHans Petter Selasky
656478d3005SHans Petter Selasky cb->pd = ib_alloc_pd(cm_id->device, 0);
657e68ff398SKip Macy if (IS_ERR(cb->pd)) {
658478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_alloc_pd failed\n");
659e68ff398SKip Macy return PTR_ERR(cb->pd);
660e68ff398SKip Macy }
661478d3005SHans Petter Selasky DEBUG_LOG("created pd %p\n", cb->pd);
662e68ff398SKip Macy
6630082e6a5SNavdeep Parhar strlcpy(cb->stats.name, cb->pd->device->name, sizeof(cb->stats.name));
664ea68a714SNavdeep Parhar
665478d3005SHans Petter Selasky attr.cqe = cb->txdepth * 2;
666478d3005SHans Petter Selasky attr.comp_vector = 0;
667e68ff398SKip Macy cb->cq = ib_create_cq(cm_id->device, krping_cq_event_handler, NULL,
668478d3005SHans Petter Selasky cb, &attr);
669e68ff398SKip Macy if (IS_ERR(cb->cq)) {
670478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_create_cq failed\n");
671e68ff398SKip Macy ret = PTR_ERR(cb->cq);
672e68ff398SKip Macy goto err1;
673e68ff398SKip Macy }
674478d3005SHans Petter Selasky DEBUG_LOG("created cq %p\n", cb->cq);
675e68ff398SKip Macy
6760082e6a5SNavdeep Parhar if (!cb->wlat && !cb->rlat && !cb->bw && !cb->frtest) {
677e68ff398SKip Macy ret = ib_req_notify_cq(cb->cq, IB_CQ_NEXT_COMP);
678e68ff398SKip Macy if (ret) {
679478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_create_cq failed\n");
680e68ff398SKip Macy goto err2;
681e68ff398SKip Macy }
682e68ff398SKip Macy }
683e68ff398SKip Macy
684e68ff398SKip Macy ret = krping_create_qp(cb);
685e68ff398SKip Macy if (ret) {
686478d3005SHans Petter Selasky printk(KERN_ERR PFX "krping_create_qp failed: %d\n", ret);
687e68ff398SKip Macy goto err2;
688e68ff398SKip Macy }
689478d3005SHans Petter Selasky DEBUG_LOG("created qp %p\n", cb->qp);
690e68ff398SKip Macy return 0;
691e68ff398SKip Macy err2:
692e68ff398SKip Macy ib_destroy_cq(cb->cq);
693e68ff398SKip Macy err1:
694e68ff398SKip Macy ib_dealloc_pd(cb->pd);
695e68ff398SKip Macy return ret;
696e68ff398SKip Macy }
697e68ff398SKip Macy
6980082e6a5SNavdeep Parhar /*
6990082e6a5SNavdeep Parhar * return the (possibly rebound) rkey for the rdma buffer.
700478d3005SHans Petter Selasky * REG mode: invalidate and rebind via reg wr.
7010082e6a5SNavdeep Parhar * other modes: just return the mr rkey.
7020082e6a5SNavdeep Parhar */
krping_rdma_rkey(struct krping_cb * cb,u64 buf,int post_inv)7030082e6a5SNavdeep Parhar static u32 krping_rdma_rkey(struct krping_cb *cb, u64 buf, int post_inv)
7040082e6a5SNavdeep Parhar {
705478d3005SHans Petter Selasky u32 rkey;
706c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
7070082e6a5SNavdeep Parhar int ret;
708478d3005SHans Petter Selasky struct scatterlist sg = {0};
7090082e6a5SNavdeep Parhar
710478d3005SHans Petter Selasky cb->invalidate_wr.ex.invalidate_rkey = cb->reg_mr->rkey;
7110082e6a5SNavdeep Parhar
7120082e6a5SNavdeep Parhar /*
713478d3005SHans Petter Selasky * Update the reg key.
7140082e6a5SNavdeep Parhar */
715478d3005SHans Petter Selasky ib_update_fast_reg_key(cb->reg_mr, ++cb->key);
716478d3005SHans Petter Selasky cb->reg_mr_wr.key = cb->reg_mr->rkey;
7170082e6a5SNavdeep Parhar
7180082e6a5SNavdeep Parhar /*
719478d3005SHans Petter Selasky * Update the reg WR with new buf info.
7200082e6a5SNavdeep Parhar */
7210082e6a5SNavdeep Parhar if (buf == (u64)cb->start_dma_addr)
722478d3005SHans Petter Selasky cb->reg_mr_wr.access = IB_ACCESS_REMOTE_READ;
7230082e6a5SNavdeep Parhar else
724478d3005SHans Petter Selasky cb->reg_mr_wr.access = IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE;
725478d3005SHans Petter Selasky sg_dma_address(&sg) = buf;
726478d3005SHans Petter Selasky sg_dma_len(&sg) = cb->size;
7270082e6a5SNavdeep Parhar
728478d3005SHans Petter Selasky ret = ib_map_mr_sg(cb->reg_mr, &sg, 1, NULL, PAGE_SIZE);
729478d3005SHans Petter Selasky BUG_ON(ret <= 0 || ret > cb->page_list_len);
730478d3005SHans Petter Selasky
731478d3005SHans Petter Selasky DEBUG_LOG(PFX "post_inv = %d, reg_mr new rkey 0x%x pgsz %u len %u"
732478d3005SHans Petter Selasky " iova_start %llx\n",
7330082e6a5SNavdeep Parhar post_inv,
734478d3005SHans Petter Selasky cb->reg_mr_wr.key,
735478d3005SHans Petter Selasky cb->reg_mr->page_size,
736ae9a8ec9SHans Petter Selasky (unsigned)cb->reg_mr->length,
737478d3005SHans Petter Selasky (unsigned long long)cb->reg_mr->iova);
7380082e6a5SNavdeep Parhar
7390082e6a5SNavdeep Parhar if (post_inv)
7400082e6a5SNavdeep Parhar ret = ib_post_send(cb->qp, &cb->invalidate_wr, &bad_wr);
7410082e6a5SNavdeep Parhar else
742478d3005SHans Petter Selasky ret = ib_post_send(cb->qp, &cb->reg_mr_wr.wr, &bad_wr);
7430082e6a5SNavdeep Parhar if (ret) {
744478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
7450082e6a5SNavdeep Parhar cb->state = ERROR;
7460082e6a5SNavdeep Parhar }
747478d3005SHans Petter Selasky rkey = cb->reg_mr->rkey;
7480082e6a5SNavdeep Parhar return rkey;
7490082e6a5SNavdeep Parhar }
7500082e6a5SNavdeep Parhar
krping_format_send(struct krping_cb * cb,u64 buf)7510082e6a5SNavdeep Parhar static void krping_format_send(struct krping_cb *cb, u64 buf)
752e68ff398SKip Macy {
753e68ff398SKip Macy struct krping_rdma_info *info = &cb->send_buf;
7540082e6a5SNavdeep Parhar u32 rkey;
755e68ff398SKip Macy
7560082e6a5SNavdeep Parhar /*
757478d3005SHans Petter Selasky * Client side will do reg or mw bind before
7580082e6a5SNavdeep Parhar * advertising the rdma buffer. Server side
7590082e6a5SNavdeep Parhar * sends have no data.
7600082e6a5SNavdeep Parhar */
761478d3005SHans Petter Selasky if (!cb->server || cb->wlat || cb->rlat || cb->bw) {
7620082e6a5SNavdeep Parhar rkey = krping_rdma_rkey(cb, buf, !cb->server_invalidate);
763e68ff398SKip Macy info->buf = htonll(buf);
7640082e6a5SNavdeep Parhar info->rkey = htonl(rkey);
765e68ff398SKip Macy info->size = htonl(cb->size);
766478d3005SHans Petter Selasky DEBUG_LOG("RDMA addr %llx rkey %x len %d\n",
7670082e6a5SNavdeep Parhar (unsigned long long)buf, rkey, cb->size);
7680082e6a5SNavdeep Parhar }
769e68ff398SKip Macy }
770e68ff398SKip Macy
krping_test_server(struct krping_cb * cb)771e68ff398SKip Macy static void krping_test_server(struct krping_cb *cb)
772e68ff398SKip Macy {
773c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
774c3987b8eSHans Petter Selasky struct ib_send_wr inv;
775e68ff398SKip Macy int ret;
776e68ff398SKip Macy
777e68ff398SKip Macy while (1) {
778e68ff398SKip Macy /* Wait for client's Start STAG/TO/Len */
7790082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem, cb->state >= RDMA_READ_ADV);
780e68ff398SKip Macy if (cb->state != RDMA_READ_ADV) {
781478d3005SHans Petter Selasky printk(KERN_ERR PFX "wait for RDMA_READ_ADV state %d\n",
782e68ff398SKip Macy cb->state);
783e68ff398SKip Macy break;
784e68ff398SKip Macy }
785e68ff398SKip Macy
786478d3005SHans Petter Selasky DEBUG_LOG("server received sink adv\n");
787e68ff398SKip Macy
788478d3005SHans Petter Selasky cb->rdma_sq_wr.rkey = cb->remote_rkey;
789478d3005SHans Petter Selasky cb->rdma_sq_wr.remote_addr = cb->remote_addr;
790478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.sg_list->length = cb->remote_len;
791478d3005SHans Petter Selasky cb->rdma_sgl.lkey = krping_rdma_rkey(cb, cb->rdma_dma_addr, !cb->read_inv);
792478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.next = NULL;
7930082e6a5SNavdeep Parhar
7940082e6a5SNavdeep Parhar /* Issue RDMA Read. */
7950082e6a5SNavdeep Parhar if (cb->read_inv)
796478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.opcode = IB_WR_RDMA_READ_WITH_INV;
7970082e6a5SNavdeep Parhar else {
7980082e6a5SNavdeep Parhar
799478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.opcode = IB_WR_RDMA_READ;
8000082e6a5SNavdeep Parhar /*
8010082e6a5SNavdeep Parhar * Immediately follow the read with a
8020082e6a5SNavdeep Parhar * fenced LOCAL_INV.
8030082e6a5SNavdeep Parhar */
804478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.next = &inv;
8050082e6a5SNavdeep Parhar memset(&inv, 0, sizeof inv);
8060082e6a5SNavdeep Parhar inv.opcode = IB_WR_LOCAL_INV;
807478d3005SHans Petter Selasky inv.ex.invalidate_rkey = cb->reg_mr->rkey;
8080082e6a5SNavdeep Parhar inv.send_flags = IB_SEND_FENCE;
8090082e6a5SNavdeep Parhar }
810e68ff398SKip Macy
811478d3005SHans Petter Selasky ret = ib_post_send(cb->qp, &cb->rdma_sq_wr.wr, &bad_wr);
812e68ff398SKip Macy if (ret) {
813478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
814e68ff398SKip Macy break;
815e68ff398SKip Macy }
816478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.next = NULL;
8170082e6a5SNavdeep Parhar
818478d3005SHans Petter Selasky DEBUG_LOG("server posted rdma read req \n");
819e68ff398SKip Macy
820e68ff398SKip Macy /* Wait for read completion */
8210082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem,
8220082e6a5SNavdeep Parhar cb->state >= RDMA_READ_COMPLETE);
823e68ff398SKip Macy if (cb->state != RDMA_READ_COMPLETE) {
824478d3005SHans Petter Selasky printk(KERN_ERR PFX
825e68ff398SKip Macy "wait for RDMA_READ_COMPLETE state %d\n",
826e68ff398SKip Macy cb->state);
827e68ff398SKip Macy break;
828e68ff398SKip Macy }
829478d3005SHans Petter Selasky DEBUG_LOG("server received read complete\n");
830e68ff398SKip Macy
831e68ff398SKip Macy /* Display data in recv buf */
832478d3005SHans Petter Selasky if (cb->verbose)
833478d3005SHans Petter Selasky printk(KERN_INFO PFX "server ping data: %s\n",
8340082e6a5SNavdeep Parhar cb->rdma_buf);
835e68ff398SKip Macy
836e68ff398SKip Macy /* Tell client to continue */
8370082e6a5SNavdeep Parhar if (cb->server && cb->server_invalidate) {
8380082e6a5SNavdeep Parhar cb->sq_wr.ex.invalidate_rkey = cb->remote_rkey;
8390082e6a5SNavdeep Parhar cb->sq_wr.opcode = IB_WR_SEND_WITH_INV;
840478d3005SHans Petter Selasky DEBUG_LOG("send-w-inv rkey 0x%x\n", cb->remote_rkey);
8410082e6a5SNavdeep Parhar }
842e68ff398SKip Macy ret = ib_post_send(cb->qp, &cb->sq_wr, &bad_wr);
843e68ff398SKip Macy if (ret) {
844478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
845e68ff398SKip Macy break;
846e68ff398SKip Macy }
847478d3005SHans Petter Selasky DEBUG_LOG("server posted go ahead\n");
848e68ff398SKip Macy
849e68ff398SKip Macy /* Wait for client's RDMA STAG/TO/Len */
8500082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem, cb->state >= RDMA_WRITE_ADV);
851e68ff398SKip Macy if (cb->state != RDMA_WRITE_ADV) {
852478d3005SHans Petter Selasky printk(KERN_ERR PFX
853e68ff398SKip Macy "wait for RDMA_WRITE_ADV state %d\n",
854e68ff398SKip Macy cb->state);
855e68ff398SKip Macy break;
856e68ff398SKip Macy }
857478d3005SHans Petter Selasky DEBUG_LOG("server received sink adv\n");
858e68ff398SKip Macy
859e68ff398SKip Macy /* RDMA Write echo data */
860478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.opcode = IB_WR_RDMA_WRITE;
861478d3005SHans Petter Selasky cb->rdma_sq_wr.rkey = cb->remote_rkey;
862478d3005SHans Petter Selasky cb->rdma_sq_wr.remote_addr = cb->remote_addr;
863478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.sg_list->length = strlen(cb->rdma_buf) + 1;
8640082e6a5SNavdeep Parhar if (cb->local_dma_lkey)
865478d3005SHans Petter Selasky cb->rdma_sgl.lkey = cb->pd->local_dma_lkey;
8660082e6a5SNavdeep Parhar else
8670082e6a5SNavdeep Parhar cb->rdma_sgl.lkey = krping_rdma_rkey(cb, cb->rdma_dma_addr, 0);
8680082e6a5SNavdeep Parhar
869478d3005SHans Petter Selasky DEBUG_LOG("rdma write from lkey %x laddr %llx len %d\n",
870478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.sg_list->lkey,
871478d3005SHans Petter Selasky (unsigned long long)cb->rdma_sq_wr.wr.sg_list->addr,
872478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.sg_list->length);
873e68ff398SKip Macy
874478d3005SHans Petter Selasky ret = ib_post_send(cb->qp, &cb->rdma_sq_wr.wr, &bad_wr);
875e68ff398SKip Macy if (ret) {
876478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
877e68ff398SKip Macy break;
878e68ff398SKip Macy }
879e68ff398SKip Macy
880e68ff398SKip Macy /* Wait for completion */
8810082e6a5SNavdeep Parhar ret = wait_event_interruptible(cb->sem, cb->state >=
8820082e6a5SNavdeep Parhar RDMA_WRITE_COMPLETE);
883e68ff398SKip Macy if (cb->state != RDMA_WRITE_COMPLETE) {
884478d3005SHans Petter Selasky printk(KERN_ERR PFX
885e68ff398SKip Macy "wait for RDMA_WRITE_COMPLETE state %d\n",
886e68ff398SKip Macy cb->state);
887e68ff398SKip Macy break;
888e68ff398SKip Macy }
889478d3005SHans Petter Selasky DEBUG_LOG("server rdma write complete \n");
890e68ff398SKip Macy
891e68ff398SKip Macy cb->state = CONNECTED;
892e68ff398SKip Macy
893e68ff398SKip Macy /* Tell client to begin again */
8940082e6a5SNavdeep Parhar if (cb->server && cb->server_invalidate) {
8950082e6a5SNavdeep Parhar cb->sq_wr.ex.invalidate_rkey = cb->remote_rkey;
8960082e6a5SNavdeep Parhar cb->sq_wr.opcode = IB_WR_SEND_WITH_INV;
897478d3005SHans Petter Selasky DEBUG_LOG("send-w-inv rkey 0x%x\n", cb->remote_rkey);
8980082e6a5SNavdeep Parhar }
899e68ff398SKip Macy ret = ib_post_send(cb->qp, &cb->sq_wr, &bad_wr);
900e68ff398SKip Macy if (ret) {
901478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
902e68ff398SKip Macy break;
903e68ff398SKip Macy }
904478d3005SHans Petter Selasky DEBUG_LOG("server posted go ahead\n");
905e68ff398SKip Macy }
906e68ff398SKip Macy }
907e68ff398SKip Macy
rlat_test(struct krping_cb * cb)908e68ff398SKip Macy static void rlat_test(struct krping_cb *cb)
909e68ff398SKip Macy {
910e68ff398SKip Macy int scnt;
911e68ff398SKip Macy int iters = cb->count;
912e68ff398SKip Macy struct timeval start_tv, stop_tv;
913e68ff398SKip Macy int ret;
914e68ff398SKip Macy struct ib_wc wc;
915c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
916e68ff398SKip Macy int ne;
917e68ff398SKip Macy
918e68ff398SKip Macy scnt = 0;
919478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.opcode = IB_WR_RDMA_READ;
920478d3005SHans Petter Selasky cb->rdma_sq_wr.rkey = cb->remote_rkey;
921478d3005SHans Petter Selasky cb->rdma_sq_wr.remote_addr = cb->remote_addr;
922478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.sg_list->length = cb->size;
923e68ff398SKip Macy
924e68ff398SKip Macy microtime(&start_tv);
925e68ff398SKip Macy if (!cb->poll) {
926e68ff398SKip Macy cb->state = RDMA_READ_ADV;
927e68ff398SKip Macy ib_req_notify_cq(cb->cq, IB_CQ_NEXT_COMP);
928e68ff398SKip Macy }
929e68ff398SKip Macy while (scnt < iters) {
930e68ff398SKip Macy
931e68ff398SKip Macy cb->state = RDMA_READ_ADV;
932478d3005SHans Petter Selasky ret = ib_post_send(cb->qp, &cb->rdma_sq_wr.wr, &bad_wr);
933e68ff398SKip Macy if (ret) {
934478d3005SHans Petter Selasky printk(KERN_ERR PFX
935e68ff398SKip Macy "Couldn't post send: ret=%d scnt %d\n",
936e68ff398SKip Macy ret, scnt);
937e68ff398SKip Macy return;
938e68ff398SKip Macy }
939e68ff398SKip Macy
940e68ff398SKip Macy do {
941e68ff398SKip Macy if (!cb->poll) {
9420082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem,
9430082e6a5SNavdeep Parhar cb->state != RDMA_READ_ADV);
944e68ff398SKip Macy if (cb->state == RDMA_READ_COMPLETE) {
945e68ff398SKip Macy ne = 1;
9460082e6a5SNavdeep Parhar ib_req_notify_cq(cb->cq,
9470082e6a5SNavdeep Parhar IB_CQ_NEXT_COMP);
948e68ff398SKip Macy } else {
949e68ff398SKip Macy ne = -1;
950e68ff398SKip Macy }
951e68ff398SKip Macy } else
952e68ff398SKip Macy ne = ib_poll_cq(cb->cq, 1, &wc);
953e68ff398SKip Macy if (cb->state == ERROR) {
954478d3005SHans Petter Selasky printk(KERN_ERR PFX
9550082e6a5SNavdeep Parhar "state == ERROR...bailing scnt %d\n",
9560082e6a5SNavdeep Parhar scnt);
957e68ff398SKip Macy return;
958e68ff398SKip Macy }
959e68ff398SKip Macy } while (ne == 0);
960e68ff398SKip Macy
961e68ff398SKip Macy if (ne < 0) {
962478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll CQ failed %d\n", ne);
963e68ff398SKip Macy return;
964e68ff398SKip Macy }
965e68ff398SKip Macy if (cb->poll && wc.status != IB_WC_SUCCESS) {
966478d3005SHans Petter Selasky printk(KERN_ERR PFX "Completion wth error at %s:\n",
967e68ff398SKip Macy cb->server ? "server" : "client");
968478d3005SHans Petter Selasky printk(KERN_ERR PFX "Failed status %d: wr_id %d\n",
969e68ff398SKip Macy wc.status, (int) wc.wr_id);
970e68ff398SKip Macy return;
971e68ff398SKip Macy }
972e68ff398SKip Macy ++scnt;
973e68ff398SKip Macy }
974e68ff398SKip Macy microtime(&stop_tv);
975e68ff398SKip Macy
976e68ff398SKip Macy if (stop_tv.tv_usec < start_tv.tv_usec) {
977e68ff398SKip Macy stop_tv.tv_usec += 1000000;
978e68ff398SKip Macy stop_tv.tv_sec -= 1;
979e68ff398SKip Macy }
980e68ff398SKip Macy
981478d3005SHans Petter Selasky printk(KERN_ERR PFX "delta sec %lu delta usec %lu iter %d size %d\n",
9822d57dc7eSNavdeep Parhar (unsigned long)(stop_tv.tv_sec - start_tv.tv_sec),
9832d57dc7eSNavdeep Parhar (unsigned long)(stop_tv.tv_usec - start_tv.tv_usec),
984e68ff398SKip Macy scnt, cb->size);
985e68ff398SKip Macy }
986e68ff398SKip Macy
wlat_test(struct krping_cb * cb)987e68ff398SKip Macy static void wlat_test(struct krping_cb *cb)
988e68ff398SKip Macy {
989e68ff398SKip Macy int ccnt, scnt, rcnt;
990e68ff398SKip Macy int iters=cb->count;
991e68ff398SKip Macy volatile char *poll_buf = (char *) cb->start_buf;
992e68ff398SKip Macy char *buf = (char *)cb->rdma_buf;
993e68ff398SKip Macy struct timeval start_tv, stop_tv;
994376e130bSHans Petter Selasky cycles_t *post_cycles_start = NULL;
995376e130bSHans Petter Selasky cycles_t *post_cycles_stop = NULL;
996376e130bSHans Petter Selasky cycles_t *poll_cycles_start = NULL;
997376e130bSHans Petter Selasky cycles_t *poll_cycles_stop = NULL;
998376e130bSHans Petter Selasky cycles_t *last_poll_cycles_start = NULL;
999e68ff398SKip Macy cycles_t sum_poll = 0, sum_post = 0, sum_last_poll = 0;
1000e68ff398SKip Macy int i;
1001e68ff398SKip Macy int cycle_iters = 1000;
1002e68ff398SKip Macy
10030082e6a5SNavdeep Parhar ccnt = 0;
10040082e6a5SNavdeep Parhar scnt = 0;
10050082e6a5SNavdeep Parhar rcnt = 0;
1006e68ff398SKip Macy
10070082e6a5SNavdeep Parhar post_cycles_start = kmalloc(cycle_iters * sizeof(cycles_t), GFP_KERNEL);
10080082e6a5SNavdeep Parhar if (!post_cycles_start) {
1009478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s kmalloc failed\n", __FUNCTION__);
1010376e130bSHans Petter Selasky goto done;
1011e68ff398SKip Macy }
10120082e6a5SNavdeep Parhar post_cycles_stop = kmalloc(cycle_iters * sizeof(cycles_t), GFP_KERNEL);
10130082e6a5SNavdeep Parhar if (!post_cycles_stop) {
1014478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s kmalloc failed\n", __FUNCTION__);
1015376e130bSHans Petter Selasky goto done;
10160082e6a5SNavdeep Parhar }
10170082e6a5SNavdeep Parhar poll_cycles_start = kmalloc(cycle_iters * sizeof(cycles_t), GFP_KERNEL);
10180082e6a5SNavdeep Parhar if (!poll_cycles_start) {
1019478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s kmalloc failed\n", __FUNCTION__);
1020376e130bSHans Petter Selasky goto done;
10210082e6a5SNavdeep Parhar }
10220082e6a5SNavdeep Parhar poll_cycles_stop = kmalloc(cycle_iters * sizeof(cycles_t), GFP_KERNEL);
10230082e6a5SNavdeep Parhar if (!poll_cycles_stop) {
1024478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s kmalloc failed\n", __FUNCTION__);
1025376e130bSHans Petter Selasky goto done;
10260082e6a5SNavdeep Parhar }
10270082e6a5SNavdeep Parhar last_poll_cycles_start = kmalloc(cycle_iters * sizeof(cycles_t),
10280082e6a5SNavdeep Parhar GFP_KERNEL);
10290082e6a5SNavdeep Parhar if (!last_poll_cycles_start) {
1030478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s kmalloc failed\n", __FUNCTION__);
1031376e130bSHans Petter Selasky goto done;
10320082e6a5SNavdeep Parhar }
1033478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.opcode = IB_WR_RDMA_WRITE;
1034478d3005SHans Petter Selasky cb->rdma_sq_wr.rkey = cb->remote_rkey;
1035478d3005SHans Petter Selasky cb->rdma_sq_wr.remote_addr = cb->remote_addr;
1036478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.sg_list->length = cb->size;
1037e68ff398SKip Macy
1038e68ff398SKip Macy if (cycle_iters > iters)
1039e68ff398SKip Macy cycle_iters = iters;
1040e68ff398SKip Macy microtime(&start_tv);
1041e68ff398SKip Macy while (scnt < iters || ccnt < iters || rcnt < iters) {
1042e68ff398SKip Macy
1043e68ff398SKip Macy /* Wait till buffer changes. */
1044e68ff398SKip Macy if (rcnt < iters && !(scnt < 1 && !cb->server)) {
1045e68ff398SKip Macy ++rcnt;
1046e68ff398SKip Macy while (*poll_buf != (char)rcnt) {
1047e68ff398SKip Macy if (cb->state == ERROR) {
1048478d3005SHans Petter Selasky printk(KERN_ERR PFX
10490082e6a5SNavdeep Parhar "state = ERROR, bailing\n");
1050376e130bSHans Petter Selasky goto done;
1051e68ff398SKip Macy }
1052e68ff398SKip Macy }
1053e68ff398SKip Macy }
1054e68ff398SKip Macy
1055e68ff398SKip Macy if (scnt < iters) {
1056c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
1057e68ff398SKip Macy
1058e68ff398SKip Macy *buf = (char)scnt+1;
1059e68ff398SKip Macy if (scnt < cycle_iters)
1060e68ff398SKip Macy post_cycles_start[scnt] = get_cycles();
1061478d3005SHans Petter Selasky if (ib_post_send(cb->qp, &cb->rdma_sq_wr.wr, &bad_wr)) {
1062478d3005SHans Petter Selasky printk(KERN_ERR PFX
10630082e6a5SNavdeep Parhar "Couldn't post send: scnt=%d\n",
1064e68ff398SKip Macy scnt);
1065376e130bSHans Petter Selasky goto done;
1066e68ff398SKip Macy }
1067e68ff398SKip Macy if (scnt < cycle_iters)
1068e68ff398SKip Macy post_cycles_stop[scnt] = get_cycles();
1069e68ff398SKip Macy scnt++;
1070e68ff398SKip Macy }
1071e68ff398SKip Macy
1072e68ff398SKip Macy if (ccnt < iters) {
1073e68ff398SKip Macy struct ib_wc wc;
1074e68ff398SKip Macy int ne;
1075e68ff398SKip Macy
1076e68ff398SKip Macy if (ccnt < cycle_iters)
1077e68ff398SKip Macy poll_cycles_start[ccnt] = get_cycles();
1078e68ff398SKip Macy do {
1079e68ff398SKip Macy if (ccnt < cycle_iters)
10800082e6a5SNavdeep Parhar last_poll_cycles_start[ccnt] =
10810082e6a5SNavdeep Parhar get_cycles();
1082e68ff398SKip Macy ne = ib_poll_cq(cb->cq, 1, &wc);
1083e68ff398SKip Macy } while (ne == 0);
1084e68ff398SKip Macy if (ccnt < cycle_iters)
1085e68ff398SKip Macy poll_cycles_stop[ccnt] = get_cycles();
1086e68ff398SKip Macy ++ccnt;
1087e68ff398SKip Macy
1088e68ff398SKip Macy if (ne < 0) {
1089478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll CQ failed %d\n", ne);
1090376e130bSHans Petter Selasky goto done;
1091e68ff398SKip Macy }
1092e68ff398SKip Macy if (wc.status != IB_WC_SUCCESS) {
1093478d3005SHans Petter Selasky printk(KERN_ERR PFX
10940082e6a5SNavdeep Parhar "Completion wth error at %s:\n",
1095e68ff398SKip Macy cb->server ? "server" : "client");
1096478d3005SHans Petter Selasky printk(KERN_ERR PFX
10970082e6a5SNavdeep Parhar "Failed status %d: wr_id %d\n",
1098e68ff398SKip Macy wc.status, (int) wc.wr_id);
1099478d3005SHans Petter Selasky printk(KERN_ERR PFX
11000082e6a5SNavdeep Parhar "scnt=%d, rcnt=%d, ccnt=%d\n",
1101e68ff398SKip Macy scnt, rcnt, ccnt);
1102376e130bSHans Petter Selasky goto done;
1103e68ff398SKip Macy }
1104e68ff398SKip Macy }
1105e68ff398SKip Macy }
1106e68ff398SKip Macy microtime(&stop_tv);
1107e68ff398SKip Macy
1108e68ff398SKip Macy if (stop_tv.tv_usec < start_tv.tv_usec) {
1109e68ff398SKip Macy stop_tv.tv_usec += 1000000;
1110e68ff398SKip Macy stop_tv.tv_sec -= 1;
1111e68ff398SKip Macy }
1112e68ff398SKip Macy
1113e68ff398SKip Macy for (i=0; i < cycle_iters; i++) {
1114e68ff398SKip Macy sum_post += post_cycles_stop[i] - post_cycles_start[i];
1115e68ff398SKip Macy sum_poll += poll_cycles_stop[i] - poll_cycles_start[i];
1116e68ff398SKip Macy sum_last_poll += poll_cycles_stop[i]-last_poll_cycles_start[i];
1117e68ff398SKip Macy }
1118478d3005SHans Petter Selasky printk(KERN_ERR PFX
11190082e6a5SNavdeep Parhar "delta sec %lu delta usec %lu iter %d size %d cycle_iters %d"
11200082e6a5SNavdeep Parhar " sum_post %llu sum_poll %llu sum_last_poll %llu\n",
11212d57dc7eSNavdeep Parhar (unsigned long)(stop_tv.tv_sec - start_tv.tv_sec),
11222d57dc7eSNavdeep Parhar (unsigned long)(stop_tv.tv_usec - start_tv.tv_usec),
1123e68ff398SKip Macy scnt, cb->size, cycle_iters,
1124e68ff398SKip Macy (unsigned long long)sum_post, (unsigned long long)sum_poll,
1125e68ff398SKip Macy (unsigned long long)sum_last_poll);
1126376e130bSHans Petter Selasky done:
11270082e6a5SNavdeep Parhar kfree(post_cycles_start);
11280082e6a5SNavdeep Parhar kfree(post_cycles_stop);
11290082e6a5SNavdeep Parhar kfree(poll_cycles_start);
11300082e6a5SNavdeep Parhar kfree(poll_cycles_stop);
11310082e6a5SNavdeep Parhar kfree(last_poll_cycles_start);
1132e68ff398SKip Macy }
1133e68ff398SKip Macy
bw_test(struct krping_cb * cb)1134e68ff398SKip Macy static void bw_test(struct krping_cb *cb)
1135e68ff398SKip Macy {
11366d0a82ffSJohn Baldwin int ccnt, scnt;
1137e68ff398SKip Macy int iters=cb->count;
1138e68ff398SKip Macy struct timeval start_tv, stop_tv;
1139376e130bSHans Petter Selasky cycles_t *post_cycles_start = NULL;
1140376e130bSHans Petter Selasky cycles_t *post_cycles_stop = NULL;
1141376e130bSHans Petter Selasky cycles_t *poll_cycles_start = NULL;
1142376e130bSHans Petter Selasky cycles_t *poll_cycles_stop = NULL;
1143376e130bSHans Petter Selasky cycles_t *last_poll_cycles_start = NULL;
1144e68ff398SKip Macy cycles_t sum_poll = 0, sum_post = 0, sum_last_poll = 0;
1145e68ff398SKip Macy int i;
1146e68ff398SKip Macy int cycle_iters = 1000;
1147e68ff398SKip Macy
11480082e6a5SNavdeep Parhar ccnt = 0;
11490082e6a5SNavdeep Parhar scnt = 0;
1150e68ff398SKip Macy
11510082e6a5SNavdeep Parhar post_cycles_start = kmalloc(cycle_iters * sizeof(cycles_t), GFP_KERNEL);
11520082e6a5SNavdeep Parhar if (!post_cycles_start) {
1153478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s kmalloc failed\n", __FUNCTION__);
1154376e130bSHans Petter Selasky goto done;
1155e68ff398SKip Macy }
11560082e6a5SNavdeep Parhar post_cycles_stop = kmalloc(cycle_iters * sizeof(cycles_t), GFP_KERNEL);
11570082e6a5SNavdeep Parhar if (!post_cycles_stop) {
1158478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s kmalloc failed\n", __FUNCTION__);
1159376e130bSHans Petter Selasky goto done;
11600082e6a5SNavdeep Parhar }
11610082e6a5SNavdeep Parhar poll_cycles_start = kmalloc(cycle_iters * sizeof(cycles_t), GFP_KERNEL);
11620082e6a5SNavdeep Parhar if (!poll_cycles_start) {
1163478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s kmalloc failed\n", __FUNCTION__);
1164376e130bSHans Petter Selasky goto done;
11650082e6a5SNavdeep Parhar }
11660082e6a5SNavdeep Parhar poll_cycles_stop = kmalloc(cycle_iters * sizeof(cycles_t), GFP_KERNEL);
11670082e6a5SNavdeep Parhar if (!poll_cycles_stop) {
1168478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s kmalloc failed\n", __FUNCTION__);
1169376e130bSHans Petter Selasky goto done;
11700082e6a5SNavdeep Parhar }
11710082e6a5SNavdeep Parhar last_poll_cycles_start = kmalloc(cycle_iters * sizeof(cycles_t),
11720082e6a5SNavdeep Parhar GFP_KERNEL);
11730082e6a5SNavdeep Parhar if (!last_poll_cycles_start) {
1174478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s kmalloc failed\n", __FUNCTION__);
1175376e130bSHans Petter Selasky goto done;
11760082e6a5SNavdeep Parhar }
1177478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.opcode = IB_WR_RDMA_WRITE;
1178478d3005SHans Petter Selasky cb->rdma_sq_wr.rkey = cb->remote_rkey;
1179478d3005SHans Petter Selasky cb->rdma_sq_wr.remote_addr = cb->remote_addr;
1180478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.sg_list->length = cb->size;
1181e68ff398SKip Macy
1182e68ff398SKip Macy if (cycle_iters > iters)
1183e68ff398SKip Macy cycle_iters = iters;
1184e68ff398SKip Macy microtime(&start_tv);
1185e68ff398SKip Macy while (scnt < iters || ccnt < iters) {
1186e68ff398SKip Macy
1187e68ff398SKip Macy while (scnt < iters && scnt - ccnt < cb->txdepth) {
1188c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
1189e68ff398SKip Macy
1190e68ff398SKip Macy if (scnt < cycle_iters)
1191e68ff398SKip Macy post_cycles_start[scnt] = get_cycles();
1192478d3005SHans Petter Selasky if (ib_post_send(cb->qp, &cb->rdma_sq_wr.wr, &bad_wr)) {
1193478d3005SHans Petter Selasky printk(KERN_ERR PFX
11940082e6a5SNavdeep Parhar "Couldn't post send: scnt=%d\n",
1195e68ff398SKip Macy scnt);
1196376e130bSHans Petter Selasky goto done;
1197e68ff398SKip Macy }
1198e68ff398SKip Macy if (scnt < cycle_iters)
1199e68ff398SKip Macy post_cycles_stop[scnt] = get_cycles();
1200e68ff398SKip Macy ++scnt;
1201e68ff398SKip Macy }
1202e68ff398SKip Macy
1203e68ff398SKip Macy if (ccnt < iters) {
1204e68ff398SKip Macy int ne;
1205e68ff398SKip Macy struct ib_wc wc;
1206e68ff398SKip Macy
1207e68ff398SKip Macy if (ccnt < cycle_iters)
1208e68ff398SKip Macy poll_cycles_start[ccnt] = get_cycles();
1209e68ff398SKip Macy do {
1210e68ff398SKip Macy if (ccnt < cycle_iters)
12110082e6a5SNavdeep Parhar last_poll_cycles_start[ccnt] =
12120082e6a5SNavdeep Parhar get_cycles();
1213e68ff398SKip Macy ne = ib_poll_cq(cb->cq, 1, &wc);
1214e68ff398SKip Macy } while (ne == 0);
1215e68ff398SKip Macy if (ccnt < cycle_iters)
1216e68ff398SKip Macy poll_cycles_stop[ccnt] = get_cycles();
1217e68ff398SKip Macy ccnt += 1;
1218e68ff398SKip Macy
1219e68ff398SKip Macy if (ne < 0) {
1220478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll CQ failed %d\n", ne);
1221376e130bSHans Petter Selasky goto done;
1222e68ff398SKip Macy }
1223e68ff398SKip Macy if (wc.status != IB_WC_SUCCESS) {
1224478d3005SHans Petter Selasky printk(KERN_ERR PFX
12250082e6a5SNavdeep Parhar "Completion wth error at %s:\n",
1226e68ff398SKip Macy cb->server ? "server" : "client");
1227478d3005SHans Petter Selasky printk(KERN_ERR PFX
12280082e6a5SNavdeep Parhar "Failed status %d: wr_id %d\n",
1229e68ff398SKip Macy wc.status, (int) wc.wr_id);
1230376e130bSHans Petter Selasky goto done;
1231e68ff398SKip Macy }
1232e68ff398SKip Macy }
1233e68ff398SKip Macy }
1234e68ff398SKip Macy microtime(&stop_tv);
1235e68ff398SKip Macy
1236e68ff398SKip Macy if (stop_tv.tv_usec < start_tv.tv_usec) {
1237e68ff398SKip Macy stop_tv.tv_usec += 1000000;
1238e68ff398SKip Macy stop_tv.tv_sec -= 1;
1239e68ff398SKip Macy }
1240e68ff398SKip Macy
1241e68ff398SKip Macy for (i=0; i < cycle_iters; i++) {
1242e68ff398SKip Macy sum_post += post_cycles_stop[i] - post_cycles_start[i];
1243e68ff398SKip Macy sum_poll += poll_cycles_stop[i] - poll_cycles_start[i];
1244e68ff398SKip Macy sum_last_poll += poll_cycles_stop[i]-last_poll_cycles_start[i];
1245e68ff398SKip Macy }
1246478d3005SHans Petter Selasky printk(KERN_ERR PFX
12470082e6a5SNavdeep Parhar "delta sec %lu delta usec %lu iter %d size %d cycle_iters %d"
12480082e6a5SNavdeep Parhar " sum_post %llu sum_poll %llu sum_last_poll %llu\n",
12492d57dc7eSNavdeep Parhar (unsigned long)(stop_tv.tv_sec - start_tv.tv_sec),
12502d57dc7eSNavdeep Parhar (unsigned long)(stop_tv.tv_usec - start_tv.tv_usec),
1251e68ff398SKip Macy scnt, cb->size, cycle_iters,
1252e68ff398SKip Macy (unsigned long long)sum_post, (unsigned long long)sum_poll,
1253e68ff398SKip Macy (unsigned long long)sum_last_poll);
1254376e130bSHans Petter Selasky done:
12550082e6a5SNavdeep Parhar kfree(post_cycles_start);
12560082e6a5SNavdeep Parhar kfree(post_cycles_stop);
12570082e6a5SNavdeep Parhar kfree(poll_cycles_start);
12580082e6a5SNavdeep Parhar kfree(poll_cycles_stop);
12590082e6a5SNavdeep Parhar kfree(last_poll_cycles_start);
1260e68ff398SKip Macy }
1261e68ff398SKip Macy
krping_rlat_test_server(struct krping_cb * cb)1262e68ff398SKip Macy static void krping_rlat_test_server(struct krping_cb *cb)
1263e68ff398SKip Macy {
1264c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
1265e68ff398SKip Macy struct ib_wc wc;
1266e68ff398SKip Macy int ret;
1267e68ff398SKip Macy
1268e68ff398SKip Macy /* Spin waiting for client's Start STAG/TO/Len */
1269e68ff398SKip Macy while (cb->state < RDMA_READ_ADV) {
1270e68ff398SKip Macy krping_cq_event_handler(cb->cq, cb);
1271e68ff398SKip Macy }
1272e68ff398SKip Macy
1273e68ff398SKip Macy /* Send STAG/TO/Len to client */
12740082e6a5SNavdeep Parhar krping_format_send(cb, cb->start_dma_addr);
1275e68ff398SKip Macy ret = ib_post_send(cb->qp, &cb->sq_wr, &bad_wr);
1276e68ff398SKip Macy if (ret) {
1277478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
1278e68ff398SKip Macy return;
1279e68ff398SKip Macy }
1280e68ff398SKip Macy
1281e68ff398SKip Macy /* Spin waiting for send completion */
1282e68ff398SKip Macy while ((ret = ib_poll_cq(cb->cq, 1, &wc) == 0));
1283e68ff398SKip Macy if (ret < 0) {
1284478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll error %d\n", ret);
1285e68ff398SKip Macy return;
1286e68ff398SKip Macy }
1287e68ff398SKip Macy if (wc.status) {
1288478d3005SHans Petter Selasky printk(KERN_ERR PFX "send completiong error %d\n", wc.status);
1289e68ff398SKip Macy return;
1290e68ff398SKip Macy }
1291478d3005SHans Petter Selasky
12920082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem, cb->state == ERROR);
1293e68ff398SKip Macy }
1294e68ff398SKip Macy
krping_wlat_test_server(struct krping_cb * cb)1295e68ff398SKip Macy static void krping_wlat_test_server(struct krping_cb *cb)
1296e68ff398SKip Macy {
1297c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
1298e68ff398SKip Macy struct ib_wc wc;
1299e68ff398SKip Macy int ret;
1300e68ff398SKip Macy
1301e68ff398SKip Macy /* Spin waiting for client's Start STAG/TO/Len */
1302e68ff398SKip Macy while (cb->state < RDMA_READ_ADV) {
1303e68ff398SKip Macy krping_cq_event_handler(cb->cq, cb);
1304e68ff398SKip Macy }
1305e68ff398SKip Macy
1306e68ff398SKip Macy /* Send STAG/TO/Len to client */
13070082e6a5SNavdeep Parhar krping_format_send(cb, cb->start_dma_addr);
1308e68ff398SKip Macy ret = ib_post_send(cb->qp, &cb->sq_wr, &bad_wr);
1309e68ff398SKip Macy if (ret) {
1310478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
1311e68ff398SKip Macy return;
1312e68ff398SKip Macy }
1313e68ff398SKip Macy
1314e68ff398SKip Macy /* Spin waiting for send completion */
1315e68ff398SKip Macy while ((ret = ib_poll_cq(cb->cq, 1, &wc) == 0));
1316e68ff398SKip Macy if (ret < 0) {
1317478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll error %d\n", ret);
1318e68ff398SKip Macy return;
1319e68ff398SKip Macy }
1320e68ff398SKip Macy if (wc.status) {
1321478d3005SHans Petter Selasky printk(KERN_ERR PFX "send completiong error %d\n", wc.status);
1322e68ff398SKip Macy return;
1323e68ff398SKip Macy }
1324e68ff398SKip Macy
1325e68ff398SKip Macy wlat_test(cb);
13260082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem, cb->state == ERROR);
1327e68ff398SKip Macy }
1328e68ff398SKip Macy
krping_bw_test_server(struct krping_cb * cb)1329e68ff398SKip Macy static void krping_bw_test_server(struct krping_cb *cb)
1330e68ff398SKip Macy {
1331c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
1332e68ff398SKip Macy struct ib_wc wc;
1333e68ff398SKip Macy int ret;
1334e68ff398SKip Macy
1335e68ff398SKip Macy /* Spin waiting for client's Start STAG/TO/Len */
1336e68ff398SKip Macy while (cb->state < RDMA_READ_ADV) {
1337e68ff398SKip Macy krping_cq_event_handler(cb->cq, cb);
1338e68ff398SKip Macy }
1339e68ff398SKip Macy
1340e68ff398SKip Macy /* Send STAG/TO/Len to client */
13410082e6a5SNavdeep Parhar krping_format_send(cb, cb->start_dma_addr);
1342e68ff398SKip Macy ret = ib_post_send(cb->qp, &cb->sq_wr, &bad_wr);
1343e68ff398SKip Macy if (ret) {
1344478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
1345e68ff398SKip Macy return;
1346e68ff398SKip Macy }
1347e68ff398SKip Macy
1348e68ff398SKip Macy /* Spin waiting for send completion */
1349e68ff398SKip Macy while ((ret = ib_poll_cq(cb->cq, 1, &wc) == 0));
1350e68ff398SKip Macy if (ret < 0) {
1351478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll error %d\n", ret);
1352e68ff398SKip Macy return;
1353e68ff398SKip Macy }
1354e68ff398SKip Macy if (wc.status) {
1355478d3005SHans Petter Selasky printk(KERN_ERR PFX "send completiong error %d\n", wc.status);
1356e68ff398SKip Macy return;
1357e68ff398SKip Macy }
1358e68ff398SKip Macy
1359e68ff398SKip Macy if (cb->duplex)
1360e68ff398SKip Macy bw_test(cb);
13610082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem, cb->state == ERROR);
13620082e6a5SNavdeep Parhar }
13630082e6a5SNavdeep Parhar
reg_supported(struct ib_device * dev)1364478d3005SHans Petter Selasky static int reg_supported(struct ib_device *dev)
13650082e6a5SNavdeep Parhar {
1366478d3005SHans Petter Selasky u64 needed_flags = IB_DEVICE_MEM_MGT_EXTENSIONS;
13670082e6a5SNavdeep Parhar
1368478d3005SHans Petter Selasky if ((dev->attrs.device_cap_flags & needed_flags) != needed_flags) {
1369478d3005SHans Petter Selasky printk(KERN_ERR PFX
1370478d3005SHans Petter Selasky "Fastreg not supported - device_cap_flags 0x%llx\n",
1371478d3005SHans Petter Selasky (unsigned long long)dev->attrs.device_cap_flags);
13720082e6a5SNavdeep Parhar return 0;
13730082e6a5SNavdeep Parhar }
1374478d3005SHans Petter Selasky DEBUG_LOG("Fastreg supported - device_cap_flags 0x%llx\n",
1375478d3005SHans Petter Selasky (unsigned long long)dev->attrs.device_cap_flags);
13760082e6a5SNavdeep Parhar return 1;
1377e68ff398SKip Macy }
1378e68ff398SKip Macy
fill_sockaddr(struct sockaddr_storage * sin,struct krping_cb * cb)1379478d3005SHans Petter Selasky static void fill_sockaddr(struct sockaddr_storage *sin, struct krping_cb *cb)
1380478d3005SHans Petter Selasky {
1381478d3005SHans Petter Selasky memset(sin, 0, sizeof(*sin));
1382478d3005SHans Petter Selasky
1383478d3005SHans Petter Selasky if (cb->addr_type == AF_INET) {
1384478d3005SHans Petter Selasky struct sockaddr_in *sin4 = (struct sockaddr_in *)sin;
1385434b6d20SHans Petter Selasky sin4->sin_len = sizeof(*sin4);
1386478d3005SHans Petter Selasky sin4->sin_family = AF_INET;
1387478d3005SHans Petter Selasky memcpy((void *)&sin4->sin_addr.s_addr, cb->addr, 4);
1388478d3005SHans Petter Selasky sin4->sin_port = cb->port;
1389478d3005SHans Petter Selasky } else if (cb->addr_type == AF_INET6) {
1390478d3005SHans Petter Selasky struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sin;
1391434b6d20SHans Petter Selasky sin6->sin6_len = sizeof(*sin6);
1392478d3005SHans Petter Selasky sin6->sin6_family = AF_INET6;
1393478d3005SHans Petter Selasky memcpy((void *)&sin6->sin6_addr, cb->addr, 16);
1394478d3005SHans Petter Selasky sin6->sin6_port = cb->port;
1395478d3005SHans Petter Selasky }
1396478d3005SHans Petter Selasky }
1397478d3005SHans Petter Selasky
krping_bind_server(struct krping_cb * cb)1398e68ff398SKip Macy static int krping_bind_server(struct krping_cb *cb)
1399e68ff398SKip Macy {
1400478d3005SHans Petter Selasky struct sockaddr_storage sin;
1401e68ff398SKip Macy int ret;
1402e68ff398SKip Macy
1403478d3005SHans Petter Selasky
1404478d3005SHans Petter Selasky fill_sockaddr(&sin, cb);
1405e68ff398SKip Macy
1406e68ff398SKip Macy ret = rdma_bind_addr(cb->cm_id, (struct sockaddr *)&sin);
1407e68ff398SKip Macy if (ret) {
1408478d3005SHans Petter Selasky printk(KERN_ERR PFX "rdma_bind_addr error %d\n", ret);
1409e68ff398SKip Macy return ret;
1410e68ff398SKip Macy }
1411478d3005SHans Petter Selasky DEBUG_LOG("rdma_bind_addr successful\n");
1412e68ff398SKip Macy
1413478d3005SHans Petter Selasky DEBUG_LOG("rdma_listen\n");
1414e68ff398SKip Macy ret = rdma_listen(cb->cm_id, 3);
1415e68ff398SKip Macy if (ret) {
1416478d3005SHans Petter Selasky printk(KERN_ERR PFX "rdma_listen failed: %d\n", ret);
1417e68ff398SKip Macy return ret;
1418e68ff398SKip Macy }
1419e68ff398SKip Macy
14200082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem, cb->state >= CONNECT_REQUEST);
1421e68ff398SKip Macy if (cb->state != CONNECT_REQUEST) {
1422478d3005SHans Petter Selasky printk(KERN_ERR PFX "wait for CONNECT_REQUEST state %d\n",
1423e68ff398SKip Macy cb->state);
1424e68ff398SKip Macy return -1;
1425e68ff398SKip Macy }
1426e68ff398SKip Macy
1427478d3005SHans Petter Selasky if (!reg_supported(cb->child_cm_id->device))
14280082e6a5SNavdeep Parhar return -EINVAL;
14290082e6a5SNavdeep Parhar
1430e68ff398SKip Macy return 0;
1431e68ff398SKip Macy }
1432e68ff398SKip Macy
krping_run_server(struct krping_cb * cb)1433e68ff398SKip Macy static void krping_run_server(struct krping_cb *cb)
1434e68ff398SKip Macy {
1435c3987b8eSHans Petter Selasky const struct ib_recv_wr *bad_wr;
1436e68ff398SKip Macy int ret;
1437e68ff398SKip Macy
1438e68ff398SKip Macy ret = krping_bind_server(cb);
1439e68ff398SKip Macy if (ret)
1440e68ff398SKip Macy return;
1441e68ff398SKip Macy
1442e68ff398SKip Macy ret = krping_setup_qp(cb, cb->child_cm_id);
1443e68ff398SKip Macy if (ret) {
1444478d3005SHans Petter Selasky printk(KERN_ERR PFX "setup_qp failed: %d\n", ret);
14450082e6a5SNavdeep Parhar goto err0;
1446e68ff398SKip Macy }
1447e68ff398SKip Macy
1448e68ff398SKip Macy ret = krping_setup_buffers(cb);
1449e68ff398SKip Macy if (ret) {
1450478d3005SHans Petter Selasky printk(KERN_ERR PFX "krping_setup_buffers failed: %d\n", ret);
1451e68ff398SKip Macy goto err1;
1452e68ff398SKip Macy }
1453e68ff398SKip Macy
1454e68ff398SKip Macy ret = ib_post_recv(cb->qp, &cb->rq_wr, &bad_wr);
1455e68ff398SKip Macy if (ret) {
1456478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_post_recv failed: %d\n", ret);
1457e68ff398SKip Macy goto err2;
1458e68ff398SKip Macy }
1459e68ff398SKip Macy
1460e68ff398SKip Macy ret = krping_accept(cb);
1461e68ff398SKip Macy if (ret) {
1462478d3005SHans Petter Selasky printk(KERN_ERR PFX "connect error %d\n", ret);
1463e68ff398SKip Macy goto err2;
1464e68ff398SKip Macy }
1465e68ff398SKip Macy
1466e68ff398SKip Macy if (cb->wlat)
1467e68ff398SKip Macy krping_wlat_test_server(cb);
1468e68ff398SKip Macy else if (cb->rlat)
1469e68ff398SKip Macy krping_rlat_test_server(cb);
1470e68ff398SKip Macy else if (cb->bw)
1471e68ff398SKip Macy krping_bw_test_server(cb);
1472478d3005SHans Petter Selasky else
1473e68ff398SKip Macy krping_test_server(cb);
1474e68ff398SKip Macy rdma_disconnect(cb->child_cm_id);
1475e68ff398SKip Macy err2:
1476e68ff398SKip Macy krping_free_buffers(cb);
1477e68ff398SKip Macy err1:
1478e68ff398SKip Macy krping_free_qp(cb);
14790082e6a5SNavdeep Parhar err0:
14800082e6a5SNavdeep Parhar rdma_destroy_id(cb->child_cm_id);
1481e68ff398SKip Macy }
1482e68ff398SKip Macy
krping_test_client(struct krping_cb * cb)1483e68ff398SKip Macy static void krping_test_client(struct krping_cb *cb)
1484e68ff398SKip Macy {
1485e68ff398SKip Macy int ping, start, cc, i, ret;
1486c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
1487e68ff398SKip Macy unsigned char c;
1488e68ff398SKip Macy
1489e68ff398SKip Macy start = 65;
1490e68ff398SKip Macy for (ping = 0; !cb->count || ping < cb->count; ping++) {
1491e68ff398SKip Macy cb->state = RDMA_READ_ADV;
1492e68ff398SKip Macy
1493e68ff398SKip Macy /* Put some ascii text in the buffer. */
1494e68ff398SKip Macy cc = sprintf(cb->start_buf, "rdma-ping-%d: ", ping);
1495e68ff398SKip Macy for (i = cc, c = start; i < cb->size; i++) {
1496e68ff398SKip Macy cb->start_buf[i] = c;
1497e68ff398SKip Macy c++;
1498e68ff398SKip Macy if (c > 122)
1499e68ff398SKip Macy c = 65;
1500e68ff398SKip Macy }
1501e68ff398SKip Macy start++;
1502e68ff398SKip Macy if (start > 122)
1503e68ff398SKip Macy start = 65;
1504e68ff398SKip Macy cb->start_buf[cb->size - 1] = 0;
1505e68ff398SKip Macy
15060082e6a5SNavdeep Parhar krping_format_send(cb, cb->start_dma_addr);
15070082e6a5SNavdeep Parhar if (cb->state == ERROR) {
1508478d3005SHans Petter Selasky printk(KERN_ERR PFX "krping_format_send failed\n");
15090082e6a5SNavdeep Parhar break;
15100082e6a5SNavdeep Parhar }
1511e68ff398SKip Macy ret = ib_post_send(cb->qp, &cb->sq_wr, &bad_wr);
1512e68ff398SKip Macy if (ret) {
1513478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
1514e68ff398SKip Macy break;
1515e68ff398SKip Macy }
1516e68ff398SKip Macy
1517e68ff398SKip Macy /* Wait for server to ACK */
15180082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem, cb->state >= RDMA_WRITE_ADV);
1519e68ff398SKip Macy if (cb->state != RDMA_WRITE_ADV) {
1520478d3005SHans Petter Selasky printk(KERN_ERR PFX
1521e68ff398SKip Macy "wait for RDMA_WRITE_ADV state %d\n",
1522e68ff398SKip Macy cb->state);
1523e68ff398SKip Macy break;
1524e68ff398SKip Macy }
1525e68ff398SKip Macy
15260082e6a5SNavdeep Parhar krping_format_send(cb, cb->rdma_dma_addr);
1527e68ff398SKip Macy ret = ib_post_send(cb->qp, &cb->sq_wr, &bad_wr);
1528e68ff398SKip Macy if (ret) {
1529478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
1530e68ff398SKip Macy break;
1531e68ff398SKip Macy }
1532e68ff398SKip Macy
1533e68ff398SKip Macy /* Wait for the server to say the RDMA Write is complete. */
15340082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem,
15350082e6a5SNavdeep Parhar cb->state >= RDMA_WRITE_COMPLETE);
1536e68ff398SKip Macy if (cb->state != RDMA_WRITE_COMPLETE) {
1537478d3005SHans Petter Selasky printk(KERN_ERR PFX
1538e68ff398SKip Macy "wait for RDMA_WRITE_COMPLETE state %d\n",
1539e68ff398SKip Macy cb->state);
1540e68ff398SKip Macy break;
1541e68ff398SKip Macy }
1542e68ff398SKip Macy
1543e68ff398SKip Macy if (cb->validate)
1544e68ff398SKip Macy if (memcmp(cb->start_buf, cb->rdma_buf, cb->size)) {
1545478d3005SHans Petter Selasky printk(KERN_ERR PFX "data mismatch!\n");
1546e68ff398SKip Macy break;
1547e68ff398SKip Macy }
1548e68ff398SKip Macy
1549478d3005SHans Petter Selasky if (cb->verbose)
1550478d3005SHans Petter Selasky printk(KERN_INFO PFX "ping data: %s\n", cb->rdma_buf);
15510082e6a5SNavdeep Parhar #ifdef SLOW_KRPING
15520082e6a5SNavdeep Parhar wait_event_interruptible_timeout(cb->sem, cb->state == ERROR, HZ);
15530082e6a5SNavdeep Parhar #endif
1554e68ff398SKip Macy }
1555e68ff398SKip Macy }
1556e68ff398SKip Macy
krping_rlat_test_client(struct krping_cb * cb)1557e68ff398SKip Macy static void krping_rlat_test_client(struct krping_cb *cb)
1558e68ff398SKip Macy {
1559c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
1560e68ff398SKip Macy struct ib_wc wc;
1561e68ff398SKip Macy int ret;
1562e68ff398SKip Macy
1563e68ff398SKip Macy cb->state = RDMA_READ_ADV;
1564e68ff398SKip Macy
1565e68ff398SKip Macy /* Send STAG/TO/Len to client */
15660082e6a5SNavdeep Parhar krping_format_send(cb, cb->start_dma_addr);
15670082e6a5SNavdeep Parhar if (cb->state == ERROR) {
1568478d3005SHans Petter Selasky printk(KERN_ERR PFX "krping_format_send failed\n");
15690082e6a5SNavdeep Parhar return;
15700082e6a5SNavdeep Parhar }
1571e68ff398SKip Macy ret = ib_post_send(cb->qp, &cb->sq_wr, &bad_wr);
1572e68ff398SKip Macy if (ret) {
1573478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
1574e68ff398SKip Macy return;
1575e68ff398SKip Macy }
1576e68ff398SKip Macy
1577e68ff398SKip Macy /* Spin waiting for send completion */
1578e68ff398SKip Macy while ((ret = ib_poll_cq(cb->cq, 1, &wc) == 0));
1579e68ff398SKip Macy if (ret < 0) {
1580478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll error %d\n", ret);
1581e68ff398SKip Macy return;
1582e68ff398SKip Macy }
1583e68ff398SKip Macy if (wc.status) {
1584478d3005SHans Petter Selasky printk(KERN_ERR PFX "send completion error %d\n", wc.status);
1585e68ff398SKip Macy return;
1586e68ff398SKip Macy }
1587e68ff398SKip Macy
1588e68ff398SKip Macy /* Spin waiting for server's Start STAG/TO/Len */
1589e68ff398SKip Macy while (cb->state < RDMA_WRITE_ADV) {
1590e68ff398SKip Macy krping_cq_event_handler(cb->cq, cb);
1591e68ff398SKip Macy }
1592e68ff398SKip Macy
1593e68ff398SKip Macy #if 0
1594e68ff398SKip Macy {
1595e68ff398SKip Macy int i;
1596e68ff398SKip Macy struct timeval start, stop;
1597e68ff398SKip Macy time_t sec;
1598e68ff398SKip Macy suseconds_t usec;
1599e68ff398SKip Macy unsigned long long elapsed;
1600e68ff398SKip Macy struct ib_wc wc;
1601c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
1602e68ff398SKip Macy int ne;
1603e68ff398SKip Macy
1604478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.opcode = IB_WR_RDMA_WRITE;
1605478d3005SHans Petter Selasky cb->rdma_sq_wr.rkey = cb->remote_rkey;
1606478d3005SHans Petter Selasky cb->rdma_sq_wr.remote_addr = cb->remote_addr;
1607478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.sg_list->length = 0;
1608478d3005SHans Petter Selasky cb->rdma_sq_wr.wr.num_sge = 0;
1609e68ff398SKip Macy
1610e68ff398SKip Macy microtime(&start);
1611e68ff398SKip Macy for (i=0; i < 100000; i++) {
1612478d3005SHans Petter Selasky if (ib_post_send(cb->qp, &cb->rdma_sq_wr.wr, &bad_wr)) {
1613478d3005SHans Petter Selasky printk(KERN_ERR PFX "Couldn't post send\n");
1614e68ff398SKip Macy return;
1615e68ff398SKip Macy }
1616e68ff398SKip Macy do {
1617e68ff398SKip Macy ne = ib_poll_cq(cb->cq, 1, &wc);
1618e68ff398SKip Macy } while (ne == 0);
1619e68ff398SKip Macy if (ne < 0) {
1620478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll CQ failed %d\n", ne);
1621e68ff398SKip Macy return;
1622e68ff398SKip Macy }
1623e68ff398SKip Macy if (wc.status != IB_WC_SUCCESS) {
1624478d3005SHans Petter Selasky printk(KERN_ERR PFX "Completion wth error at %s:\n",
1625e68ff398SKip Macy cb->server ? "server" : "client");
1626478d3005SHans Petter Selasky printk(KERN_ERR PFX "Failed status %d: wr_id %d\n",
1627e68ff398SKip Macy wc.status, (int) wc.wr_id);
1628e68ff398SKip Macy return;
1629e68ff398SKip Macy }
1630e68ff398SKip Macy }
1631e68ff398SKip Macy microtime(&stop);
1632e68ff398SKip Macy
1633e68ff398SKip Macy if (stop.tv_usec < start.tv_usec) {
1634e68ff398SKip Macy stop.tv_usec += 1000000;
1635e68ff398SKip Macy stop.tv_sec -= 1;
1636e68ff398SKip Macy }
1637e68ff398SKip Macy sec = stop.tv_sec - start.tv_sec;
1638e68ff398SKip Macy usec = stop.tv_usec - start.tv_usec;
1639e68ff398SKip Macy elapsed = sec * 1000000 + usec;
1640478d3005SHans Petter Selasky printk(KERN_ERR PFX "0B-write-lat iters 100000 usec %llu\n", elapsed);
1641e68ff398SKip Macy }
1642e68ff398SKip Macy #endif
1643e68ff398SKip Macy
1644e68ff398SKip Macy rlat_test(cb);
1645e68ff398SKip Macy }
1646e68ff398SKip Macy
krping_wlat_test_client(struct krping_cb * cb)1647e68ff398SKip Macy static void krping_wlat_test_client(struct krping_cb *cb)
1648e68ff398SKip Macy {
1649c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
1650e68ff398SKip Macy struct ib_wc wc;
1651e68ff398SKip Macy int ret;
1652e68ff398SKip Macy
1653e68ff398SKip Macy cb->state = RDMA_READ_ADV;
1654e68ff398SKip Macy
1655e68ff398SKip Macy /* Send STAG/TO/Len to client */
16560082e6a5SNavdeep Parhar krping_format_send(cb, cb->start_dma_addr);
16570082e6a5SNavdeep Parhar if (cb->state == ERROR) {
1658478d3005SHans Petter Selasky printk(KERN_ERR PFX "krping_format_send failed\n");
16590082e6a5SNavdeep Parhar return;
16600082e6a5SNavdeep Parhar }
1661e68ff398SKip Macy ret = ib_post_send(cb->qp, &cb->sq_wr, &bad_wr);
1662e68ff398SKip Macy if (ret) {
1663478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
1664e68ff398SKip Macy return;
1665e68ff398SKip Macy }
1666e68ff398SKip Macy
1667e68ff398SKip Macy /* Spin waiting for send completion */
1668e68ff398SKip Macy while ((ret = ib_poll_cq(cb->cq, 1, &wc) == 0));
1669e68ff398SKip Macy if (ret < 0) {
1670478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll error %d\n", ret);
1671e68ff398SKip Macy return;
1672e68ff398SKip Macy }
1673e68ff398SKip Macy if (wc.status) {
1674478d3005SHans Petter Selasky printk(KERN_ERR PFX "send completion error %d\n", wc.status);
1675e68ff398SKip Macy return;
1676e68ff398SKip Macy }
1677e68ff398SKip Macy
1678e68ff398SKip Macy /* Spin waiting for server's Start STAG/TO/Len */
1679e68ff398SKip Macy while (cb->state < RDMA_WRITE_ADV) {
1680e68ff398SKip Macy krping_cq_event_handler(cb->cq, cb);
1681e68ff398SKip Macy }
1682e68ff398SKip Macy
1683e68ff398SKip Macy wlat_test(cb);
1684e68ff398SKip Macy }
1685e68ff398SKip Macy
krping_bw_test_client(struct krping_cb * cb)1686e68ff398SKip Macy static void krping_bw_test_client(struct krping_cb *cb)
1687e68ff398SKip Macy {
1688c3987b8eSHans Petter Selasky const struct ib_send_wr *bad_wr;
1689e68ff398SKip Macy struct ib_wc wc;
1690e68ff398SKip Macy int ret;
1691e68ff398SKip Macy
1692e68ff398SKip Macy cb->state = RDMA_READ_ADV;
1693e68ff398SKip Macy
1694e68ff398SKip Macy /* Send STAG/TO/Len to client */
16950082e6a5SNavdeep Parhar krping_format_send(cb, cb->start_dma_addr);
16960082e6a5SNavdeep Parhar if (cb->state == ERROR) {
1697478d3005SHans Petter Selasky printk(KERN_ERR PFX "krping_format_send failed\n");
16980082e6a5SNavdeep Parhar return;
16990082e6a5SNavdeep Parhar }
1700e68ff398SKip Macy ret = ib_post_send(cb->qp, &cb->sq_wr, &bad_wr);
1701e68ff398SKip Macy if (ret) {
1702478d3005SHans Petter Selasky printk(KERN_ERR PFX "post send error %d\n", ret);
1703e68ff398SKip Macy return;
1704e68ff398SKip Macy }
1705e68ff398SKip Macy
1706e68ff398SKip Macy /* Spin waiting for send completion */
1707e68ff398SKip Macy while ((ret = ib_poll_cq(cb->cq, 1, &wc) == 0));
1708e68ff398SKip Macy if (ret < 0) {
1709478d3005SHans Petter Selasky printk(KERN_ERR PFX "poll error %d\n", ret);
1710e68ff398SKip Macy return;
1711e68ff398SKip Macy }
1712e68ff398SKip Macy if (wc.status) {
1713478d3005SHans Petter Selasky printk(KERN_ERR PFX "send completion error %d\n", wc.status);
1714e68ff398SKip Macy return;
1715e68ff398SKip Macy }
1716e68ff398SKip Macy
1717e68ff398SKip Macy /* Spin waiting for server's Start STAG/TO/Len */
1718e68ff398SKip Macy while (cb->state < RDMA_WRITE_ADV) {
1719e68ff398SKip Macy krping_cq_event_handler(cb->cq, cb);
1720e68ff398SKip Macy }
1721e68ff398SKip Macy
1722e68ff398SKip Macy bw_test(cb);
1723e68ff398SKip Macy }
1724e68ff398SKip Macy
17259d31afabSNavdeep Parhar /*
1726478d3005SHans Petter Selasky * Manual qp flush test
17279d31afabSNavdeep Parhar */
flush_qp(struct krping_cb * cb)1728478d3005SHans Petter Selasky static void flush_qp(struct krping_cb *cb)
17299d31afabSNavdeep Parhar {
1730c3987b8eSHans Petter Selasky struct ib_send_wr wr = { 0 };
1731c3987b8eSHans Petter Selasky const struct ib_send_wr *bad;
1732c3987b8eSHans Petter Selasky struct ib_recv_wr recv_wr = { 0 };
1733c3987b8eSHans Petter Selasky const struct ib_recv_wr *recv_bad;
17349d31afabSNavdeep Parhar struct ib_wc wc;
17359d31afabSNavdeep Parhar int ret;
1736478d3005SHans Petter Selasky int flushed = 0;
1737478d3005SHans Petter Selasky int ccnt = 0;
17389d31afabSNavdeep Parhar
1739478d3005SHans Petter Selasky rdma_disconnect(cb->cm_id);
1740478d3005SHans Petter Selasky DEBUG_LOG("disconnected!\n");
1741478d3005SHans Petter Selasky
1742478d3005SHans Petter Selasky wr.opcode = IB_WR_SEND;
1743478d3005SHans Petter Selasky wr.wr_id = 0xdeadbeefcafebabe;
1744478d3005SHans Petter Selasky ret = ib_post_send(cb->qp, &wr, &bad);
1745478d3005SHans Petter Selasky if (ret) {
1746478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s post_send failed ret %d\n", __func__, ret);
17479d31afabSNavdeep Parhar return;
17489d31afabSNavdeep Parhar }
17499d31afabSNavdeep Parhar
1750478d3005SHans Petter Selasky recv_wr.wr_id = 0xcafebabedeadbeef;
1751478d3005SHans Petter Selasky ret = ib_post_recv(cb->qp, &recv_wr, &recv_bad);
17529d31afabSNavdeep Parhar if (ret) {
1753478d3005SHans Petter Selasky printk(KERN_ERR PFX "%s post_recv failed ret %d\n", __func__, ret);
17549d31afabSNavdeep Parhar return;
17559d31afabSNavdeep Parhar }
17569d31afabSNavdeep Parhar
1757478d3005SHans Petter Selasky /* poll until the flush WRs complete */
17589d31afabSNavdeep Parhar do {
17599d31afabSNavdeep Parhar ret = ib_poll_cq(cb->cq, 1, &wc);
17609d31afabSNavdeep Parhar if (ret < 0) {
1761478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_poll_cq failed %d\n", ret);
1762478d3005SHans Petter Selasky return;
17639d31afabSNavdeep Parhar }
1764478d3005SHans Petter Selasky if (ret == 0)
1765478d3005SHans Petter Selasky continue;
1766478d3005SHans Petter Selasky ccnt++;
1767478d3005SHans Petter Selasky if (wc.wr_id == 0xdeadbeefcafebabe ||
1768478d3005SHans Petter Selasky wc.wr_id == 0xcafebabedeadbeef)
1769478d3005SHans Petter Selasky flushed++;
1770478d3005SHans Petter Selasky } while (flushed != 2);
1771478d3005SHans Petter Selasky DEBUG_LOG("qp_flushed! ccnt %u\n", ccnt);
17729d31afabSNavdeep Parhar }
17739d31afabSNavdeep Parhar
krping_fr_test(struct krping_cb * cb)1774478d3005SHans Petter Selasky static void krping_fr_test(struct krping_cb *cb)
17750082e6a5SNavdeep Parhar {
1776c3987b8eSHans Petter Selasky struct ib_send_wr inv;
1777c3987b8eSHans Petter Selasky const struct ib_send_wr *bad;
1778478d3005SHans Petter Selasky struct ib_reg_wr fr;
17790082e6a5SNavdeep Parhar struct ib_wc wc;
17800082e6a5SNavdeep Parhar u8 key = 0;
17810082e6a5SNavdeep Parhar struct ib_mr *mr;
17820082e6a5SNavdeep Parhar int ret;
17830082e6a5SNavdeep Parhar int size = cb->size;
17840082e6a5SNavdeep Parhar int plen = (((size - 1) & PAGE_MASK) + PAGE_SIZE) >> PAGE_SHIFT;
17859d31afabSNavdeep Parhar unsigned long start;
17860082e6a5SNavdeep Parhar int count = 0;
17870082e6a5SNavdeep Parhar int scnt = 0;
1788478d3005SHans Petter Selasky struct scatterlist sg = {0};
17890082e6a5SNavdeep Parhar
1790478d3005SHans Petter Selasky mr = ib_alloc_mr(cb->pd, IB_MR_TYPE_MEM_REG, plen);
1791478d3005SHans Petter Selasky if (IS_ERR(mr)) {
1792478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_alloc_mr failed %ld\n", PTR_ERR(mr));
17930082e6a5SNavdeep Parhar return;
17940082e6a5SNavdeep Parhar }
17950082e6a5SNavdeep Parhar
1796c3125bc5SHans Petter Selasky sg_dma_address(&sg) = (dma_addr_t)0xcafebabe0000ULL;
1797478d3005SHans Petter Selasky sg_dma_len(&sg) = size;
1798478d3005SHans Petter Selasky ret = ib_map_mr_sg(mr, &sg, 1, NULL, PAGE_SIZE);
1799478d3005SHans Petter Selasky if (ret <= 0) {
1800478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_map_mr_sge err %d\n", ret);
1801478d3005SHans Petter Selasky goto err2;
18020082e6a5SNavdeep Parhar }
18030082e6a5SNavdeep Parhar
18040082e6a5SNavdeep Parhar memset(&fr, 0, sizeof fr);
1805478d3005SHans Petter Selasky fr.wr.opcode = IB_WR_REG_MR;
1806478d3005SHans Petter Selasky fr.access = IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE;
1807478d3005SHans Petter Selasky fr.mr = mr;
1808478d3005SHans Petter Selasky fr.wr.next = &inv;
1809478d3005SHans Petter Selasky
18100082e6a5SNavdeep Parhar memset(&inv, 0, sizeof inv);
18110082e6a5SNavdeep Parhar inv.opcode = IB_WR_LOCAL_INV;
18120082e6a5SNavdeep Parhar inv.send_flags = IB_SEND_SIGNALED;
18130082e6a5SNavdeep Parhar
1814478d3005SHans Petter Selasky DEBUG_LOG("fr_test: stag index 0x%x plen %u size %u depth %u\n", mr->rkey >> 8, plen, cb->size, cb->txdepth);
18150082e6a5SNavdeep Parhar start = time_uptime;
1816478d3005SHans Petter Selasky while (!cb->count || count <= cb->count) {
1817478d3005SHans Petter Selasky if (SIGPENDING(curthread)) {
1818478d3005SHans Petter Selasky printk(KERN_ERR PFX "signal!\n");
1819478d3005SHans Petter Selasky break;
1820478d3005SHans Petter Selasky }
18210082e6a5SNavdeep Parhar if ((time_uptime - start) >= 9) {
1822478d3005SHans Petter Selasky DEBUG_LOG("fr_test: pausing 1 second! count %u latest size %u plen %u\n", count, size, plen);
18239d31afabSNavdeep Parhar wait_event_interruptible_timeout(cb->sem, cb->state == ERROR, HZ);
18240082e6a5SNavdeep Parhar if (cb->state == ERROR)
18250082e6a5SNavdeep Parhar break;
18260082e6a5SNavdeep Parhar start = time_uptime;
18270082e6a5SNavdeep Parhar }
18280082e6a5SNavdeep Parhar while (scnt < (cb->txdepth>>1)) {
18290082e6a5SNavdeep Parhar ib_update_fast_reg_key(mr, ++key);
1830478d3005SHans Petter Selasky fr.key = mr->rkey;
18310082e6a5SNavdeep Parhar inv.ex.invalidate_rkey = mr->rkey;
1832478d3005SHans Petter Selasky
18330082e6a5SNavdeep Parhar size = arc4random() % cb->size;
18340082e6a5SNavdeep Parhar if (size == 0)
18350082e6a5SNavdeep Parhar size = cb->size;
1836478d3005SHans Petter Selasky sg_dma_len(&sg) = size;
1837478d3005SHans Petter Selasky ret = ib_map_mr_sg(mr, &sg, 1, NULL, PAGE_SIZE);
1838478d3005SHans Petter Selasky if (ret <= 0) {
1839478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_map_mr_sge err %d\n", ret);
18400082e6a5SNavdeep Parhar goto err2;
18410082e6a5SNavdeep Parhar }
1842478d3005SHans Petter Selasky ret = ib_post_send(cb->qp, &fr.wr, &bad);
1843478d3005SHans Petter Selasky if (ret) {
1844478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_post_send failed %d\n", ret);
1845478d3005SHans Petter Selasky goto err2;
1846478d3005SHans Petter Selasky }
1847478d3005SHans Petter Selasky scnt++;
18480082e6a5SNavdeep Parhar }
18490082e6a5SNavdeep Parhar
18500082e6a5SNavdeep Parhar ret = ib_poll_cq(cb->cq, 1, &wc);
18510082e6a5SNavdeep Parhar if (ret < 0) {
1852478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_poll_cq failed %d\n", ret);
18530082e6a5SNavdeep Parhar goto err2;
18540082e6a5SNavdeep Parhar }
18550082e6a5SNavdeep Parhar if (ret == 1) {
18560082e6a5SNavdeep Parhar if (wc.status) {
1857478d3005SHans Petter Selasky printk(KERN_ERR PFX "completion error %u\n", wc.status);
18580082e6a5SNavdeep Parhar goto err2;
18590082e6a5SNavdeep Parhar }
18600082e6a5SNavdeep Parhar count++;
18610082e6a5SNavdeep Parhar scnt--;
18620082e6a5SNavdeep Parhar }
18630082e6a5SNavdeep Parhar }
18640082e6a5SNavdeep Parhar err2:
1865478d3005SHans Petter Selasky flush_qp(cb);
1866478d3005SHans Petter Selasky DEBUG_LOG("fr_test: done!\n");
18670082e6a5SNavdeep Parhar ib_dereg_mr(mr);
18680082e6a5SNavdeep Parhar }
18690082e6a5SNavdeep Parhar
krping_connect_client(struct krping_cb * cb)1870e68ff398SKip Macy static int krping_connect_client(struct krping_cb *cb)
1871e68ff398SKip Macy {
1872e68ff398SKip Macy struct rdma_conn_param conn_param;
1873e68ff398SKip Macy int ret;
1874e68ff398SKip Macy
1875e68ff398SKip Macy memset(&conn_param, 0, sizeof conn_param);
1876e68ff398SKip Macy conn_param.responder_resources = 1;
1877e68ff398SKip Macy conn_param.initiator_depth = 1;
1878e68ff398SKip Macy conn_param.retry_count = 10;
1879e68ff398SKip Macy
1880e68ff398SKip Macy ret = rdma_connect(cb->cm_id, &conn_param);
1881e68ff398SKip Macy if (ret) {
1882478d3005SHans Petter Selasky printk(KERN_ERR PFX "rdma_connect error %d\n", ret);
1883e68ff398SKip Macy return ret;
1884e68ff398SKip Macy }
1885e68ff398SKip Macy
18860082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem, cb->state >= CONNECTED);
1887e68ff398SKip Macy if (cb->state == ERROR) {
1888478d3005SHans Petter Selasky printk(KERN_ERR PFX "wait for CONNECTED state %d\n", cb->state);
1889e68ff398SKip Macy return -1;
1890e68ff398SKip Macy }
1891e68ff398SKip Macy
1892478d3005SHans Petter Selasky DEBUG_LOG("rdma_connect successful\n");
1893e68ff398SKip Macy return 0;
1894e68ff398SKip Macy }
1895e68ff398SKip Macy
krping_bind_client(struct krping_cb * cb)1896e68ff398SKip Macy static int krping_bind_client(struct krping_cb *cb)
1897e68ff398SKip Macy {
1898478d3005SHans Petter Selasky struct sockaddr_storage sin;
1899e68ff398SKip Macy int ret;
1900e68ff398SKip Macy
1901478d3005SHans Petter Selasky fill_sockaddr(&sin, cb);
1902e68ff398SKip Macy
1903478d3005SHans Petter Selasky ret = rdma_resolve_addr(cb->cm_id, NULL, (struct sockaddr *)&sin, 2000);
1904e68ff398SKip Macy if (ret) {
1905478d3005SHans Petter Selasky printk(KERN_ERR PFX "rdma_resolve_addr error %d\n", ret);
1906e68ff398SKip Macy return ret;
1907e68ff398SKip Macy }
1908e68ff398SKip Macy
19090082e6a5SNavdeep Parhar wait_event_interruptible(cb->sem, cb->state >= ROUTE_RESOLVED);
1910e68ff398SKip Macy if (cb->state != ROUTE_RESOLVED) {
1911478d3005SHans Petter Selasky printk(KERN_ERR PFX
1912e68ff398SKip Macy "addr/route resolution did not resolve: state %d\n",
1913e68ff398SKip Macy cb->state);
19140082e6a5SNavdeep Parhar return -EINTR;
1915e68ff398SKip Macy }
1916e68ff398SKip Macy
1917478d3005SHans Petter Selasky if (!reg_supported(cb->cm_id->device))
19180082e6a5SNavdeep Parhar return -EINVAL;
19190082e6a5SNavdeep Parhar
1920478d3005SHans Petter Selasky DEBUG_LOG("rdma_resolve_addr - rdma_resolve_route successful\n");
1921e68ff398SKip Macy return 0;
1922e68ff398SKip Macy }
1923e68ff398SKip Macy
krping_run_client(struct krping_cb * cb)1924e68ff398SKip Macy static void krping_run_client(struct krping_cb *cb)
1925e68ff398SKip Macy {
1926c3987b8eSHans Petter Selasky const struct ib_recv_wr *bad_wr;
1927e68ff398SKip Macy int ret;
1928e68ff398SKip Macy
192998450752SHans Petter Selasky /* set type of service, if any */
193098450752SHans Petter Selasky if (cb->tos != 0)
193198450752SHans Petter Selasky rdma_set_service_type(cb->cm_id, cb->tos);
193298450752SHans Petter Selasky
1933e68ff398SKip Macy ret = krping_bind_client(cb);
1934e68ff398SKip Macy if (ret)
1935e68ff398SKip Macy return;
1936e68ff398SKip Macy
1937e68ff398SKip Macy ret = krping_setup_qp(cb, cb->cm_id);
1938e68ff398SKip Macy if (ret) {
1939478d3005SHans Petter Selasky printk(KERN_ERR PFX "setup_qp failed: %d\n", ret);
1940e68ff398SKip Macy return;
1941e68ff398SKip Macy }
1942e68ff398SKip Macy
1943e68ff398SKip Macy ret = krping_setup_buffers(cb);
1944e68ff398SKip Macy if (ret) {
1945478d3005SHans Petter Selasky printk(KERN_ERR PFX "krping_setup_buffers failed: %d\n", ret);
1946e68ff398SKip Macy goto err1;
1947e68ff398SKip Macy }
1948e68ff398SKip Macy
1949e68ff398SKip Macy ret = ib_post_recv(cb->qp, &cb->rq_wr, &bad_wr);
1950e68ff398SKip Macy if (ret) {
1951478d3005SHans Petter Selasky printk(KERN_ERR PFX "ib_post_recv failed: %d\n", ret);
1952e68ff398SKip Macy goto err2;
1953e68ff398SKip Macy }
1954e68ff398SKip Macy
1955e68ff398SKip Macy ret = krping_connect_client(cb);
1956e68ff398SKip Macy if (ret) {
1957478d3005SHans Petter Selasky printk(KERN_ERR PFX "connect error %d\n", ret);
1958e68ff398SKip Macy goto err2;
1959e68ff398SKip Macy }
1960e68ff398SKip Macy
1961e68ff398SKip Macy if (cb->wlat)
1962e68ff398SKip Macy krping_wlat_test_client(cb);
1963e68ff398SKip Macy else if (cb->rlat)
1964e68ff398SKip Macy krping_rlat_test_client(cb);
1965e68ff398SKip Macy else if (cb->bw)
1966e68ff398SKip Macy krping_bw_test_client(cb);
19670082e6a5SNavdeep Parhar else if (cb->frtest)
19680082e6a5SNavdeep Parhar krping_fr_test(cb);
1969e68ff398SKip Macy else
1970e68ff398SKip Macy krping_test_client(cb);
1971e68ff398SKip Macy rdma_disconnect(cb->cm_id);
1972e68ff398SKip Macy err2:
1973e68ff398SKip Macy krping_free_buffers(cb);
1974e68ff398SKip Macy err1:
1975e68ff398SKip Macy krping_free_qp(cb);
1976e68ff398SKip Macy }
1977e68ff398SKip Macy
19784f939024SHans Petter Selasky static uint16_t
krping_get_ipv6_scope_id(char * name)19794f939024SHans Petter Selasky krping_get_ipv6_scope_id(char *name)
19804f939024SHans Petter Selasky {
19814f939024SHans Petter Selasky struct ifnet *ifp;
19824f939024SHans Petter Selasky uint16_t retval;
19834f939024SHans Petter Selasky
19844f939024SHans Petter Selasky if (name == NULL)
19854f939024SHans Petter Selasky return (0);
19864f939024SHans Petter Selasky CURVNET_SET_QUIET(TD_TO_VNET(curthread));
19874f939024SHans Petter Selasky ifp = ifunit_ref(name);
19884f939024SHans Petter Selasky CURVNET_RESTORE();
19894f939024SHans Petter Selasky if (ifp == NULL)
19904f939024SHans Petter Selasky return (0);
1991*cfaab41cSJustin Hibbits retval = if_getindex(ifp);
19924f939024SHans Petter Selasky if_rele(ifp);
19934f939024SHans Petter Selasky return (retval);
19944f939024SHans Petter Selasky }
19954f939024SHans Petter Selasky
krping_doit(char * cmd)1996478d3005SHans Petter Selasky int krping_doit(char *cmd)
1997e68ff398SKip Macy {
1998e68ff398SKip Macy struct krping_cb *cb;
1999e68ff398SKip Macy int op;
2000e68ff398SKip Macy int ret = 0;
2001e68ff398SKip Macy char *optarg;
20024f939024SHans Petter Selasky char *scope;
2003e68ff398SKip Macy unsigned long optint;
2004e68ff398SKip Macy
20050082e6a5SNavdeep Parhar cb = kzalloc(sizeof(*cb), GFP_KERNEL);
2006e68ff398SKip Macy if (!cb)
20070082e6a5SNavdeep Parhar return -ENOMEM;
2008e68ff398SKip Macy
20090082e6a5SNavdeep Parhar mutex_lock(&krping_mutex);
20100082e6a5SNavdeep Parhar list_add_tail(&cb->list, &krping_cbs);
20110082e6a5SNavdeep Parhar mutex_unlock(&krping_mutex);
2012e68ff398SKip Macy
2013e68ff398SKip Macy cb->server = -1;
2014e68ff398SKip Macy cb->state = IDLE;
2015e68ff398SKip Macy cb->size = 64;
2016e68ff398SKip Macy cb->txdepth = RPING_SQ_DEPTH;
20170082e6a5SNavdeep Parhar init_waitqueue_head(&cb->sem);
2018e68ff398SKip Macy
2019e68ff398SKip Macy while ((op = krping_getopt("krping", &cmd, krping_opts, NULL, &optarg,
2020e68ff398SKip Macy &optint)) != 0) {
2021e68ff398SKip Macy switch (op) {
2022e68ff398SKip Macy case 'a':
2023e68ff398SKip Macy cb->addr_str = optarg;
2024478d3005SHans Petter Selasky cb->addr_type = AF_INET;
2025478d3005SHans Petter Selasky DEBUG_LOG("ipaddr (%s)\n", optarg);
20264f939024SHans Petter Selasky if (inet_pton(AF_INET, optarg, cb->addr) != 1) {
2027478d3005SHans Petter Selasky printk(KERN_ERR PFX "bad addr string %s\n",
20280082e6a5SNavdeep Parhar optarg);
2029e68ff398SKip Macy ret = EINVAL;
2030e68ff398SKip Macy }
2031478d3005SHans Petter Selasky break;
2032478d3005SHans Petter Selasky case 'A':
2033478d3005SHans Petter Selasky cb->addr_str = optarg;
2034478d3005SHans Petter Selasky cb->addr_type = AF_INET6;
2035478d3005SHans Petter Selasky DEBUG_LOG("ipv6addr (%s)\n", optarg);
20364f939024SHans Petter Selasky scope = strstr(optarg, "%");
20374f939024SHans Petter Selasky /* extract scope ID, if any */
20384f939024SHans Petter Selasky if (scope != NULL)
20394f939024SHans Petter Selasky *scope++ = 0;
20404f939024SHans Petter Selasky /* extract IPv6 network address */
20414f939024SHans Petter Selasky if (inet_pton(AF_INET6, optarg, cb->addr) != 1) {
20424f939024SHans Petter Selasky printk(KERN_ERR PFX "bad addr string %s\n",
20434f939024SHans Petter Selasky optarg);
20444f939024SHans Petter Selasky ret = EINVAL;
20454f939024SHans Petter Selasky } else if (IN6_IS_SCOPE_LINKLOCAL((struct in6_addr *)cb->addr) ||
20464f939024SHans Petter Selasky IN6_IS_ADDR_MC_INTFACELOCAL((struct in6_addr *)cb->addr)) {
20474f939024SHans Petter Selasky uint16_t scope_id = krping_get_ipv6_scope_id(scope);
20484f939024SHans Petter Selasky DEBUG_LOG("ipv6 scope ID = %d\n", scope_id);
20494f939024SHans Petter Selasky cb->addr[2] = scope_id >> 8;
20504f939024SHans Petter Selasky cb->addr[3] = scope_id & 0xFF;
20514f939024SHans Petter Selasky }
2052e68ff398SKip Macy break;
2053e68ff398SKip Macy case 'p':
2054e68ff398SKip Macy cb->port = htons(optint);
2055478d3005SHans Petter Selasky DEBUG_LOG("port %d\n", (int)optint);
2056e68ff398SKip Macy break;
2057e68ff398SKip Macy case 'P':
2058e68ff398SKip Macy cb->poll = 1;
2059478d3005SHans Petter Selasky DEBUG_LOG("server\n");
2060e68ff398SKip Macy break;
2061e68ff398SKip Macy case 's':
2062e68ff398SKip Macy cb->server = 1;
2063478d3005SHans Petter Selasky DEBUG_LOG("server\n");
2064e68ff398SKip Macy break;
2065e68ff398SKip Macy case 'c':
2066e68ff398SKip Macy cb->server = 0;
2067478d3005SHans Petter Selasky DEBUG_LOG("client\n");
2068e68ff398SKip Macy break;
2069e68ff398SKip Macy case 'S':
2070e68ff398SKip Macy cb->size = optint;
2071e68ff398SKip Macy if ((cb->size < 1) ||
2072e68ff398SKip Macy (cb->size > RPING_BUFSIZE)) {
2073478d3005SHans Petter Selasky printk(KERN_ERR PFX "Invalid size %d "
2074e68ff398SKip Macy "(valid range is 1 to %d)\n",
2075e68ff398SKip Macy cb->size, RPING_BUFSIZE);
2076e68ff398SKip Macy ret = EINVAL;
2077e68ff398SKip Macy } else
2078478d3005SHans Petter Selasky DEBUG_LOG("size %d\n", (int)optint);
2079e68ff398SKip Macy break;
2080e68ff398SKip Macy case 'C':
2081e68ff398SKip Macy cb->count = optint;
2082e68ff398SKip Macy if (cb->count < 0) {
2083478d3005SHans Petter Selasky printk(KERN_ERR PFX "Invalid count %d\n",
2084e68ff398SKip Macy cb->count);
2085e68ff398SKip Macy ret = EINVAL;
2086e68ff398SKip Macy } else
2087478d3005SHans Petter Selasky DEBUG_LOG("count %d\n", (int) cb->count);
2088e68ff398SKip Macy break;
2089e68ff398SKip Macy case 'v':
2090e68ff398SKip Macy cb->verbose++;
2091478d3005SHans Petter Selasky DEBUG_LOG("verbose\n");
2092e68ff398SKip Macy break;
2093e68ff398SKip Macy case 'V':
2094e68ff398SKip Macy cb->validate++;
2095478d3005SHans Petter Selasky DEBUG_LOG("validate data\n");
2096e68ff398SKip Macy break;
2097e68ff398SKip Macy case 'l':
2098e68ff398SKip Macy cb->wlat++;
2099e68ff398SKip Macy break;
21000082e6a5SNavdeep Parhar case 'L':
21010082e6a5SNavdeep Parhar cb->rlat++;
21020082e6a5SNavdeep Parhar break;
2103e68ff398SKip Macy case 'B':
2104e68ff398SKip Macy cb->bw++;
2105e68ff398SKip Macy break;
2106e68ff398SKip Macy case 'd':
21070082e6a5SNavdeep Parhar cb->duplex++;
2108e68ff398SKip Macy break;
21090082e6a5SNavdeep Parhar case 'I':
21100082e6a5SNavdeep Parhar cb->server_invalidate = 1;
21110082e6a5SNavdeep Parhar break;
211298450752SHans Petter Selasky case 't':
211398450752SHans Petter Selasky cb->tos = optint;
211498450752SHans Petter Selasky DEBUG_LOG("type of service, tos=%d\n", (int) cb->tos);
211598450752SHans Petter Selasky break;
21160082e6a5SNavdeep Parhar case 'T':
21170082e6a5SNavdeep Parhar cb->txdepth = optint;
2118478d3005SHans Petter Selasky DEBUG_LOG("txdepth %d\n", (int) cb->txdepth);
21190082e6a5SNavdeep Parhar break;
21200082e6a5SNavdeep Parhar case 'Z':
21210082e6a5SNavdeep Parhar cb->local_dma_lkey = 1;
2122478d3005SHans Petter Selasky DEBUG_LOG("using local dma lkey\n");
21230082e6a5SNavdeep Parhar break;
21240082e6a5SNavdeep Parhar case 'R':
21250082e6a5SNavdeep Parhar cb->read_inv = 1;
2126478d3005SHans Petter Selasky DEBUG_LOG("using read-with-inv\n");
21270082e6a5SNavdeep Parhar break;
21280082e6a5SNavdeep Parhar case 'f':
21290082e6a5SNavdeep Parhar cb->frtest = 1;
2130478d3005SHans Petter Selasky DEBUG_LOG("fast-reg test!\n");
213109fe6320SNavdeep Parhar break;
2132e68ff398SKip Macy default:
2133478d3005SHans Petter Selasky printk(KERN_ERR PFX "unknown opt %s\n", optarg);
21340082e6a5SNavdeep Parhar ret = -EINVAL;
2135e68ff398SKip Macy break;
2136e68ff398SKip Macy }
2137e68ff398SKip Macy }
2138e68ff398SKip Macy if (ret)
2139e68ff398SKip Macy goto out;
2140e68ff398SKip Macy
2141e68ff398SKip Macy if (cb->server == -1) {
2142478d3005SHans Petter Selasky printk(KERN_ERR PFX "must be either client or server\n");
2143478d3005SHans Petter Selasky ret = -EINVAL;
2144478d3005SHans Petter Selasky goto out;
2145478d3005SHans Petter Selasky }
2146478d3005SHans Petter Selasky
2147478d3005SHans Petter Selasky if (cb->server && cb->frtest) {
2148478d3005SHans Petter Selasky printk(KERN_ERR PFX "must be client to run frtest\n");
21490082e6a5SNavdeep Parhar ret = -EINVAL;
2150e68ff398SKip Macy goto out;
2151e68ff398SKip Macy }
2152e68ff398SKip Macy
21530082e6a5SNavdeep Parhar if ((cb->frtest + cb->bw + cb->rlat + cb->wlat) > 1) {
2154478d3005SHans Petter Selasky printk(KERN_ERR PFX "Pick only one test: fr, bw, rlat, wlat\n");
21550082e6a5SNavdeep Parhar ret = -EINVAL;
21560082e6a5SNavdeep Parhar goto out;
21570082e6a5SNavdeep Parhar }
21580082e6a5SNavdeep Parhar
2159478d3005SHans Petter Selasky if (cb->wlat || cb->rlat || cb->bw) {
2160478d3005SHans Petter Selasky printk(KERN_ERR PFX "wlat, rlat, and bw tests only support mem_mode MR - which is no longer supported\n");
21610082e6a5SNavdeep Parhar ret = -EINVAL;
21620082e6a5SNavdeep Parhar goto out;
21630082e6a5SNavdeep Parhar }
21640082e6a5SNavdeep Parhar
216558c277d8SHans Petter Selasky cb->cm_id = rdma_create_id(TD_TO_VNET(curthread), krping_cma_event_handler, cb, RDMA_PS_TCP, IB_QPT_RC);
2166e68ff398SKip Macy if (IS_ERR(cb->cm_id)) {
2167e68ff398SKip Macy ret = PTR_ERR(cb->cm_id);
2168478d3005SHans Petter Selasky printk(KERN_ERR PFX "rdma_create_id error %d\n", ret);
2169e68ff398SKip Macy goto out;
2170e68ff398SKip Macy }
2171478d3005SHans Petter Selasky DEBUG_LOG("created cm_id %p\n", cb->cm_id);
21720082e6a5SNavdeep Parhar
2173e68ff398SKip Macy if (cb->server)
2174e68ff398SKip Macy krping_run_server(cb);
2175e68ff398SKip Macy else
2176e68ff398SKip Macy krping_run_client(cb);
2177ea68a714SNavdeep Parhar
2178478d3005SHans Petter Selasky DEBUG_LOG("destroy cm_id %p\n", cb->cm_id);
2179e68ff398SKip Macy rdma_destroy_id(cb->cm_id);
2180e68ff398SKip Macy out:
21810082e6a5SNavdeep Parhar mutex_lock(&krping_mutex);
21820082e6a5SNavdeep Parhar list_del(&cb->list);
21830082e6a5SNavdeep Parhar mutex_unlock(&krping_mutex);
21840082e6a5SNavdeep Parhar kfree(cb);
2185e68ff398SKip Macy return ret;
2186e68ff398SKip Macy }
2187e68ff398SKip Macy
21880082e6a5SNavdeep Parhar void
krping_walk_cb_list(void (* f)(struct krping_stats *,void *),void * arg)21890082e6a5SNavdeep Parhar krping_walk_cb_list(void (*f)(struct krping_stats *, void *), void *arg)
21900082e6a5SNavdeep Parhar {
21910082e6a5SNavdeep Parhar struct krping_cb *cb;
21920082e6a5SNavdeep Parhar
21930082e6a5SNavdeep Parhar mutex_lock(&krping_mutex);
21940082e6a5SNavdeep Parhar list_for_each_entry(cb, &krping_cbs, list)
21950082e6a5SNavdeep Parhar (*f)(cb->pd ? &cb->stats : NULL, arg);
21960082e6a5SNavdeep Parhar mutex_unlock(&krping_mutex);
21970082e6a5SNavdeep Parhar }
2198e8f206ccSHans Petter Selasky
2199e8f206ccSHans Petter Selasky void
krping_cancel_all(void)2200e8f206ccSHans Petter Selasky krping_cancel_all(void)
2201e8f206ccSHans Petter Selasky {
2202e8f206ccSHans Petter Selasky struct krping_cb *cb;
2203e8f206ccSHans Petter Selasky
2204e8f206ccSHans Petter Selasky mutex_lock(&krping_mutex);
2205e8f206ccSHans Petter Selasky list_for_each_entry(cb, &krping_cbs, list) {
2206e8f206ccSHans Petter Selasky cb->state = ERROR;
2207e8f206ccSHans Petter Selasky wake_up_interruptible(&cb->sem);
2208e8f206ccSHans Petter Selasky }
2209e8f206ccSHans Petter Selasky mutex_unlock(&krping_mutex);
2210e8f206ccSHans Petter Selasky }
2211e8f206ccSHans Petter Selasky
2212