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;
next prev 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).