[PATCH 4.6 007/203] EDAC: Fix workqueues poll period resetting

From: Greg Kroah-Hartman
Date: Mon Jul 25 2016 - 18:23:46 EST


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

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

From: Nicholas Krause <xerofoify@xxxxxxxxx>

commit fbedcaf43fba35677c01a4ae51e6f79edf4049ba upstream.

After the workqueue cleanup, we're registering workqueues based on
the presence of an ->edac_check function. When that is the case,
we're setting OP_RUNNING_POLL. But we forgot to check that in
edac_mc_reset_delay_period(), leading to:

BUG: unable to handle kernel paging request at 0000000000015d10
IP: [ .. ] queued_spin_lock_slowpath
PGD 3ffcc8067 PUD 3ffc56067 PMD 0
Oops: 0002 [#1] SMP
Modules linked in: ...
CPU: 1 PID: 2792 Comm: edactest Not tainted 4.6.0-dirty #1
Hardware name: HP ProLiant MicroServer, BIOS O41 10/01/2013
Stack:
Call Trace:
? _raw_spin_lock_irqsave
? lock_timer_base.isra.34
? del_timer
? try_to_grab_pending
? mod_delayed_work_on
? edac_mc_reset_delay_period
? edac_set_poll_msec
? param_attr_store
? module_attr_store
? kernfs_fop_write
? __vfs_write
? __vfs_read
? __alloc_fd
? vfs_write
? SyS_write
? entry_SYSCALL_64_fastpath
Code:
RIP [ .. ] queued_spin_lock_slowpath
RSP <>
CR2: 0000000000015d10
---[ end trace 3f286bc71cca15d1 ]---
Kernel panic - not syncing: Fatal exception

Fix it.

Signed-off-by: Nicholas Krause <xerofoify@xxxxxxxxx>
Cc: Mauro Carvalho Chehab <mchehab@xxxxxxxxxxxxxxx>
Cc: linux-edac <linux-edac@xxxxxxxxxxxxxxx>
Link: http://lkml.kernel.org/r/1463697958-13406-1-git-send-email-xerofoify@xxxxxxxxx
[ Rewrite commit message. ]
Signed-off-by: Borislav Petkov <bp@xxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/edac/edac_mc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -565,7 +565,8 @@ void edac_mc_reset_delay_period(unsigned
list_for_each(item, &mc_devices) {
mci = list_entry(item, struct mem_ctl_info, link);

- edac_mod_work(&mci->work, value);
+ if (mci->op_state == OP_RUNNING_POLL)
+ edac_mod_work(&mci->work, value);
}
mutex_unlock(&mem_ctls_mutex);
}