From: Oleg Nesterov <oleg@redhat.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>,
Thomas Gleixner <tglx@linutronix.de>,
Mike Galbraith <efault@gmx.de>, Ingo Molnar <mingo@elte.hu>,
LKML <linux-kernel@vger.kernel.org>,
pm list <linux-pm@lists.linux-foundation.org>,
Greg KH <gregkh@suse.de>, Jesse Barnes <jbarnes@virtuousgeek.org>,
Tejun Heo <tj@kernel.org>
Subject: Re: GPF in run_workqueue()/list_del_init(cwq->worklist.next) on resume (was: Re: Help needed: Resume problems in 2.6.32-rc, perhaps related to preempt_count leakage in keventd)
Date: Wed, 11 Nov 2009 17:13:48 +0100 [thread overview]
Message-ID: <20091111161348.GA27394@redhat.com> (raw)
In-Reply-To: <alpine.LFD.2.01.0911101343590.31845@localhost.localdomain>
On 11/10, Linus Torvalds wrote:
>
> > In the meantime I got another trace, this time with a slab corruption involved.
> > Note that it crashed in exactly the same place as previously.
>
> I'm leaving your crash log appended for the new cc's, and I would not be
> at all surprised to hear that the slab corruption is related. The whole
> 6b6b6b6b pattern does imply a use-after-free on the workqueue,
Yes, RCX = 6b6b6b6b6b6b6b6b, and according to decodecode the faulting
instruction is "mov %rdx,0x8(%rcx)". Looks like the pending work was
freed.
Rafael, could you reproduce the problem with the debugging patch below?
It tries to detect the case when the pending work was corrupted and
prints its work->func (saved in the previous item). It should work
if the work_struct was freed and poisoned, or if it was re-initialized.
See ck_work().
Oleg.
--- TH/include/linux/workqueue.h~WQ_DBG 2009-10-15 12:09:50.000000000 +0200
+++ TH/include/linux/workqueue.h 2009-11-11 16:20:16.000000000 +0100
@@ -27,6 +27,7 @@ struct work_struct {
#define WORK_STRUCT_PENDING 0 /* T if work item pending execution */
#define WORK_STRUCT_FLAG_MASK (3UL)
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
+ work_func_t next_func;
struct list_head entry;
work_func_t func;
#ifdef CONFIG_LOCKDEP
@@ -65,7 +66,7 @@ struct execute_work {
#define __WORK_INITIALIZER(n, f) { \
.data = WORK_DATA_INIT(), \
.entry = { &(n).entry, &(n).entry }, \
- .func = (f), \
+ .func = (f), .next_func = NULL, \
__WORK_INIT_LOCKDEP_MAP(#n, &(n)) \
}
--- TH/kernel/workqueue.c~WQ_DBG 2009-10-17 20:25:07.000000000 +0200
+++ TH/kernel/workqueue.c 2009-11-11 16:49:53.000000000 +0100
@@ -36,6 +36,7 @@
#define CREATE_TRACE_POINTS
#include <trace/events/workqueue.h>
+#define tow(p) list_entry((p), struct work_struct, entry)
/*
* The per-CPU workqueue (if single thread, we always use the first
* possible cpu).
@@ -44,7 +45,9 @@ struct cpu_workqueue_struct {
spinlock_t lock;
+ work_func_t next_func;
struct list_head worklist;
+
wait_queue_head_t more_work;
struct work_struct *current_work;
@@ -137,6 +140,10 @@ static void insert_work(struct cpu_workq
*/
smp_wmb();
list_add_tail(&work->entry, head);
+
+ work->next_func = tow(work->entry.next)->func;
+ tow(work->entry.prev)->next_func = work->func;
+
wake_up(&cwq->more_work);
}
@@ -261,9 +268,22 @@ int queue_delayed_work_on(int cpu, struc
}
EXPORT_SYMBOL_GPL(queue_delayed_work_on);
+static int ck_work(struct cpu_workqueue_struct *cwq, struct work_struct *work)
+{
+ if (cwq->next_func == work->func && cwq == get_wq_data(work) &&
+ work->entry.prev == &cwq->worklist &&
+ test_bit(WORK_STRUCT_PENDING, work_data_bits(work)))
+ return 0;
+
+ printk(KERN_CRIT "ERR!! ");
+ print_symbol("%s\n", (unsigned long)cwq->next_func);
+ return 1;
+}
+
static void run_workqueue(struct cpu_workqueue_struct *cwq)
{
spin_lock_irq(&cwq->lock);
+again:
while (!list_empty(&cwq->worklist)) {
struct work_struct *work = list_entry(cwq->worklist.next,
struct work_struct, entry);
@@ -279,8 +299,20 @@ static void run_workqueue(struct cpu_wor
*/
struct lockdep_map lockdep_map = work->lockdep_map;
#endif
+ if (ck_work(cwq, work)) {
+ struct list_head *pos = &cwq->worklist;
+ while (pos->prev != &work->entry)
+ pos = pos->prev;
+
+ cwq->next_func = tow(pos)->func;
+ cwq->worklist.next = pos;
+ pos->prev = &cwq->worklist;
+ goto again;
+ }
+
trace_workqueue_execution(cwq->thread, work);
cwq->current_work = work;
+ cwq->next_func = work->next_func;
list_del_init(cwq->worklist.next);
spin_unlock_irq(&cwq->lock);
@@ -485,6 +517,7 @@ static int try_to_grab_pending(struct wo
*/
smp_rmb();
if (cwq == get_wq_data(work)) {
+ tow(work->entry.prev)->next_func = work->next_func;
list_del_init(&work->entry);
ret = 1;
}
next prev parent reply other threads:[~2009-11-11 16:19 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-09 11:50 Help needed: Resume problems in 2.6.32-rc, perhaps related to preempt_count leakage in keventd Rafael J. Wysocki
2009-11-09 12:02 ` Ingo Molnar
2009-11-09 12:24 ` Rafael J. Wysocki
2009-11-09 12:49 ` Ingo Molnar
2009-11-09 14:02 ` Thomas Gleixner
2009-11-09 14:16 ` Mike Galbraith
2009-11-09 14:27 ` Rafael J. Wysocki
2009-11-09 14:30 ` Mike Galbraith
2009-11-09 15:47 ` Rafael J. Wysocki
2009-11-09 16:19 ` Mike Galbraith
2009-11-09 17:36 ` Rafael J. Wysocki
2009-11-09 18:50 ` Thomas Gleixner
2009-11-09 20:00 ` Rafael J. Wysocki
2009-11-09 20:31 ` [linux-pm] " Alan Stern
2009-11-09 20:48 ` Rafael J. Wysocki
2009-11-09 21:24 ` Alan Stern
2009-11-09 20:45 ` GPF in run_workqueue()/list_del_init(cwq->worklist.next) on resume (was: Re: Help needed: Resume problems in 2.6.32-rc, perhaps related to preempt_count leakage in keventd) Rafael J. Wysocki
2009-11-09 21:42 ` Linus Torvalds
2009-11-10 0:19 ` Rafael J. Wysocki
2009-11-10 22:02 ` Linus Torvalds
2009-11-11 8:08 ` GPF in run_workqueue()/list_del_init(cwq->worklist.next) on resume Tejun Heo
2009-11-11 18:13 ` Oleg Nesterov
2009-11-12 4:56 ` Tejun Heo
2009-11-12 18:35 ` Oleg Nesterov
2009-11-12 19:14 ` Tejun Heo
2009-11-16 11:01 ` Tejun Heo
2009-11-11 11:52 ` GPF in run_workqueue()/list_del_init(cwq->worklist.next) on resume (was: Re: Help needed: Resume problems in 2.6.32-rc, perhaps related to preempt_count leakage in keventd) Rafael J. Wysocki
2009-11-11 19:52 ` Linus Torvalds
2009-11-11 20:18 ` Marcel Holtmann
2009-11-11 20:25 ` Linus Torvalds
2009-11-11 21:18 ` Rafael J. Wysocki
2009-11-11 21:13 ` Oliver Neukum
2009-11-11 21:38 ` Linus Torvalds
2009-11-11 21:44 ` Oliver Neukum
2009-11-11 16:13 ` Oleg Nesterov [this message]
2009-11-11 20:00 ` Rafael J. Wysocki
2009-11-11 20:11 ` Linus Torvalds
2009-11-11 20:20 ` Marcel Holtmann
2009-11-11 20:24 ` Oleg Nesterov
2009-11-11 21:15 ` Oliver Neukum
2009-11-11 17:17 ` Oleg Nesterov
2009-11-12 17:33 ` Thomas Gleixner
2009-11-12 19:17 ` GPF in run_workqueue()/list_del_init(cwq->worklist.next) on resume Tejun Heo
2009-11-12 20:53 ` Thomas Gleixner
2009-11-12 20:53 ` GPF in run_workqueue()/list_del_init(cwq->worklist.next) on resume (was: Re: Help needed: Resume problems in 2.6.32-rc, perhaps related to preempt_count leakage in keventd) Rafael J. Wysocki
2009-11-12 20:55 ` Thomas Gleixner
2009-11-12 22:55 ` Rafael J. Wysocki
2009-11-12 23:08 ` Thomas Gleixner
2009-11-15 23:37 ` Frederic Weisbecker
2009-11-15 23:40 ` Frederic Weisbecker
2009-11-09 19:13 ` Help needed: Resume problems in 2.6.32-rc, perhaps related to preempt_count leakage in keventd Thomas Gleixner
2009-11-09 20:03 ` Rafael J. Wysocki
2009-11-09 14:26 ` Rafael J. Wysocki
2009-11-09 14:44 ` Mike Galbraith
2009-11-09 15:47 ` Rafael J. Wysocki
2009-11-09 15:57 ` Linus Torvalds
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=20091111161348.GA27394@redhat.com \
--to=oleg@redhat.com \
--cc=efault@gmx.de \
--cc=gregkh@suse.de \
--cc=jbarnes@virtuousgeek.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=mingo@elte.hu \
--cc=rjw@sisk.pl \
--cc=tglx@linutronix.de \
--cc=tj@kernel.org \
--cc=torvalds@linux-foundation.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