[Pkg-ofed-commits] [librdmacm] 01/04: Imported Upstream version 1.0.21

Ana Beatriz Guerrero López ana at moszumanska.debian.org
Mon Jul 20 14:33:53 UTC 2015


This is an automated email from the git hooks/post-receive script.

ana pushed a commit to branch master
in repository librdmacm.

commit c93f9ebe127ecc9790cd8e8cba6a937d7e45468e
Author: Ana Guerrero López <ana at ekaia.org>
Date:   Mon Jul 20 15:55:04 2015 +0200

    Imported Upstream version 1.0.21
---
 configure          |  20 ++++----
 configure.ac       |   2 +-
 examples/rping.c   |  69 +++++++++++++++++++++-----
 examples/rstream.c |  29 +++++++++--
 librdmacm.spec     |   4 +-
 librdmacm.spec.in  |   2 +-
 src/cma.c          |  48 ++++++++++++------
 src/indexer.c      |   5 --
 src/indexer.h      |   1 -
 src/preload.c      | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/rsocket.c      |  83 ++++++++++++++++++--------------
 11 files changed, 315 insertions(+), 87 deletions(-)

diff --git a/configure b/configure
index 84f929d..3154434 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.67 for librdmacm 1.0.19.1.
+# Generated by GNU Autoconf 2.67 for librdmacm 1.0.21.
 #
 # Report bugs to <linux-rdma at vger.kernel.org>.
 #
@@ -701,8 +701,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='librdmacm'
 PACKAGE_TARNAME='librdmacm'
-PACKAGE_VERSION='1.0.19.1'
-PACKAGE_STRING='librdmacm 1.0.19.1'
+PACKAGE_VERSION='1.0.21'
+PACKAGE_STRING='librdmacm 1.0.21'
 PACKAGE_BUGREPORT='linux-rdma at vger.kernel.org'
 PACKAGE_URL=''
 
