<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">Received: from mnm [127.0.0.1]
	by localhost with POP3 (fetchmail-5.9.0)
	for akpm@localhost (single-drop); Sat, 06 Mar 2004 05:45:35 -0800 (PST)
Received: from fire-2.osdl.org (air1.pdx.osdl.net [172.20.0.5])
	by mail.osdl.org (8.11.6/8.11.6) with ESMTP id i26DeME07198
	for &lt;akpm@mail.gateway.osdl.net&gt;; Sat, 6 Mar 2004 05:40:22 -0800
Received: from smtp.cistron-office.nl (mail@10fwd.cistron-office.nl [62.216.29.197])
	by fire-2.osdl.org (8.12.8/8.12.8) with ESMTP id i26DeK5q022022
	(version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO)
	for &lt;akpm@osdl.org&gt;; Sat, 6 Mar 2004 05:40:22 -0800
Received: from subspace.cistron-office.nl ([62.216.29.200])
	by smtp.cistron-office.nl with esmtp (Exim 3.35 #1 (Debian))
	id 1Azc2M-00078X-00; Sat, 06 Mar 2004 14:40:18 +0100
Received: from miquels by subspace.cistron-office.nl with local (Exim 3.35 #1 (Debian))
	id 1Azc2M-0003jd-00; Sat, 06 Mar 2004 14:40:18 +0100
Date: Sat, 6 Mar 2004 14:40:18 +0100
From: Miquel van Smoorenburg &lt;miquels@cistron.nl&gt;
To: Andrew Morton &lt;akpm@osdl.org&gt;
Cc: Joe Thornber &lt;thornber@redhat.com&gt;
Subject: Re: [PATCH] dm-rwlock.patch (Re: 2.6.4-rc1-mm1: queue-congestion-dm-implementation patch)
Message-ID: &lt;20040306134018.GA13030@cistron.nl&gt;
References: &lt;cistron.200403011400.51008.kevcorry@us.ibm.com&gt; &lt;20040302130137.GA9941@cistron.nl&gt; &lt;200403020826.52448.kevcorry@us.ibm.com&gt; &lt;20040303211624.GA11008@cistron.nl&gt; &lt;20040305135544.318de1a6.akpm@osdl.org&gt;
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: &lt;20040305135544.318de1a6.akpm@osdl.org&gt;
X-NCC-RegID: nl.cistron
User-Agent: Mutt/1.5.4i
Sender: Miquel van Smoorenburg &lt;miquels@subspace.cistron-office.nl&gt;
X-MIMEDefang-Filter: osdl$Revision: 1.55 $
X-Scanned-By: MIMEDefang 2.36
X-Spam-Checker-Version: SpamAssassin 2.60 (1.212-2003-09-23-exp) on mnm
X-Spam-Level: 
X-Spam-Status: No, hits=-4.9 required=2.0 tests=BAYES_00 autolearn=ham 
	version=2.60

According to Andrew Morton:
&gt; Miquel van Smoorenburg &lt;miquels@cistron.nl&gt; wrote:
&gt; &gt;
&gt; &gt; I posted a patch in the wrong thread earlier today, and the patch also
&gt; &gt; wasn't so good. This should be better, but I'll let Joe be the
&gt; &gt; judge of that. At least it survived my testing.
&gt; 
&gt; Joe just sent me a dm update which broke your patch big-time.
&gt; 
&gt; I've dropped a snapshot of my tree at
&gt; http://www.zipworld.com.au/~akpm/linux/patches/stuff/x.gz (against rc2). 
&gt; Would you have time to update and retest the rwlock patch?

Sure. I'm taking a new approach, since the rwlock patch was still
not correct - sleeping functions could still be called under
the rwlock, for example dm-crypt does that in its mapping function.
Fixing that would get way too complicated. So:

dm-maplock.patch

This patch adds a rwlock_t maplock to the struct mapped_device.
The -&gt;map member is only updated with that lock held. dm_any_congested
takes the lock, and so can be sure that the table under -&gt;map won't change.

This patch is much smaller and simpler than dm-rwlock.patch.

--- linux-2.6.4-rc2-mmX.orig/drivers/md/dm.c	2004-03-06 04:00:02.000000000 +0100
+++ linux-2.6.4-rc2-mmX/drivers/md/dm.c	2004-03-06 13:24:20.000000000 +0100
@@ -49,6 +49,7 @@
 
 struct mapped_device {
 	struct rw_semaphore lock;
+	rwlock_t maplock;
 	atomic_t holders;
 
 	unsigned long flags;
@@ -564,9 +565,12 @@
 	int r;
 	struct mapped_device *md = congested_data;
 
-	down_read(&amp;md-&gt;lock);
-	r = dm_table_any_congested(md-&gt;map, bdi_bits);
-	up_read(&amp;md-&gt;lock);
+	read_lock(&amp;md-&gt;maplock);
+	if (md-&gt;map == NULL || test_bit(DMF_BLOCK_IO, &amp;md-&gt;flags))
+		r = bdi_bits;
+	else
+		r = dm_table_any_congested(md-&gt;map, bdi_bits);
+	read_unlock(&amp;md-&gt;maplock);
 
 	return r;
 }
@@ -642,6 +646,7 @@
 
 	memset(md, 0, sizeof(*md));
 	init_rwsem(&amp;md-&gt;lock);
+	rwlock_init(&amp;md-&gt;maplock);
 	atomic_set(&amp;md-&gt;holders, 1);
 
 	md-&gt;queue = blk_alloc_queue(GFP_KERNEL);
@@ -741,7 +746,9 @@
 	if (size == 0)
 		return 0;
 
+	write_lock(&amp;md-&gt;maplock);
 	md-&gt;map = t;
+	write_unlock(&amp;md-&gt;maplock);
 	dm_table_event_callback(md-&gt;map, event_callback, md);
 
 	dm_table_get(t);
@@ -751,12 +758,16 @@
 
 static void __unbind(struct mapped_device *md)
 {
-	if (!md-&gt;map)
+	struct dm_table *map = md-&gt;map;
+
+	if (!map)
 		return;
 
-	dm_table_event_callback(md-&gt;map, NULL, NULL);
-	dm_table_put(md-&gt;map);
+	dm_table_event_callback(map, NULL, NULL);
+	write_lock(&amp;md-&gt;maplock);
 	md-&gt;map = NULL;
+	write_unlock(&amp;md-&gt;maplock);
+	dm_table_put(map);
 }
 
 /*
</pre></body></html>