mirror of
https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9.git
synced 2026-09-09 00:08:12 +08:00
Merge: Apply select fixes to drivers/watchdog
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/8388 JIRA: https://issues.redhat.com/browse/RHEL-192487 These commits fix potential bugs in RHEL. Signed-off-by: David Arcari <darcari@redhat.com> Approved-by: Tony Camuso <tcamuso@redhat.com> Approved-by: Ricardo Robaina <rrobaina@redhat.com> Approved-by: Steve Best <sbest@redhat.com> Approved-by: Rafael Aquini <raquini@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
This commit is contained in:
@@ -1034,6 +1034,7 @@ static int watchdog_cdev_register(struct watchdog_device *wdd)
|
||||
|
||||
/* Fill in the data structures */
|
||||
cdev_init(&wd_data->cdev, &watchdog_fops);
|
||||
wd_data->cdev.owner = wdd->ops->owner;
|
||||
|
||||
/* Add the device */
|
||||
err = cdev_device_add(&wd_data->cdev, &wd_data->dev);
|
||||
@@ -1043,13 +1044,11 @@ static int watchdog_cdev_register(struct watchdog_device *wdd)
|
||||
if (wdd->id == 0) {
|
||||
misc_deregister(&watchdog_miscdev);
|
||||
old_wd_data = NULL;
|
||||
put_device(&wd_data->dev);
|
||||
}
|
||||
put_device(&wd_data->dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
wd_data->cdev.owner = wdd->ops->owner;
|
||||
|
||||
/* Record time of most recent heartbeat as 'just before now'. */
|
||||
wd_data->last_hw_keepalive = ktime_sub(ktime_get(), 1);
|
||||
watchdog_set_open_deadline(wd_data);
|
||||
|
||||
+29
-15
@@ -40,6 +40,7 @@ int __read_mostly watchdog_user_enabled = 1;
|
||||
static int __read_mostly watchdog_hardlockup_user_enabled = WATCHDOG_HARDLOCKUP_DEFAULT;
|
||||
static int __read_mostly watchdog_softlockup_user_enabled = 1;
|
||||
int __read_mostly watchdog_thresh = 10;
|
||||
static int __read_mostly watchdog_thresh_next;
|
||||
static int __read_mostly watchdog_hardlockup_available;
|
||||
|
||||
struct cpumask watchdog_cpumask __read_mostly;
|
||||
@@ -684,12 +685,20 @@ int lockup_detector_offline_cpu(unsigned int cpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __lockup_detector_reconfigure(void)
|
||||
static void __lockup_detector_reconfigure(bool thresh_changed)
|
||||
{
|
||||
cpus_read_lock();
|
||||
watchdog_hardlockup_stop();
|
||||
|
||||
softlockup_stop_all();
|
||||
/*
|
||||
* To prevent watchdog_timer_fn from using the old interval and
|
||||
* the new watchdog_thresh at the same time, which could lead to
|
||||
* false softlockup reports, it is necessary to update the
|
||||
* watchdog_thresh after the softlockup is completed.
|
||||
*/
|
||||
if (thresh_changed)
|
||||
watchdog_thresh = READ_ONCE(watchdog_thresh_next);
|
||||
set_sample_period();
|
||||
lockup_detector_update_enable();
|
||||
if (watchdog_enabled && watchdog_thresh)
|
||||
@@ -707,7 +716,7 @@ static void __lockup_detector_reconfigure(void)
|
||||
void lockup_detector_reconfigure(void)
|
||||
{
|
||||
mutex_lock(&watchdog_mutex);
|
||||
__lockup_detector_reconfigure();
|
||||
__lockup_detector_reconfigure(false);
|
||||
mutex_unlock(&watchdog_mutex);
|
||||
}
|
||||
|
||||
@@ -727,27 +736,29 @@ static __init void lockup_detector_setup(void)
|
||||
return;
|
||||
|
||||
mutex_lock(&watchdog_mutex);
|
||||
__lockup_detector_reconfigure();
|
||||
__lockup_detector_reconfigure(false);
|
||||
softlockup_initialized = true;
|
||||
mutex_unlock(&watchdog_mutex);
|
||||
}
|
||||
|
||||
#else /* CONFIG_SOFTLOCKUP_DETECTOR */
|
||||
static void __lockup_detector_reconfigure(void)
|
||||
static void __lockup_detector_reconfigure(bool thresh_changed)
|
||||
{
|
||||
cpus_read_lock();
|
||||
watchdog_hardlockup_stop();
|
||||
if (thresh_changed)
|
||||
watchdog_thresh = READ_ONCE(watchdog_thresh_next);
|
||||
lockup_detector_update_enable();
|
||||
watchdog_hardlockup_start();
|
||||
cpus_read_unlock();
|
||||
}
|
||||
void lockup_detector_reconfigure(void)
|
||||
{
|
||||
__lockup_detector_reconfigure();
|
||||
__lockup_detector_reconfigure(false);
|
||||
}
|
||||
static inline void lockup_detector_setup(void)
|
||||
{
|
||||
__lockup_detector_reconfigure();
|
||||
__lockup_detector_reconfigure(false);
|
||||
}
|
||||
#endif /* !CONFIG_SOFTLOCKUP_DETECTOR */
|
||||
|
||||
@@ -783,11 +794,11 @@ void lockup_detector_soft_poweroff(void)
|
||||
#ifdef CONFIG_SYSCTL
|
||||
|
||||
/* Propagate any changes to the watchdog infrastructure */
|
||||
static void proc_watchdog_update(void)
|
||||
static void proc_watchdog_update(bool thresh_changed)
|
||||
{
|
||||
/* Remove impossible cpus to keep sysctl output clean. */
|
||||
cpumask_and(&watchdog_cpumask, &watchdog_cpumask, cpu_possible_mask);
|
||||
__lockup_detector_reconfigure();
|
||||
__lockup_detector_reconfigure(thresh_changed);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -809,6 +820,7 @@ static int proc_watchdog_common(int which, struct ctl_table *table, int write,
|
||||
|
||||
mutex_lock(&watchdog_mutex);
|
||||
|
||||
old = *param;
|
||||
if (!write) {
|
||||
/*
|
||||
* On read synchronize the userspace interface. This is a
|
||||
@@ -816,11 +828,11 @@ static int proc_watchdog_common(int which, struct ctl_table *table, int write,
|
||||
*/
|
||||
*param = (watchdog_enabled & which) != 0;
|
||||
err = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
|
||||
*param = old;
|
||||
} else {
|
||||
old = READ_ONCE(*param);
|
||||
err = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
|
||||
if (!err && old != READ_ONCE(*param))
|
||||
proc_watchdog_update();
|
||||
proc_watchdog_update(false);
|
||||
}
|
||||
mutex_unlock(&watchdog_mutex);
|
||||
return err;
|
||||
@@ -869,11 +881,13 @@ int proc_watchdog_thresh(struct ctl_table *table, int write,
|
||||
|
||||
mutex_lock(&watchdog_mutex);
|
||||
|
||||
old = READ_ONCE(watchdog_thresh);
|
||||
watchdog_thresh_next = READ_ONCE(watchdog_thresh);
|
||||
|
||||
old = watchdog_thresh_next;
|
||||
err = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
|
||||
|
||||
if (!err && write && old != READ_ONCE(watchdog_thresh))
|
||||
proc_watchdog_update();
|
||||
if (!err && write && old != READ_ONCE(watchdog_thresh_next))
|
||||
proc_watchdog_update(true);
|
||||
|
||||
mutex_unlock(&watchdog_mutex);
|
||||
return err;
|
||||
@@ -894,7 +908,7 @@ int proc_watchdog_cpumask(struct ctl_table *table, int write,
|
||||
|
||||
err = proc_do_large_bitmap(table, write, buffer, lenp, ppos);
|
||||
if (!err && write)
|
||||
proc_watchdog_update();
|
||||
proc_watchdog_update(false);
|
||||
|
||||
mutex_unlock(&watchdog_mutex);
|
||||
return err;
|
||||
@@ -914,7 +928,7 @@ static struct ctl_table watchdog_sysctls[] = {
|
||||
},
|
||||
{
|
||||
.procname = "watchdog_thresh",
|
||||
.data = &watchdog_thresh,
|
||||
.data = &watchdog_thresh_next,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_watchdog_thresh,
|
||||
|
||||
Reference in New Issue
Block a user