From mboxrd@z Thu Jan 1 00:00:00 1970 From: teigland@sourceware.org Date: 7 Aug 2007 19:20:55 -0000 Subject: [Cluster-devel] cluster/group/dlm_controld deadlock.c Message-ID: <20070807192055.27267.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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); } } }