From: Richard Purdie <rpurdie@openedhand.com>
To: Michael Buesch <mb@bu3sch.de>
Cc: Johannes Berg <johannes@sipsolutions.net>,
linux-wireless <linux-wireless@vger.kernel.org>,
Larry Finger <Larry.Finger@lwfinger.net>
Subject: Re: b43 problem with led trigger registration
Date: Sun, 16 Dec 2007 22:09:22 +0000 [thread overview]
Message-ID: <1197842962.4653.27.camel@localhost.localdomain> (raw)
In-Reply-To: <200712162157.00759.mb@bu3sch.de>
On Sun, 2007-12-16 at 21:57 +0100, Michael Buesch wrote:
> On Sunday 16 December 2007 21:43:19 Richard Purdie wrote:
> > On Sun, 2007-12-16 at 21:38 +0100, Johannes Berg wrote:
> > > > > drivers/leds/led-triggers.c:led_trigger_register:
> > > > >
> > > > > | read_lock(&leds_list_lock);
> > > > > | list_for_each_entry(led_cdev, &leds_list, node) {
> > > > > | down_write(&led_cdev->trigger_lock);
> > > > >
> > > > > introduced in
> > > > >
> > > > > commit dc47206e552c0850ad11f7e9a1fca0a3c92f5d65
> > > > > Author: Richard Purdie <rpurdie@rpsys.net>
> > > > > Date: Sat Nov 10 13:29:04 2007 +0000
> > > > >
> > > > > leds: Fix led trigger locking bugs
> > > > >
> > > > > I guess the read_lock needs to be a mutex/rw semaphore.
> > > >
> > > > Uh, yes. Was this patch tested at all?
> > >
> > > Not with default triggers, I guess. The code in question only triggers
> > > when a default is assigned to any LED I think.
> >
> > Amongst other things it was tested on the Zaurus which has default
> > triggers. What is the problem you're seeing?
>
> You are scheduling (down_write) while holding a spinlock (leds_list_lock).
Eeek, yes, its the LED core's fault.
dc47206e552c0850ad11f7e9a1fca0a3c92f5d65 is needed for various reasons
but that means the patch below is also needed. Its been compile tested,
once its runtime tested I'll push asap.
Richard
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index ba8b04b..64c66b3 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -106,9 +106,9 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
goto err_out;
/* add to the list of leds */
- write_lock(&leds_list_lock);
+ down_write(&leds_list_lock);
list_add_tail(&led_cdev->node, &leds_list);
- write_unlock(&leds_list_lock);
+ up_write(&leds_list_lock);
#ifdef CONFIG_LEDS_TRIGGERS
init_rwsem(&led_cdev->trigger_lock);
@@ -155,9 +155,9 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
device_unregister(led_cdev->dev);
- write_lock(&leds_list_lock);
+ down_write(&leds_list_lock);
list_del(&led_cdev->node);
- write_unlock(&leds_list_lock);
+ up_write(&leds_list_lock);
}
EXPORT_SYMBOL_GPL(led_classdev_unregister);
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index 9b015f9..5d1ca10 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -14,11 +14,11 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
-#include <linux/spinlock.h>
+#include <linux/rwsem.h>
#include <linux/leds.h>
#include "leds.h"
-DEFINE_RWLOCK(leds_list_lock);
+DECLARE_RWSEM(leds_list_lock);
LIST_HEAD(leds_list);
EXPORT_SYMBOL_GPL(leds_list);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 0bdb786..13c9026 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -169,7 +169,7 @@ int led_trigger_register(struct led_trigger *trigger)
up_write(&triggers_list_lock);
/* Register with any LEDs that have this as a default trigger */
- read_lock(&leds_list_lock);
+ down_read(&leds_list_lock);
list_for_each_entry(led_cdev, &leds_list, node) {
down_write(&led_cdev->trigger_lock);
if (!led_cdev->trigger && led_cdev->default_trigger &&
@@ -177,7 +177,7 @@ int led_trigger_register(struct led_trigger *trigger)
led_trigger_set(led_cdev, trigger);
up_write(&led_cdev->trigger_lock);
}
- read_unlock(&leds_list_lock);
+ up_read(&leds_list_lock);
return 0;
}
@@ -212,14 +212,14 @@ void led_trigger_unregister(struct led_trigger *trigger)
up_write(&triggers_list_lock);
/* Remove anyone actively using this trigger */
- read_lock(&leds_list_lock);
+ down_read(&leds_list_lock);
list_for_each_entry(led_cdev, &leds_list, node) {
down_write(&led_cdev->trigger_lock);
if (led_cdev->trigger == trigger)
led_trigger_set(led_cdev, NULL);
up_write(&led_cdev->trigger_lock);
}
- read_unlock(&leds_list_lock);
+ up_read(&leds_list_lock);
}
void led_trigger_unregister_simple(struct led_trigger *trigger)
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index f2f3884..12b6fe9 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -14,6 +14,7 @@
#define __LEDS_H_INCLUDED
#include <linux/device.h>
+#include <linux/rwsem.h>
#include <linux/leds.h>
static inline void led_set_brightness(struct led_classdev *led_cdev,
@@ -26,7 +27,7 @@ static inline void led_set_brightness(struct led_classdev *led_cdev,
led_cdev->brightness_set(led_cdev, value);
}
-extern rwlock_t leds_list_lock;
+extern struct rw_semaphore leds_list_lock;
extern struct list_head leds_list;
#ifdef CONFIG_LEDS_TRIGGERS
next prev parent reply other threads:[~2007-12-16 22:09 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-16 16:20 b43 problem with led trigger registration Johannes Berg
2007-12-16 17:19 ` Larry Finger
2007-12-16 17:59 ` Johannes Berg
2007-12-16 18:00 ` John W. Linville
2007-12-16 18:50 ` Johannes Berg
2007-12-16 19:36 ` Michael Buesch
2007-12-16 19:59 ` Johannes Berg
2007-12-16 20:26 ` Michael Buesch
2007-12-16 20:38 ` Johannes Berg
2007-12-16 20:43 ` Richard Purdie
2007-12-16 20:46 ` Johannes Berg
2007-12-16 20:57 ` Michael Buesch
2007-12-16 22:09 ` Richard Purdie [this message]
2007-12-16 22:17 ` Johannes Berg
2007-12-16 22:32 ` Richard Purdie
2007-12-16 22:39 ` Johannes Berg
2007-12-16 21:00 ` Johannes Berg
2007-12-16 21:16 ` Larry Finger
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=1197842962.4653.27.camel@localhost.localdomain \
--to=rpurdie@openedhand.com \
--cc=Larry.Finger@lwfinger.net \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
--cc=mb@bu3sch.de \
/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.