|
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