[Cluster-devel] cluster/group/dlm_controld deadlock.c

teigland at sourceware.org teigland at sourceware.org
Tue Aug 7 19:20:55 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	teigland at sourceware.org	2007-08-07 19:20:55

Modified files:
	group/dlm_controld: deadlock.c 

Log message:
	don't add the same transaction to a waitfor list more than once

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/group/dlm_controld/deadlock.c.diff?cvsroot=cluster&r1=1.2&r2=1.3

--- cluster/group/dlm_controld/deadlock.c	2007/08/06 21:50:26	1.2
+++ cluster/group/dlm_controld/deadlock.c	2007/08/07 19:20:54	1.3
@@ -732,7 +732,8 @@
 		return;
 	}
 
-	log_group(ls, "write_checkpoint: open ckpt handle %llx", (long long)h);
+	log_group(ls, "write_checkpoint: open ckpt handle %llx",
+		  (unsigned long long)h);
 	ls->lock_ckpt_handle = (uint64_t) h;
 
 	list_for_each_entry(r, &ls->resources, list) {
@@ -791,7 +792,7 @@
 	}
 	if (error != CPG_OK) {
 		log_error("cpg_mcast_joined error %d handle %llx",
-			  (int)error, (long long)h);
+			  (int)error, (unsigned long long)h);
 		disable_deadlock();
 		return -1;
 	}
@@ -1232,7 +1233,7 @@
 
 	if (waiting_lkb->trans->xid == granted_lkb->trans->xid) {
 		log_debug("waiting and granted same trans %llx",
-			  (long long)waiting_lkb->trans->xid);
+			  (unsigned long long)waiting_lkb->trans->xid);
 		return 0;
 	}
 
@@ -1240,19 +1241,35 @@
 				waiting_lkb->lock.rqmode);
 }
 
-/* TODO: don't add new waitfor trans if we're already waiting for the same
-   trans for another lock */
+static int in_waitfor(struct trans *tr, struct trans *add_tr)
+{
+	int i;
+
+	for (i = 0; i < tr->waitfor_alloc; i++) {
+		if (!tr->waitfor[i])
+			continue;
+		if (tr->waitfor[i] == add_tr)
+			return 1;
+	}
+	return 0;
+}
 
-static void add_waitfor(struct dlm_lkb *waiting_lkb,
+static void add_waitfor(struct lockspace *ls, struct dlm_lkb *waiting_lkb,
 			struct dlm_lkb *granted_lkb)
 {
-	struct trans *tr;
+	struct trans *tr = waiting_lkb->trans;
 	int old_alloc, i;
 
 	if (locks_compat(waiting_lkb, granted_lkb))
 		return;
 
-	tr = waiting_lkb->trans;
+	/* don't add the same trans to the waitfor list multiple times */
+	if (tr->waitfor_count && in_waitfor(tr, granted_lkb->trans)) {
+		log_group(ls, "trans %llx already waiting for trans %llx",
+			  (unsigned long long)tr->xid,
+			  (unsigned long long)granted_lkb->trans->xid);
+		return;
+	}
 
 	if (tr->waitfor_count == tr->waitfor_alloc) {
 		old_alloc = tr->waitfor_alloc;
@@ -1289,7 +1306,7 @@
 				if (granted_lkb->lock.status==DLM_LKSTS_WAITING)
 					continue;
 				/* granted_lkb status is GRANTED or CONVERT */
-				add_waitfor(waiting_lkb, granted_lkb);
+				add_waitfor(ls, waiting_lkb, granted_lkb);
 			}
 		}
 	}




More information about the Cluster-devel mailing list