@@ -1423,7 +1423,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures librdmacm 1.0.19.1 to adapt to many kinds of systems.
+\`configure' configures librdmacm 1.0.21 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1493,7 +1493,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of librdmacm 1.0.19.1:";;
+     short | recursive ) echo "Configuration of librdmacm 1.0.21:";;
    esac
   cat <<\_ACEOF
 
@@ -1597,7 +1597,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-librdmacm configure 1.0.19.1
+librdmacm configure 1.0.21
 generated by GNU Autoconf 2.67
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2190,7 +2190,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by librdmacm $as_me 1.0.19.1, which was
+It was created by librdmacm $as_me 1.0.21, which was
 generated by GNU Autoconf 2.67.  Invocation command line was
 
   $ $0 $@
@@ -3009,7 +3009,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='librdmacm'
- VERSION='1.0.19.1'
+ VERSION='1.0.21'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -12362,7 +12362,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by librdmacm $as_me 1.0.19.1, which was
+This file was extended by librdmacm $as_me 1.0.21, which was
 generated by GNU Autoconf 2.67.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -12428,7 +12428,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-librdmacm config.status 1.0.19.1
+librdmacm config.status 1.0.21
 configured by $0, generated by GNU Autoconf 2.67,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 0f5390e..768e257 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
 dnl Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.63])
-AC_INIT([librdmacm],[1.0.19.1],[linux-rdma at vger.kernel.org])
+AC_INIT([librdmacm],[1.0.21],[linux-rdma at vger.kernel.org])
 AC_CONFIG_SRCDIR([src/cma.c])
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_MACRO_DIR(config)
diff --git a/examples/rping.c b/examples/rping.c
index 949cbe6..9486314 100644
--- a/examples/rping.c
+++ b/examples/rping.c
@@ -277,15 +277,20 @@ static int rping_cq_event_handler(struct rping_cb *cb)
 	struct ibv_wc wc;
 	struct ibv_recv_wr *bad_wr;
 	int ret;
+	int flushed = 0;
 
 	while ((ret = ibv_poll_cq(cb->cq, 1, &wc)) == 1) {
 		ret = 0;
 
 		if (wc.status) {
-			if (wc.status != IBV_WC_WR_FLUSH_ERR)
-				fprintf(stderr,
-					"cq completion failed status %d\n",
-					wc.status);
+			if (wc.status == IBV_WC_WR_FLUSH_ERR) {
+				flushed = 1;
+				continue;
+
+			}
+			fprintf(stderr,
+				"cq completion failed status %d\n",
+				wc.status);
 			ret = -1;
 			goto error;
 		}
@@ -334,7 +339,7 @@ static int rping_cq_event_handler(struct rping_cb *cb)
 		fprintf(stderr, "poll error %d\n", ret);
 		goto error;
 	}
-	return 0;
+	return flushed;
 
 error:
 	cb->state = ERROR;
@@ -788,7 +793,11 @@ static void *rping_persistent_server_thread(void *arg)
 		goto err2;
 	}
 
-	pthread_create(&cb->cqthread, NULL, cq_thread, cb);
+	ret = pthread_create(&cb->cqthread, NULL, cq_thread, cb);
+	if (ret) {
+		perror("pthread_create");
+		goto err2;
+	}
 
 	ret = rping_accept(cb);
 	if (ret) {
@@ -820,11 +829,27 @@ static int rping_run_persistent_server(struct rping_cb *listening_cb)
 {
 	int ret;
 	struct rping_cb *cb;
+	pthread_attr_t attr;
 
 	ret = rping_bind_server(listening_cb);
 	if (ret)
 		return ret;
 
+	/*
+	 * Set persistent server threads to DEATCHED state so
+	 * they release all their resources when they exit.
+	 */
+	ret = pthread_attr_init(&attr);
+	if (ret) {
+		perror("pthread_attr_init");
+		return ret;
+	}
+	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+	if (ret) {
+		perror("pthread_attr_setdetachstate");
+		return ret;
+	}
+
 	while (1) {
 		sem_wait(&listening_cb->sem);
 		if (listening_cb->state != CONNECT_REQUEST) {
@@ -836,7 +861,12 @@ static int rping_run_persistent_server(struct rping_cb *listening_cb)
 		cb = clone_cb(listening_cb);
 		if (!cb)
 			return -1;
-		pthread_create(&cb->persistent_server_thread, NULL, rping_persistent_server_thread, cb);
+
+		ret = pthread_create(&cb->persistent_server_thread, &attr, rping_persistent_server_thread, cb);
+		if (ret) {
+			perror("pthread_create");
+			return ret;
+		}
 	}
 	return 0;
 }
@@ -875,7 +905,11 @@ static int rping_run_server(struct rping_cb *cb)
 		goto err2;
 	}
 
-	pthread_create(&cb->cqthread, NULL, cq_thread, cb);
+	ret = pthread_create(&cb->cqthread, NULL, cq_thread, cb);
+	if (ret) {
+		perror("pthread_create");
+		goto err2;
+	}
 
 	ret = rping_accept(cb);
 	if (ret) {
@@ -1050,23 +1084,28 @@ static int rping_run_client(struct rping_cb *cb)
 		goto err2;
 	}
 
-	pthread_create(&cb->cqthread, NULL, cq_thread, cb);
+	ret = pthread_create(&cb->cqthread, NULL, cq_thread, cb);
+	if (ret) {
+		perror("pthread_create");
+		goto err2;
+	}
 
 	ret = rping_connect_client(cb);
 	if (ret) {
 		fprintf(stderr, "connect error %d\n", ret);
-		goto err2;
+		goto err3;
 	}
 
 	ret = rping_test_client(cb);
 	if (ret) {
 		fprintf(stderr, "rping client failed: %d\n", ret);
-		goto err3;
+		goto err4;
 	}
 
 	ret = 0;
-err3:
+err4:
 	rdma_disconnect(cb->cm_id);
+err3:
 	pthread_join(cb->cqthread, NULL);
 err2:
 	rping_free_buffers(cb);
@@ -1216,7 +1255,11 @@ int main(int argc, char *argv[])
 	}
 	DEBUG_LOG("created cm_id %p\n", cb->cm_id);
 
-	pthread_create(&cb->cmthread, NULL, cm_thread, cb);
+	ret = pthread_create(&cb->cmthread, NULL, cm_thread, cb);
+	if (ret) {
+		perror("pthread_create");
+		goto out2;
+	}
 
 	if (cb->server) {
 		if (persistent_server)
diff --git a/examples/rstream.c b/examples/rstream.c
index 05598a8..d93e9aa 100644
--- a/examples/rstream.c
+++ b/examples/rstream.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2012 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2014-2015 Mellanox Technologies LTD. All rights reserved.
  *
  * This software is available to you under the OpenIB.org BSD license
  * below:
@@ -401,8 +402,8 @@ static int server_connect(void)
 
 static int client_connect(void)
 {
-	struct rdma_addrinfo *rai = NULL;
-	struct addrinfo *ai;
+	struct rdma_addrinfo *rai = NULL, *rai_src = NULL;
+	struct addrinfo *ai, *ai_src;
 	struct pollfd fds;
 	int ret, err;
 	socklen_t len;
@@ -415,6 +416,20 @@ static int client_connect(void)
 		return ret;
 	}
 
+	if (src_addr) {
+		if (use_rgai) {
+			rai_hints.ai_flags |= RAI_PASSIVE;
+			ret = rdma_getaddrinfo(src_addr, port, &rai_hints, &rai_src);
+		} else {
+			ai_hints.ai_flags |= RAI_PASSIVE;
+			ret = getaddrinfo(src_addr, port, &ai_hints, &ai_src);
+		}
+		if (ret) {
+			perror("getaddrinfo src_addr");
+			return ret;
+		}
+	}
+
 	rs = rai ? rs_socket(rai->ai_family, SOCK_STREAM, 0) :
 		   rs_socket(ai->ai_family, SOCK_STREAM, 0);
 	if (rs < 0) {
@@ -424,7 +439,15 @@ static int client_connect(void)
 	}
 
 	set_options(rs);
-	/* TODO: bind client to src_addr */
+
+	if (src_addr) {
+		ret = rai ? rs_bind(rs, rai_src->ai_src_addr, rai_src->ai_src_len) :
+			    rs_bind(rs, ai_src->ai_addr, ai_src->ai_addrlen);
+		if (ret) {
+			perror("rbind");
+			goto close;
+		}
+	}
 
 	if (rai && rai->ai_route) {
 		ret = rs_setsockopt(rs, SOL_RDMA, RDMA_ROUTE, rai->ai_route,
diff --git a/librdmacm.spec b/librdmacm.spec
index a2e0ab5..101f77f 100644
--- a/librdmacm.spec
+++ b/librdmacm.spec
@@ -1,7 +1,7 @@
-%define ver 1.0.19.1
+%define ver 1.0.21
 
 Name: librdmacm
-Version: 1.0.19.1
+Version: 1.0.21
 Release: 1%{?dist}
 Summary: Userspace RDMA Connection Manager
 
diff --git a/librdmacm.spec.in b/librdmacm.spec.in
index 81dca99..53a39e6 100644
--- a/librdmacm.spec.in
+++ b/librdmacm.spec.in
@@ -1,7 +1,7 @@
 %define ver @VERSION@
 
 Name: librdmacm
-Version: 1.0.19.1
+Version: 1.0.21
 Release: 1%{?dist}
 Summary: Userspace RDMA Connection Manager
 
diff --git a/src/cma.c b/src/cma.c
index 749140e..3e6262c 100644
--- a/src/cma.c
+++ b/src/cma.c
@@ -49,6 +49,7 @@
 #include <stddef.h>
 #include <netdb.h>
 #include <syslog.h>
+#include <limits.h>
 
 #include "cma.h"
 #include "indexer.h"
@@ -73,10 +74,15 @@ do {						\
 	(req)->response = (uintptr_t) (resp);	\
 } while (0)
 
+struct cma_port {
+	uint8_t			link_layer;
+};
+
 struct cma_device {
 	struct ibv_context *verbs;
 	struct ibv_pd	   *pd;
 	struct ibv_xrcd    *xrcd;
+	struct cma_port    *port;
 	uint64_t	    guid;
 	int		    port_cnt;
 	int		    refcnt;
@@ -142,6 +148,7 @@ static void ucma_cleanup(void)
 			if (cma_dev_array[cma_dev_cnt].refcnt)
 				ibv_dealloc_pd(cma_dev_array[cma_dev_cnt].pd);
 			ibv_close_device(cma_dev_array[cma_dev_cnt].verbs);
+			free(cma_dev_array[cma_dev_cnt].port);
 			cma_init_cnt--;
 		}
 
@@ -166,17 +173,12 @@ static int check_abi_version(void)
 		 * backports, assume the most recent version of the ABI.  If
 		 * we're wrong, we'll simply fail later when calling the ABI.
 		 */
-		fprintf(stderr, PFX "Warning: couldn't read ABI version.\n");
-		fprintf(stderr, PFX "Warning: assuming: %d\n", abi_ver);
 		return 0;
 	}
 
 	abi_ver = strtol(value, NULL, 10);
 	if (abi_ver < RDMA_USER_CM_MIN_ABI_VERSION ||
 	    abi_ver > RDMA_USER_CM_MAX_ABI_VERSION) {
-		fprintf(stderr, PFX "Fatal: kernel ABI version %d "
-				"doesn't match library version %d.\n",
-				abi_ver, RDMA_USER_CM_MAX_ABI_VERSION);
 		return -1;
 	}
 	return 0;
@@ -230,13 +232,11 @@ int ucma_init(void)
 
 	dev_list = ibv_get_device_list(&dev_cnt);
 	if (!dev_list) {
-		fprintf(stderr, PFX "Fatal: unable to get RDMA device list\n");
 		ret = ERR(ENODEV);
 		goto err1;
 	}
 
 	if (!dev_cnt) {
-		fprintf(stderr, PFX "Fatal: no RDMA devices found\n");
 		ret = ERR(ENODEV);
 		goto err2;
 	}
@@ -272,7 +272,6 @@ static struct ibv_context *ucma_open_device(uint64_t guid)
 
 	dev_list = ibv_get_device_list(NULL);
 	if (!dev_list) {
-		fprintf(stderr, PFX "Fatal: unable to get RDMA device list\n");
 		return NULL;
 	}
 
@@ -283,17 +282,15 @@ static struct ibv_context *ucma_open_device(uint64_t guid)
 		}
 	}
 
-	if (!verbs)
-		fprintf(stderr, PFX "Fatal: unable to open RDMA device\n");
-
 	ibv_free_device_list(dev_list);
 	return verbs;
 }
 
 static int ucma_init_device(struct cma_device *cma_dev)
 {
+	struct ibv_port_attr port_attr;
 	struct ibv_device_attr attr;
-	int ret;
+	int i, ret;
 
 	if (cma_dev->verbs)
 		return 0;
@@ -304,11 +301,23 @@ static int ucma_init_device(struct cma_device *cma_dev)
 
 	ret = ibv_query_device(cma_dev->verbs, &attr);
 	if (ret) {
-		fprintf(stderr, PFX "Fatal: unable to query RDMA device\n");
 		ret = ERR(ret);
 		goto err;
 	}
 
+	cma_dev->port = malloc(sizeof *cma_dev->port * attr.phys_port_cnt);
+	if (!cma_dev->port) {
+		ret = ERR(ENOMEM);
+		goto err;
+	}
+
+	for (i = 1; i <= attr.phys_port_cnt; i++) {
+		if (ibv_query_port(cma_dev->verbs, i, &port_attr))
+			cma_dev->port[i - 1].link_layer = IBV_LINK_LAYER_UNSPECIFIED;
+		else
+			cma_dev->port[i - 1].link_layer = port_attr.link_layer;
+	}
+
 	cma_dev->port_cnt = attr.phys_port_cnt;
 	cma_dev->max_qpsize = attr.max_qp_wr;
 	cma_dev->max_initiator_depth = (uint8_t) attr.max_qp_init_rd_atom;
@@ -389,7 +398,6 @@ struct rdma_event_channel *rdma_create_event_channel(void)
 
 	channel->fd = open("/dev/infiniband/rdma_cm", O_RDWR | O_CLOEXEC);
 	if (channel->fd < 0) {
-		fprintf(stderr, PFX "Fatal: unable to open /dev/infiniband/rdma_cm\n");
 		goto err;
 	}
 	return channel;
@@ -1034,8 +1042,10 @@ static int rdma_init_qp_attr(struct rdma_cm_id *id, struct ibv_qp_attr *qp_attr,
 
 static int ucma_modify_qp_rtr(struct rdma_cm_id *id, uint8_t resp_res)
 {
+	struct cma_id_private *id_priv;
 	struct ibv_qp_attr qp_attr;
 	int qp_attr_mask, ret;
+	uint8_t link_layer;
 
 	if (!id->qp)
 		return ERR(EINVAL);
@@ -1055,6 +1065,16 @@ static int ucma_modify_qp_rtr(struct rdma_cm_id *id, uint8_t resp_res)
 	if (ret)
 		return ret;
 
+	/*
+	 * Workaround for rdma_ucm kernel bug:
+	 * mask off qp_attr_mask bits 21-24 which are used for RoCE
+	 */
+	id_priv = container_of(id, struct cma_id_private, id);
+	link_layer = id_priv->cma_dev->port[id->port_num - 1].link_layer;
+
+	if (link_layer == IBV_LINK_LAYER_INFINIBAND)
+		qp_attr_mask &= UINT_MAX ^ 0xe00000;
+
 	if (resp_res != RDMA_MAX_RESP_RES)
 		qp_attr.max_dest_rd_atomic = resp_res;
 	return rdma_seterrno(ibv_modify_qp(id->qp, &qp_attr, qp_attr_mask));
diff --git a/src/indexer.c b/src/indexer.c
index f9042f5..be2e69c 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -151,7 +151,6 @@ int idm_set(struct index_map *idm, int index, void *item)
 
 	entry = idm->array[idx_array_index(index)];
 	entry[idx_entry_index(index)] = item;
-	idm->count[idx_array_index(index)]++;
 	return index;
 }
 
@@ -163,9 +162,5 @@ void *idm_clear(struct index_map *idm, int index)
 	entry = idm->array[idx_array_index(index)];
 	item = entry[idx_entry_index(index)];
 	entry[idx_entry_index(index)] = NULL;
-	if (--idm->count[idx_array_index(index)] == 0) {
-		free(idm->array[idx_array_index(index)]);
-		idm->array[idx_array_index(index)] = NULL;
-	}
 	return item;
 }
diff --git a/src/indexer.h b/src/indexer.h
index fc8eae2..0c5f388 100644
--- a/src/indexer.h
+++ b/src/indexer.h
@@ -85,7 +85,6 @@ static inline void *idx_at(struct indexer *idx, int index)
 struct index_map
 {
 	void **array[IDX_ARRAY_SIZE];
-	int count[IDX_ARRAY_SIZE];
 };
 
 int idm_set(struct index_map *idm, int index, void *item);
diff --git a/src/preload.c b/src/preload.c
index fb2149b..e7822ae 100644
--- a/src/preload.c
+++ b/src/preload.c
@@ -50,6 +50,9 @@
 #include <netinet/tcp.h>
 #include <unistd.h>
 #include <semaphore.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
 
 #include <rdma/rdma_cma.h>
 #include <rdma/rdma_verbs.h>
@@ -122,6 +125,136 @@ struct fd_info {
 	atomic_t refcnt;
 };
 
+struct config_entry {
+	char *name;
+	int domain;
+	int type;
+	int protocol;
+};
+
+static struct config_entry *config;
+static int config_cnt;
+extern char *program_invocation_short_name;
+
+
+static void free_config(void)
+{
+	while (config_cnt)
+		free(config[--config_cnt].name);
+
+	free(config);
+}
+
+/*
+ * Config file format:
+ * # Starting '#' indicates comment
+ * # wild card values are supported using '*'
+ * # domain - *, INET, INET6, IB
+ * # type - *, STREAM, DGRAM
+ * # protocol - *, TCP, UDP
+ * program_name domain type protocol
+ */
+static void scan_config(void)
+{
+	struct config_entry *new_config;
+	FILE *fp;
+	char line[120], prog[64], dom[16], type[16], proto[16];
+
+	fp = fopen(RS_CONF_DIR "/preload_config", "r");
+	if (!fp)
+		return;
+
+	while (fgets(line, sizeof(line), fp)) {
+		if (line[0] == '#')
+			continue;
+
+		if (sscanf(line, "%64s%16s%16s%16s", prog, dom, type, proto) != 4)
+			continue;
+
+		new_config = realloc(config, (config_cnt + 1) *
+					     sizeof(struct config_entry));
+		if (!new_config)
+			break;
+
+		config = new_config;
+		memset(&config[config_cnt], 0, sizeof(struct config_entry));
+
+		if (!strcasecmp(dom, "INET") ||
+		    !strcasecmp(dom, "AF_INET") ||
+		    !strcasecmp(dom, "PF_INET")) {
+			config[config_cnt].domain = AF_INET;
+		} else if (!strcasecmp(dom, "INET6") ||
+			   !strcasecmp(dom, "AF_INET6") ||
+			   !strcasecmp(dom, "PF_INET6")) {
+			config[config_cnt].domain = AF_INET6;
+		} else if (!strcasecmp(dom, "IB") ||
+			   !strcasecmp(dom, "AF_IB") ||
+			   !strcasecmp(dom, "PF_IB")) {
+			config[config_cnt].domain = AF_IB;
+		} else if (strcmp(dom, "*")) {
+			continue;
+		}
+
+		if (!strcasecmp(type, "STREAM") ||
+		    !strcasecmp(type, "SOCK_STREAM")) {
+			config[config_cnt].type = SOCK_STREAM;
+		} else if (!strcasecmp(type, "DGRAM") ||
+			   !strcasecmp(type, "SOCK_DGRAM")) {
+			config[config_cnt].type = SOCK_DGRAM;
+		} else if (strcmp(type, "*")) {
+			continue;
+		}
+
+		if (!strcasecmp(proto, "TCP") ||
+		    !strcasecmp(proto, "IPPROTO_TCP")) {
+			config[config_cnt].protocol = IPPROTO_TCP;
+		} else if (!strcasecmp(proto, "UDP") ||
+			   !strcasecmp(proto, "IPPROTO_UDP")) {
+			config[config_cnt].protocol = IPPROTO_UDP;
+		} else if (strcmp(proto, "*")) {
+			continue;
+		}
+
+		if (strcmp(prog, "*")) {
+		    if (!(config[config_cnt].name = strdup(prog)))
+			    continue;
+		}
+
+		config_cnt++;
+	}
+
+	fclose(fp);
+	if (config_cnt)
+		atexit(free_config);
+}
+
+static int intercept_socket(int domain, int type, int protocol)
+{
+	int i;
+
+	if (!config_cnt)
+		return 1;
+
+	if (!protocol) {
+		if (type == SOCK_STREAM)
+			protocol = IPPROTO_TCP;
+		else if (type == SOCK_DGRAM)
+			protocol = IPPROTO_UDP;
+	}
+
+	for (i = 0; i < config_cnt; i++) {
+		if ((!config[i].name ||
+		     !strncasecmp(config[i].name, program_invocation_short_name,
+				  strlen(config[i].name))) &&
+		    (!config[i].domain || config[i].domain == domain) &&
+		    (!config[i].type || config[i].type == type) &&
+		    (!config[i].protocol || config[i].protocol == protocol))
+			return 1;
+	}
+
+	return 0;
+}
+
 static int fd_open(void)
 {
 	struct fd_info *fdi;
@@ -308,6 +441,7 @@ static void init_preload(void)
 	rs.fcntl = dlsym(RTLD_DEFAULT, "rfcntl");
 
 	getenv_options();
+	scan_config();
 	init = 1;
 out:
 	pthread_mutex_unlock(&mut);
@@ -404,10 +538,11 @@ int socket(int domain, int type, int protocol)
 	static __thread int recursive;
 	int index, ret;
 
-	if (recursive)
+	init_preload();
+
+	if (recursive || !intercept_socket(domain, type, protocol))
 		goto real;
 
-	init_preload();
 	index = fd_open();
 	if (index < 0)
 		return index;
diff --git a/src/rsocket.c b/src/rsocket.c
index 7007897..95d791c 100644
--- a/src/rsocket.c
+++ b/src/rsocket.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2013 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2008-2014 Intel Corporation.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -352,7 +352,7 @@ struct rsocket {
 	};
 
 	int		  opts;
-	long		  fd_flags;
+	int		  fd_flags;
 	uint64_t	  so_opts;
 	uint64_t	  ipv6_opts;
 	void		  *optval;
@@ -381,6 +381,7 @@ struct rsocket {
 	dlist_entry	  iomap_list;
 	dlist_entry	  iomap_queue;
 	int		  iomap_pending;
+	int		  unack_cqe;
 };
 
 #define DS_UDP_TAG 0x55555555
@@ -609,7 +610,7 @@ static struct rsocket *rs_alloc(struct rsocket *inherited_rs, int type)
 	return rs;
 }
 
-static int rs_set_nonblocking(struct rsocket *rs, long arg)
+static int rs_set_nonblocking(struct rsocket *rs, int arg)
 {
 	struct ds_qp *qp;
 	int ret = 0;
@@ -838,10 +839,6 @@ static int rs_create_ep(struct rsocket *rs)
 	rs_set_qp_size(rs);
 	if (rs->cm_id->verbs->device->transport_type == IBV_TRANSPORT_IWARP)
 		rs->opts |= RS_OPT_MSG_SEND;
-	ret = rs_init_bufs(rs);
-	if (ret)
-		return ret;
-
 	ret = rs_create_cq(rs, rs->cm_id);
 	if (ret)
 		return ret;
@@ -866,6 +863,10 @@ static int rs_create_ep(struct rsocket *rs)
 	if ((rs->opts & RS_OPT_MSG_SEND) && (rs->sq_inline < RS_MSG_SIZE))
 		return ERR(ENOTSUP);
 
+	ret = rs_init_bufs(rs);
+	if (ret)
+		return ret;
+
 	for (i = 0; i < rs->rq_size; i++) {
 		ret = rs_post_recv(rs);
 		if (ret)
@@ -967,9 +968,6 @@ static void rs_free(struct rsocket *rs)
 		return;
 	}
 
-	if (rs->index >= 0)
-		rs_remove(rs);
-
 	if (rs->rmsg)
 		free(rs->rmsg);
 
@@ -993,11 +991,16 @@ static void rs_free(struct rsocket *rs)
 
 	if (rs->cm_id) {
 		rs_free_iomappings(rs);
-		if (rs->cm_id->qp)
+		if (rs->cm_id->qp) {
+			ibv_ack_cq_events(rs->cm_id->recv_cq, rs->unack_cqe);
 			rdma_destroy_qp(rs->cm_id);
+		}
 		rdma_destroy_id(rs->cm_id);
 	}
 
+	if (rs->index >= 0)
+		rs_remove(rs);
+
 	fastlock_destroy(&rs->map_lock);
 	fastlock_destroy(&rs->cq_wait_lock);
 	fastlock_destroy(&rs->cq_lock);
@@ -1174,9 +1177,14 @@ int rlisten(int socket, int backlog)
 	rs = idm_lookup(&idm, socket);
 	if (!rs)
 		return ERR(EBADF);
-	ret = rdma_listen(rs->cm_id, backlog);
-	if (!ret)
-		rs->state = rs_listening;
+
+	if (rs->state != rs_listening) {
+		ret = rdma_listen(rs->cm_id, backlog);
+		if (!ret)
+			rs->state = rs_listening;
+	} else {
+		ret = 0;
+	}
 	return ret;
 }
 
@@ -1965,9 +1973,12 @@ static int rs_get_cq_event(struct rsocket *rs)
 
 	ret = ibv_get_cq_event(rs->cm_id->recv_cq_channel, &cq, &context);
 	if (!ret) {
-		ibv_ack_cq_events(rs->cm_id->recv_cq, 1);
+		if (++rs->unack_cqe >= rs->sq_size + rs->rq_size) {
+			ibv_ack_cq_events(rs->cm_id->recv_cq, rs->unack_cqe);
+			rs->unack_cqe = 0;
+		}
 		rs->cq_armed = 0;
-	} else if (errno != EAGAIN) {
+	} else if (!(errno == EAGAIN || errno == EINTR)) {
 		rs->state = rs_error;
 	}
 
@@ -2383,7 +2394,7 @@ ssize_t rrecv(int socket, void *buf, size_t len, int flags)
 	struct rsocket *rs;
 	size_t left = len;
 	uint32_t end_size, rsize;
-	int ret;
+	int ret = 0;
 
 	rs = idm_at(&idm, socket);
 	if (rs->type == SOCK_DGRAM) {
@@ -2410,7 +2421,6 @@ ssize_t rrecv(int socket, void *buf, size_t len, int flags)
 				break;
 		}
 
-		ret = 0;
 		if (flags & MSG_PEEK) {
 			left = len - rs_peek(rs, buf, left);
 			break;
@@ -2445,7 +2455,7 @@ ssize_t rrecv(int socket, void *buf, size_t len, int flags)
 	} while (left && (flags & MSG_WAITALL) && (rs->state & rs_readable));
 
 	fastlock_release(&rs->rlock);
-	return ret ? ret : len - left;
+	return (ret && left == len) ? ret : len - left;
 }
 
 ssize_t rrecvfrom(int socket, void *buf, size_t len, int flags,
@@ -2954,19 +2964,22 @@ check_cq:
 
 	if (rs->state & rs_opening) {
 		ret = rs_do_connect(rs);
-		if (ret) {
-			if (errno == EINPROGRESS) {
-				errno = 0;
-				return 0;
-			} else {
-				return POLLOUT;
-			}
+		if (ret && (errno == EINPROGRESS)) {
+			errno = 0;
+		} else {
+			goto check_cq;
 		}
-		goto check_cq;
 	}
 
-	if (rs->state == rs_connect_error)
-		return (rs->err && events & POLLOUT) ? POLLOUT : 0;
+	if (rs->state == rs_connect_error) {
+		revents = 0;
+		if (events & POLLOUT)
+			revents |= POLLOUT;
+		if (events & POLLIN)
+			revents |= POLLIN;
+		revents |= POLLERR;
+		return revents;
+	}
 
 	return 0;
 }
@@ -3673,7 +3686,7 @@ int rfcntl(int socket, int cmd, ... /* arg */ )
 {
 	struct rsocket *rs;
 	va_list args;
-	long param;
+	int param;
 	int ret = 0;
 
 	rs = idm_lookup(&idm, socket);
@@ -3682,15 +3695,15 @@ int rfcntl(int socket, int cmd, ... /* arg */ )
 	va_start(args, cmd);
 	switch (cmd) {
 	case F_GETFL:
-		ret = (int) rs->fd_flags;
+		ret = rs->fd_flags;
 		break;
 	case F_SETFL:
-		param = va_arg(args, long);
-		if (param & O_NONBLOCK)
-			ret = rs_set_nonblocking(rs, O_NONBLOCK);
+		param = va_arg(args, int);
+		if ((rs->fd_flags & O_NONBLOCK) != (param & O_NONBLOCK))
+			ret = rs_set_nonblocking(rs, param & O_NONBLOCK);
 
 		if (!ret)
-			rs->fd_flags |= param;
+			rs->fd_flags = param;
 		break;
 	default:
 		ret = ERR(ENOTSUP);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ofed/librdmacm.git



More information about the Pkg-ofed-commits mailing list