diff options
author | Dave Jiang <djiang@mvista.com> | 2007-07-19 04:49:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-19 13:04:54 -0400 |
commit | 81d87cb13e367bb804bf44889ae0de7369705d6c (patch) | |
tree | 1c135cb57d92ae3baf2b3308f01fb548ab39f644 /drivers/edac/edac_module.c | |
parent | 535c6a53035d8911f6b90455550c5fde0da7b866 (diff) |
drivers/edac: mod MC to use workq instead of kthread
Move the memory controller object to work queue based implementation from the
kernel thread based.
Signed-off-by: Dave Jiang <djiang@mvista.com>
Signed-off-by: Douglas Thompson <dougthompson@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/edac/edac_module.c')
-rw-r--r-- | drivers/edac/edac_module.c | 86 |
1 files changed, 11 insertions, 75 deletions
diff --git a/drivers/edac/edac_module.c b/drivers/edac/edac_module.c index 2f84f0d035be..dc900ed75178 100644 --- a/drivers/edac/edac_module.c +++ b/drivers/edac/edac_module.c | |||
@@ -1,6 +1,14 @@ | |||
1 | 1 | /* | |
2 | #include <linux/freezer.h> | 2 | * edac_module.c |
3 | #include <linux/kthread.h> | 3 | * |
4 | * (C) 2007 www.douglaskthompson.com | ||
5 | * This file is licensed under the terms of the GNU General Public | ||
6 | * License version 2. This program is licensed "as is" without any | ||
7 | * warranty of any kind, whether express or implied. | ||
8 | * | ||
9 | * Author: Doug Thompson <norsk5@xmission.com> | ||
10 | * | ||
11 | */ | ||
4 | #include <linux/edac.h> | 12 | #include <linux/edac.h> |
5 | 13 | ||
6 | #include "edac_core.h" | 14 | #include "edac_core.h" |
@@ -17,10 +25,6 @@ EXPORT_SYMBOL_GPL(edac_debug_level); | |||
17 | /* scope is to module level only */ | 25 | /* scope is to module level only */ |
18 | struct workqueue_struct *edac_workqueue; | 26 | struct workqueue_struct *edac_workqueue; |
19 | 27 | ||
20 | /* private to this file */ | ||
21 | static struct task_struct *edac_thread; | ||
22 | |||
23 | |||
24 | /* | 28 | /* |
25 | * sysfs object: /sys/devices/system/edac | 29 | * sysfs object: /sys/devices/system/edac |
26 | * need to export to other files in this modules | 30 | * need to export to other files in this modules |
@@ -84,63 +88,6 @@ static void edac_unregister_sysfs_edac_name(void) | |||
84 | edac_class_valid = 0; | 88 | edac_class_valid = 0; |
85 | } | 89 | } |
86 | 90 | ||
87 | |||
88 | /* | ||
89 | * Check MC status every edac_get_poll_msec(). | ||
90 | * Check PCI status every edac_get_poll_msec() as well. | ||
91 | * | ||
92 | * This where the work gets done for edac. | ||
93 | * | ||
94 | * SMP safe, doesn't use NMI, and auto-rate-limits. | ||
95 | */ | ||
96 | static void do_edac_check(void) | ||
97 | { | ||
98 | debugf3("%s()\n", __func__); | ||
99 | |||
100 | /* perform the poll activities */ | ||
101 | edac_check_mc_devices(); | ||
102 | edac_pci_do_parity_check(); | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * handler for EDAC to check if NMI type handler has asserted interrupt | ||
107 | */ | ||
108 | static int edac_assert_error_check_and_clear(void) | ||
109 | { | ||
110 | int vreg; | ||
111 | |||
112 | if(edac_op_state == EDAC_OPSTATE_POLL) | ||
113 | return 1; | ||
114 | |||
115 | vreg = atomic_read(&edac_err_assert); | ||
116 | if(vreg) { | ||
117 | atomic_set(&edac_err_assert, 0); | ||
118 | return 1; | ||
119 | } | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * Action thread for EDAC to perform the POLL operations | ||
126 | */ | ||
127 | static int edac_kernel_thread(void *arg) | ||
128 | { | ||
129 | int msec; | ||
130 | |||
131 | while (!kthread_should_stop()) { | ||
132 | if(edac_assert_error_check_and_clear()) | ||
133 | do_edac_check(); | ||
134 | |||
135 | /* goto sleep for the interval */ | ||
136 | msec = (HZ * edac_get_poll_msec()) / 1000; | ||
137 | schedule_timeout_interruptible(msec); | ||
138 | try_to_freeze(); | ||
139 | } | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | /* | 91 | /* |
145 | * edac_workqueue_setup | 92 | * edac_workqueue_setup |
146 | * initialize the edac work queue for polling operations | 93 | * initialize the edac work queue for polling operations |
@@ -221,19 +168,9 @@ static int __init edac_init(void) | |||
221 | goto error_pci; | 168 | goto error_pci; |
222 | } | 169 | } |
223 | 170 | ||
224 | /* create our kernel thread */ | ||
225 | edac_thread = kthread_run(edac_kernel_thread, NULL, "kedac"); | ||
226 | |||
227 | if (IS_ERR(edac_thread)) { | ||
228 | err = PTR_ERR(edac_thread); | ||
229 | goto error_work; | ||
230 | } | ||
231 | |||
232 | return 0; | 171 | return 0; |
233 | 172 | ||
234 | /* Error teardown stack */ | 173 | /* Error teardown stack */ |
235 | error_work: | ||
236 | edac_workqueue_teardown(); | ||
237 | error_pci: | 174 | error_pci: |
238 | edac_sysfs_pci_teardown(); | 175 | edac_sysfs_pci_teardown(); |
239 | error_mem: | 176 | error_mem: |
@@ -251,7 +188,6 @@ error: | |||
251 | static void __exit edac_exit(void) | 188 | static void __exit edac_exit(void) |
252 | { | 189 | { |
253 | debugf0("%s()\n", __func__); | 190 | debugf0("%s()\n", __func__); |
254 | kthread_stop(edac_thread); | ||
255 | 191 | ||
256 | /* tear down the various subsystems*/ | 192 | /* tear down the various subsystems*/ |
257 | edac_workqueue_teardown(); | 193 | edac_workqueue_teardown(); |