public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
	Tejun Heo <tj@kernel.org>, Duncan <1i5t5.duncan@cox.net>,
	"Rafael J. Wysocki" <rjw@sisk.pl>,
	Andreas Herrmann <andreas.herrmann3@amd.com>
Subject: [ 012/108] cpufreq/powernow-k8: workqueue user shouldnt migrate the kworker to another CPU
Date: Sun, 07 Oct 2012 23:58:46 +0100	[thread overview]
Message-ID: <20121007225836.389989481@decadent.org.uk> (raw)
In-Reply-To: <20121007225834.673681075@decadent.org.uk>

3.2-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Tejun Heo <tj@kernel.org>

commit 6889125b8b4e09c5e53e6ecab3433bed1ce198c9 upstream.

powernowk8_target() runs off a per-cpu work item and if the
cpufreq_policy->cpu is different from the current one, it migrates the
kworker to the target CPU by manipulating current->cpus_allowed.  The
function migrates the kworker back to the original CPU but this is
still broken.  Workqueue concurrency management requires the kworkers
to stay on the same CPU and powernowk8_target() ends up triggerring
BUG_ON(rq != this_rq()) in try_to_wake_up_local() if it contends on
fidvid_mutex and sleeps.

It is unclear why this bug is being reported now.  Duncan says it
appeared to be a regression of 3.6-rc1 and couldn't reproduce it on
3.5.  Bisection seemed to point to 63d95a91 "workqueue: use @pool
instead of @gcwq or @cpu where applicable" which is an non-functional
change.  Given that the reproduce case sometimes took upto days to
trigger, it's easy to be misled while bisecting.  Maybe something made
contention on fidvid_mutex more likely?  I don't know.

This patch fixes the bug by using work_on_cpu() instead if @pol->cpu
isn't the same as the current one.  The code assumes that
cpufreq_policy->cpu is kept online by the caller, which Rafael tells
me is the case.

stable: ed48ece27c ("workqueue: reimplement work_on_cpu() using
        system_wq") should be applied before this; otherwise, the
        behavior could be horrible.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Duncan <1i5t5.duncan@cox.net>
Tested-by: Duncan <1i5t5.duncan@cox.net>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Andreas Herrmann <andreas.herrmann3@amd.com>
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=47301
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 drivers/cpufreq/powernow-k8.c |   63 ++++++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 29 deletions(-)

diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index c0e8164..1a40935 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -35,7 +35,6 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/cpumask.h>
-#include <linux/sched.h>	/* for current / set_cpus_allowed() */
 #include <linux/io.h>
 #include <linux/delay.h>
 
@@ -1139,16 +1138,23 @@ static int transition_frequency_pstate(struct powernow_k8_data *data,
 	return res;
 }
 
-/* Driver entry point to switch to the target frequency */
-static int powernowk8_target(struct cpufreq_policy *pol,
-		unsigned targfreq, unsigned relation)
+struct powernowk8_target_arg {
+	struct cpufreq_policy		*pol;
+	unsigned			targfreq;
+	unsigned			relation;
+};
+
+static long powernowk8_target_fn(void *arg)
 {
-	cpumask_var_t oldmask;
+	struct powernowk8_target_arg *pta = arg;
+	struct cpufreq_policy *pol = pta->pol;
+	unsigned targfreq = pta->targfreq;
+	unsigned relation = pta->relation;
 	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
 	u32 checkfid;
 	u32 checkvid;
 	unsigned int newstate;
-	int ret = -EIO;
+	int ret;
 
 	if (!data)
 		return -EINVAL;
@@ -1156,29 +1162,16 @@ static int powernowk8_target(struct cpufreq_policy *pol,
 	checkfid = data->currfid;
 	checkvid = data->currvid;
 
-	/* only run on specific CPU from here on. */
-	/* This is poor form: use a workqueue or smp_call_function_single */
-	if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
-		return -ENOMEM;
-
-	cpumask_copy(oldmask, tsk_cpus_allowed(current));
-	set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
-
-	if (smp_processor_id() != pol->cpu) {
-		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
-		goto err_out;
-	}
-
 	if (pending_bit_stuck()) {
 		printk(KERN_ERR PFX "failing targ, change pending bit set\n");
-		goto err_out;
+		return -EIO;
 	}
 
 	pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
 		pol->cpu, targfreq, pol->min, pol->max, relation);
 
 	if (query_current_values_with_pending_wait(data))
-		goto err_out;
+		return -EIO;
 
 	if (cpu_family != CPU_HW_PSTATE) {
 		pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
@@ -1196,7 +1189,7 @@ static int powernowk8_target(struct cpufreq_policy *pol,
 
 	if (cpufreq_frequency_table_target(pol, data->powernow_table,
 				targfreq, relation, &newstate))
-		goto err_out;
+		return -EIO;
 
 	mutex_lock(&fidvid_mutex);
 
@@ -1209,9 +1202,8 @@ static int powernowk8_target(struct cpufreq_policy *pol,
 		ret = transition_frequency_fidvid(data, newstate);
 	if (ret) {
 		printk(KERN_ERR PFX "transition frequency failed\n");
-		ret = 1;
 		mutex_unlock(&fidvid_mutex);
-		goto err_out;
+		return 1;
 	}
 	mutex_unlock(&fidvid_mutex);
 
@@ -1220,12 +1212,25 @@ static int powernowk8_target(struct cpufreq_policy *pol,
 				data->powernow_table[newstate].index);
 	else
 		pol->cur = find_khz_freq_from_fid(data->currfid);
-	ret = 0;
 
-err_out:
-	set_cpus_allowed_ptr(current, oldmask);
-	free_cpumask_var(oldmask);
-	return ret;
+	return 0;
+}
+
+/* Driver entry point to switch to the target frequency */
+static int powernowk8_target(struct cpufreq_policy *pol,
+		unsigned targfreq, unsigned relation)
+{
+	struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq,
+					     .relation = relation };
+
+	/*
+	 * Must run on @pol->cpu.  cpufreq core is responsible for ensuring
+	 * that we're bound to the current CPU and pol->cpu stays online.
+	 */
+	if (smp_processor_id() == pol->cpu)
+		return powernowk8_target_fn(&pta);
+	else
+		return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
 }
 
 /* Driver entry point to verify the policy and range of frequencies */



  parent reply	other threads:[~2012-10-07 23:47 UTC|newest]

Thread overview: 114+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-07 22:58 [ 000/108] 3.2.31-stable review Ben Hutchings
2012-10-07 22:58 ` [ 001/108] target: Fix ->data_length re-assignment bug with SCSI overflow Ben Hutchings
2012-10-07 22:58 ` [ 002/108] ASoC: samsung dma - Dont indicate support for pause/resume Ben Hutchings
2012-10-07 22:58 ` [ 003/108] fs/proc: fix potential unregister_sysctl_table hang Ben Hutchings
2012-10-07 22:58 ` [ 004/108] mm/ia64: fix a memory block size bug Ben Hutchings
2012-10-07 22:58 ` [ 005/108] nbd: clear waiting_queue on shutdown Ben Hutchings
2012-10-07 22:58 ` [ 006/108] drivers/rtc/rtc-twl.c: ensure all interrupts are disabled during probe Ben Hutchings
2012-10-07 22:58 ` [ 007/108] mm/page_alloc: fix the page address of higher pages buddy calculation Ben Hutchings
2012-10-07 22:58 ` [ 008/108] memory hotplug: fix section info double registration bug Ben Hutchings
2012-10-07 22:58 ` [ 009/108] cciss: fix handling of protocol error Ben Hutchings
2012-10-07 22:58 ` [ 010/108] vfs: dcache: use DCACHE_DENTRY_KILLED instead of DCACHE_DISCONNECTED in d_kill() Ben Hutchings
2012-10-07 22:58 ` [ 011/108] workqueue: reimplement work_on_cpu() using system_wq Ben Hutchings
2012-10-07 22:58 ` Ben Hutchings [this message]
2012-10-07 22:58 ` [ 013/108] sched: Fix ancient race in do_exit() Ben Hutchings
2012-10-07 22:58 ` [ 014/108] hpwdt: Fix kdump issue in hpwdt Ben Hutchings
2012-10-07 22:58 ` [ 015/108] rtlwifi: rtl8192ce: Log message that B_CUT device may not work Ben Hutchings
2012-10-07 22:58 ` [ 016/108] brcmfmac: fix big endian bug in i-scan Ben Hutchings
2012-10-07 22:58 ` [ 017/108] brcmfmac: Fix big endian host configuration data Ben Hutchings
2012-10-07 22:58 ` [ 018/108] dmaengine: at_hdmac: fix comment in atc_prep_slave_sg() Ben Hutchings
2012-10-07 22:58 ` [ 019/108] dmaengine: at_hdmac: check that each sg data length is non-null Ben Hutchings
2012-10-07 22:58 ` [ 020/108] ARM: 7532/1: decompressor: reset SCTLR.TRE for VMSA ARMv7 cores Ben Hutchings
2012-10-07 22:58 ` [ 021/108] drm/i915: Reduce a pin-leak BUG into a WARN Ben Hutchings
2012-10-07 22:58 ` [ 022/108] drm/i915: HDMI - Clear Audio Enable bit for Hot Plug Ben Hutchings
2012-10-07 22:58 ` [ 023/108] [SCSI] bnx2i: Fixed NULL ptr deference for 1G bnx2 Linux iSCSI offload Ben Hutchings
2012-10-07 22:58 ` [ 024/108] [SCSI] mpt2sas: Fix for issue - Unable to boot from the drive connected to HBA Ben Hutchings
2012-10-07 22:58 ` [ 025/108] hwmon: (ads7871) Add name sysfs attribute Ben Hutchings
2012-10-07 22:59 ` [ 026/108] DMA: PL330: Check the pointer returned by kzalloc Ben Hutchings
2012-10-07 22:59 ` [ 027/108] [SCSI] hpsa: fix handling of protocol error Ben Hutchings
2012-10-07 22:59 ` [ 028/108] ARM: imx: armadillo5x0: Fix illegal register access Ben Hutchings
2012-10-07 23:37   ` Estevam Fabio-R49496
2012-10-10  2:24     ` Ben Hutchings
2012-10-07 22:59 ` [ 029/108] hwmon: (ad7314) Add name sysfs attribute Ben Hutchings
2012-10-07 22:59 ` [ 030/108] cifs: fix return value in cifsConvertToUTF16 Ben Hutchings
2012-10-07 22:59 ` [ 031/108] cfg80211: fix possible circular lock on reg_regdb_search() Ben Hutchings
2012-10-07 22:59 ` [ 032/108] xen/boot: Disable BIOS SMP MP table search Ben Hutchings
2012-10-07 22:59 ` [ 033/108] asix: Support DLink DUB-E100 H/W Ver C1 Ben Hutchings
2012-10-07 22:59 ` [ 034/108] Input: i8042 - disable mux on Toshiba C850D Ben Hutchings
2012-10-07 22:59 ` [ 035/108] tracing: Dont call page_to_pfn() if page is NULL Ben Hutchings
2012-10-07 22:59 ` [ 036/108] can: janz-ican3: fix support for older hardware revisions Ben Hutchings
2012-10-07 22:59 ` [ 037/108] can: ti_hecc: fix oops during rmmod Ben Hutchings
2012-10-07 22:59 ` [ 038/108] HID: logitech: fix mask to enable DJ mode Ben Hutchings
2012-10-07 22:59 ` [ 039/108] HID: logitech: dont use stack based dj_report structures Ben Hutchings
2012-10-07 22:59 ` [ 040/108] dj: memory scribble in logi_dj Ben Hutchings
2012-10-07 22:59 ` [ 041/108] HID: Fix logitech-dj: missing Unifying device issue Ben Hutchings
2012-10-07 22:59 ` [ 042/108] hwmon: (fam15h_power) Tweak runavg_range on resume Ben Hutchings
2012-10-07 22:59 ` [ 043/108] xen/boot: Disable NUMA for PV guests Ben Hutchings
2012-10-07 22:59 ` [ 044/108] gpio-lpc32xx: Fix value handling of gpio_direction_output() Ben Hutchings
2012-10-07 22:59 ` [ 045/108] sb_edac: Avoid overflow errors at memory size calculation Ben Hutchings
2012-10-07 22:59 ` [ 046/108] dm: handle requests beyond end of device instead of using BUG_ON Ben Hutchings
2012-10-07 22:59 ` [ 047/108] dm table: clear add_random unless all devices have it set Ben Hutchings
2012-10-07 22:59 ` [ 048/108] md/raid10: fix "enough" function for detecting if array is failed Ben Hutchings
2012-10-07 22:59 ` [ 049/108] USB: Fix race condition when removing host controllers Ben Hutchings
2012-10-07 22:59 ` [ 050/108] asus-laptop: HRWS/HWRS typo Ben Hutchings
2012-10-07 22:59 ` [ 051/108] Bluetooth: btusb: Add vendor specific ID (0a5c:21f4) BCM20702A0 Ben Hutchings
2012-10-07 22:59 ` [ 052/108] Bluetooth: Use USB_VENDOR_AND_INTERFACE() for Broadcom devices Ben Hutchings
2012-10-07 22:59 ` [ 053/108] Bluetooth: Add support for Apple vendor-specific devices Ben Hutchings
2012-10-07 22:59 ` [ 054/108] net: Statically initialize init_net.dev_base_head Ben Hutchings
2012-10-07 22:59 ` [ 055/108] Fix a dead loop in async_synchronize_full() Ben Hutchings
2012-10-07 22:59 ` [ 056/108] rds: set correct msg_namelen Ben Hutchings
2012-10-07 22:59 ` [ 057/108] [libata] Prevent interface errors with Seagate FreeAgent GoFlex Ben Hutchings
2012-10-07 22:59 ` [ 058/108] mmc: Prevent 1.8V switch for SD hosts that dont support UHS modes Ben Hutchings
2012-10-07 22:59 ` [ 059/108] Bluetooth: Change signature of smp_conn_security() Ben Hutchings
2012-10-07 22:59 ` [ 060/108] Bluetooth: Fix sending a HCI Authorization Request over LE links Ben Hutchings
2012-10-07 22:59 ` [ 061/108] pch_uart: Add eg20t_port lock field, avoid recursive spinlocks Ben Hutchings
2012-10-07 22:59 ` [ 062/108] irq_remap: disable IRQ remapping if any IOAPIC lacks an IOMMU Ben Hutchings
2012-10-07 22:59 ` [ 063/108] vfs: dcache: fix deadlock in tree traversal Ben Hutchings
2012-10-07 22:59 ` [ 064/108] usb: gadget: dummy_hcd: fixup error probe path Ben Hutchings
2012-10-07 22:59 ` [ 065/108] CPU hotplug, cpusets, suspend: Dont modify cpusets during suspend/resume Ben Hutchings
2012-10-07 22:59 ` [ 066/108] Revert "drm/radeon: rework pll selection (v3)" Ben Hutchings
2012-10-07 22:59 ` [ 067/108] x86/alternatives: Fix p6 nops on non-modular kernels Ben Hutchings
2012-10-07 22:59 ` [ 068/108] HID: hidraw: add proper error handling to raw event reporting Ben Hutchings
2012-10-08 19:34   ` Herton Ronaldo Krzesinski
2012-10-10  2:25     ` Ben Hutchings
2012-10-07 22:59 ` [ 069/108] HID: hidraw: fix list->buffer memleak Ben Hutchings
2012-10-07 22:59 ` [ 070/108] HID: hidraw: improve error handling in hidraw_init() Ben Hutchings
2012-10-07 22:59 ` [ 071/108] HID: hidraw: dont deallocate memory when it is in use Ben Hutchings
2012-10-07 22:59 ` [ 072/108] PCI: acpiphp: check whether _ADR evaluation succeeded Ben Hutchings
2012-10-07 22:59 ` [ 073/108] bnx2x: fix rx checksum validation for IPv6 Ben Hutchings
2012-10-07 22:59 ` [ 074/108] xfrm: Workaround incompatibility of ESN and async crypto Ben Hutchings
2012-10-07 22:59 ` [ 075/108] xfrm_user: return error pointer instead of NULL Ben Hutchings
2012-10-07 22:59 ` [ 076/108] xfrm_user: return error pointer instead of NULL #2 Ben Hutchings
2012-10-07 22:59 ` [ 077/108] xfrm: fix a read lock imbalance in make_blackhole Ben Hutchings
2012-10-07 22:59 ` [ 078/108] xfrm_user: fix info leak in copy_to_user_auth() Ben Hutchings
2012-10-07 22:59 ` [ 079/108] xfrm_user: fix info leak in copy_to_user_state() Ben Hutchings
2012-10-07 22:59 ` [ 080/108] xfrm_user: fix info leak in copy_to_user_policy() Ben Hutchings
2012-10-07 22:59 ` [ 081/108] xfrm_user: fix info leak in copy_to_user_tmpl() Ben Hutchings
2012-10-07 22:59 ` [ 082/108] xfrm_user: dont copy esn replay window twice for new states Ben Hutchings
2012-10-07 22:59 ` [ 083/108] xfrm_user: ensure user supplied esn replay window is valid Ben Hutchings
2012-10-07 22:59 ` [ 084/108] net: ethernet: davinci_cpdma: decrease the desc count when cleaning up the remaining packets Ben Hutchings
2012-10-07 22:59 ` [ 085/108] ixp4xx_hss: fix build failure due to missing linux/module.h inclusion Ben Hutchings
2012-10-07 23:00 ` [ 086/108] netxen: check for root bus in netxen_mask_aer_correctable Ben Hutchings
2012-10-07 23:00 ` [ 087/108] net-sched: sch_cbq: avoid infinite loop Ben Hutchings
2012-10-07 23:00 ` [ 088/108] pkt_sched: fix virtual-start-time update in QFQ Ben Hutchings
2012-10-07 23:00 ` [ 089/108] sierra_net: Endianess bug fix Ben Hutchings
2012-10-07 23:00 ` [ 090/108] 8021q: fix mac_len recomputation in vlan_untag() Ben Hutchings
2012-10-07 23:00 ` [ 091/108] ipv6: release reference of ip6_null_entrys dst entry in __ip6_del_rt Ben Hutchings
2012-10-07 23:00 ` [ 092/108] tcp: flush DMA queue before sk_wait_data if rcv_wnd is zero Ben Hutchings
2012-10-07 23:00 ` [ 093/108] sctp: Dont charge for data in sndbuf again when transmitting packet Ben Hutchings
2012-10-07 23:00 ` [ 094/108] pppoe: drop PPPOX_ZOMBIEs in pppoe_release Ben Hutchings
2012-10-07 23:00 ` [ 095/108] net: small bug on rxhash calculation Ben Hutchings
2012-10-07 23:00 ` [ 096/108] net: guard tcp_set_keepalive() to tcp sockets Ben Hutchings
2012-10-07 23:00 ` [ 097/108] ipv4: raw: fix icmp_filter() Ben Hutchings
2012-10-07 23:00 ` [ 098/108] ipv6: raw: fix icmpv6_filter() Ben Hutchings
2012-10-07 23:00 ` [ 099/108] ipv6: mip6: fix mip6_mh_filter() Ben Hutchings
2012-10-07 23:00 ` [ 100/108] l2tp: fix a typo in l2tp_eth_dev_recv() Ben Hutchings
2012-10-07 23:00 ` [ 101/108] netrom: copy_datagram_iovec can fail Ben Hutchings
2012-10-07 23:00 ` [ 102/108] net: do not disable sg for packets requiring no checksum Ben Hutchings
2012-10-07 23:00 ` [ 103/108] aoe: assert AoE packets marked as " Ben Hutchings
2012-10-07 23:00 ` [ 104/108] tg3: Fix TSO CAP for 5704 devs w / ASF enabled Ben Hutchings
2012-10-07 23:00 ` [ 105/108] Bluetooth: Support AR3011 in Acer Iconia Tab W500 Ben Hutchings
2012-10-07 23:00 ` [ 106/108] Bluetooth: add support for atheros 0930:0219 Ben Hutchings
2012-10-07 23:00 ` [ 107/108] Bluetooth: add support for atheros 0489:e057 Ben Hutchings
2012-10-07 23:00 ` [ 108/108] Bluetooth: Add support for Sony Vaio T-Series Ben Hutchings
2012-10-08 13:05 ` [ 000/108] 3.2.31-stable review Ben Hutchings

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20121007225836.389989481@decadent.org.uk \
    --to=ben@decadent.org.uk \
    --cc=1i5t5.duncan@cox.net \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=andreas.herrmann3@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rjw@sisk.pl \
    --cc=stable@vger.kernel.org \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox