|
2 | 2 | #include <linux/mm.h> |
3 | 3 | #include <linux/gfp.h> |
4 | 4 | #include <linux/kernel.h> |
| 5 | +#include <linux/workqueue.h> |
5 | 6 |
|
6 | 7 | #include <asm/mce.h> |
7 | 8 |
|
@@ -123,16 +124,12 @@ static u64 dfs_pfn; |
123 | 124 | /* Amount of errors after which we offline */ |
124 | 125 | static unsigned int count_threshold = COUNT_MASK; |
125 | 126 |
|
126 | | -/* |
127 | | - * The timer "decays" element count each timer_interval which is 24hrs by |
128 | | - * default. |
129 | | - */ |
130 | | - |
131 | | -#define CEC_TIMER_DEFAULT_INTERVAL 24 * 60 * 60 /* 24 hrs */ |
132 | | -#define CEC_TIMER_MIN_INTERVAL 1 * 60 * 60 /* 1h */ |
133 | | -#define CEC_TIMER_MAX_INTERVAL 30 * 24 * 60 * 60 /* one month */ |
134 | | -static struct timer_list cec_timer; |
135 | | -static u64 timer_interval = CEC_TIMER_DEFAULT_INTERVAL; |
| 127 | +/* Each element "decays" each decay_interval which is 24hrs by default. */ |
| 128 | +#define CEC_DECAY_DEFAULT_INTERVAL 24 * 60 * 60 /* 24 hrs */ |
| 129 | +#define CEC_DECAY_MIN_INTERVAL 1 * 60 * 60 /* 1h */ |
| 130 | +#define CEC_DECAY_MAX_INTERVAL 30 * 24 * 60 * 60 /* one month */ |
| 131 | +static struct delayed_work cec_work; |
| 132 | +static u64 decay_interval = CEC_DECAY_DEFAULT_INTERVAL; |
136 | 133 |
|
137 | 134 | /* |
138 | 135 | * Decrement decay value. We're using DECAY_BITS bits to denote decay of an |
@@ -160,20 +157,21 @@ static void do_spring_cleaning(struct ce_array *ca) |
160 | 157 | /* |
161 | 158 | * @interval in seconds |
162 | 159 | */ |
163 | | -static void cec_mod_timer(struct timer_list *t, unsigned long interval) |
| 160 | +static void cec_mod_work(unsigned long interval) |
164 | 161 | { |
165 | 162 | unsigned long iv; |
166 | 163 |
|
167 | | - iv = interval * HZ + jiffies; |
168 | | - |
169 | | - mod_timer(t, round_jiffies(iv)); |
| 164 | + iv = interval * HZ; |
| 165 | + mod_delayed_work(system_wq, &cec_work, round_jiffies(iv)); |
170 | 166 | } |
171 | 167 |
|
172 | | -static void cec_timer_fn(struct timer_list *unused) |
| 168 | +static void cec_work_fn(struct work_struct *work) |
173 | 169 | { |
| 170 | + mutex_lock(&ce_mutex); |
174 | 171 | do_spring_cleaning(&ce_arr); |
| 172 | + mutex_unlock(&ce_mutex); |
175 | 173 |
|
176 | | - cec_mod_timer(&cec_timer, timer_interval); |
| 174 | + cec_mod_work(decay_interval); |
177 | 175 | } |
178 | 176 |
|
179 | 177 | /* |
@@ -380,15 +378,15 @@ static int decay_interval_set(void *data, u64 val) |
380 | 378 | { |
381 | 379 | *(u64 *)data = val; |
382 | 380 |
|
383 | | - if (val < CEC_TIMER_MIN_INTERVAL) |
| 381 | + if (val < CEC_DECAY_MIN_INTERVAL) |
384 | 382 | return -EINVAL; |
385 | 383 |
|
386 | | - if (val > CEC_TIMER_MAX_INTERVAL) |
| 384 | + if (val > CEC_DECAY_MAX_INTERVAL) |
387 | 385 | return -EINVAL; |
388 | 386 |
|
389 | | - timer_interval = val; |
| 387 | + decay_interval = val; |
390 | 388 |
|
391 | | - cec_mod_timer(&cec_timer, timer_interval); |
| 389 | + cec_mod_work(decay_interval); |
392 | 390 | return 0; |
393 | 391 | } |
394 | 392 | DEFINE_DEBUGFS_ATTRIBUTE(decay_interval_ops, u64_get, decay_interval_set, "%lld\n"); |
@@ -432,7 +430,7 @@ static int array_dump(struct seq_file *m, void *v) |
432 | 430 |
|
433 | 431 | seq_printf(m, "Flags: 0x%x\n", ca->flags); |
434 | 432 |
|
435 | | - seq_printf(m, "Timer interval: %lld seconds\n", timer_interval); |
| 433 | + seq_printf(m, "Decay interval: %lld seconds\n", decay_interval); |
436 | 434 | seq_printf(m, "Decays: %lld\n", ca->decays_done); |
437 | 435 |
|
438 | 436 | seq_printf(m, "Action threshold: %d\n", count_threshold); |
@@ -478,7 +476,7 @@ static int __init create_debugfs_nodes(void) |
478 | 476 | } |
479 | 477 |
|
480 | 478 | decay = debugfs_create_file("decay_interval", S_IRUSR | S_IWUSR, d, |
481 | | - &timer_interval, &decay_interval_ops); |
| 479 | + &decay_interval, &decay_interval_ops); |
482 | 480 | if (!decay) { |
483 | 481 | pr_warn("Error creating decay_interval debugfs node!\n"); |
484 | 482 | goto err; |
@@ -514,8 +512,8 @@ void __init cec_init(void) |
514 | 512 | if (create_debugfs_nodes()) |
515 | 513 | return; |
516 | 514 |
|
517 | | - timer_setup(&cec_timer, cec_timer_fn, 0); |
518 | | - cec_mod_timer(&cec_timer, CEC_TIMER_DEFAULT_INTERVAL); |
| 515 | + INIT_DELAYED_WORK(&cec_work, cec_work_fn); |
| 516 | + schedule_delayed_work(&cec_work, CEC_DECAY_DEFAULT_INTERVAL); |
519 | 517 |
|
520 | 518 | pr_info("Correctable Errors collector initialized.\n"); |
521 | 519 | } |
|
0 commit comments