diff options
author | Simon Rettberg | 2022-02-12 23:56:35 +0100 |
---|---|---|
committer | Simon Rettberg | 2022-02-18 21:34:55 +0100 |
commit | eb2876f6542af2bfa47c7a6905ecc4f81f1d2ad3 (patch) | |
tree | 17ebb5fd2d4770a4dd67f857f2488221cd46874c /src/kernel/sysfs.c | |
parent | [KERNEL] Add missing include to fix compile on 4.14.x (diff) | |
download | dnbd3-eb2876f6542af2bfa47c7a6905ecc4f81f1d2ad3.tar.gz dnbd3-eb2876f6542af2bfa47c7a6905ecc4f81f1d2ad3.tar.xz dnbd3-eb2876f6542af2bfa47c7a6905ecc4f81f1d2ad3.zip |
[KERNEL] Refactor to use workqueues and blk-mq only
Using workqueues frees us from having to manage the lifecycle
of three dedicated threads. Discovery (alt server checks) and
sending keepalive packets is now done using work on the
power efficient system queue. Sending and receiving happens
via dedicated work queues with higher priority.
blk-mq has also been around for quite a while in the kernel,
so switching to it doesn't hurt backwards compatibility.
As the code is now refactored to work more as blk-mq is designed,
backwards compatibility even improved while at the same time
freeing us from an arsenal of macros that were required to make
the blk-mq port look and feel like the old implementation.
For example, the code now compiles on CentOS 7 with kernel 3.10
without requiring special macros to detect the heavily modified
RedHat kernel with all its backported features.
A few other design limitations have been rectified along the way,
e.g. switching to another server now doesn't internally disconnect
from the current one first, which theoretically could lead to a
non-working setup, if the new server isn't reachable and then -
because of some transient network error - switching back also
fails. As the discover-thread was torn down from the disconnect
call, the connection would also not repair itself eventually.
we now establish the new connection in parallel to the old one,
and only if that succeeds do we replace the old one with it,
similar to how the automatic alt-server switch already does it.
Diffstat (limited to 'src/kernel/sysfs.c')
-rw-r--r-- | src/kernel/sysfs.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/kernel/sysfs.c b/src/kernel/sysfs.c index 79bc21e..3e5febd 100644 --- a/src/kernel/sysfs.c +++ b/src/kernel/sysfs.c @@ -22,7 +22,6 @@ #include <linux/kobject.h> #include "sysfs.h" -#include "utils.h" #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -33,7 +32,12 @@ */ ssize_t show_cur_server_addr(char *buf, dnbd3_device_t *dev) { - return MIN(snprintf(buf, PAGE_SIZE, "%pISpc\n", &dev->cur_server.host), PAGE_SIZE); + ssize_t ret; + + spin_lock(&dev->blk_lock); + ret = MIN(snprintf(buf, PAGE_SIZE, "%pISpc\n", &dev->cur_server.host), PAGE_SIZE); + spin_unlock(&dev->blk_lock); + return ret; } /** @@ -42,7 +46,11 @@ ssize_t show_cur_server_addr(char *buf, dnbd3_device_t *dev) */ ssize_t show_alt_servers(char *buf, dnbd3_device_t *dev) { - int i, size = PAGE_SIZE, ret; + int i, size = PAGE_SIZE; + ssize_t ret; + + if (mutex_lock_interruptible(&dev->alt_servers_lock) != 0) + return 0; for (i = 0; i < NUMBER_SERVERS; ++i) { if (dev->alt_servers[i].host.ss_family == 0) @@ -63,6 +71,7 @@ ssize_t show_alt_servers(char *buf, dnbd3_device_t *dev) break; } } + mutex_unlock(&dev->alt_servers_lock); return PAGE_SIZE - size; } @@ -71,7 +80,12 @@ ssize_t show_alt_servers(char *buf, dnbd3_device_t *dev) */ ssize_t show_image_name(char *buf, dnbd3_device_t *dev) { - return MIN(snprintf(buf, PAGE_SIZE, "%s\n", dev->imgname), PAGE_SIZE); + ssize_t ret; + + spin_lock(&dev->blk_lock); + ret = MIN(snprintf(buf, PAGE_SIZE, "%s\n", dev->imgname), PAGE_SIZE); + spin_unlock(&dev->blk_lock); + return ret; } /** @@ -79,11 +93,13 @@ ssize_t show_image_name(char *buf, dnbd3_device_t *dev) */ ssize_t show_rid(char *buf, dnbd3_device_t *dev) { + // No locking here, primitive type, no pointer to allocated memory return MIN(snprintf(buf, PAGE_SIZE, "%d\n", dev->rid), PAGE_SIZE); } ssize_t show_update_available(char *buf, dnbd3_device_t *dev) { + // Same story return MIN(snprintf(buf, PAGE_SIZE, "%d\n", dev->update_available), PAGE_SIZE); } |