linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Kristian Høgsberg" <krh@bitplanet.net>
To: Ben Collins <bcollins@debian.org>
Cc: Andrew Morton <akpm@osdl.org>,
	kakadu_croc@yahoo.com, linux-kernel@vger.kernel.org,
	linux1394-devel@lists.sourceforge.net
Subject: Re: 2.6.0-test7-mm1
Date: Sat, 18 Oct 2003 14:39:39 +0200	[thread overview]
Message-ID: <3F91348B.5080102@bitplanet.net> (raw)
In-Reply-To: <20031016022547.GA615@phunnypharm.org>

[-- Attachment #1: Type: text/plain, Size: 1948 bytes --]

Ben Collins wrote:
> On Wed, Oct 15, 2003 at 10:53:59AM -0700, Andrew Morton wrote:
> 
>>Ben Collins <bcollins@debian.org> wrote:
>>
>>>>highlevel_add_host() does read_lock() and then proceeds to do things like
>>>
>>> > starting kernel threads under that lock.  The locking is pretty broken
>>> > in there :(
>>>
>>> No, highlevel_add_host() itself doesn't start any threads. But it does
>>> pass around data that needs to be locked from changes, and one of the
>>> handlers happens to start a thread, and other things allocate memory
>>> (such as this case).
>>>
>>> It's ugly, and I've been trying to clean it up. This case can be fixed
>>> quickly with a simple check in hpsb_create_hostinfo() to pass GFP_ATOMIC
>>> to kmalloc.
>>
>>nodemgr_add_host() looks like the hard one.  Maybe make hl_drivers_lock a
>>sleeping lock?
> 
> 
> Problem is, things like bus resets happen in interrupt, and while I can
> push off some things to occur in the nodemgr thread, a lot of other
> stuff has to happen in the interrupt, and they require the same lock.

I was looking briefly at this too, and as you say, the problem is that 
some things have to happen in interrupt, others happen in process 
context.  I've attached a patch that implements one way to fix it: 
double book-keeping - we maintain two lists of the highlevel drivers, 
one protected by a semaphore another protected by the rw spinlock. The 
lists are identical, except between the two list_add_tail()'s (and the 
two list_del()'s), but that doesn't allow any harmful race conditions.

A more radical approach would be to split the highlevel interface into 
two interfaces add_host() + remove_host() in a hpsb_host_notification 
interface and the rest in another interface.  The driver would have to 
register both interfaces if it needs them. Some drivers only use 
add_host() and remove_host(), so they could register only the 
hpsb_host_notification interface.

best regards,
Kristian

[-- Attachment #2: double-list-patch --]
[-- Type: text/plain, Size: 2789 bytes --]

Index: highlevel.c
===================================================================
--- highlevel.c	(revision 1073)
+++ highlevel.c	(working copy)
@@ -37,9 +37,18 @@
 };
 
 
+/* Double bookkeeping: hl_drivers and hl_sem_drivers are essentially
+ * the same lists, but hl_sem_list is protected by a semaphore and is
+ * used to notify highlevel drivers when we add and remove hosts. The
+ * other, hl_drivers is protected by an rw spinlock, and is used when
+ * we notify highlevel drivers of bus resets and incoming packets. */
+
 static LIST_HEAD(hl_drivers);
 static rwlock_t hl_drivers_lock = RW_LOCK_UNLOCKED;
 
+static LIST_HEAD(hl_sem_drivers);
+static DECLARE_MUTEX(hl_drivers_sem);
+
 static LIST_HEAD(addr_space);
 static rwlock_t addr_space_lock = RW_LOCK_UNLOCKED;
 
@@ -238,6 +247,10 @@
 
 	rwlock_init(&hl->host_info_lock);
 
+	down(&hl_drivers_sem);
+	list_add_tail(&hl->hl_sem_list, &hl_sem_drivers);
+	up(&hl_drivers_sem);
+
 	write_lock_irqsave(&hl_drivers_lock, flags);
         list_add_tail(&hl->hl_list, &hl_drivers);
 	write_unlock_irqrestore(&hl_drivers_lock, flags);
@@ -272,6 +285,10 @@
         list_del(&hl->hl_list);
 	write_unlock_irqrestore(&hl_drivers_lock, flags);
 
+	down(&hl_drivers_sem);
+	list_del(&hl->hl_sem_list);
+	up(&hl_drivers_sem);
+
         if (hl->remove_host) {
 		down(&hpsb_hosts_lock);
 		list_for_each(lh, &hpsb_hosts) {
@@ -391,33 +408,28 @@
 
 void highlevel_add_host(struct hpsb_host *host)
 {
-        struct list_head *entry;
         struct hpsb_highlevel *hl;
 
-        read_lock(&hl_drivers_lock);
-        list_for_each(entry, &hl_drivers) {
-                hl = list_entry(entry, struct hpsb_highlevel, hl_list);
+	down(&hl_drivers_sem);
+	list_for_each_entry(hl, &hl_sem_drivers, hl_sem_list) {
 		if (hl->add_host)
 			hl->add_host(host);
         }
-        read_unlock(&hl_drivers_lock);
+	up(&hl_drivers_sem);
 }
 
 void highlevel_remove_host(struct hpsb_host *host)
 {
-        struct list_head *entry;
         struct hpsb_highlevel *hl;
 
-	read_lock(&hl_drivers_lock);
-	list_for_each(entry, &hl_drivers) {
-                hl = list_entry(entry, struct hpsb_highlevel, hl_list);
-
+	down(&hl_drivers_sem);
+	list_for_each_entry(hl, &hl_sem_drivers, hl_sem_list) {
 		if (hl->remove_host) {
 			hl->remove_host(host);
 			hpsb_destroy_hostinfo(hl, host);
 		}
         }
-	read_unlock(&hl_drivers_lock);
+	up(&hl_drivers_sem);
 }
 
 void highlevel_host_reset(struct hpsb_host *host)
Index: highlevel.h
===================================================================
--- highlevel.h	(revision 1073)
+++ highlevel.h	(working copy)
@@ -56,6 +56,7 @@
                              int cts, u8 *data, size_t length);
 
 
+	struct list_head hl_sem_list;
 	struct list_head hl_list;
 	struct list_head addr_list;
 

  parent reply	other threads:[~2003-10-18 12:49 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-10-15 10:11 2.6.0-test7-mm1 Bradley Chapman
2003-10-15 10:22 ` 2.6.0-test7-mm1 Andrew Morton
2003-10-15 12:34   ` 2.6.0-test7-mm1 Bradley Chapman
2003-10-15 12:46     ` 2.6.0-test7-mm1 Tim Schmielau
2003-10-15 12:53       ` 2.6.0-test7-mm1 Bradley Chapman
2003-10-15 17:28     ` 2.6.0-test7-mm1 Andrew Morton
2003-10-15 17:40       ` 2.6.0-test7-mm1 Ben Collins
2003-10-15 17:53         ` 2.6.0-test7-mm1 Andrew Morton
2003-10-16  2:25           ` 2.6.0-test7-mm1 Ben Collins
2003-10-16 14:04             ` 2.6.0-test7-mm1 Anton Blanchard
2003-10-18 12:39             ` Kristian Høgsberg [this message]
2003-10-18 13:27               ` 2.6.0-test7-mm1 Ben Collins
2003-10-18 18:07                 ` This bug appears under 2.6.0-test8 as well (was: 2.6.0-test7-mm1) Bradley Chapman
2003-10-18 19:46                   ` Ben Collins
2003-10-27 20:13                     ` Mike Fedyk
2003-10-27 20:21                       ` Ben Collins
2003-10-15 21:14   ` 2.6.0-test7-mm1 Alexander Hoogerhuis
2003-10-15 21:44     ` 2.6.0-test7-mm1 Andrew Morton
     [not found] <20031016083124.45a171a5.akpm@osdl.org>
2003-10-17  7:03 ` 2.6.0-test7-mm1 Bradley Chapman
2003-10-17  7:25   ` 2.6.0-test7-mm1 Andrew Morton
2003-10-17  9:15     ` 2.6.0-test7-mm1 Russell King
  -- strict thread matches above, loose matches on Subject: below --
2003-10-16 14:44 2.6.0-test7-mm1 Steven Pratt
2003-10-16 14:58 ` 2.6.0-test7-mm1 Andrew Morton
2003-10-16 23:13   ` 2.6.0-test7-mm1 Steven Pratt
2003-10-17  7:23   ` 2.6.0-test7-mm1 Kirill Korotaev
2003-10-16 14:58 ` 2.6.0-test7-mm1 William Lee Irwin III
2003-10-19 14:16 ` 2.6.0-test7-mm1 Alexander Hoogerhuis
2003-10-15 12:17 2.6.0-test7-mm1 Jan Killius
2003-10-15  8:36 2.6.0-test7-mm1 Andrew Morton
2003-10-15 15:20 ` 2.6.0-test7-mm1 Luiz Capitulino
2003-10-15 15:42 ` 2.6.0-test7-mm1 Luiz Capitulino
2003-10-15 16:55   ` 2.6.0-test7-mm1 William Lee Irwin III
2003-10-15 21:40     ` 2.6.0-test7-mm1 William Lee Irwin III
2003-10-16 15:11       ` 2.6.0-test7-mm1 Luiz Capitulino
2003-10-17  8:58     ` 2.6.0-test7-mm1 Kirill Korotaev
2003-10-17  9:10       ` 2.6.0-test7-mm1 William Lee Irwin III
2003-10-17 12:02       ` 2.6.0-test7-mm1 Luiz Capitulino
2003-10-18 17:43 ` 2.6.0-test7-mm1 Thomas Schlichter
2003-10-18 17:50   ` 2.6.0-test7-mm1 Andrew Morton

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=3F91348B.5080102@bitplanet.net \
    --to=krh@bitplanet.net \
    --cc=akpm@osdl.org \
    --cc=bcollins@debian.org \
    --cc=kakadu_croc@yahoo.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux1394-devel@lists.sourceforge.net \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).