]>
Commit | Line | Data |
---|---|---|
813b2f22 JB |
1 | diff -Nur librdmacm-1.0.19/examples/rping.c librdmacm-1.0.19.ssa1/examples/rping.c |
2 | --- librdmacm-1.0.19/examples/rping.c 2014-07-17 00:30:15.000000000 +0200 | |
3 | +++ librdmacm-1.0.19.ssa1/examples/rping.c 2015-01-22 18:11:28.000000000 +0100 | |
4 | @@ -277,15 +277,20 @@ | |
5 | struct ibv_wc wc; | |
6 | struct ibv_recv_wr *bad_wr; | |
7 | int ret; | |
8 | + int flushed = 0; | |
9 | ||
10 | while ((ret = ibv_poll_cq(cb->cq, 1, &wc)) == 1) { | |
11 | ret = 0; | |
12 | ||
13 | if (wc.status) { | |
14 | - if (wc.status != IBV_WC_WR_FLUSH_ERR) | |
15 | - fprintf(stderr, | |
16 | - "cq completion failed status %d\n", | |
17 | - wc.status); | |
18 | + if (wc.status == IBV_WC_WR_FLUSH_ERR) { | |
19 | + flushed = 1; | |
20 | + continue; | |
21 | + | |
22 | + } | |
23 | + fprintf(stderr, | |
24 | + "cq completion failed status %d\n", | |
25 | + wc.status); | |
26 | ret = -1; | |
27 | goto error; | |
28 | } | |
29 | @@ -334,7 +339,7 @@ | |
30 | fprintf(stderr, "poll error %d\n", ret); | |
31 | goto error; | |
32 | } | |
33 | - return 0; | |
34 | + return flushed; | |
35 | ||
36 | error: | |
37 | cb->state = ERROR; | |
38 | @@ -1055,18 +1060,19 @@ | |
39 | ret = rping_connect_client(cb); | |
40 | if (ret) { | |
41 | fprintf(stderr, "connect error %d\n", ret); | |
42 | - goto err2; | |
43 | + goto err3; | |
44 | } | |
45 | ||
46 | ret = rping_test_client(cb); | |
47 | if (ret) { | |
48 | fprintf(stderr, "rping client failed: %d\n", ret); | |
49 | - goto err3; | |
50 | + goto err4; | |
51 | } | |
52 | ||
53 | ret = 0; | |
54 | -err3: | |
55 | +err4: | |
56 | rdma_disconnect(cb->cm_id); | |
57 | +err3: | |
58 | pthread_join(cb->cqthread, NULL); | |
59 | err2: | |
60 | rping_free_buffers(cb); | |
61 | diff -Nur librdmacm-1.0.19/src/cma.c librdmacm-1.0.19.ssa1/src/cma.c | |
62 | --- librdmacm-1.0.19/src/cma.c 2014-07-17 00:30:15.000000000 +0200 | |
63 | +++ librdmacm-1.0.19.ssa1/src/cma.c 2015-01-22 19:46:41.000000000 +0100 | |
64 | @@ -49,6 +49,7 @@ | |
65 | #include <stddef.h> | |
66 | #include <netdb.h> | |
67 | #include <syslog.h> | |
68 | +#include <limits.h> | |
69 | ||
70 | #include "cma.h" | |
71 | #include "indexer.h" | |
72 | @@ -1035,7 +1036,9 @@ | |
73 | static int ucma_modify_qp_rtr(struct rdma_cm_id *id, uint8_t resp_res) | |
74 | { | |
75 | struct ibv_qp_attr qp_attr; | |
76 | + struct ibv_port_attr port_attr; | |
77 | int qp_attr_mask, ret; | |
78 | + uint8_t link_layer; | |
79 | ||
80 | if (!id->qp) | |
81 | return ERR(EINVAL); | |
82 | @@ -1055,6 +1058,17 @@ | |
83 | if (ret) | |
84 | return ret; | |
85 | ||
86 | + /* Workaround for rdma_ucm kernel bug */ | |
87 | + ret = ibv_query_port(id->verbs, id->port_num, &port_attr); | |
88 | + if (ret) | |
89 | + link_layer = IBV_LINK_LAYER_UNSPECIFIED; | |
90 | + else | |
91 | + link_layer = port_attr.link_layer; | |
92 | + | |
93 | + if (id->verbs->device->transport_type == IBV_TRANSPORT_IB && | |
94 | + link_layer == IBV_LINK_LAYER_INFINIBAND) | |
95 | + qp_attr_mask &= UINT_MAX ^ 0xe00000; /* mask off bits 21-24 which are used for RoCE */ | |
96 | + | |
97 | if (resp_res != RDMA_MAX_RESP_RES) | |
98 | qp_attr.max_dest_rd_atomic = resp_res; | |
99 | return rdma_seterrno(ibv_modify_qp(id->qp, &qp_attr, qp_attr_mask)); | |
100 | diff -Nur librdmacm-1.0.19/src/preload.c librdmacm-1.0.19.ssa1/src/preload.c | |
101 | --- librdmacm-1.0.19/src/preload.c 2014-07-17 00:30:15.000000000 +0200 | |
102 | +++ librdmacm-1.0.19.ssa1/src/preload.c 2015-01-22 18:11:29.000000000 +0100 | |
103 | @@ -50,6 +50,9 @@ | |
104 | #include <netinet/tcp.h> | |
105 | #include <unistd.h> | |
106 | #include <semaphore.h> | |
107 | +#include <ctype.h> | |
108 | +#include <stdlib.h> | |
109 | +#include <stdio.h> | |
110 | ||
111 | #include <rdma/rdma_cma.h> | |
112 | #include <rdma/rdma_verbs.h> | |
113 | @@ -122,6 +125,136 @@ | |
114 | atomic_t refcnt; | |
115 | }; | |
116 | ||
117 | +struct config_entry { | |
118 | + char *name; | |
119 | + int domain; | |
120 | + int type; | |
121 | + int protocol; | |
122 | +}; | |
123 | + | |
124 | +static struct config_entry *config; | |
125 | +static int config_cnt; | |
126 | +extern char *program_invocation_short_name; | |
127 | + | |
128 | + | |
129 | +static void free_config(void) | |
130 | +{ | |
131 | + while (config_cnt) | |
132 | + free(config[--config_cnt].name); | |
133 | + | |
134 | + free(config); | |
135 | +} | |
136 | + | |
137 | +/* | |
138 | + * Config file format: | |
139 | + * # Starting '#' indicates comment | |
140 | + * # wild card values are supported using '*' | |
141 | + * # domain - *, INET, INET6, IB | |
142 | + * # type - *, STREAM, DGRAM | |
143 | + * # protocol - *, TCP, UDP | |
144 | + * program_name domain type protocol | |
145 | + */ | |
146 | +static void scan_config(void) | |
147 | +{ | |
148 | + struct config_entry *new_config; | |
149 | + FILE *fp; | |
150 | + char line[120], prog[64], dom[16], type[16], proto[16]; | |
151 | + | |
152 | + fp = fopen(RS_CONF_DIR "/preload_config", "r"); | |
153 | + if (!fp) | |
154 | + return; | |
155 | + | |
156 | + while (fgets(line, sizeof(line), fp)) { | |
157 | + if (line[0] == '#') | |
158 | + continue; | |
159 | + | |
160 | + if (sscanf(line, "%64s%16s%16s%16s", prog, dom, type, proto) != 4) | |
161 | + continue; | |
162 | + | |
163 | + new_config = realloc(config, (config_cnt + 1) * | |
164 | + sizeof(struct config_entry)); | |
165 | + if (!new_config) | |
166 | + break; | |
167 | + | |
168 | + config = new_config; | |
169 | + memset(&config[config_cnt], 0, sizeof(struct config_entry)); | |
170 | + | |
171 | + if (!strcasecmp(dom, "INET") || | |
172 | + !strcasecmp(dom, "AF_INET") || | |
173 | + !strcasecmp(dom, "PF_INET")) { | |
174 | + config[config_cnt].domain = AF_INET; | |
175 | + } else if (!strcasecmp(dom, "INET6") || | |
176 | + !strcasecmp(dom, "AF_INET6") || | |
177 | + !strcasecmp(dom, "PF_INET6")) { | |
178 | + config[config_cnt].domain = AF_INET6; | |
179 | + } else if (!strcasecmp(dom, "IB") || | |
180 | + !strcasecmp(dom, "AF_IB") || | |
181 | + !strcasecmp(dom, "PF_IB")) { | |
182 | + config[config_cnt].domain = AF_IB; | |
183 | + } else if (strcmp(dom, "*")) { | |
184 | + continue; | |
185 | + } | |
186 | + | |
187 | + if (!strcasecmp(type, "STREAM") || | |
188 | + !strcasecmp(type, "SOCK_STREAM")) { | |
189 | + config[config_cnt].type = SOCK_STREAM; | |
190 | + } else if (!strcasecmp(type, "DGRAM") || | |
191 | + !strcasecmp(type, "SOCK_DGRAM")) { | |
192 | + config[config_cnt].type = SOCK_DGRAM; | |
193 | + } else if (strcmp(type, "*")) { | |
194 | + continue; | |
195 | + } | |
196 | + | |
197 | + if (!strcasecmp(proto, "TCP") || | |
198 | + !strcasecmp(proto, "IPPROTO_TCP")) { | |
199 | + config[config_cnt].protocol = IPPROTO_TCP; | |
200 | + } else if (!strcasecmp(proto, "UDP") || | |
201 | + !strcasecmp(proto, "IPPROTO_UDP")) { | |
202 | + config[config_cnt].protocol = IPPROTO_UDP; | |
203 | + } else if (strcmp(proto, "*")) { | |
204 | + continue; | |
205 | + } | |
206 | + | |
207 | + if (strcmp(prog, "*")) { | |
208 | + if (!(config[config_cnt].name = strdup(prog))) | |
209 | + continue; | |
210 | + } | |
211 | + | |
212 | + config_cnt++; | |
213 | + } | |
214 | + | |
215 | + fclose(fp); | |
216 | + if (config_cnt) | |
217 | + atexit(free_config); | |
218 | +} | |
219 | + | |
220 | +static int intercept_socket(int domain, int type, int protocol) | |
221 | +{ | |
222 | + int i; | |
223 | + | |
224 | + if (!config_cnt) | |
225 | + return 1; | |
226 | + | |
227 | + if (!protocol) { | |
228 | + if (type == SOCK_STREAM) | |
229 | + protocol = IPPROTO_TCP; | |
230 | + else if (type == SOCK_DGRAM) | |
231 | + protocol = IPPROTO_UDP; | |
232 | + } | |
233 | + | |
234 | + for (i = 0; i < config_cnt; i++) { | |
235 | + if ((!config[i].name || | |
236 | + !strncasecmp(config[i].name, program_invocation_short_name, | |
237 | + strlen(config[i].name))) && | |
238 | + (!config[i].domain || config[i].domain == domain) && | |
239 | + (!config[i].type || config[i].type == type) && | |
240 | + (!config[i].protocol || config[i].protocol == protocol)) | |
241 | + return 1; | |
242 | + } | |
243 | + | |
244 | + return 0; | |
245 | +} | |
246 | + | |
247 | static int fd_open(void) | |
248 | { | |
249 | struct fd_info *fdi; | |
250 | @@ -308,6 +441,7 @@ | |
251 | rs.fcntl = dlsym(RTLD_DEFAULT, "rfcntl"); | |
252 | ||
253 | getenv_options(); | |
254 | + scan_config(); | |
255 | init = 1; | |
256 | out: | |
257 | pthread_mutex_unlock(&mut); | |
258 | @@ -404,10 +538,11 @@ | |
259 | static __thread int recursive; | |
260 | int index, ret; | |
261 | ||
262 | - if (recursive) | |
263 | + init_preload(); | |
264 | + | |
265 | + if (recursive || !intercept_socket(domain, type, protocol)) | |
266 | goto real; | |
267 | ||
268 | - init_preload(); | |
269 | index = fd_open(); | |
270 | if (index < 0) | |
271 | return index; | |
272 | diff -Nur librdmacm-1.0.19/src/rsocket.c librdmacm-1.0.19.ssa1/src/rsocket.c | |
273 | --- librdmacm-1.0.19/src/rsocket.c 2014-07-17 00:30:15.000000000 +0200 | |
274 | +++ librdmacm-1.0.19.ssa1/src/rsocket.c 2015-01-22 18:11:29.000000000 +0100 | |
275 | @@ -1,5 +1,5 @@ | |
276 | /* | |
277 | - * Copyright (c) 2008-2013 Intel Corporation. All rights reserved. | |
278 | + * Copyright (c) 2008-2014 Intel Corporation. All rights reserved. | |
279 | * | |
280 | * This software is available to you under a choice of one of two | |
281 | * licenses. You may choose to be licensed under the terms of the GNU | |
282 | @@ -381,6 +381,7 @@ | |
283 | dlist_entry iomap_list; | |
284 | dlist_entry iomap_queue; | |
285 | int iomap_pending; | |
286 | + int unack_cqe; | |
287 | }; | |
288 | ||
289 | #define DS_UDP_TAG 0x55555555 | |
290 | @@ -967,9 +968,6 @@ | |
291 | return; | |
292 | } | |
293 | ||
294 | - if (rs->index >= 0) | |
295 | - rs_remove(rs); | |
296 | - | |
297 | if (rs->rmsg) | |
298 | free(rs->rmsg); | |
299 | ||
300 | @@ -993,11 +991,16 @@ | |
301 | ||
302 | if (rs->cm_id) { | |
303 | rs_free_iomappings(rs); | |
304 | - if (rs->cm_id->qp) | |
305 | + if (rs->cm_id->qp) { | |
306 | + ibv_ack_cq_events(rs->cm_id->recv_cq, rs->unack_cqe); | |
307 | rdma_destroy_qp(rs->cm_id); | |
308 | + } | |
309 | rdma_destroy_id(rs->cm_id); | |
310 | } | |
311 | ||
312 | + if (rs->index >= 0) | |
313 | + rs_remove(rs); | |
314 | + | |
315 | fastlock_destroy(&rs->map_lock); | |
316 | fastlock_destroy(&rs->cq_wait_lock); | |
317 | fastlock_destroy(&rs->cq_lock); | |
318 | @@ -1174,9 +1177,14 @@ | |
319 | rs = idm_lookup(&idm, socket); | |
320 | if (!rs) | |
321 | return ERR(EBADF); | |
322 | - ret = rdma_listen(rs->cm_id, backlog); | |
323 | - if (!ret) | |
324 | - rs->state = rs_listening; | |
325 | + | |
326 | + if (rs->state != rs_listening) { | |
327 | + ret = rdma_listen(rs->cm_id, backlog); | |
328 | + if (!ret) | |
329 | + rs->state = rs_listening; | |
330 | + } else { | |
331 | + ret = 0; | |
332 | + } | |
333 | return ret; | |
334 | } | |
335 | ||
336 | @@ -1965,9 +1973,12 @@ | |
337 | ||
338 | ret = ibv_get_cq_event(rs->cm_id->recv_cq_channel, &cq, &context); | |
339 | if (!ret) { | |
340 | - ibv_ack_cq_events(rs->cm_id->recv_cq, 1); | |
341 | + if (++rs->unack_cqe >= rs->sq_size + rs->rq_size) { | |
342 | + ibv_ack_cq_events(rs->cm_id->recv_cq, rs->unack_cqe); | |
343 | + rs->unack_cqe = 0; | |
344 | + } | |
345 | rs->cq_armed = 0; | |
346 | - } else if (errno != EAGAIN) { | |
347 | + } else if (!(errno == EAGAIN || errno == EINTR)) { | |
348 | rs->state = rs_error; | |
349 | } | |
350 | ||
351 | @@ -2383,7 +2394,7 @@ | |
352 | struct rsocket *rs; | |
353 | size_t left = len; | |
354 | uint32_t end_size, rsize; | |
355 | - int ret; | |
356 | + int ret = 0; | |
357 | ||
358 | rs = idm_at(&idm, socket); | |
359 | if (rs->type == SOCK_DGRAM) { | |
360 | @@ -2410,7 +2421,6 @@ | |
361 | break; | |
362 | } | |
363 | ||
364 | - ret = 0; | |
365 | if (flags & MSG_PEEK) { | |
366 | left = len - rs_peek(rs, buf, left); | |
367 | break; | |
368 | @@ -2445,7 +2455,7 @@ | |
369 | } while (left && (flags & MSG_WAITALL) && (rs->state & rs_readable)); | |
370 | ||
371 | fastlock_release(&rs->rlock); | |
372 | - return ret ? ret : len - left; | |
373 | + return (ret && left == len) ? ret : len - left; | |
374 | } | |
375 | ||
376 | ssize_t rrecvfrom(int socket, void *buf, size_t len, int flags, |