@@ -1,5 +1,5 @@
.\" Licensed under the OpenIB.org BSD license (FreeBSD Variant) - See COPYING.md
-.TH "RSOCKET" 7 "2013-01-21" "librdmacm" "Librdmacm Programmer's Manual" librdmacm
+.TH "RSOCKET" 7 "2019-04-16" "librdmacm" "Librdmacm Programmer's Manual" librdmacm
.SH NAME
rsocket \- RDMA socket API
.SH SYNOPSIS
@@ -147,6 +147,10 @@ iomap_size - default size of remote iomapping table
.P
polling_time - default number of microseconds to poll for data before waiting
.P
+wake_up_interval - maximum number of milliseconds to block in poll.
+This value is used to safe guard against potential application hangs
+in rpoll().
+.P
All configuration files should contain a single integer value. Values may
be set by issuing a command similar to the following example.
.P
@@ -129,6 +129,7 @@ static uint16_t def_rqsize = 384;
static uint32_t def_mem = (1 << 17);
static uint32_t def_wmem = (1 << 17);
static uint32_t polling_time = 10;
+static int wake_up_interval = 2000;
/*
* Immediate data format is determined by the upper bits
@@ -543,6 +544,10 @@ static void rs_configure(void)
fclose(f);
}
+ if ((f = fopen(RS_CONF_DIR "/wake_up_interval", "r"))) {
+ failable_fscanf(f, "%d", &wake_up_interval);
+ fclose(f);
+ }
if ((f = fopen(RS_CONF_DIR "/inline_default", "r"))) {
failable_fscanf(f, "%hu", &def_inline);
fclose(f);
@@ -3259,7 +3264,7 @@ int rpoll(struct pollfd *fds, nfds_t nfds, int timeout)
struct pollfd *rfds;
uint64_t start_time;
uint32_t poll_time = 0;
- int ret;
+ int pollsleep, ret;
do {
ret = rs_poll_check(fds, nfds);
@@ -3288,10 +3293,13 @@ int rpoll(struct pollfd *fds, nfds_t nfds, int timeout)
timeout -= (int) ((rs_time_us() - start_time) / 1000);
if (timeout <= 0)
return 0;
+ pollsleep = min(timeout, wake_up_interval);
+ } else {
+ pollsleep = wake_up_interval;
}
- ret = poll(rfds, nfds + 1, timeout);
- if (ret <= 0) {
+ ret = poll(rfds, nfds + 1, pollsleep);
+ if (ret < 0) {
rs_poll_exit();
break;
}
The changes to rpoll to use a signaling fd to wake up blocked threads, combined with suspending polling while rsockets states may be changing _should_ prevent any threads from blocking indefinitely in rpoll() when a desired state change occurs. However, to be extra safe and proactive that we don't end up hanging an application, we periodically wake up any polling thread, so that it can recheck its rsocket states. This is simply a proactive measure to allow apps to make forward progress and not in response to any known issues. The sleeping interval is set to an arbitrary value of 2 seconds, but can be overridden using config files. Signed-off-by: Sean Hefty <sean.hefty@intel.com> --- librdmacm/man/rsocket.7.in | 6 +++++- librdmacm/rsocket.c | 14 +++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-)