All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hannes Reinecke <hare@suse.de>
To: Christophe Varoqui <christophe.varoqui@gmail.com>
Cc: dm-devel@redhat.com, Mike Snitzer <snitzer@redhat.com>
Subject: [PATCH 56/57] multipathd: push down lock in checkerloop()
Date: Wed, 27 Apr 2016 13:10:57 +0200	[thread overview]
Message-ID: <1461755458-29225-57-git-send-email-hare@suse.de> (raw)
In-Reply-To: <1461755458-29225-1-git-send-email-hare@suse.de>

Instead of grabbing the lock at the start of the checkerloop
and releasing it at the end we should be holding it only
during the time when we actually need it.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 multipathd/main.c | 136 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 87 insertions(+), 49 deletions(-)

diff --git a/multipathd/main.c b/multipathd/main.c
index 41b5a49..132101f 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -416,7 +416,11 @@ uev_add_map (struct uevent * uev, struct vectors * vecs)
 			return 1;
 		}
 	}
+	pthread_cleanup_push(cleanup_lock, &vecs->lock);
+	lock(vecs->lock);
+	pthread_testcancel();
 	rc = ev_add_map(uev->kernel, alias, vecs);
+	lock_cleanup_pop(vecs->lock);
 	FREE(alias);
 	return rc;
 }
@@ -512,6 +516,10 @@ uev_remove_map (struct uevent * uev, struct vectors * vecs)
 		return 0;
 	}
 	minor = uevent_get_minor(uev);
+
+	pthread_cleanup_push(cleanup_lock, &vecs->lock);
+	lock(vecs->lock);
+	pthread_testcancel();
 	mpp = find_mp_by_minor(vecs->mpvec, minor);
 
 	if (!mpp) {
@@ -528,10 +536,12 @@ uev_remove_map (struct uevent * uev, struct vectors * vecs)
 	orphan_paths(vecs->pathvec, mpp);
 	remove_map_and_stop_waiter(mpp, vecs, 1);
 out:
+	lock_cleanup_pop(vecs->lock);
 	FREE(alias);
 	return 0;
 }
 
+/* Called from CLI handler */
 int
 ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs)
 {
@@ -567,6 +577,9 @@ uev_add_path (struct uevent *uev, struct vectors * vecs)
 		return 1;
 	}
 
+	pthread_cleanup_push(cleanup_lock, &vecs->lock);
+	lock(vecs->lock);
+	pthread_testcancel();
 	pp = find_path_by_dev(vecs->pathvec, uev->kernel);
 	if (pp) {
 		int r;
@@ -594,8 +607,10 @@ uev_add_path (struct uevent *uev, struct vectors * vecs)
 				ret = 1;
 			}
 		}
-		return ret;
 	}
+	lock_cleanup_pop(vecs->lock);
+	if (pp)
+		return ret;
 
 	/*
 	 * get path vital state
@@ -608,6 +623,9 @@ uev_add_path (struct uevent *uev, struct vectors * vecs)
 		condlog(3, "%s: failed to get path info", uev->kernel);
 		return 1;
 	}
+	pthread_cleanup_push(cleanup_lock, &vecs->lock);
+	lock(vecs->lock);
+	pthread_testcancel();
 	ret = store_path(vecs->pathvec, pp);
 	if (!ret) {
 		pp->checkint = conf->checkint;
@@ -619,7 +637,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs)
 		free_path(pp);
 		ret = 1;
 	}
-
+	lock_cleanup_pop(vecs->lock);
 	return ret;
 }
 
@@ -687,12 +705,12 @@ rescan:
 			 */
 			start_waiter = 1;
 		}
-		else
+		if (!start_waiter)
 			goto fail; /* leave path added to pathvec */
 	}
 
-	/* persistent reseravtion check*/
-	mpath_pr_event_handle(pp);	
+	/* persistent reservation check*/
+	mpath_pr_event_handle(pp);
 
 	/*
 	 * push the map to the device-mapper
@@ -720,7 +738,7 @@ retry:
 		 * deal with asynchronous uevents :((
 		 */
 		if (mpp->action == ACT_RELOAD && retries-- > 0) {
-			condlog(0, "%s: uev_add_path sleep", mpp->alias);
+			condlog(0, "%s: ev_add_path sleep", mpp->alias);
 			sleep(1);
 			update_mpp_paths(mpp, vecs->pathvec);
 			goto rescan;
@@ -749,8 +767,7 @@ retry:
 		condlog(2, "%s [%s]: path added to devmap %s",
 			pp->dev, pp->dev_t, mpp->alias);
 		return 0;
-	}
-	else
+	} else
 		goto fail;
 
 fail_map:
@@ -764,17 +781,22 @@ static int
 uev_remove_path (struct uevent *uev, struct vectors * vecs)
 {
 	struct path *pp;
+	int ret;
 
 	condlog(2, "%s: remove path (uevent)", uev->kernel);
+	pthread_cleanup_push(cleanup_lock, &vecs->lock);
+	lock(vecs->lock);
+	pthread_testcancel();
 	pp = find_path_by_dev(vecs->pathvec, uev->kernel);
-
+	if (pp)
+		ret = ev_remove_path(pp, vecs);
+	lock_cleanup_pop(vecs->lock);
 	if (!pp) {
 		/* Not an error; path might have been purged earlier */
 		condlog(0, "%s: path already removed", uev->kernel);
 		return 0;
 	}
-
-	return ev_remove_path(pp, vecs);
+	return ret;
 }
 
 int
@@ -877,35 +899,50 @@ static int
 uev_update_path (struct uevent *uev, struct vectors * vecs)
 {
 	int ro, retval = 0;
-	struct path * pp;
-
-	pp = find_path_by_dev(vecs->pathvec, uev->kernel);
-	if (!pp) {
-		condlog(0, "%s: spurious uevent, path not found",
-			uev->kernel);
-		return 1;
-	}
-
-	if (pp->initialized == INIT_REQUESTED_UDEV)
-		return uev_add_path(uev, vecs);
 
 	ro = uevent_get_disk_ro(uev);
 
 	if (ro >= 0) {
+		struct path * pp;
+		struct multipath *mpp = NULL;
+
 		condlog(2, "%s: update path write_protect to '%d' (uevent)",
 			uev->kernel, ro);
-		if (pp->mpp) {
-			if (pp->mpp->wait_for_udev) {
-				pp->mpp->wait_for_udev = 2;
-				return 0;
+		pthread_cleanup_push(cleanup_lock, &vecs->lock);
+		lock(vecs->lock);
+		pthread_testcancel();
+		/*
+		 * pthread_mutex_lock() and pthread_mutex_unlock()
+		 * need to be at the same indentation level, hence
+		 * this slightly convoluted codepath.
+		 */
+		pp = find_path_by_dev(vecs->pathvec, uev->kernel);
+		if (pp) {
+			if (pp->initialized == INIT_REQUESTED_UDEV) {
+				retval = 2;
+			} else {
+				mpp = pp->mpp;
+				if (mpp && mpp->wait_for_udev) {
+					mpp->wait_for_udev = 2;
+					mpp = NULL;
+					retval = 0;
+				}
 			}
+			if (mpp) {
+				retval = reload_map(vecs, mpp, 0);
 
-			retval = reload_map(vecs, pp->mpp, 0);
-
-			condlog(2, "%s: map %s reloaded (retval %d)",
-				uev->kernel, pp->mpp->alias, retval);
+				condlog(2, "%s: map %s reloaded (retval %d)",
+					uev->kernel, mpp->alias, retval);
+			}
 		}
-
+		lock_cleanup_pop(vecs->lock);
+		if (!pp) {
+			condlog(0, "%s: spurious uevent, path not found",
+				uev->kernel);
+			return 1;
+		}
+		if (retval == 2)
+			return uev_add_path(uev, vecs);
 	}
 
 	return retval;
@@ -1002,10 +1039,6 @@ uev_trigger (struct uevent * uev, void * trigger_data)
 	if (running_state == DAEMON_SHUTDOWN)
 		return 0;
 
-	pthread_cleanup_push(cleanup_lock, &vecs->lock);
-	lock(vecs->lock);
-	pthread_testcancel();
-
 	/*
 	 * device map event
 	 * Add events are ignored here as the tables
@@ -1044,7 +1077,6 @@ uev_trigger (struct uevent * uev, void * trigger_data)
 	}
 
 out:
-	lock_cleanup_pop(vecs->lock);
 	return r;
 }
 
@@ -1627,17 +1659,6 @@ checkerloop (void *ap)
 
 		if (gettimeofday(&start_time, NULL) != 0)
 			start_time.tv_sec = 0;
-
-		rc = set_config_state(DAEMON_RUNNING);
-		if (rc == ETIMEDOUT) {
-			condlog(4, "timeout waiting for DAEMON_IDLE");
-			continue;
-		}
-
-		pthread_cleanup_push(cleanup_lock, &vecs->lock);
-		lock(vecs->lock);
-		pthread_testcancel();
-		strict_timing = conf->strict_timing;
 		if (start_time.tv_sec && last_time.tv_sec) {
 			timersub(&start_time, &last_time, &diff_time);
 			condlog(4, "tick (%lu.%06lu secs)",
@@ -1653,28 +1674,45 @@ checkerloop (void *ap)
 		if (use_watchdog)
 			sd_notify(0, "WATCHDOG=1");
 #endif
+		rc = set_config_state(DAEMON_RUNNING);
+		if (rc == ETIMEDOUT) {
+			condlog(4, "timeout waiting for DAEMON_IDLE");
+			continue;
+		}
+		strict_timing = conf->strict_timing;
 		if (vecs->pathvec) {
+			pthread_cleanup_push(cleanup_lock, &vecs->lock);
+			lock(vecs->lock);
+			pthread_testcancel();
 			vector_foreach_slot (vecs->pathvec, pp, i) {
 				num_paths += check_path(vecs, pp, ticks);
 			}
+			lock_cleanup_pop(vecs->lock);
 		}
 		if (vecs->mpvec) {
+			pthread_cleanup_push(cleanup_lock, &vecs->lock);
+			lock(vecs->lock);
+			pthread_testcancel();
 			defered_failback_tick(vecs->mpvec);
 			retry_count_tick(vecs->mpvec);
 			missing_uev_wait_tick(vecs);
+			lock_cleanup_pop(vecs->lock);
 		}
 		if (count)
 			count--;
 		else {
+			pthread_cleanup_push(cleanup_lock, &vecs->lock);
+			lock(vecs->lock);
+			pthread_testcancel();
 			condlog(4, "map garbage collection");
 			mpvec_garbage_collector(vecs);
 			count = MAPGCINT;
+			lock_cleanup_pop(vecs->lock);
 		}
 
-		lock_cleanup_pop(vecs->lock);
 		diff_time.tv_usec = 0;
 		if (start_time.tv_sec &&
-		    gettimeofday(&end_time, NULL)) {
+		    gettimeofday(&end_time, NULL) == 0) {
 			timersub(&end_time, &start_time, &diff_time);
 			if (num_paths) {
 				condlog(3, "checked %d path%s in %lu.%06lu secs",
-- 
2.6.6

  parent reply	other threads:[~2016-04-27 11:10 UTC|newest]

Thread overview: 114+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-27 11:10 [PATCH 00/57] SLES resync Hannes Reinecke
2016-04-27 11:10 ` [PATCH 01/57] kpartx: Fixup persistent name generation Hannes Reinecke
2016-04-27 11:10 ` [PATCH 02/57] kpartx: handle more than 256 loop devices Hannes Reinecke
2016-04-27 11:10 ` [PATCH 03/57] kpartx: parse emulated DASD devices Hannes Reinecke
2016-04-27 11:10 ` [PATCH 04/57] kpartx: Install rules file with correct prefix Hannes Reinecke
2016-04-27 11:10 ` [PATCH 05/57] Add HP MSA 2040 to the hardware table Hannes Reinecke
2016-04-28 22:06   ` Sebastian Herbszt
2016-04-29  5:55     ` Hannes Reinecke
2016-05-01 21:30       ` Sebastian Herbszt
2016-06-09 14:20       ` Xose Vazquez Perez
2016-06-10  6:17         ` Hannes Reinecke
2016-06-10 14:30           ` Xose Vazquez Perez
2016-06-11 10:06             ` Hannes Reinecke
2016-04-27 11:10 ` [PATCH 06/57] Use ALUA for HP 3PAR Hannes Reinecke
2016-04-28 22:25   ` Sebastian Herbszt
2016-04-29  5:58     ` Hannes Reinecke
2016-05-01 21:46       ` Sebastian Herbszt
2016-04-27 11:10 ` [PATCH 07/57] Add LIO-ORG/SUSE RBD backend hardware defaults Hannes Reinecke
2016-04-28 22:32   ` Sebastian Herbszt
2016-04-27 11:10 ` [PATCH 08/57] Allow for empty SCSI revision Hannes Reinecke
2016-04-27 11:10 ` [PATCH 09/57] libmultipath: Do not use 'sscanf' for parsing integers Hannes Reinecke
2016-04-27 11:10 ` [PATCH 10/57] libmultipath: finally fix dev_loss_tmo setting Hannes Reinecke
2016-04-27 11:10 ` [PATCH 11/57] multipathd: fixup queueing mode in 'show maps status' Hannes Reinecke
2016-04-27 11:10 ` [PATCH 12/57] multipathd: fixup a crash when invoking CLI commands Hannes Reinecke
2016-04-27 11:10 ` [PATCH 13/57] multipathd: print error message for invalid arguments Hannes Reinecke
2016-04-27 11:10 ` [PATCH 14/57] libmultipath: correctly initialize pp->sg_id Hannes Reinecke
2016-04-27 11:10 ` [PATCH 15/57] libmultipath: correctly display checker status Hannes Reinecke
2016-04-27 11:10 ` [PATCH 16/57] libmultipath: call get_uid() for all paths Hannes Reinecke
2016-04-27 11:10 ` [PATCH 17/57] libmultipath: additional logging messages when formatting callout Hannes Reinecke
2016-04-27 11:10 ` [PATCH 18/57] libmpathpersist: Fixup whitespaces in Makefile Hannes Reinecke
2016-04-27 11:10 ` [PATCH 19/57] multipathd: Do not print misleading message 'not found in pathvec' Hannes Reinecke
2016-05-02 15:40   ` Benjamin Marzinski
2016-05-03  5:47     ` Hannes Reinecke
2016-05-03  7:27       ` Christophe Varoqui
2016-04-27 11:10 ` [PATCH 20/57] multipathd: Do not update the paths vec when removing paths Hannes Reinecke
2016-04-29 22:39   ` Benjamin Marzinski
2016-05-02  5:48     ` Hannes Reinecke
2016-05-02 15:12       ` Benjamin Marzinski
2016-05-02 17:46         ` Hannes Reinecke
2016-04-27 11:10 ` [PATCH 21/57] libmultipath: avoid double semicolon in lock.h Hannes Reinecke
2016-04-27 11:10 ` [PATCH 22/57] multipath: use option '-i' when called from udev Hannes Reinecke
2016-05-02 15:31   ` Benjamin Marzinski
2016-05-03  5:44     ` Hannes Reinecke
2016-05-03  6:37       ` Christophe Varoqui
2016-05-03 14:14         ` Benjamin Marzinski
2016-05-03 14:39           ` Hannes Reinecke
2016-04-27 11:10 ` [PATCH 23/57] multipath: remove warning 'failed to get wwid' Hannes Reinecke
2016-05-02 15:43   ` Benjamin Marzinski
2016-05-03  5:48     ` Hannes Reinecke
2016-04-27 11:10 ` [PATCH 24/57] Add dependency on systemd-udevd.service Hannes Reinecke
2016-04-27 11:10 ` [PATCH 25/57] Load all device handler modules on startup Hannes Reinecke
2016-04-27 11:10 ` [PATCH 26/57] 11-dm-mpath.rules: Only import ID_FS_XXX variables if not set Hannes Reinecke
2016-04-27 11:10 ` [PATCH 27/57] Ensure multipathd is started before systemd-udev-trigger.service Hannes Reinecke
2016-04-27 11:10 ` [PATCH 28/57] libmultipath: use a shared lock to co-operate with udev Hannes Reinecke
2016-05-02 16:26   ` Benjamin Marzinski
2016-05-03  5:57     ` Hannes Reinecke
2016-05-03 14:27       ` Benjamin Marzinski
2016-05-03 14:38         ` Alasdair G Kergon
2016-05-03 14:47         ` Benjamin Marzinski
2016-05-03 15:31         ` Germano Percossi
2016-05-03 20:23           ` Benjamin Marzinski
2016-05-04 11:25             ` Germano Percossi
2016-04-27 11:10 ` [PATCH 29/57] Only filter for udev property if uid_attribute is present Hannes Reinecke
2016-04-27 11:10 ` [PATCH 30/57] multipathd: skip uninitialized devices during reconfiguration Hannes Reinecke
2016-05-02 19:14   ` Benjamin Marzinski
2016-05-03  6:04     ` Hannes Reinecke
2016-04-27 11:10 ` [PATCH 31/57] multipathd: improve uxlsnr Hannes Reinecke
2016-04-27 11:10 ` [PATCH 32/57] libmultipath: remove 'needsync' argument from dm_simplecmd_noflush Hannes Reinecke
2016-04-27 11:10 ` [PATCH 33/57] libmultipath: remove 'use_uuid' argument from dm_addmap() Hannes Reinecke
2016-04-27 11:10 ` [PATCH 34/57] Always set DM_UDEV_DISABLE_LIBRARY_FALLBACK Hannes Reinecke
2016-04-27 11:10 ` [PATCH 35/57] libmultipath: pass in cookie as argument for dm_simplecmd() Hannes Reinecke
2016-04-27 11:10 ` [PATCH 36/57] libmultipath: pass in 'cookie' as argument for dm_addmap() Hannes Reinecke
2016-05-02 22:23   ` Benjamin Marzinski
2016-05-03  6:24     ` Hannes Reinecke
2016-05-03  9:31     ` Hannes Reinecke
2016-05-03 14:39       ` Benjamin Marzinski
2016-05-03 14:43         ` Hannes Reinecke
2016-05-03 14:57           ` Benjamin Marzinski
2016-04-27 11:10 ` [PATCH 37/57] Remove 'udev_sync' argument from dm_simplecmd() Hannes Reinecke
2016-05-02 23:33   ` Benjamin Marzinski
2016-04-27 11:10 ` [PATCH 38/57] libmultipath: Fixup 'DM_DEVICE_RELOAD' handling Hannes Reinecke
2016-04-27 11:10 ` [PATCH 39/57] devmapper: do not flush I/O for DM_DEVICE_CREATE Hannes Reinecke
2016-04-27 11:10 ` [PATCH 40/57] libmultipath: fixup dm_rename to complete cookie on failure Hannes Reinecke
2016-05-03  1:16   ` Benjamin Marzinski
2016-04-27 11:10 ` [PATCH 41/57] multipathd: accept zero-size paths in ev_add_path() Hannes Reinecke
2016-04-27 11:10 ` [PATCH 42/57] Use multipath wwid if path wwid is empty Hannes Reinecke
2016-04-27 11:10 ` [PATCH 43/57] multipathd: set uxsock_timeout after reconfiguration Hannes Reinecke
2016-04-27 11:10 ` [PATCH 44/57] multipathd: Do not switch paths on empty multipath tables Hannes Reinecke
2016-04-27 11:10 ` [PATCH 45/57] libmultipath: remove 'get_info' argument for adopt_paths() Hannes Reinecke
2016-04-27 11:10 ` [PATCH 46/57] libmultipath: ensure 'dev_t' is set when store paths Hannes Reinecke
2016-04-27 11:10 ` [PATCH 47/57] libmultipath: sanity check on store_path() Hannes Reinecke
2016-04-27 11:10 ` [PATCH 48/57] dmparser: Use find_path_by_dev() Hannes Reinecke
2016-04-27 11:10 ` [PATCH 49/57] multipathd: do not flush maps on startup Hannes Reinecke
2016-05-03  2:30   ` Benjamin Marzinski
2016-05-03  6:35     ` Hannes Reinecke
2016-04-27 11:10 ` [PATCH 50/57] multipathd: strict loop timings Hannes Reinecke
2016-04-27 11:10 ` [PATCH 51/57] multipathd: Provide standard error description on cli failure Hannes Reinecke
2016-04-27 11:10 ` [PATCH 52/57] libmultipath: make 'dm_addmap' static Hannes Reinecke
2016-04-27 11:10 ` [PATCH 53/57] multipathd: implement 'show map $map format $fmt' Hannes Reinecke
2016-05-03 16:21   ` Benjamin Marzinski
2016-04-27 11:10 ` [PATCH 54/57] multipathd: Increase uxclnt timeout Hannes Reinecke
2016-04-27 11:10 ` [PATCH 55/57] multipathd: asynchronous configuration Hannes Reinecke
2016-05-03 18:23   ` Benjamin Marzinski
2016-05-03 18:25   ` Benjamin Marzinski
2016-05-04  6:47     ` Hannes Reinecke
2016-04-27 11:10 ` Hannes Reinecke [this message]
2016-05-03 22:17   ` [PATCH 56/57] multipathd: push down lock in checkerloop() Benjamin Marzinski
2016-05-03 23:24     ` Benjamin Marzinski
2016-05-04  6:40       ` Hannes Reinecke
2016-05-04  6:39     ` Hannes Reinecke
2016-04-27 11:10 ` [PATCH 57/57] Allow specific CLI commands to run unlocked Hannes Reinecke
2016-05-04  3:02   ` Benjamin Marzinski
2016-05-03  7:23 ` [PATCH 00/57] SLES resync Christophe Varoqui
2016-05-04  3:06 ` Benjamin Marzinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1461755458-29225-57-git-send-email-hare@suse.de \
    --to=hare@suse.de \
    --cc=christophe.varoqui@gmail.com \
    --cc=dm-devel@redhat.com \
    --cc=snitzer@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.