linux/drivers/char/hangcheck-timer.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * hangcheck-timer.c
 *
 * Driver for a little io fencing timer.
 *
 * Copyright (C) 2002, 2003 Oracle.  All rights reserved.
 *
 * Author: Joel Becker <[email protected]>
 */

/*
 * The hangcheck-timer driver uses the TSC to catch delays that
 * jiffies does not notice.  A timer is set.  When the timer fires, it
 * checks whether it was delayed and if that delay exceeds a given
 * margin of error.  The hangcheck_tick module parameter takes the timer
 * duration in seconds.  The hangcheck_margin parameter defines the
 * margin of error, in seconds.  The defaults are 60 seconds for the
 * timer and 180 seconds for the margin of error.  IOW, a timer is set
 * for 60 seconds.  When the timer fires, the callback checks the
 * actual duration that the timer waited.  If the duration exceeds the
 * allotted time and margin (here 60 + 180, or 240 seconds), the machine
 * is restarted.  A healthy machine will have the duration match the
 * expected timeout very closely.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/sysrq.h>
#include <linux/timer.h>
#include <linux/hrtimer.h>

#define VERSION_STR

#define DEFAULT_IOFENCE_MARGIN
#define DEFAULT_IOFENCE_TICK

static int hangcheck_tick =;
static int hangcheck_margin =;
static int hangcheck_reboot;  /* Defaults to not reboot */
static int hangcheck_dump_tasks;  /* Defaults to not dumping SysRQ T */

/* options - modular */
module_param(hangcheck_tick, int, 0);
MODULE_PARM_DESC();
module_param(hangcheck_margin, int, 0);
MODULE_PARM_DESC();
module_param(hangcheck_reboot, int, 0);
MODULE_PARM_DESC();
module_param(hangcheck_dump_tasks, int, 0);
MODULE_PARM_DESC();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_VERSION();

/* options - nonmodular */
#ifndef MODULE

static int __init hangcheck_parse_tick(char *str)
{}

static int __init hangcheck_parse_margin(char *str)
{}

static int __init hangcheck_parse_reboot(char *str)
{}

static int __init hangcheck_parse_dump_tasks(char *str)
{}

__setup();
__setup();
__setup();
__setup();
#endif /* not MODULE */

#define TIMER_FREQ

/* Last time scheduled */
static unsigned long long hangcheck_tsc, hangcheck_tsc_margin;

static void hangcheck_fire(struct timer_list *);

static DEFINE_TIMER(hangcheck_ticktock, hangcheck_fire);

static void hangcheck_fire(struct timer_list *unused)
{}


static int __init hangcheck_init(void)
{}


static void __exit hangcheck_exit(void)
{}

module_init();
module_exit(hangcheck_exit);