summaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-30 14:14:25 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-30 14:14:25 +0200
commit7bc583d102d6f89c3dc4b502caec6ba03c9d318f (patch)
tree550e6333f2205f006849984b52408ed796bcd0c5 /drivers/base
parentMerge branch 'acpi-assorted' (diff)
parentACPI / hotplug: Remove containers synchronously (diff)
downloadlinux-7bc583d102d6f89c3dc4b502caec6ba03c9d318f.tar.xz
linux-7bc583d102d6f89c3dc4b502caec6ba03c9d318f.zip
Merge branch 'acpi-hotplug'
* acpi-hotplug: ACPI / hotplug: Remove containers synchronously driver core / ACPI: Avoid device hot remove locking issues
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c43
-rw-r--r--drivers/base/memory.c4
2 files changed, 31 insertions, 16 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 8856d74545d9..ac419a15fcd4 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -49,6 +49,28 @@ static struct kobject *dev_kobj;
struct kobject *sysfs_dev_char_kobj;
struct kobject *sysfs_dev_block_kobj;
+static DEFINE_MUTEX(device_hotplug_lock);
+
+void lock_device_hotplug(void)
+{
+ mutex_lock(&device_hotplug_lock);
+}
+
+void unlock_device_hotplug(void)
+{
+ mutex_unlock(&device_hotplug_lock);
+}
+
+int lock_device_hotplug_sysfs(void)
+{
+ if (mutex_trylock(&device_hotplug_lock))
+ return 0;
+
+ /* Avoid busy looping (5 ms of sleep should do). */
+ msleep(5);
+ return restart_syscall();
+}
+
#ifdef CONFIG_BLOCK
static inline int device_is_not_partition(struct device *dev)
{
@@ -408,9 +430,9 @@ static ssize_t show_online(struct device *dev, struct device_attribute *attr,
{
bool val;
- lock_device_hotplug();
+ device_lock(dev);
val = !dev->offline;
- unlock_device_hotplug();
+ device_unlock(dev);
return sprintf(buf, "%u\n", val);
}
@@ -424,7 +446,10 @@ static ssize_t store_online(struct device *dev, struct device_attribute *attr,
if (ret < 0)
return ret;
- lock_device_hotplug();
+ ret = lock_device_hotplug_sysfs();
+ if (ret)
+ return ret;
+
ret = val ? device_online(dev) : device_offline(dev);
unlock_device_hotplug();
return ret < 0 ? ret : count;
@@ -1479,18 +1504,6 @@ EXPORT_SYMBOL_GPL(put_device);
EXPORT_SYMBOL_GPL(device_create_file);
EXPORT_SYMBOL_GPL(device_remove_file);
-static DEFINE_MUTEX(device_hotplug_lock);
-
-void lock_device_hotplug(void)
-{
- mutex_lock(&device_hotplug_lock);
-}
-
-void unlock_device_hotplug(void)
-{
- mutex_unlock(&device_hotplug_lock);
-}
-
static int device_check_offline(struct device *dev, void *not_used)
{
int ret;
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 2b7813ec6d02..6f4c99ff1ce7 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -351,7 +351,9 @@ store_mem_state(struct device *dev,
mem = container_of(dev, struct memory_block, dev);
- lock_device_hotplug();
+ ret = lock_device_hotplug_sysfs();
+ if (ret)
+ return ret;
if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) {
offline = false;