From 024440d2ec9712c077cd315de7ae6bc9f6f14f1b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 Mar 2008 14:47:13 -0800 Subject: driver core: fix up Kconfig text for CONFIG_SYSFS_DEPRECATED As things get moved into this config option, the hard date of 2006 does not work anymore, so update the text to be more descriptive. Cc: Kay Sievers Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- init/Kconfig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index f698a5af500..e6606e6e99e 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -382,10 +382,11 @@ config SYSFS_DEPRECATED If enabled, this option will also move any device structures that belong to a class, back into the /sys/class hierarchy, in - order to support older versions of udev. + order to support older versions of udev and some userspace + programs. - If you are using a distro that was released in 2006 or later, - it should be safe to say N here. + If you are using a distro with the most recent userspace + packages, it should be safe to say N here. config CGROUP_MEM_CONT bool "Memory controller for cgroups" -- cgit v1.2.3 From d47846c5866b7d98a1173c86a39d810a06647329 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 4 Mar 2008 14:54:47 +0100 Subject: sysfs: CONFIG_SYSFS_DEPRECATED fix CONFIG_SYSFS_DEPRECATED=y changed its meaning recently and causes regressions in working setups that had SYSFS_DEPRECATED disabled. so rename it to SYSFS_DEPRECATED_V2 so that testers pick up the new default via 'make oldconfig', even if their old .config's disabled CONFIG_SYSFS_DEPRECATED ... Signed-off-by: Ingo Molnar Cc: Kay Sievers Cc: Linus Torvalds Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- init/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/init/Kconfig b/init/Kconfig index e6606e6e99e..98ebf372541 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -367,9 +367,13 @@ config RESOURCE_COUNTERS depends on CGROUPS config SYSFS_DEPRECATED + bool + +config SYSFS_DEPRECATED_V2 bool "Create deprecated sysfs files" depends on SYSFS default y + select SYSFS_DEPRECATED help This option creates deprecated symlinks such as the "device"-link, the :-link, and the -- cgit v1.2.3 From a4573c488dd531c6e2d308ce8a7413c4a2646207 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 26 Feb 2008 09:36:38 -0800 Subject: kobject: properly initialize ksets kset_initialize was calling kobject_init_internal() which didn't initialize the kobject as well as kobject_init() was. So have kobject_init() call kobject_init_internal() and move the logic to initalize the kobject there. Cc: Kay Sievers Cc: Hannes Reinecke Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/kobject.c b/lib/kobject.c index d784daeb857..0d03252f87a 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -153,6 +153,10 @@ static void kobject_init_internal(struct kobject *kobj) return; kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); + kobj->state_in_sysfs = 0; + kobj->state_add_uevent_sent = 0; + kobj->state_remove_uevent_sent = 0; + kobj->state_initialized = 1; } @@ -289,13 +293,8 @@ void kobject_init(struct kobject *kobj, struct kobj_type *ktype) dump_stack(); } - kref_init(&kobj->kref); - INIT_LIST_HEAD(&kobj->entry); + kobject_init_internal(kobj); kobj->ktype = ktype; - kobj->state_in_sysfs = 0; - kobj->state_add_uevent_sent = 0; - kobj->state_remove_uevent_sent = 0; - kobj->state_initialized = 1; return; error: -- cgit v1.2.3 From 7a8d37a37380e2b1500592d40b7ec384dbebe7a0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 25 Feb 2008 00:35:04 +0100 Subject: PM: Do not acquire device semaphores upfront during suspend Remove the code that acquires all device semaphores from the suspend code path as it causes multiple problems to appear (most notably, http://bugzilla.kernel.org/show_bug.cgi?id=10030) and revert the change introduced by commit 4145ed6dc597a9bea5f6ae8c574653b2de10620f depending on the code being removed. Remove pm_sleep_lock()/pm_sleep_unlock() from device_add() to avoid the issue reported at http://bugzilla.kernel.org/show_bug.cgi?id=9874. It should fix the regreesions reported at: http://bugzilla.kernel.org/show_bug.cgi?id=9874 http://bugzilla.kernel.org/show_bug.cgi?id=10030 Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 8 ---- drivers/base/power/main.c | 106 +++++++--------------------------------------- drivers/usb/core/usb.c | 2 +- 3 files changed, 17 insertions(+), 99 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 9c0070b5bd3..1e2e0fa8a45 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -770,13 +770,6 @@ int device_add(struct device *dev) struct class_interface *class_intf; int error; - error = pm_sleep_lock(); - if (error) { - dev_warn(dev, "Suspicious %s during suspend\n", __FUNCTION__); - dump_stack(); - return error; - } - dev = get_device(dev); if (!dev || !strlen(dev->bus_id)) { error = -EINVAL; @@ -843,7 +836,6 @@ int device_add(struct device *dev) } Done: put_device(dev); - pm_sleep_unlock(); return error; BusError: device_pm_remove(dev); diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index ee9d1c8db0d..b0c16f6fc18 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -48,7 +48,6 @@ */ LIST_HEAD(dpm_active); -static LIST_HEAD(dpm_locked); static LIST_HEAD(dpm_off); static LIST_HEAD(dpm_off_irq); static LIST_HEAD(dpm_destroy); @@ -81,28 +80,6 @@ void device_pm_add(struct device *dev) */ void device_pm_remove(struct device *dev) { - /* - * If this function is called during a suspend, it will be blocked, - * because we're holding the device's semaphore at that time, which may - * lead to a deadlock. In that case we want to print a warning. - * However, it may also be called by unregister_dropped_devices() with - * the device's semaphore released, in which case the warning should - * not be printed. - */ - if (down_trylock(&dev->sem)) { - if (down_read_trylock(&pm_sleep_rwsem)) { - /* No suspend in progress, wait on dev->sem */ - down(&dev->sem); - up_read(&pm_sleep_rwsem); - } else { - /* Suspend in progress, we may deadlock */ - dev_warn(dev, "Suspicious %s during suspend\n", - __FUNCTION__); - dump_stack(); - /* The user has been warned ... */ - down(&dev->sem); - } - } pr_debug("PM: Removing info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", kobject_name(&dev->kobj)); @@ -110,7 +87,6 @@ void device_pm_remove(struct device *dev) dpm_sysfs_remove(dev); list_del_init(&dev->power.entry); mutex_unlock(&dpm_list_mtx); - up(&dev->sem); } /** @@ -230,6 +206,8 @@ static int resume_device(struct device *dev) TRACE_DEVICE(dev); TRACE_RESUME(0); + down(&dev->sem); + if (dev->bus && dev->bus->resume) { dev_dbg(dev,"resuming\n"); error = dev->bus->resume(dev); @@ -245,6 +223,8 @@ static int resume_device(struct device *dev) error = dev->class->resume(dev); } + up(&dev->sem); + TRACE_RESUME(error); return error; } @@ -266,7 +246,7 @@ static void dpm_resume(void) struct list_head *entry = dpm_off.next; struct device *dev = to_device(entry); - list_move_tail(entry, &dpm_locked); + list_move_tail(entry, &dpm_active); mutex_unlock(&dpm_list_mtx); resume_device(dev); mutex_lock(&dpm_list_mtx); @@ -274,25 +254,6 @@ static void dpm_resume(void) mutex_unlock(&dpm_list_mtx); } -/** - * unlock_all_devices - Release each device's semaphore - * - * Go through the dpm_off list. Put each device on the dpm_active - * list and unlock it. - */ -static void unlock_all_devices(void) -{ - mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_locked)) { - struct list_head *entry = dpm_locked.prev; - struct device *dev = to_device(entry); - - list_move(entry, &dpm_active); - up(&dev->sem); - } - mutex_unlock(&dpm_list_mtx); -} - /** * unregister_dropped_devices - Unregister devices scheduled for removal * @@ -305,7 +266,6 @@ static void unregister_dropped_devices(void) struct list_head *entry = dpm_destroy.next; struct device *dev = to_device(entry); - up(&dev->sem); mutex_unlock(&dpm_list_mtx); /* This also removes the device from the list */ device_unregister(dev); @@ -324,7 +284,6 @@ void device_resume(void) { might_sleep(); dpm_resume(); - unlock_all_devices(); unregister_dropped_devices(); up_write(&pm_sleep_rwsem); } @@ -388,18 +347,15 @@ int device_power_down(pm_message_t state) struct list_head *entry = dpm_off.prev; struct device *dev = to_device(entry); - list_del_init(&dev->power.entry); error = suspend_device_late(dev, state); if (error) { printk(KERN_ERR "Could not power down device %s: " "error %d\n", kobject_name(&dev->kobj), error); - if (list_empty(&dev->power.entry)) - list_add(&dev->power.entry, &dpm_off); break; } - if (list_empty(&dev->power.entry)) - list_add(&dev->power.entry, &dpm_off_irq); + if (!list_empty(&dev->power.entry)) + list_move(&dev->power.entry, &dpm_off_irq); } if (!error) @@ -419,6 +375,8 @@ static int suspend_device(struct device *dev, pm_message_t state) { int error = 0; + down(&dev->sem); + if (dev->power.power_state.event) { dev_dbg(dev, "PM: suspend %d-->%d\n", dev->power.power_state.event, state.event); @@ -441,6 +399,9 @@ static int suspend_device(struct device *dev, pm_message_t state) error = dev->bus->suspend(dev, state); suspend_report_result(dev->bus->suspend, error); } + + up(&dev->sem); + return error; } @@ -461,11 +422,10 @@ static int dpm_suspend(pm_message_t state) int error = 0; mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_locked)) { - struct list_head *entry = dpm_locked.prev; + while (!list_empty(&dpm_active)) { + struct list_head *entry = dpm_active.prev; struct device *dev = to_device(entry); - list_del_init(&dev->power.entry); mutex_unlock(&dpm_list_mtx); error = suspend_device(dev, state); if (error) { @@ -476,50 +436,17 @@ static int dpm_suspend(pm_message_t state) (error == -EAGAIN ? " (please convert to suspend_late)" : "")); - mutex_lock(&dpm_list_mtx); - if (list_empty(&dev->power.entry)) - list_add(&dev->power.entry, &dpm_locked); break; } mutex_lock(&dpm_list_mtx); - if (list_empty(&dev->power.entry)) - list_add(&dev->power.entry, &dpm_off); + if (!list_empty(&dev->power.entry)) + list_move(&dev->power.entry, &dpm_off); } mutex_unlock(&dpm_list_mtx); return error; } -/** - * lock_all_devices - Acquire every device's semaphore - * - * Go through the dpm_active list. Carefully lock each device's - * semaphore and put it in on the dpm_locked list. - */ -static void lock_all_devices(void) -{ - mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_active)) { - struct list_head *entry = dpm_active.next; - struct device *dev = to_device(entry); - - /* Required locking order is dev->sem first, - * then dpm_list_mutex. Hence this awkward code. - */ - get_device(dev); - mutex_unlock(&dpm_list_mtx); - down(&dev->sem); - mutex_lock(&dpm_list_mtx); - - if (list_empty(entry)) - up(&dev->sem); /* Device was removed */ - else - list_move_tail(entry, &dpm_locked); - put_device(dev); - } - mutex_unlock(&dpm_list_mtx); -} - /** * device_suspend - Save state and stop all devices in system. * @state: new power management state @@ -533,7 +460,6 @@ int device_suspend(pm_message_t state) might_sleep(); down_write(&pm_sleep_rwsem); - lock_all_devices(); error = dpm_suspend(state); if (error) device_resume(); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index f6f19908f5f..1f0db51190c 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -233,7 +233,7 @@ static int ksuspend_usb_init(void) * singlethreaded. Its job doesn't justify running on more * than one CPU. */ - ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd"); + ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd"); if (!ksuspend_usb_wq) return -ENOMEM; return 0; -- cgit v1.2.3 From 1b3cbec1dcb6747b587b40335f5de1d9e035063c Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 29 Feb 2008 11:50:22 -0500 Subject: PM: fix new mutex-locking bug in the PM core This patch (as1041) fixes a bug introduced by the acquire-all-device-semaphores reversion. The error pathway of dpm_suspend() fails to reacquire a mutex it should be holding. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/base/power/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index b0c16f6fc18..d887d5cb5be 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -428,6 +428,7 @@ static int dpm_suspend(pm_message_t state) mutex_unlock(&dpm_list_mtx); error = suspend_device(dev, state); + mutex_lock(&dpm_list_mtx); if (error) { printk(KERN_ERR "Could not suspend device %s: " "error %d%s\n", @@ -438,7 +439,6 @@ static int dpm_suspend(pm_message_t state) "")); break; } - mutex_lock(&dpm_list_mtx); if (!list_empty(&dev->power.entry)) list_move(&dev->power.entry, &dpm_off); } -- cgit v1.2.3 From 135dee0cd0eb2638fab899b428e51f00e8c046a8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 3 Mar 2008 23:46:51 +0100 Subject: driver core: Remove dpm_sysfs_remove() from error path of device_add() Since device_pm_remove(dev) calls dpm_sysfs_remove(dev), it's incorrect to call the latter after the former in the device_add() error path. Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 1e2e0fa8a45..7f59c2f2ebc 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -839,7 +839,6 @@ int device_add(struct device *dev) return error; BusError: device_pm_remove(dev); - dpm_sysfs_remove(dev); PMError: if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, -- cgit v1.2.3 From c1fe539a7e031302af1d121163e7ce68e679ba8c Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 27 Feb 2008 15:38:23 +0100 Subject: Driver core: Fix cleanup when failing device_add(). Driver core: Fix cleanup when failing device_add(). - Don't call cleanup_device_parent() if we didn't call setup_parent(). - dev->kobj.parent may be NULL when cleanup_device_parent() is called, so we need to handle glue_dir == NULL in cleanup_glue_dir(). Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 7f59c2f2ebc..7de543d1d0b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -621,7 +621,8 @@ static struct kobject *get_device_parent(struct device *dev, static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) { /* see if we live in a "glue" directory */ - if (!dev->class || glue_dir->kset != &dev->class->class_dirs) + if (!glue_dir || !dev->class || + glue_dir->kset != &dev->class->class_dirs) return; kobject_put(glue_dir); @@ -773,7 +774,7 @@ int device_add(struct device *dev) dev = get_device(dev); if (!dev || !strlen(dev->bus_id)) { error = -EINVAL; - goto Error; + goto Done; } pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__); -- cgit v1.2.3 From 3634634edd49c115da931998b9540bcc17665b05 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 13 Feb 2008 17:08:16 -0800 Subject: debugfs: fix sparse warnings extern does not belong in C files, move declaration to linux/debugfs.h fs/debugfs/file.c:42:30: warning: symbol 'debugfs_file_operations' was not declared. Should it be static? fs/debugfs/file.c:54:31: warning: symbol 'debugfs_link_operations' was not declared. Should it be static? Signed-off-by: Harvey Harrison Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 4 ---- include/linux/debugfs.h | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index d26e2826ba5..e9602d85c11 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -29,10 +29,6 @@ #define DEBUGFS_MAGIC 0x64626720 -/* declared over in file.c */ -extern struct file_operations debugfs_file_operations; -extern struct inode_operations debugfs_link_operations; - static struct vfsmount *debugfs_mount; static int debugfs_mount_count; diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index f592d6de3b9..7266124361b 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -27,6 +27,11 @@ struct debugfs_blob_wrapper { }; #if defined(CONFIG_DEBUG_FS) + +/* declared over in file.c */ +extern const struct file_operations debugfs_file_operations; +extern const struct inode_operations debugfs_link_operations; + struct dentry *debugfs_create_file(const char *name, mode_t mode, struct dentry *parent, void *data, const struct file_operations *fops); -- cgit v1.2.3