On Wednesday, February 06, 2013 10:11:25 PM Rafael J. Wysocki wrote: > On Thursday, February 07, 2013 12:25:13 AM Artem Savkov wrote: > > I get the following BUG on suspend using systemd-sleep(this doesn't > > happen with pm-suspend). This seems to be introduced by some of the > > Viresh's patches. > > Which branch from which day? OK, I've reproduced it and the appended patch fixes it for me. Can you please try it and report back? Rafael --- From: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> Subject: cpufreq: Move sysfs_remove_link() from under a spinlock Commit 73bf0fc "cpufreq: Don't remove sysfs link for policy->cpu" attempted to fix a bug in __cpufreq_remove_dev() by avoiding to remove the link to the "cpufreq" directory for policy->cpu, but it rearranged the code in such a way that sysfs_remove_link() ended up under a spinlock, which caused complaints about sleeping in atomic context to be emitted into the kernel log during system suspend. To fix this, revert commit 73bf0fc partially and move the sysfs_remove_link() in question to a separate block executed for cpus > 1 outside of the spinlock. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> --- drivers/cpufreq/cpufreq.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) Index: test/drivers/cpufreq/cpufreq.c =================================================================== --- test.orig/drivers/cpufreq/cpufreq.c +++ test/drivers/cpufreq/cpufreq.c @@ -1058,9 +1058,7 @@ static int __cpufreq_remove_dev(struct d cpus = cpumask_weight(data->cpus); cpumask_clear_cpu(cpu, data->cpus); - if (cpu != data->cpu) { - sysfs_remove_link(&dev->kobj, "cpufreq"); - } else if (cpus > 1) { + if (unlikely(cpu == data->cpu && cpus > 1)) { /* first sibling now owns the new sysfs dir */ cpu_dev = get_cpu_device(cpumask_first(data->cpus)); sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); @@ -1085,9 +1083,14 @@ static int __cpufreq_remove_dev(struct d pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); cpufreq_cpu_put(data); unlock_policy_rwsem_write(cpu); - - /* If cpu is last user of policy, free policy */ - if (cpus == 1) { + if (cpus > 1) { + sysfs_remove_link(&dev->kobj, "cpufreq"); + if (cpufreq_driver->target) { + __cpufreq_governor(data, CPUFREQ_GOV_START); + __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); + } + } else { + /* If cpu is the last user of policy, free policy */ lock_policy_rwsem_write(cpu); kobj = &data->kobj; cmp = &data->kobj_unregister; @@ -1110,9 +1113,6 @@ static int __cpufreq_remove_dev(struct d free_cpumask_var(data->related_cpus); free_cpumask_var(data->cpus); kfree(data); - } else if (cpufreq_driver->target) { - __cpufreq_governor(data, CPUFREQ_GOV_START); - __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); } return 0; -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. -- To unsubscribe from this list: send the line "unsubscribe cpufreq" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html