[dm-devel] [PATCH 4/6] multipathd: allow uxlsnr clients to interrupt checking paths

Benjamin Marzinski bmarzins at redhat.com
Sat Jul 30 05:12:58 UTC 2022


The uxlsnr clients never block waiting on the vecs->lock. Instead they
register to get woken up and call trylock() when the lock is dropped.
Add code to track when they are registered to get woken up. The
checkerloop now checks if there are waiting uxlsnr clients as well.

Signed-off-by: Benjamin Marzinski <bmarzins at redhat.com>
---
 multipathd/main.c   |  3 ++-
 multipathd/uxlsnr.c | 20 +++++++++++++++-----
 multipathd/uxlsnr.h |  1 +
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/multipathd/main.c b/multipathd/main.c
index 73c95806..78374377 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -2647,7 +2647,8 @@ checkerloop (void *ap)
 					num_paths += rc;
 				if (++paths_checked % 128 == 0 &&
 				    check_id < INT_MAX &&
-				    lock_has_waiters(&vecs->lock)) {
+				    (lock_has_waiters(&vecs->lock) ||
+				     waiting_clients())) {
 					get_monotonic_time(&end_time);
 					timespecsub(&end_time, &chk_start_time,
 						    &diff_time);
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
index 645e356c..04bcd020 100644
--- a/multipathd/uxlsnr.c
+++ b/multipathd/uxlsnr.c
@@ -91,6 +91,7 @@ static LIST_HEAD(clients);
 static struct pollfd *polls;
 static int notify_fd = -1;
 static int idle_fd = -1;
+static bool clients_need_lock = false;
 
 static bool _socket_client_is_root(int fd)
 {
@@ -309,15 +310,22 @@ static struct timespec *get_soonest_timeout(struct timespec *ts)
 	return ts;
 }
 
-static bool need_vecs_lock(void)
+bool waiting_clients(void)
+{
+	return clients_need_lock;
+}
+
+static void check_for_locked_work(struct client *skip)
 {
 	struct client *c;
 
 	list_for_each_entry(c, &clients, node) {
-		if (c->state == CLT_LOCKED_WORK)
-			return true;
+		if (c != skip && c->state == CLT_LOCKED_WORK) {
+			clients_need_lock = true;
+			return;
+		}
 	}
-	return false;
+	clients_need_lock = false;
 }
 
 static int parse_cmd(struct client *c)
@@ -494,6 +502,7 @@ static int client_state_machine(struct client *c, struct vectors *vecs,
 			/* don't use cleanup_lock(), lest we wakeup ourselves */
 			pthread_cleanup_push_cast(__unlock, &vecs->lock);
 			c->error = execute_handler(c, vecs);
+			check_for_locked_work(c);
 			pthread_cleanup_pop(1);
 			condlog(4, "%s: cli[%d] grabbed lock", __func__, c->fd);
 			free_keys(c->cmdvec);
@@ -661,7 +670,8 @@ void *uxsock_listen(long ux_sock, void *trigger_data)
 			polls[POLLFD_NOTIFY].events = POLLIN;
 
 		polls[POLLFD_IDLE].fd = idle_fd;
-		if (need_vecs_lock())
+		check_for_locked_work(NULL);
+		if (clients_need_lock)
 			polls[POLLFD_IDLE].events = POLLIN;
 		else
 			polls[POLLFD_IDLE].events = 0;
diff --git a/multipathd/uxlsnr.h b/multipathd/uxlsnr.h
index 60c3a2c7..3e45930b 100644
--- a/multipathd/uxlsnr.h
+++ b/multipathd/uxlsnr.h
@@ -3,6 +3,7 @@
 
 #include <stdbool.h>
 
+bool waiting_clients(void);
 void uxsock_cleanup(void *arg);
 void *uxsock_listen(long ux_sock,
 		    void * trigger_data);
-- 
2.17.2



More information about the dm-devel mailing list