aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ras/cec.c46
1 files changed, 22 insertions, 24 deletions
diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index dbfe3e61d2c2..673f8a128397 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -2,6 +2,7 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/gfp.h> 3#include <linux/gfp.h>
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/workqueue.h>
5 6
6#include <asm/mce.h> 7#include <asm/mce.h>
7 8
@@ -123,16 +124,12 @@ static u64 dfs_pfn;
123/* Amount of errors after which we offline */ 124/* Amount of errors after which we offline */
124static unsigned int count_threshold = COUNT_MASK; 125static unsigned int count_threshold = COUNT_MASK;
125 126
126/* 127/* Each element "decays" each decay_interval which is 24hrs by default. */
127 * The timer "decays" element count each timer_interval which is 24hrs by 128#define CEC_DECAY_DEFAULT_INTERVAL 24 * 60 * 60 /* 24 hrs */
128 * default. 129#define CEC_DECAY_MIN_INTERVAL 1 * 60 * 60 /* 1h */
129 */ 130#define CEC_DECAY_MAX_INTERVAL 30 * 24 * 60 * 60 /* one month */
130 131static struct delayed_work cec_work;
131#define CEC_TIMER_DEFAULT_INTERVAL 24 * 60 * 60 /* 24 hrs */ 132static u64 decay_interval = CEC_DECAY_DEFAULT_INTERVAL;
132#define CEC_TIMER_MIN_INTERVAL 1 * 60 * 60 /* 1h */
133#define CEC_TIMER_MAX_INTERVAL 30 * 24 * 60 * 60 /* one month */
134static struct timer_list cec_timer;
135static u64 timer_interval = CEC_TIMER_DEFAULT_INTERVAL;
136 133
137/* 134/*
138 * Decrement decay value. We're using DECAY_BITS bits to denote decay of an 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 * @interval in seconds 158 * @interval in seconds
162 */ 159 */
163static void cec_mod_timer(struct timer_list *t, unsigned long interval) 160static void cec_mod_work(unsigned long interval)
164{ 161{
165 unsigned long iv; 162 unsigned long iv;
166 163
167 iv = interval * HZ + jiffies; 164 iv = interval * HZ;
168 165 mod_delayed_work(system_wq, &cec_work, round_jiffies(iv));
169 mod_timer(t, round_jiffies(iv));
170} 166}
171 167
172static void cec_timer_fn(struct timer_list *unused) 168static void cec_work_fn(struct work_struct *work)
173{ 169{
170 mutex_lock(&ce_mutex);
174 do_spring_cleaning(&ce_arr); 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 *(u64 *)data = val; 379 *(u64 *)data = val;
382 380
383 if (val < CEC_TIMER_MIN_INTERVAL) 381 if (val < CEC_DECAY_MIN_INTERVAL)
384 return -EINVAL; 382 return -EINVAL;
385 383
386 if (val > CEC_TIMER_MAX_INTERVAL) 384 if (val > CEC_DECAY_MAX_INTERVAL)
387 return -EINVAL; 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 return 0; 390 return 0;
393} 391}
394DEFINE_DEBUGFS_ATTRIBUTE(decay_interval_ops, u64_get, decay_interval_set, "%lld\n"); 392DEFINE_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 seq_printf(m, "Flags: 0x%x\n", ca->flags); 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 seq_printf(m, "Decays: %lld\n", ca->decays_done); 434 seq_printf(m, "Decays: %lld\n", ca->decays_done);
437 435
438 seq_printf(m, "Action threshold: %d\n", count_threshold); 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 decay = debugfs_create_file("decay_interval", S_IRUSR | S_IWUSR, d, 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 if (!decay) { 480 if (!decay) {
483 pr_warn("Error creating decay_interval debugfs node!\n"); 481 pr_warn("Error creating decay_interval debugfs node!\n");
484 goto err; 482 goto err;
@@ -514,8 +512,8 @@ void __init cec_init(void)
514 if (create_debugfs_nodes()) 512 if (create_debugfs_nodes())
515 return; 513 return;
516 514
517 timer_setup(&cec_timer, cec_timer_fn, 0); 515 INIT_DELAYED_WORK(&cec_work, cec_work_fn);
518 cec_mod_timer(&cec_timer, CEC_TIMER_DEFAULT_INTERVAL); 516 schedule_delayed_work(&cec_work, CEC_DECAY_DEFAULT_INTERVAL);
519 517
520 pr_info("Correctable Errors collector initialized.\n"); 518 pr_info("Correctable Errors collector initialized.\n");
521} 519}