diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 54d8b43574cc63a0851150b93fe8c79ffdf3a557..0050d6cbf4977b5dc0e35a31f6b7dfae488e7450 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -898,10 +898,7 @@ static inline int ss7_grab(struct dahdi_pvt *pvt, struct dahdi_ss7 *pri)
 	do {
 		res = ast_mutex_trylock(&pri->lock);
 		if (res) {
-			ast_mutex_unlock(&pvt->lock);
-			/* Release the lock and try again */
-			usleep(1);
-			ast_mutex_lock(&pvt->lock);
+			DEADLOCK_AVOIDANCE(&pvt->lock);
 		}
 	} while (res);
 	/* Then break the poll */
@@ -3755,9 +3752,7 @@ static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_ch
 
 	ast_channel_lock(c0);
 	while (ast_channel_trylock(c1)) {
-		ast_channel_unlock(c0);
-		usleep(1);
-		ast_channel_lock(c0);
+		CHANNEL_DEADLOCK_AVOIDANCE(c0);
 	}
 
 	p0 = c0->tech_pvt;
@@ -3927,9 +3922,7 @@ static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_ch
 		
 		ast_channel_lock(c0);
 		while (ast_channel_trylock(c1)) {
-			ast_channel_unlock(c0);
-			usleep(1);
-			ast_channel_lock(c0);
+			CHANNEL_DEADLOCK_AVOIDANCE(c0);
 		}
 
 		p0 = c0->tech_pvt;
@@ -4469,14 +4462,12 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
 						   the private structure -- not especially easy or clean */
 						while (p->subs[SUB_THREEWAY].owner && ast_channel_trylock(p->subs[SUB_THREEWAY].owner)) {
 							/* Yuck, didn't get the lock on the 3-way, gotta release everything and re-grab! */
-							ast_mutex_unlock(&p->lock);
-							ast_channel_unlock(ast);
-							usleep(1);
+							DLA_UNLOCK(&p->lock);
+							CHANNEL_DEADLOCK_AVOIDANCE(ast);
 							/* We can grab ast and p in that order, without worry.  We should make sure
 							   nothing seriously bad has happened though like some sort of bizarre double
 							   masquerade! */
-							ast_channel_lock(ast);
-							ast_mutex_lock(&p->lock);
+							DLA_LOCK(&p->lock);
 							if (p->owner != ast) {
 								ast_log(LOG_WARNING, "This isn't good...\n");
 								return NULL;
diff --git a/channels/chan_features.c b/channels/chan_features.c
index 65146f4635e80f16489022af48c57dd70a4a5a00..74e2d1698cafe45cc22be65f13511491020feb71 100644
--- a/channels/chan_features.c
+++ b/channels/chan_features.c
@@ -139,9 +139,7 @@ static void wakeup_sub(struct feature_pvt *p, int a)
 	for (;;) {
 		if (p->subs[a].owner) {
 			if (ast_mutex_trylock(&p->subs[a].owner->lock)) {
-				ast_mutex_unlock(&p->lock);
-				usleep(1);
-				ast_mutex_lock(&p->lock);
+				DEADLOCK_AVOIDANCE(&p->lock);
 			} else {
 				ast_queue_frame(p->subs[a].owner, &null);
 				ast_mutex_unlock(&p->subs[a].owner->lock);
diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index 9951d1240db2af14b4b124be2886bb4759ba4eb1..fc0c7f3c0e2040951bfcb3626ba091f7100483a1 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -304,9 +304,7 @@ static int oh323_simulate_dtmf_end(const void *data)
 		ast_mutex_lock(&pvt->lock);
 		/* Don't hold pvt lock while trying to lock the channel */
 		while(pvt->owner && ast_channel_trylock(pvt->owner)) {
-			ast_mutex_unlock(&pvt->lock);
-			usleep(1);
-			ast_mutex_lock(&pvt->lock);
+			DEADLOCK_AVOIDANCE(&pvt->lock);
 		}
 
 		if (pvt->owner) {
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index aeae13b70e55631040f6756380927d7d9c3fadb1..2432a6bb41f6a9fe42361fabfd95c52eb72ed245 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -2248,9 +2248,7 @@ retry:
 	if (owner) {
 		if (ast_channel_trylock(owner)) {
 			ast_debug(3, "Avoiding IAX destroy deadlock\n");
-			ast_mutex_unlock(&iaxsl[callno]);
-			usleep(1);
-			ast_mutex_lock(&iaxsl[callno]);
+			DEADLOCK_AVOIDANCE(&iaxsl[callno]);
 			goto retry;
 		}
 	}
diff --git a/channels/chan_local.c b/channels/chan_local.c
index aade7b2c256f0f51c5e7b2fb72a5e3438c802dab..0a1a1695dbaaaea4df79ab45eddb87afec456df8 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -219,15 +219,13 @@ static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_fra
 
 	/* Ensure that we have both channels locked */
 	while (other && ast_channel_trylock(other)) {
-		ast_mutex_unlock(&p->lock);
-		if (us && us_locked) {
-			ast_channel_unlock(us);
-		}
-		usleep(1);
+		DLA_UNLOCK(&p->lock);
 		if (us && us_locked) {
-			ast_channel_lock(us);
+			CHANNEL_DEADLOCK_AVOIDANCE(us);
+		} else {
+			usleep(1);
 		}
-		ast_mutex_lock(&p->lock);
+		DLA_LOCK(&p->lock);
 		other = isoutbound ? p->owner : p->chan;
 	}
 
diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h
index 3f261c6a37faef094d28631fa0b9dba91fa00686..4122978fb80cc77c63aee738011562348a59de85 100644
--- a/include/asterisk/lock.h
+++ b/include/asterisk/lock.h
@@ -289,6 +289,21 @@ int ast_find_lock_info(void *lock_addr, const char **filename, int *lineno, cons
 		} \
 	} while (0)
 
+#define DLA_UNLOCK(lock) \
+	do { \
+		const char *__filename, *__func, *__mutex_name; \
+		int __lineno; \
+		int __res = ast_find_lock_info(lock, &__filename, &__lineno, &__func, &__mutex_name); \
+		ast_mutex_unlock(lock);
+
+#define DLA_LOCK(lock) \
+		if (__res < 0) { /* Shouldn't ever happen, but just in case... */ \
+			ast_mutex_lock(lock); \
+		} else { \
+			__ast_pthread_mutex_lock(__filename, __lineno, __func, __mutex_name, lock); \
+		} \
+	} while (0)
+
 static inline void ast_reentrancy_lock(struct ast_lock_track *lt)
 {
 	pthread_mutex_lock(&lt->reentr_mutex);
@@ -1429,6 +1444,10 @@ static inline int _ast_rwlock_trywrlock(ast_rwlock_t *t, const char *name,
 	usleep(1); \
 	ast_mutex_unlock(lock);
 
+#define DLA_UNLOCK(lock)	ast_mutex_unlock(lock)
+
+#define DLA_LOCK(lock)	ast_mutex_lock(lock)
+
 typedef pthread_mutex_t ast_mutex_t;
 
 #define AST_MUTEX_INIT_VALUE			((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)