FAILED: patch "[PATCH] RAS/CEC: Convert the timer callback to a workqueue" failed to apply to 4.14-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 0ade0b6240c4853cf9725924c46c10f4251639d7 Mon Sep 17 00:00:00 2001
From: Cong Wang <[email protected]>
Date: Tue, 16 Apr 2019 14:33:51 -0700
Subject: [PATCH] RAS/CEC: Convert the timer callback to a workqueue
cec_timer_fn() is a timer callback which reads ce_arr.array[] and updates its decay values. However, it runs in interrupt context and the mutex protection the CEC uses for that array, is inadequate. Convert the used timer to a workqueue to keep the tasks the CEC performs preemptible and thus low-prio.
[ bp: Rewrite commit message.
s/timer/decay/gi to make it agnostic as to what facility is used. ]
drivers/ras/cec.c +22 -24
@@ -2,6 +2,7 @@#include <linux/mm.h> #include <linux/gfp.h> #include <linux/kernel.h> +#include <linux/workqueue.h> #include <asm/mce.h>
@@ -123,16 +124,12 @@ static u64 dfs_pfn;/* Amount of errors after which we offline */ static unsigned int count_threshold =COUNT_MASK ; -/* -* The timer "decays" element count each timer_interval which is 24hrs by -* default. -*/ - -#define CEC_TIMER_DEFAULT_INTERVAL 24 * 60 * 60/* 24 hrs */ -#define CEC_TIMER_MIN_INTERVAL 1 * 60 * 60/* 1h */ -#define CEC_TIMER_MAX_INTERVAL 30 * 24 * 60 * 60/* one month */ -static struct timer_list cec_timer; -static u64 timer_interval =CEC_TIMER_DEFAULT_INTERVAL ; +/* Each element "decays" each decay_interval which is 24hrs by default. */ +#define CEC_DECAY_DEFAULT_INTERVAL 24 * 60 * 60/* 24 hrs */ +#define CEC_DECAY_MIN_INTERVAL 1 * 60 * 60/* 1h */ +#define CEC_DECAY_MAX_INTERVAL 30 * 24 * 60 * 60/* one month */ +static struct delayed_work cec_work; +static u64 decay_interval =CEC_DECAY_DEFAULT_INTERVAL ;/* * 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)/* * @interval in seconds */ -static void cec_mod_timer (struct timer_list *t,unsigned long interval) +static void cec_mod_work (unsigned long interval) {unsigned long iv; - iv = interval *HZ + jiffies; - -mod_timer (t,round_jiffies (iv)); + iv = interval *HZ ; +mod_delayed_work (system_wq, &cec_work,round_jiffies (iv)); } -static void cec_timer_fn (struct timer_list *unused) +static void cec_work_fn (struct work_struct *work) { +mutex_lock (&ce_mutex);do_spring_cleaning (&ce_arr); +mutex_unlock (&ce_mutex); -cec_mod_timer (&cec_timer, timer_interval); +cec_mod_work (decay_interval); }/*
@@ -380,15 +378,15 @@ static int decay_interval_set(void *data, u64 val) { *(u64 *)data = val; -if (val <CEC_TIMER_MIN_INTERVAL ) +if (val <CEC_DECAY_MIN_INTERVAL )return -EINVAL ; -if (val >CEC_TIMER_MAX_INTERVAL ) +if (val >CEC_DECAY_MAX_INTERVAL )return -EINVAL ; - timer_interval = val; + decay_interval = val; -cec_mod_timer (&cec_timer, timer_interval); +cec_mod_work (decay_interval);return 0 ; }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)seq_printf (m,"Flags: 0x%x\n" , ca->flags); -seq_printf (m,"Timer interval: %lld seconds\n" , timer_interval); +seq_printf (m,"Decay interval: %lld seconds\n" , decay_interval);seq_printf (m,"Decays: %lld\n" , ca->decays_done);seq_printf (m,"Action threshold: %d\n" , count_threshold);
@@ -478,7 +476,7 @@ static int __init create_debugfs_nodes(void) } decay =debugfs_create_file ("decay_interval" ,S_IRUSR |S_IWUSR , d, - &timer_interval, &decay_interval_ops); + &decay_interval, &decay_interval_ops);if (!decay) {pr_warn ("Error creating decay_interval debugfs node!\n" ); goto err;
@@ -514,8 +512,8 @@ void __init cec_init(void)if (create_debugfs_nodes ())return ; -timer_setup (&cec_timer, cec_timer_fn,0 ); -cec_mod_timer (&cec_timer,CEC_TIMER_DEFAULT_INTERVAL ); +INIT_DELAYED_WORK (&cec_work, cec_work_fn); +schedule_delayed_work (&cec_work,CEC_DECAY_DEFAULT_INTERVAL );pr_info ("Correctable Errors collector initialized.\n" ); }