From: Chris Wright <chrisw@sous-sol.org>
To: linux-kernel@vger.kernel.org, stable@kernel.org, torvalds@osdl.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
Zwane Mwaikambo <zwane@arm.linux.org.uk>,
"Theodore Ts'o" <tytso@mit.edu>,
Randy Dunlap <rdunlap@xenotime.net>,
Dave Jones <davej@redhat.com>,
Chuck Wolber <chuckw@quantumlinux.com>,
akpm@osdl.org, alan@lxorguk.ukuu.org.uk, ntl@pobox.com
Subject: [PATCH 07/17] [PATCH] fix workqueue oops during cpu offline
Date: Thu, 12 Jan 2006 18:37:45 -0800 [thread overview]
Message-ID: <20060113032243.154673000@sorel.sous-sol.org> (raw)
In-Reply-To: 20060113032102.154909000@sorel.sous-sol.org
[-- Attachment #1: fix-workqueue-oops-during-cpu-offline.patch --]
[-- Type: text/plain, Size: 3871 bytes --]
-stable review patch. If anyone has any objections, please let us know.
------------------
Use first_cpu(cpu_possible_map) for the single-thread workqueue case. We
used to hardcode 0, but that broke on systems where !cpu_possible(0) when
workqueue_struct->cpu_workqueue_struct was changed from a static array to
alloc_percpu.
Commit id bce61dd49d6ba7799be2de17c772e4c701558f14 ("Fix hardcoded cpu=0 in
workqueue for per_cpu_ptr() calls") fixed that for Ben's funky sparc64
system, but it regressed my Power5. Offlining cpu 0 oopses upon the next
call to queue_work for a single-thread workqueue, because now we try to
manipulate per_cpu_ptr(wq->cpu_wq, 1), which is uninitialized.
So we need to establish an unchanging "slot" for single-thread workqueues
which will have a valid percpu allocation. Since alloc_percpu keys off of
cpu_possible_map, which must not change after initialization, make this
slot == first_cpu(cpu_possible_map).
Signed-off-by: Nathan Lynch <ntl@pobox.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
---
kernel/workqueue.c | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)
Index: linux-2.6.15.y/kernel/workqueue.c
===================================================================
--- linux-2.6.15.y.orig/kernel/workqueue.c
+++ linux-2.6.15.y/kernel/workqueue.c
@@ -29,7 +29,8 @@
#include <linux/kthread.h>
/*
- * The per-CPU workqueue (if single thread, we always use cpu 0's).
+ * The per-CPU workqueue (if single thread, we always use the first
+ * possible cpu).
*
* The sequence counters are for flush_scheduled_work(). It wants to wait
* until until all currently-scheduled works are completed, but it doesn't
@@ -69,6 +70,8 @@ struct workqueue_struct {
static DEFINE_SPINLOCK(workqueue_lock);
static LIST_HEAD(workqueues);
+static int singlethread_cpu;
+
/* If it's single threaded, it isn't in the list of workqueues. */
static inline int is_single_threaded(struct workqueue_struct *wq)
{
@@ -102,7 +105,7 @@ int fastcall queue_work(struct workqueue
if (!test_and_set_bit(0, &work->pending)) {
if (unlikely(is_single_threaded(wq)))
- cpu = any_online_cpu(cpu_online_map);
+ cpu = singlethread_cpu;
BUG_ON(!list_empty(&work->entry));
__queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
ret = 1;
@@ -118,7 +121,7 @@ static void delayed_work_timer_fn(unsign
int cpu = smp_processor_id();
if (unlikely(is_single_threaded(wq)))
- cpu = any_online_cpu(cpu_online_map);
+ cpu = singlethread_cpu;
__queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
}
@@ -267,7 +270,7 @@ void fastcall flush_workqueue(struct wor
if (is_single_threaded(wq)) {
/* Always use first cpu's area. */
- flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, any_online_cpu(cpu_online_map)));
+ flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, singlethread_cpu));
} else {
int cpu;
@@ -320,7 +323,7 @@ struct workqueue_struct *__create_workqu
lock_cpu_hotplug();
if (singlethread) {
INIT_LIST_HEAD(&wq->list);
- p = create_workqueue_thread(wq, any_online_cpu(cpu_online_map));
+ p = create_workqueue_thread(wq, singlethread_cpu);
if (!p)
destroy = 1;
else
@@ -374,7 +377,7 @@ void destroy_workqueue(struct workqueue_
/* We don't need the distraction of CPUs appearing and vanishing. */
lock_cpu_hotplug();
if (is_single_threaded(wq))
- cleanup_workqueue_thread(wq, any_online_cpu(cpu_online_map));
+ cleanup_workqueue_thread(wq, singlethread_cpu);
else {
for_each_online_cpu(cpu)
cleanup_workqueue_thread(wq, cpu);
@@ -543,6 +546,7 @@ static int __devinit workqueue_cpu_callb
void init_workqueues(void)
{
+ singlethread_cpu = first_cpu(cpu_possible_map);
hotcpu_notifier(workqueue_cpu_callback, 0);
keventd_wq = create_workqueue("events");
BUG_ON(!keventd_wq);
--
next prev parent reply other threads:[~2006-01-13 3:23 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-01-13 2:37 [PATCH 00/17] -stable review Chris Wright
2006-01-13 2:37 ` [PATCH 01/17] BRIDGE: Fix faulty check in br_stp_recalculate_bridge_id() Chris Wright
2006-01-13 18:46 ` Ingo Oeser
2006-01-13 19:39 ` Chris Wright
2006-01-14 13:33 ` Ingo Oeser
2006-01-13 2:37 ` [PATCH 02/17] UFS: inode->i_sem is not released in error path Chris Wright
2006-01-13 2:37 ` [PATCH 03/17] [PATCH] skge: handle out of memory on ring changes Chris Wright
2006-01-13 2:37 ` [PATCH 04/17] [ATYFB]: Fix onboard video on SPARC Blade 100 for 2.6.{13,14,15} Chris Wright
2006-01-13 2:37 ` [PATCH 05/17] ppc32: Re-add embed_config.c to ml300/ep405 Chris Wright
2006-01-13 2:37 ` [PATCH 06/17] [PATCH] vgacon: fix doublescan mode Chris Wright
2006-01-13 2:37 ` Chris Wright [this message]
2006-01-13 2:37 ` [PATCH 08/17] [PATCH] netlink oops fix due to incorrect error code Chris Wright
2006-01-13 2:37 ` [PATCH 09/17] [NETFILTER]: Fix crash in ip_nat_pptp Chris Wright
2006-01-13 2:37 ` [PATCH 10/17] [NETFILTER]: Fix another " Chris Wright
2006-01-13 2:37 ` [PATCH 11/17] [EBTABLES] Dont match tcp/udp source/destination port for IP fragments Chris Wright
2006-01-13 2:37 ` [PATCH 12/17] [SPARC64]: Fix ptrace/strace Chris Wright
2006-01-13 2:37 ` [PATCH 13/17] [SPARC64]: Fix sys_fstat64() entry in 64-bit syscall table Chris Wright
2006-01-13 2:37 ` [PATCH 14/17] [AF_NETLINK]: Fix DoS in netlink_rcv_skb() (CVE-2006-0035) Chris Wright
2006-01-13 2:37 ` [PATCH 15/17] [PATCH] moxa serial: add proper capability check Chris Wright
2006-01-13 9:00 ` Alan Cox
2006-01-13 2:37 ` [PATCH 16/17] " [PATCH] fix /sys/class/net/" <if>/wireless without dev->get_wireless_stats Chris Wright
2006-01-13 2:37 ` [PATCH 17/17] [PATCH] arch/sparc64/Kconfig: fix HUGETLB_PAGE_SIZE_64K dependencies Chris Wright
2006-01-13 15:15 ` Remove slashed from disk names when creation dev names in sysfs patch in stable? (was: Re: [PATCH 00/17] -stable review) Sander
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=20060113032243.154673000@sorel.sous-sol.org \
--to=chrisw@sous-sol.org \
--cc=akpm@osdl.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=chuckw@quantumlinux.com \
--cc=davej@redhat.com \
--cc=jmforbes@linuxtx.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ntl@pobox.com \
--cc=rdunlap@xenotime.net \
--cc=stable@kernel.org \
--cc=torvalds@osdl.org \
--cc=tytso@mit.edu \
--cc=zwane@arm.linux.org.uk \
/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;
as well as URLs for NNTP newsgroup(s).