All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: stable-review@kernel.org, torvalds@linux-foundation.org,
	akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
	Srinivas Eeda <srinivas.eeda@oracle.com>,
	Sunil Mushran <sunil.mushran@oracle.com>,
	Joel Becker <joel.becker@oracle.com>
Subject: [09/59] ocfs2 fix o2dlm dlm run purgelist (rev 3)
Date: Tue, 24 Aug 2010 15:24:21 -0700	[thread overview]
Message-ID: <20100824222523.175807603@clark.site> (raw)
In-Reply-To: <20100824224625.GA5449@kroah.com>

2.6.32-stable review patch.  If anyone has any objections, please let us know.

------------------

From: Srinivas Eeda <srinivas.eeda@oracle.com>

commit 7beaf243787f85a2ef9213ccf13ab4a243283fde upstream.

This patch fixes two problems in dlm_run_purgelist

1. If a lockres is found to be in use, dlm_run_purgelist keeps trying to purge
the same lockres instead of trying the next lockres.

2. When a lockres is found unused, dlm_run_purgelist releases lockres spinlock
before setting DLM_LOCK_RES_DROPPING_REF and calls dlm_purge_lockres.
spinlock is reacquired but in this window lockres can get reused. This leads
to BUG.

This patch modifies dlm_run_purgelist to skip lockres if it's in use and purge
 next lockres. It also sets DLM_LOCK_RES_DROPPING_REF before releasing the
lockres spinlock protecting it from getting reused.

Signed-off-by: Srinivas Eeda <srinivas.eeda@oracle.com>
Acked-by: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 fs/ocfs2/dlm/dlmthread.c |   80 +++++++++++++++++++----------------------------
 1 file changed, 34 insertions(+), 46 deletions(-)

--- a/fs/ocfs2/dlm/dlmthread.c
+++ b/fs/ocfs2/dlm/dlmthread.c
@@ -153,45 +153,25 @@ void dlm_lockres_calc_usage(struct dlm_c
 	spin_unlock(&dlm->spinlock);
 }
 
-static int dlm_purge_lockres(struct dlm_ctxt *dlm,
+static void dlm_purge_lockres(struct dlm_ctxt *dlm,
 			     struct dlm_lock_resource *res)
 {
 	int master;
 	int ret = 0;
 
-	spin_lock(&res->spinlock);
-	if (!__dlm_lockres_unused(res)) {
-		mlog(0, "%s:%.*s: tried to purge but not unused\n",
-		     dlm->name, res->lockname.len, res->lockname.name);
-		__dlm_print_one_lock_resource(res);
-		spin_unlock(&res->spinlock);
-		BUG();
-	}
-
-	if (res->state & DLM_LOCK_RES_MIGRATING) {
-		mlog(0, "%s:%.*s: Delay dropref as this lockres is "
-		     "being remastered\n", dlm->name, res->lockname.len,
-		     res->lockname.name);
-		/* Re-add the lockres to the end of the purge list */
-		if (!list_empty(&res->purge)) {
-			list_del_init(&res->purge);
-			list_add_tail(&res->purge, &dlm->purge_list);
-		}
-		spin_unlock(&res->spinlock);
-		return 0;
-	}
+	assert_spin_locked(&dlm->spinlock);
+	assert_spin_locked(&res->spinlock);
 
 	master = (res->owner == dlm->node_num);
 
-	if (!master)
-		res->state |= DLM_LOCK_RES_DROPPING_REF;
-	spin_unlock(&res->spinlock);
 
 	mlog(0, "purging lockres %.*s, master = %d\n", res->lockname.len,
 	     res->lockname.name, master);
 
 	if (!master) {
+		res->state |= DLM_LOCK_RES_DROPPING_REF;
 		/* drop spinlock...  retake below */
+		spin_unlock(&res->spinlock);
 		spin_unlock(&dlm->spinlock);
 
 		spin_lock(&res->spinlock);
@@ -209,31 +189,35 @@ static int dlm_purge_lockres(struct dlm_
 		mlog(0, "%s:%.*s: dlm_deref_lockres returned %d\n",
 		     dlm->name, res->lockname.len, res->lockname.name, ret);
 		spin_lock(&dlm->spinlock);
+		spin_lock(&res->spinlock);
 	}
 
-	spin_lock(&res->spinlock);
 	if (!list_empty(&res->purge)) {
 		mlog(0, "removing lockres %.*s:%p from purgelist, "
 		     "master = %d\n", res->lockname.len, res->lockname.name,
 		     res, master);
 		list_del_init(&res->purge);
-		spin_unlock(&res->spinlock);
 		dlm_lockres_put(res);
 		dlm->purge_count--;
-	} else
-		spin_unlock(&res->spinlock);
+	}
+
+	if (!__dlm_lockres_unused(res)) {
+		mlog(ML_ERROR, "found lockres %s:%.*s: in use after deref\n",
+		     dlm->name, res->lockname.len, res->lockname.name);
+		__dlm_print_one_lock_resource(res);
+		BUG();
+	}
 
 	__dlm_unhash_lockres(res);
 
 	/* lockres is not in the hash now.  drop the flag and wake up
 	 * any processes waiting in dlm_get_lock_resource. */
 	if (!master) {
-		spin_lock(&res->spinlock);
 		res->state &= ~DLM_LOCK_RES_DROPPING_REF;
 		spin_unlock(&res->spinlock);
 		wake_up(&res->wq);
-	}
-	return 0;
+	} else
+		spin_unlock(&res->spinlock);
 }
 
 static void dlm_run_purge_list(struct dlm_ctxt *dlm,
@@ -252,17 +236,7 @@ static void dlm_run_purge_list(struct dl
 		lockres = list_entry(dlm->purge_list.next,
 				     struct dlm_lock_resource, purge);
 
-		/* Status of the lockres *might* change so double
-		 * check. If the lockres is unused, holding the dlm
-		 * spinlock will prevent people from getting and more
-		 * refs on it -- there's no need to keep the lockres
-		 * spinlock. */
 		spin_lock(&lockres->spinlock);
-		unused = __dlm_lockres_unused(lockres);
-		spin_unlock(&lockres->spinlock);
-
-		if (!unused)
-			continue;
 
 		purge_jiffies = lockres->last_used +
 			msecs_to_jiffies(DLM_PURGE_INTERVAL_MS);
@@ -274,15 +248,29 @@ static void dlm_run_purge_list(struct dl
 			 * in tail order, we can stop at the first
 			 * unpurgable resource -- anyone added after
 			 * him will have a greater last_used value */
+			spin_unlock(&lockres->spinlock);
 			break;
 		}
 
+		/* Status of the lockres *might* change so double
+		 * check. If the lockres is unused, holding the dlm
+		 * spinlock will prevent people from getting and more
+		 * refs on it. */
+		unused = __dlm_lockres_unused(lockres);
+		if (!unused ||
+		    (lockres->state & DLM_LOCK_RES_MIGRATING)) {
+			mlog(0, "lockres %s:%.*s: is in use or "
+			     "being remastered, used %d, state %d\n",
+			     dlm->name, lockres->lockname.len,
+			     lockres->lockname.name, !unused, lockres->state);
+			list_move_tail(&dlm->purge_list, &lockres->purge);
+			spin_unlock(&lockres->spinlock);
+			continue;
+		}
+
 		dlm_lockres_get(lockres);
 
-		/* This may drop and reacquire the dlm spinlock if it
-		 * has to do migration. */
-		if (dlm_purge_lockres(dlm, lockres))
-			BUG();
+		dlm_purge_lockres(dlm, lockres);
 
 		dlm_lockres_put(lockres);
 



  parent reply	other threads:[~2010-08-24 22:53 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-24 22:46 [00/59] 2.6.32.21-stable review Greg KH
2010-08-24 22:24 ` [01/59] memstick: fix hangs on unexpected device removal in mspro_blk Greg KH
2010-08-24 22:24 ` [02/59] ASoC: Fix inverted mute controls for WM8580 Greg KH
2010-08-24 22:24 ` [03/59] ASoC: Remove DSP mode support for WM8776 Greg KH
2010-08-24 22:24 ` [04/59] ALSA: riptide - Fix detection / load of firmware files Greg KH
2010-08-24 22:24 ` [05/59] ALSA: emu10k1 - delay the PCM interrupts (add pcm_irq_delay parameter) Greg KH
2010-08-24 22:24 ` [06/59] ALSA: hda - Fix missing stream for second ADC on Realtek ALC260 HDA codec Greg KH
2010-08-24 22:24 ` [07/59] ocfs2: do not overwrite error codes in ocfs2_init_acl Greg KH
2010-08-24 22:24 ` [08/59] ocfs2/dlm: fix a dead lock Greg KH
2010-08-24 22:24 ` Greg KH [this message]
2010-08-24 22:24 ` [10/59] ocfs2: Count more refcount records in file system fragmentation Greg KH
2010-08-24 22:24 ` [11/59] ocfs2/dlm: avoid incorrect bit set in refmap on recovery master Greg KH
2010-08-24 22:24 ` [12/59] ocfs2/dlm: remove potential deadlock -V3 Greg KH
2010-08-24 22:24 ` [13/59] x86, hotplug: Serialize CPU hotplug to avoid bringup concurrency issues Greg KH
2010-08-24 22:24 ` [14/59] x86, apic: Fix apic=debug boot crash Greg KH
2010-08-24 22:24 ` [15/59] Fix the nested PR lock calling issue in ACL Greg KH
2010-08-24 22:24 ` [16/59] hwmon: (pc87360) Fix device resource declaration Greg KH
2010-08-24 22:24 ` [17/59] ARM: Tighten check for allowable CPSR values Greg KH
2010-08-24 22:24 ` [18/59] nfs: Add "lookupcache" to displayed mount options Greg KH
2010-08-24 22:24 ` [19/59] ath5k: disable ASPM L0s for all cards Greg KH
2010-08-24 22:24 ` [20/59] pxa3xx: fix ns2cycle equation Greg KH
2010-08-24 22:24 ` [21/59] drm/i915/edp: Flush the write before waiting for PLLs Greg KH
2010-08-24 22:24 ` [22/59] dm mpath: fix NULL pointer dereference when path parameters missing Greg KH
2010-08-24 22:24 ` [23/59] dm ioctl: release _hash_lock between devices in remove_all Greg KH
2010-08-24 22:24 ` [24/59] mm: make the vma list be doubly linked Greg KH
2010-08-24 22:24 ` [25/59] mm: make the mlock() stack guard page checks stricter Greg KH
2010-08-24 22:24 ` [26/59] mm: make stack guard page logic use vm_prev pointer Greg KH
2010-08-24 22:24 ` [27/59] drm/i915: fix hibernation since i915 self-reclaim fixes Greg KH
2010-08-24 22:24 ` [28/59] drm/i915: add reclaimable to i915 self-reclaimable page allocations Greg KH
2010-08-24 22:24 ` [29/59] slab: fix object alignment Greg KH
2010-08-24 22:24 ` [30/59] sunxvr500: Ignore secondary output PCI devices Greg KH
2010-08-24 22:24 ` [31/59] sparc64: Add missing ID to parport probing code Greg KH
2010-08-24 22:24 ` [32/59] sparc64: Fix rwsem constant bug leading to hangs Greg KH
2010-08-24 22:24 ` [33/59] sparc64: Fix atomic64_t routine return values Greg KH
2010-08-24 22:24 ` [34/59] net: Fix a memmove bug in dev_gro_receive() Greg KH
2010-08-24 22:24 ` [35/59] can: add limit for nframes and clean up signed/unsigned variables Greg KH
2010-08-24 22:24 ` [36/59] isdn: fix information leak Greg KH
2010-08-24 22:24 ` [37/59] act_nat: the checksum of ICMP doesnt have pseudo header Greg KH
2010-08-24 22:24 ` [38/59] vmscan: raise the bar to PAGEOUT_IO_SYNC stalls Greg KH
2010-08-24 22:24 ` [39/59] pcmcia: avoid buffer overflow in pcmcia_setup_isa_irq Greg KH
2010-08-24 22:24 ` [40/59] ext4: consolidate in_range() definitions Greg KH
2010-08-24 22:24 ` [41/59] Oprofile: Change CPUIDS from decimal to hex, and add some comments Greg KH
2010-08-24 22:24 ` [42/59] oprofile: add support for Intel processor model 30 Greg KH
2010-08-24 22:24 ` [43/59] fixes for using make 3.82 Greg KH
2010-08-24 22:24 ` [44/59] ALSA: intel8x0: Mute External Amplifier by default for ThinkPad X31 Greg KH
2010-08-24 22:24 ` [45/59] netlink: fix compat recvmsg Greg KH
2010-08-24 22:24 ` [46/59] drm/radeon/kms: fix typo in radeon_compute_pll_gain Greg KH
2010-08-24 22:24 ` [47/59] drm: stop information leak of old kernel stack Greg KH
2010-08-24 22:25 ` [48/59] powerpc: Fix typo in uImage target Greg KH
2010-08-24 22:25 ` [49/59] powerpc: Initialise paca->kstack before early_setup_secondary Greg KH
2010-08-26  7:10   ` Matt Evans
2010-08-26 23:25     ` Greg KH
2010-08-24 22:25 ` [50/59] USB: option: add Celot CT-650 Greg KH
2010-08-24 22:25 ` [51/59] USB: add device IDs for igotu to navman Greg KH
2010-08-24 22:25 ` [52/59] USB: pl2303: New vendor and product id Greg KH
2010-08-24 22:25 ` [53/59] USB: CP210x Fix Break On/Off Greg KH
2010-08-24 22:25 ` [54/59] USB: ftdi_sio: fix endianess of max packet size Greg KH
2010-08-24 22:25 ` [55/59] USB: io_ti: check firmware version before updating Greg KH
2010-08-24 22:25 ` [56/59] USB: xhci: Remove buggy assignment in next_trb() Greg KH
2010-08-24 22:25 ` [57/59] USB: ftdi_sio: Add ID for Ionics PlugComputer Greg KH
2010-08-24 22:25 ` [58/59] USB: ftdi_sio: add product ID for Lenz LI-USB Greg KH
2010-08-24 22:25 ` [59/59] x86, apic: ack all pending irqs when crashed/on kexec Greg KH

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=20100824222523.175807603@clark.site \
    --to=gregkh@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=joel.becker@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=srinivas.eeda@oracle.com \
    --cc=stable-review@kernel.org \
    --cc=stable@kernel.org \
    --cc=sunil.mushran@oracle.com \
    --cc=torvalds@linux-foundation.org \
    /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.