diff options
author | Mike Christie <michael.christie@oracle.com> | 2021-07-28 19:24:52 -0500 |
---|---|---|
committer | Mike Christie <michael.christie@oracle.com> | 2021-07-28 19:24:52 -0500 |
commit | 72949ef68220c47e0accfd9630d036c0473a5209 (patch) | |
tree | 47a97bf6c9b0b41fdd0c6de4f21d7cf338b12a81 | |
parent | 40ece0cae611d59061837fd423819cbe6628dacf (diff) | |
download | open-iscsi-prctl-flusher-support.tar.gz |
iscsid: set PR_SET_IO_FLUSHERprctl-flusher-support
When iscsid makes syscalls that lead to memory allocations the kernel
might use GFP_KERNEL. This can lead to pages being written to iscsi
disks managed by iscsid. If we are doing a syscall to try and reconnect
the session the disk is accessed through then we could deadlock.
When in the iscsi layer we can select our GFP flags but when making
syscalls to the network layer we have to set PR_SET_IO_FLUSHER so we
use the correct GFP flags.
Signed-off-by: Mike Christie <michael.christie@oracle.com>
-rw-r--r-- | usr/iscsid.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/usr/iscsid.c b/usr/iscsid.c index dc54fec..478c83d 100644 --- a/usr/iscsid.c +++ b/usr/iscsid.c @@ -34,6 +34,7 @@ #include <sys/wait.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/prctl.h> #ifndef NO_SYSTEMD #include <systemd/sd-daemon.h> #endif @@ -56,6 +57,10 @@ #include "iscsid_req.h" #include "iscsi_err.h" +#ifndef PR_SET_IO_FLUSHER +#define PR_SET_IO_FLUSHER 57 +#endif + /* global config info */ struct iscsi_daemon_config daemon_config; struct iscsi_daemon_config *dconfig = &daemon_config; @@ -616,6 +621,15 @@ int main(int argc, char *argv[]) exit(ISCSI_ERR); } + if (prctl(PR_SET_IO_FLUSHER, 1, 0, 0, 0) == -1) { + if (errno == EINVAL) { + log_info("prctl could not mark iscsid with the PR_SET_IO_FLUSHER flag, because the feature is not supported in this kernel. Will proceed, but iscsid may hang during session level recovery if memory is low.\n"); + } else { + log_error("prctl could not mark iscsid with the PR_SET_IO_FLUSHER flag due to error %s\n", + strerror(errno)); + } + } + set_state_to_ready(); event_loop(ipc, control_fd, mgmt_ipc_fd); |