[PATCH v4 20/22] libmultipath: don't wait in libcheck_pending

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Disable waiting in the libcheck_pending() checker class functions.
Instead, they now just check if the checker has already completed.
A future patch will re-add waiting outside of libcheck_pending().

Reviewed-by: Martin Wilck <mwilck@xxxxxxxx>
Signed-off-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx>
---
 libmultipath/checkers/directio.c | 41 ++++++++++++++++----------------
 libmultipath/checkers/tur.c      | 20 +++-------------
 2 files changed, 23 insertions(+), 38 deletions(-)

diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c
index 4beed02e..f37b0d39 100644
--- a/libmultipath/checkers/directio.c
+++ b/libmultipath/checkers/directio.c
@@ -64,7 +64,6 @@ struct directio_context {
 	int		reset_flags;
 	struct aio_group *aio_grp;
 	struct async_req *req;
-	struct timespec endtime;
 	bool waited_for;
 };
 
@@ -291,18 +290,17 @@ get_events(struct aio_group *aio_grp, struct timespec *timeout)
 }
 
 static void
-check_pending(struct directio_context *ct, struct timespec endtime)
+check_pending(struct directio_context *ct, struct timespec timeout)
 {
 	int r;
-	struct timespec currtime, timeout;
+	struct timespec endtime, currtime;
 
 	ct->waited_for = true;
+	get_monotonic_time(&endtime);
+	endtime.tv_sec += timeout.tv_sec;
+	endtime.tv_nsec += timeout.tv_nsec;
+	normalize_timespec(&endtime);
 	while(1) {
-		get_monotonic_time(&currtime);
-		timespecsub(&endtime, &currtime, &timeout);
-		if (timeout.tv_sec < 0)
-			timeout.tv_sec = timeout.tv_nsec = 0;
-
 		r = get_events(ct->aio_grp, &timeout);
 
 		if (ct->req->state != PATH_PENDING) {
@@ -311,6 +309,10 @@ check_pending(struct directio_context *ct, struct timespec endtime)
 		} else if (r == 0 ||
 			   (timeout.tv_sec == 0 && timeout.tv_nsec == 0))
 			return;
+		get_monotonic_time(&currtime);
+		timespecsub(&endtime, &currtime, &timeout);
+		if (timeout.tv_sec < 0)
+			timeout.tv_sec = timeout.tv_nsec = 0;
 	}
 }
 
@@ -320,7 +322,7 @@ check_state(int fd, struct directio_context *ct, int sync, int timeout_secs)
 	struct stat	sb;
 	int		rc;
 	struct io_event event;
-	struct timespec endtime;
+	struct timespec timeout = { .tv_sec = timeout_secs };
 
 	if (fstat(fd, &sb) == 0) {
 		LOG(4, "called for %x", (unsigned) sb.st_rdev);
@@ -345,20 +347,13 @@ check_state(int fd, struct directio_context *ct, int sync, int timeout_secs)
 			LOG(3, "io_submit error %i", -rc);
 			return PATH_UNCHECKED;
 		}
-		get_monotonic_time(&ct->endtime);
-		ct->endtime.tv_nsec += 1000 * 1000;
-		normalize_timespec(&ct->endtime);
 		ct->waited_for = false;
 	}
 	ct->running++;
 	if (!sync)
 		return PATH_PENDING;
 
-	get_monotonic_time(&endtime);
-	endtime.tv_sec += timeout_secs;
-	normalize_timespec(&endtime);
-
-	check_pending(ct, endtime);
+	check_pending(ct, timeout);
 	if (ct->req->state != PATH_PENDING)
 		return ct->req->state;
 
@@ -401,13 +396,16 @@ int libcheck_pending(struct checker *c)
 	int rc;
 	struct io_event event;
 	struct directio_context *ct = (struct directio_context *)c->context;
+	struct timespec no_wait = { .tv_sec = 0 };
 
 	/* The if path checker isn't running, just return the exiting value. */
-	if (!ct || !ct->running)
-		return c->path_state;
+	if (!ct || !ct->running) {
+		rc = c->path_state;
+		goto out;
+	}
 
 	if (ct->req->state == PATH_PENDING)
-		check_pending(ct, ct->endtime);
+		check_pending(ct, no_wait);
 	else
 		ct->running = 0;
 	rc = ct->req->state;
@@ -420,8 +418,9 @@ int libcheck_pending(struct checker *c)
 		else
 			LOG(4, "async io pending");
 	}
-	set_msgid(c, rc);
 
+out:
+	set_msgid(c, rc);
 	return rc;
 }
 
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
index 41d6b9c3..5d606708 100644
--- a/libmultipath/checkers/tur.c
+++ b/libmultipath/checkers/tur.c
@@ -58,7 +58,6 @@ struct tur_checker_context {
 	int msgid;
 	struct checker_context ctx;
 	unsigned int nr_timeouts;
-	struct timespec endtime;
 	bool waited_for;
 };
 
@@ -299,14 +298,6 @@ void *libcheck_thread(struct checker_context *ctx)
 	return ((void *)0);
 }
 
-
-static void tur_timeout(struct timespec *tsp)
-{
-	get_monotonic_time(tsp);
-	tsp->tv_nsec += 1000 * 1000; /* 1 millisecond */
-	normalize_timespec(tsp);
-}
-
 static void tur_set_async_timeout(struct checker *c)
 {
 	struct tur_checker_context *ct = c->context;
@@ -328,16 +319,12 @@ static int tur_check_async_timeout(struct checker *c)
 int check_pending(struct checker *c)
 {
 	struct tur_checker_context *ct = c->context;
-	int r, tur_status = PATH_PENDING;
+	int tur_status = PATH_PENDING;
 
 	pthread_mutex_lock(&ct->lock);
 
-	for (r = 0;
-	     r == 0 && ct->state == PATH_PENDING &&
-	     ct->msgid == MSG_TUR_RUNNING;
-	     r = pthread_cond_timedwait(&ct->active, &ct->lock, &ct->endtime));
-
-	if (!r) {
+	if (ct->state != PATH_PENDING || ct->msgid != MSG_TUR_RUNNING)
+	{
 		tur_status = ct->state;
 		c->msgid = ct->msgid;
 	}
@@ -487,7 +474,6 @@ int libcheck_check(struct checker * c)
 				" sync mode", major(ct->devt), minor(ct->devt));
 			return tur_check(c->fd, c->timeout, &c->msgid);
 		}
-		tur_timeout(&ct->endtime);
 	}
 
 	return tur_status;
-- 
2.45.0





[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux