From: Philip A. Prindeville <[email protected]>

Use RCU protection around a hook to allow ledtrig-ide-disk to instrument
itself into ide-disk without requiring static linkage.

Signed-off-by: Philip A. Prindeville <[email protected]>
---
 drivers/ide/ide-disk.c          |   15 ++++++++++++++-
 drivers/leds/Kconfig            |    3 ++-
 drivers/leds/ledtrig-ide-disk.c |    8 ++++++--
 include/linux/leds.h            |   10 +++++-----
 4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 2747980..de472ed 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -178,6 +178,10 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t 
*drive, struct request *rq,
  * 1073741822 == 549756 MB or 48bit addressing fake drive
  */
 
+void __rcu (*ide_activity_hook)(void) __read_mostly = NULL;
+
+EXPORT_SYMBOL(ide_activity_hook);
+
 static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
                                      sector_t block)
 {
@@ -186,7 +190,16 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, 
struct request *rq,
        BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED);
        BUG_ON(rq->cmd_type != REQ_TYPE_FS);
 
-       ledtrig_ide_activity();
+       {
+               void (*ide_activity)(void);
+
+               rcu_read_lock();
+               ide_activity = rcu_dereference(ide_activity_hook);
+
+               if (ide_activity)
+                       ide_activity();
+               rcu_read_unlock();
+       }
 
        pr_debug("%s: %sing: block=%llu, sectors=%u, buffer=0x%08lx\n",
                 drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 4a40561..26e5f03 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -411,7 +411,8 @@ config LEDS_TRIGGER_TIMER
          If unsure, say Y.
 
 config LEDS_TRIGGER_IDE_DISK
-       bool "LED IDE Disk Trigger"
+       tristate "LED IDE Disk Trigger"
+       depends on (TREE_RCU || TREE_PREEMPT_RCU || TINY_RCU || 
TINY_PREEMPT_TCU)
        depends on IDE_GD_ATA
        depends on LEDS_TRIGGERS
        help
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
index ec099fc..77a1f74 100644
--- a/drivers/leds/ledtrig-ide-disk.c
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -25,13 +25,12 @@ static DEFINE_TIMER(ledtrig_ide_timer, 
ledtrig_ide_timerfunc, 0, 0);
 static int ide_activity;
 static int ide_lastactivity;
 
-void ledtrig_ide_activity(void)
+static void ledtrig_ide_activity(void)
 {
        ide_activity++;
        if (!timer_pending(&ledtrig_ide_timer))
                mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
 }
-EXPORT_SYMBOL(ledtrig_ide_activity);
 
 static void ledtrig_ide_timerfunc(unsigned long data)
 {
@@ -48,11 +47,16 @@ static void ledtrig_ide_timerfunc(unsigned long data)
 static int __init ledtrig_ide_init(void)
 {
        led_trigger_register_simple("ide-disk", &ledtrig_ide);
+
+       rcu_assign_pointer(ide_activity_hook, ledtrig_ide_activity);
        return 0;
 }
 
 static void __exit ledtrig_ide_exit(void)
 {
+       rcu_assign_pointer(ide_activity_hook, NULL);
+       synchronize_rcu();
+
        led_trigger_unregister_simple(ledtrig_ide);
 }
 
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 61e0340..28571f2 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -160,11 +160,11 @@ extern void led_trigger_blink(struct led_trigger *trigger,
 
 #endif
 
-/* Trigger specific functions */
-#ifdef CONFIG_LEDS_TRIGGER_IDE_DISK
-extern void ledtrig_ide_activity(void);
-#else
-#define ledtrig_ide_activity() do {} while(0)
+#if defined(CONFIG_TINY_RCU) || defined(CONFIG_TINY_PREEMPT_RCU) \
+       || defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
+#include <linux/rcupdate.h>
+
+extern void __rcu (*ide_activity_hook)(void) __read_mostly;
 #endif
 
 /*
-- 
1.7.4.4

_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to