Message ID | 1873989.qC1mdEKIl9@vostro.rjw.lan (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
On Thu, Feb 07, 2013 at 01:41:57AM +0100, Rafael J. Wysocki wrote: > 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? The log is from linux-next-20130205, still reproducible on -20130206 > OK, I've reproduced it and the appended patch fixes it for me. Can you please > try it and report back? I've tried the patch and the bug is still reproducible. I might be wrong but it seems that the bug happens on first __cpufreq_remove_dev call(CPU1) on __cpufreq_governor(data, CPUFREQ_GOV_STOP) call (line ~1050) but changes in your patch are all below that call.
On 7 February 2013 06:11, Rafael J. Wysocki <rjw@sisk.pl> wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > 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@intel.com> BTW, i have dropped this patch completely as i got another lock fixing patch :) -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Friday, February 08, 2013 11:24:39 AM Viresh Kumar wrote: > On 7 February 2013 06:11, Rafael J. Wysocki <rjw@sisk.pl> wrote: > > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > 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@intel.com> > > BTW, i have dropped this patch completely as i got another lock fixing > patch :) Sure, I suppose you can get a better fix. :-) Thanks, Rafael
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;