29 Apr, 2020

1 commit

  • [ Upstream commit 982bb70517aef2225bad1d802887b733db492cc0 ]

    Currently the watchdog core does not initialize the last_hw_keepalive
    time during watchdog startup. This will cause the watchdog to be pinged
    immediately if enough time has passed from the system boot-up time, and
    some types of watchdogs like K3 RTI does not like this.

    To avoid the issue, setup the last_hw_keepalive time during watchdog
    startup.

    Signed-off-by: Tero Kristo
    Reviewed-by: Guenter Roeck
    Link: https://lore.kernel.org/r/20200302200426.6492-3-t-kristo@ti.com
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck
    Signed-off-by: Sasha Levin

    Tero Kristo
     

11 Feb, 2020

1 commit

  • commit 69503e585192fdd84b240f18a0873d20e18a2e0a upstream.

    After the commit 44ea39420fc9 ("drivers/watchdog: make use of
    devm_register_reboot_notifier()") the struct notifier_block reboot_nb in
    the struct watchdog_device is removed from the reboot notifiers chain at
    the time watchdog's chardev is closed. But at least in i6300esb.c case
    reboot_nb is embedded in the struct esb_dev which can be freed on its
    device removal and before the chardev is closed, thus UAF at reboot:

    [ 7.728581] esb_probe: esb_dev.watchdog_device ffff91316f91ab28
    ts# uname -r note the address ^^^
    5.5.0-rc5-ae6088-wdog
    ts# ./openwdog0 &
    [1] 696
    ts# opened /dev/watchdog0, sleeping 10s...
    ts# echo 1 > /sys/devices/pci0000\:00/0000\:00\:09.0/remove
    [ 178.086079] devres:rel_nodes: dev ffff91317668a0b0 data ffff91316f91ab28
    esb_dev.watchdog_device.reboot_nb memory is freed here ^^^
    ts# ...woken up
    [ 181.459010] devres:rel_nodes: dev ffff913171781000 data ffff913174a1dae8
    [ 181.460195] devm_unreg_reboot_notifier: res ffff913174a1dae8 nb ffff91316f91ab78
    attempt to use memory already freed ^^^
    [ 181.461063] devm_unreg_reboot_notifier: nb->call 6b6b6b6b6b6b6b6b
    [ 181.461243] devm_unreg_reboot_notifier: nb->next 6b6b6b6b6b6b6b6b
    freed memory is filled with a slub poison ^^^
    [1]+ Done ./openwdog0
    ts# reboot
    [ 229.921862] systemd-shutdown[1]: Rebooting.
    [ 229.939265] notifier_call_chain: nb ffffffff9c6c2f20 nb->next ffffffff9c6d50c0
    [ 229.943080] notifier_call_chain: nb ffffffff9c6d50c0 nb->next 6b6b6b6b6b6b6b6b
    [ 229.946054] notifier_call_chain: nb 6b6b6b6b6b6b6b6b INVAL
    [ 229.957584] general protection fault: 0000 [#1] SMP
    [ 229.958770] CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted 5.5.0-rc5-ae6088-wdog
    [ 229.960224] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ...
    [ 229.963288] RIP: 0010:notifier_call_chain+0x66/0xd0
    [ 229.969082] RSP: 0018:ffffb20dc0013d88 EFLAGS: 00010246
    [ 229.970812] RAX: 000000000000002e RBX: 6b6b6b6b6b6b6b6b RCX: 00000000000008b3
    [ 229.972929] RDX: 0000000000000000 RSI: 0000000000000096 RDI: ffffffff9ccc46ac
    [ 229.975028] RBP: 0000000000000001 R08: 0000000000000000 R09: 00000000000008b3
    [ 229.977039] R10: 0000000000000001 R11: ffffffff9c26c740 R12: 0000000000000000
    [ 229.979155] R13: 6b6b6b6b6b6b6b6b R14: 0000000000000000 R15: 00000000fffffffa
    ... slub_debug=FZP poison ^^^
    [ 229.989089] Call Trace:
    [ 229.990157] blocking_notifier_call_chain+0x43/0x59
    [ 229.991401] kernel_restart_prepare+0x14/0x30
    [ 229.992607] kernel_restart+0x9/0x30
    [ 229.993800] __do_sys_reboot+0x1d2/0x210
    [ 230.000149] do_syscall_64+0x3d/0x130
    [ 230.001277] entry_SYSCALL_64_after_hwframe+0x44/0xa9
    [ 230.002639] RIP: 0033:0x7f5461bdd177
    [ 230.016402] Modules linked in: i6300esb
    [ 230.050261] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

    Fix the crash by reverting 44ea39420fc9 so unregister_reboot_notifier()
    is called when watchdog device is removed. This also makes handling of
    the reboot notifier unified with the handling of the restart handler,
    which is freed with unregister_restart_handler() in the same place.

    Fixes: 44ea39420fc9 ("drivers/watchdog: make use of devm_register_reboot_notifier()")
    Cc: stable@vger.kernel.org # v4.15+
    Signed-off-by: Vladis Dronov
    Reviewed-by: Guenter Roeck
    Link: https://lore.kernel.org/r/20200108125347.6067-1-vdronov@redhat.com
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck
    Signed-off-by: Greg Kroah-Hartman

    Vladis Dronov
     

05 Jan, 2020

2 commits

  • [ Upstream commit 72139dfa2464e43957d330266994740bb7be2535 ]

    The struct cdev is embedded in the struct watchdog_core_data. In the
    current code, we manage the watchdog_core_data with a kref, but the
    cdev is manged by a kobject. There is no any relationship between
    this kref and kobject. So it is possible that the watchdog_core_data is
    freed before the cdev is entirely released. We can easily get the
    following call trace with CONFIG_DEBUG_KOBJECT_RELEASE and
    CONFIG_DEBUG_OBJECTS_TIMERS enabled.
    ODEBUG: free active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x38
    WARNING: CPU: 23 PID: 1028 at lib/debugobjects.c:481 debug_print_object+0xb0/0xf0
    Modules linked in: softdog(-) deflate ctr twofish_generic twofish_common camellia_generic serpent_generic blowfish_generic blowfish_common cast5_generic cast_common cmac xcbc af_key sch_fq_codel openvswitch nsh nf_conncount nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4
    CPU: 23 PID: 1028 Comm: modprobe Not tainted 5.3.0-next-20190924-yoctodev-standard+ #180
    Hardware name: Marvell OcteonTX CN96XX board (DT)
    pstate: 00400009 (nzcv daif +PAN -UAO)
    pc : debug_print_object+0xb0/0xf0
    lr : debug_print_object+0xb0/0xf0
    sp : ffff80001cbcfc70
    x29: ffff80001cbcfc70 x28: ffff800010ea2128
    x27: ffff800010bad000 x26: 0000000000000000
    x25: ffff80001103c640 x24: ffff80001107b268
    x23: ffff800010bad9e8 x22: ffff800010ea2128
    x21: ffff000bc2c62af8 x20: ffff80001103c600
    x19: ffff800010e867d8 x18: 0000000000000060
    x17: 0000000000000000 x16: 0000000000000000
    x15: ffff000bd7240470 x14: 6e6968207473696c
    x13: 5f72656d6974203a x12: 6570797420746365
    x11: 6a626f2029302065 x10: 7461747320657669
    x9 : 7463612820657669 x8 : 3378302f3078302b
    x7 : 0000000000001d7a x6 : ffff800010fd5889
    x5 : 0000000000000000 x4 : 0000000000000000
    x3 : 0000000000000000 x2 : ffff000bff948548
    x1 : 276a1c9e1edc2300 x0 : 0000000000000000
    Call trace:
    debug_print_object+0xb0/0xf0
    debug_check_no_obj_freed+0x1e8/0x210
    kfree+0x1b8/0x368
    watchdog_cdev_unregister+0x88/0xc8
    watchdog_dev_unregister+0x38/0x48
    watchdog_unregister_device+0xa8/0x100
    softdog_exit+0x18/0xfec4 [softdog]
    __arm64_sys_delete_module+0x174/0x200
    el0_svc_handler+0xd0/0x1c8
    el0_svc+0x8/0xc

    This is a common issue when using cdev embedded in a struct.
    Fortunately, we already have a mechanism to solve this kind of issue.
    Please see commit 233ed09d7fda ("chardev: add helper function to
    register char devs with a struct device") for more detail.

    In this patch, we choose to embed the struct device into the
    watchdog_core_data, and use the API provided by the commit 233ed09d7fda
    to make sure that the release of watchdog_core_data and cdev are
    in sequence.

    Signed-off-by: Kevin Hao
    Reviewed-by: Guenter Roeck
    Link: https://lore.kernel.org/r/20191008112934.29669-1-haokexin@gmail.com
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck
    Signed-off-by: Sasha Levin

    Kevin Hao
     
  • [ Upstream commit a19f89335f4bda3d77d991c96583e3e51856acbb ]

    When PREEMPT_RT is enabled, all hrtimer expiry functions are
    deferred for execution into the context of ksoftirqd unless otherwise
    annotated.

    Deferring the expiry of the hrtimer used by the watchdog core, however,
    is a waste, as the callback does nothing but queue a kthread work item
    and wakeup watchdogd.

    It's worst then that, too: the deferral through ksoftirqd also means
    that for correct behavior a user must adjust the scheduling parameters
    of both watchdogd _and_ ksoftirqd, which is unnecessary and has other
    side effects (like causing unrelated expiry functions to execute at
    potentially elevated priority).

    Instead, mark the hrtimer used by the watchdog core as being _HARD to
    allow it's execution directly from hardirq context. The work done in
    this expiry function is well-bounded and minimal.

    A user still must adjust the scheduling parameters of the watchdogd
    to be correct w.r.t. their application needs.

    Link: https://lkml.kernel.org/r/0e02d8327aeca344096c246713033887bc490dd7.1538089180.git.julia@ni.com
    Cc: Guenter Roeck
    Reported-and-tested-by: Steffen Trumtrar
    Reported-by: Tim Sander
    Signed-off-by: Julia Cartwright
    Acked-by: Guenter Roeck
    [bigeasy: use only HRTIMER_MODE_REL_HARD]
    Signed-off-by: Sebastian Andrzej Siewior
    Reviewed-by: Guenter Roeck
    Link: https://lore.kernel.org/r/20191105144506.clyadjbvnn7b7b2m@linutronix.de
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck
    Signed-off-by: Sasha Levin

    Julia Cartwright
     

09 Jul, 2019

4 commits

  • This gets rid of the unnecessary license boilerplate, and avoids
    having to deal with individual patches one by one.

    No functional changes.

    Reviewed-by: Jerry Hoemann
    Acked-by: Sylvain Lemieux
    Reviewed-by: Matthias Brugger
    Acked-by: William Breathitt Gray
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     
  • When the watchdog device is not open by userspace, the kernel takes
    care of pinging it. When the open_timeout feature is in use, we should
    ensure that the hardware fires close to open_timeout seconds after the
    kernel has assumed responsibility for the device.

    To do this, simply reuse the logic that is already in place for
    ensuring the same thing when userspace is responsible for regularly
    pinging the device:

    - When watchdog_active(wdd), this patch doesn't change anything.

    - When !watchdog_active(wdd), the "virtual timeout" should be taken to
    be ->open_deadline". When the open_timeout feature is not used or the
    device has been opened at least once, ->open_deadline is KTIME_MAX,
    and the arithmetic ends up returning keepalive_interval as we used to.

    This has been tested on a Wandboard with various combinations of
    open_timeout and timeout-sec properties for the on-board watchdog by
    booting with 'init=/bin/sh', timestamping the lines on the serial
    console, and comparing the timestamp of the 'imx2-wdt 20bc000.wdog:
    timeout nnn sec' line with the timestamp of the 'U-Boot SPL ...'
    line (which appears just after reset).

    Suggested-by: Guenter Roeck
    Signed-off-by: Rasmus Villemoes
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Rasmus Villemoes
     
  • This allows setting a default value for the watchdog.open_timeout
    commandline parameter via Kconfig.

    Some BSPs allow remote updating of the kernel image and root file
    system, but updating the bootloader requires physical access. Hence, if
    one has a firmware update that requires relaxing the
    watchdog.open_timeout a little, the value used must be baked into the
    kernel image itself and cannot come from the u-boot environment via the
    kernel command line.

    Being able to set the initial value in .config doesn't change the fact
    that the value on the command line, if present, takes precedence, and is
    of course immensely useful for development purposes while one has
    console acccess, as well as usable in the cases where one can make a
    permanent update of the kernel command line.

    Signed-off-by: Rasmus Villemoes
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Rasmus Villemoes
     
  • The watchdog framework takes care of feeding a hardware watchdog until
    userspace opens /dev/watchdogN. If that never happens for some reason
    (buggy init script, corrupt root filesystem or whatnot) but the kernel
    itself is fine, the machine stays up indefinitely. This patch allows
    setting an upper limit for how long the kernel will take care of the
    watchdog, thus ensuring that the watchdog will eventually reset the
    machine.

    A value of 0 (the default) means infinite timeout, preserving the
    current behaviour.

    This is particularly useful for embedded devices where some fallback
    logic is implemented in the bootloader (e.g., use a different root
    partition, boot from network, ...).

    There is already handle_boot_enabled serving a similar purpose. However,
    such a binary choice is unsuitable if the hardware watchdog cannot be
    programmed by the bootloader to provide a timeout long enough for
    userspace to get up and running. Many of the embedded devices we see use
    external (gpio-triggered) watchdogs with a fixed timeout of the order of
    1-2 seconds.

    The open timeout only applies for the first open from
    userspace. Should userspace need to close the watchdog device, with
    the intention of re-opening it shortly, the application can emulate
    the open timeout feature by combining the nowayout feature with an
    appropriate WDIOC_SETTIMEOUT immediately prior to closing the device.

    Signed-off-by: Rasmus Villemoes
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Rasmus Villemoes
     

06 May, 2019

1 commit

  • Using scripts/coccinelle/api/stream_open.cocci added in 10dce8af3422
    ("fs: stream_open - opener for stream-like files so that read and write
    can run simultaneously without deadlock"), search and convert to
    stream_open all in-kernel nonseekable_open users for which read and
    write actually do not depend on ppos and where there is no other methods
    in file_operations which assume @offset access.

    I've verified each generated change manually - that it is correct to convert -
    and each other nonseekable_open instance left - that it is either not correct
    to convert there, or that it is not converted due to current stream_open.cocci
    limitations. The script also does not convert files that should be valid to
    convert, but that currently have .llseek = noop_llseek or generic_file_llseek
    for unknown reason despite file being opened with nonseekable_open (e.g.
    drivers/input/mousedev.c)

    Among cases converted 14 were potentially vulnerable to read vs write deadlock
    (see details in 10dce8af3422):

    drivers/char/pcmcia/cm4000_cs.c:1685:7-23: ERROR: cm4000_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/gnss/core.c:45:1-17: ERROR: gnss_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/hid/uhid.c:635:1-17: ERROR: uhid_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/infiniband/core/user_mad.c:988:1-17: ERROR: umad_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/input/evdev.c:527:1-17: ERROR: evdev_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/input/misc/uinput.c:401:1-17: ERROR: uinput_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/isdn/capi/capi.c:963:8-24: ERROR: capi_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/leds/uleds.c:77:1-17: ERROR: uleds_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/media/rc/lirc_dev.c:198:1-17: ERROR: lirc_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/s390/char/fs3270.c:488:1-17: ERROR: fs3270_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/usb/misc/ldusb.c:310:1-17: ERROR: ld_usb_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    drivers/xen/evtchn.c:667:8-24: ERROR: evtchn_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    net/batman-adv/icmp_socket.c:80:1-17: ERROR: batadv_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.
    net/rfkill/core.c:1146:8-24: ERROR: rfkill_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix.

    and the rest were just safe to convert to stream_open because their read and
    write do not use ppos at all and corresponding file_operations do not
    have methods that assume @offset file access(*):

    arch/powerpc/platforms/52xx/mpc52xx_gpt.c:631:8-24: WARNING: mpc52xx_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_ibox_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_ibox_stat_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_mbox_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_mbox_stat_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_wbox_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_wbox_stat_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    arch/um/drivers/harddog_kern.c:88:8-24: WARNING: harddog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    arch/x86/kernel/cpu/microcode/core.c:430:33-49: WARNING: microcode_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/char/ds1620.c:215:8-24: WARNING: ds1620_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/char/dtlk.c:301:1-17: WARNING: dtlk_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/char/ipmi/ipmi_watchdog.c:840:9-25: WARNING: ipmi_wdog_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/char/pcmcia/scr24x_cs.c:95:8-24: WARNING: scr24x_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/char/tb0219.c:246:9-25: WARNING: tb0219_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/firewire/nosy.c:306:8-24: WARNING: nosy_ops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/hwmon/fschmd.c:840:8-24: WARNING: watchdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/hwmon/w83793.c:1344:8-24: WARNING: watchdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/infiniband/core/ucma.c:1747:8-24: WARNING: ucma_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/infiniband/core/ucm.c:1178:8-24: WARNING: ucm_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/infiniband/core/uverbs_main.c:1086:8-24: WARNING: uverbs_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/input/joydev.c:282:1-17: WARNING: joydev_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/pci/switch/switchtec.c:393:1-17: WARNING: switchtec_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/platform/chrome/cros_ec_debugfs.c:135:8-24: WARNING: cros_ec_console_log_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/rtc/rtc-ds1374.c:470:9-25: WARNING: ds1374_wdt_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/rtc/rtc-m41t80.c:805:9-25: WARNING: wdt_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/s390/char/tape_char.c:293:2-18: WARNING: tape_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/s390/char/zcore.c:194:8-24: WARNING: zcore_reipl_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/s390/crypto/zcrypt_api.c:528:8-24: WARNING: zcrypt_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/spi/spidev.c:594:1-17: WARNING: spidev_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/staging/pi433/pi433_if.c:974:1-17: WARNING: pi433_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/acquirewdt.c:203:8-24: WARNING: acq_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/advantechwdt.c:202:8-24: WARNING: advwdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/alim1535_wdt.c:252:8-24: WARNING: ali_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/alim7101_wdt.c:217:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/ar7_wdt.c:166:8-24: WARNING: ar7_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/at91rm9200_wdt.c:113:8-24: WARNING: at91wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/ath79_wdt.c:135:8-24: WARNING: ath79_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/bcm63xx_wdt.c:119:8-24: WARNING: bcm63xx_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/cpu5wdt.c:143:8-24: WARNING: cpu5wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/cpwd.c:397:8-24: WARNING: cpwd_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/eurotechwdt.c:319:8-24: WARNING: eurwdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/f71808e_wdt.c:528:8-24: WARNING: watchdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/gef_wdt.c:232:8-24: WARNING: gef_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/geodewdt.c:95:8-24: WARNING: geodewdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/ib700wdt.c:241:8-24: WARNING: ibwdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/ibmasr.c:326:8-24: WARNING: asr_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/indydog.c:80:8-24: WARNING: indydog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/intel_scu_watchdog.c:307:8-24: WARNING: intel_scu_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/iop_wdt.c:104:8-24: WARNING: iop_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/it8712f_wdt.c:330:8-24: WARNING: it8712f_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/ixp4xx_wdt.c:68:8-24: WARNING: ixp4xx_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/ks8695_wdt.c:145:8-24: WARNING: ks8695wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/m54xx_wdt.c:88:8-24: WARNING: m54xx_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/machzwd.c:336:8-24: WARNING: zf_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/mixcomwd.c:153:8-24: WARNING: mixcomwd_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/mtx-1_wdt.c:121:8-24: WARNING: mtx1_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/mv64x60_wdt.c:136:8-24: WARNING: mv64x60_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/nuc900_wdt.c:134:8-24: WARNING: nuc900wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/nv_tco.c:164:8-24: WARNING: nv_tco_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/pc87413_wdt.c:289:8-24: WARNING: pc87413_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/pcwd.c:698:8-24: WARNING: pcwd_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/pcwd.c:737:8-24: WARNING: pcwd_temp_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/pcwd_pci.c:581:8-24: WARNING: pcipcwd_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/pcwd_pci.c:623:8-24: WARNING: pcipcwd_temp_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/pcwd_usb.c:488:8-24: WARNING: usb_pcwd_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/pcwd_usb.c:527:8-24: WARNING: usb_pcwd_temperature_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/pika_wdt.c:121:8-24: WARNING: pikawdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/pnx833x_wdt.c:119:8-24: WARNING: pnx833x_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/rc32434_wdt.c:153:8-24: WARNING: rc32434_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/rdc321x_wdt.c:145:8-24: WARNING: rdc321x_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/riowd.c:79:1-17: WARNING: riowd_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/sa1100_wdt.c:62:8-24: WARNING: sa1100dog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/sbc60xxwdt.c:211:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/sbc7240_wdt.c:139:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/sbc8360.c:274:8-24: WARNING: sbc8360_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/sbc_epx_c3.c:81:8-24: WARNING: epx_c3_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/sbc_fitpc2_wdt.c:78:8-24: WARNING: fitpc2_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/sb_wdog.c:108:1-17: WARNING: sbwdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/sc1200wdt.c:181:8-24: WARNING: sc1200wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/sc520_wdt.c:261:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/sch311x_wdt.c:319:8-24: WARNING: sch311x_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/scx200_wdt.c:105:8-24: WARNING: scx200_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/smsc37b787_wdt.c:369:8-24: WARNING: wb_smsc_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/w83877f_wdt.c:227:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/w83977f_wdt.c:301:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/wafer5823wdt.c:200:8-24: WARNING: wafwdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/watchdog_dev.c:828:8-24: WARNING: watchdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/wdrtas.c:379:8-24: WARNING: wdrtas_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/wdrtas.c:445:8-24: WARNING: wdrtas_temp_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/wdt285.c:104:1-17: WARNING: watchdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/wdt977.c:276:8-24: WARNING: wdt977_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/wdt.c:424:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/wdt.c:484:8-24: WARNING: wdt_temp_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/wdt_pci.c:464:8-24: WARNING: wdtpci_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open.
    drivers/watchdog/wdt_pci.c:527:8-24: WARNING: wdtpci_temp_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    net/batman-adv/log.c:105:1-17: WARNING: batadv_log_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    sound/core/control.c:57:7-23: WARNING: snd_ctl_f_ops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.
    sound/core/rawmidi.c:385:7-23: WARNING: snd_rawmidi_f_ops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    sound/core/seq/seq_clientmgr.c:310:7-23: WARNING: snd_seq_f_ops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open.
    sound/core/timer.c:1428:7-23: WARNING: snd_timer_f_ops: .read() has stream semantic; safe to change nonseekable_open -> stream_open.

    One can also recheck/review the patch via generating it with explanation comments included via

    $ make coccicheck MODE=patch COCCI=scripts/coccinelle/api/stream_open.cocci SPFLAGS="-D explain"

    (*) This second group also contains cases with read/write deadlocks that
    stream_open.cocci don't yet detect, but which are still valid to convert to
    stream_open since ppos is not used. For example drivers/pci/switch/switchtec.c
    calls wait_for_completion_interruptible() in its .read, but stream_open.cocci
    currently detects only "wait_event*" as blocking.

    Cc: Michael Kerrisk
    Cc: Yongzhi Pan
    Cc: Jonathan Corbet
    Cc: David Vrabel
    Cc: Juergen Gross
    Cc: Miklos Szeredi
    Cc: Tejun Heo
    Cc: Kirill Tkhai
    Cc: Arnd Bergmann
    Cc: Christoph Hellwig
    Cc: Greg Kroah-Hartman
    Cc: Julia Lawall
    Cc: Nikolaus Rath
    Cc: Han-Wen Nienhuys
    Cc: Anatolij Gustschin
    Cc: Jeff Dike
    Cc: Richard Weinberger
    Cc: Anton Ivanov
    Cc: Borislav Petkov
    Cc: Thomas Gleixner
    Cc: Ingo Molnar
    Cc: "James R. Van Zandt"
    Cc: Corey Minyard
    Cc: Harald Welte
    Acked-by: Lubomir Rintel [scr24x_cs]
    Cc: Stefan Richter
    Cc: Johan Hovold
    Cc: David Herrmann
    Cc: Jiri Kosina
    Cc: Benjamin Tissoires
    Cc: Jean Delvare
    Acked-by: Guenter Roeck [watchdog/* hwmon/*]
    Cc: Rudolf Marek
    Cc: Dmitry Torokhov
    Cc: Karsten Keil
    Cc: Jacek Anaszewski
    Cc: Pavel Machek
    Cc: Mauro Carvalho Chehab
    Cc: Kurt Schwemmer
    Acked-by: Logan Gunthorpe [drivers/pci/switch/switchtec]
    Acked-by: Bjorn Helgaas [drivers/pci/switch/switchtec]
    Cc: Benson Leung
    Acked-by: Enric Balletbo i Serra [platform/chrome]
    Cc: Alessandro Zummo
    Acked-by: Alexandre Belloni [rtc/*]
    Cc: Mark Brown
    Cc: Wim Van Sebroeck
    Cc: Florian Fainelli
    Cc: bcm-kernel-feedback-list@broadcom.com
    Cc: Wan ZongShun
    Cc: Zwane Mwaikambo
    Cc: Marek Lindner
    Cc: Simon Wunderlich
    Cc: Antonio Quartulli
    Cc: "David S. Miller"
    Cc: Johannes Berg
    Cc: Jaroslav Kysela
    Cc: Takashi Iwai
    Signed-off-by: Kirill Smelkov

    Kirill Smelkov
     

02 Oct, 2018

1 commit

  • watchdog_stop() calls watchdog_update_worker() which needs a valid
    wdd->wd_data pointer. So, when unregistering the cdev, clear the
    pointers after we call watchdog_stop(), not before.

    Fixes: bb292ac1c602 ("watchdog: Introduce watchdog_stop_on_unregister helper")
    Signed-off-by: Wolfram Sang
    Reviewed-by: Fabrizio Castro
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Wolfram Sang
     

21 Jan, 2018

1 commit

  • commit 4cd13c21b207e ("softirq: Let ksoftirqd do its job") has the
    effect of deferring timer handling in case of high CPU load, hence
    delaying the delayed work allthought the worker is running which
    high realtime priority.

    As hrtimers are not managed by softirqs, this patch replaces the
    delayed work by a plain work and uses an hrtimer to schedule that work.

    Signed-off-by: Christophe Leroy
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Christophe Leroy
     

29 Dec, 2017

2 commits

  • When running a command like 'chrt -f 50 dd if=/dev/zero of=/dev/null',
    the watchdog_worker fails to service the HW watchdog and the
    HW watchdog fires long before the watchdog soft timeout.

    At the moment, the watchdog_worker is invoked as a delayed work.
    Delayed works are handled by non realtime kernel threads. The
    WQ_HIGHPRI flag only increases the niceness of that threads.

    This patch replaces the delayed work logic by kthread delayed work,
    and sets the associated kernel task to SCHED_FIFO with the highest
    priority, in order to ensure that the watchdog worker will run as
    soon as possible.

    Signed-off-by: Christophe Leroy
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Christophe Leroy
     
  • In preparation to enabling -Wimplicit-fallthrough, mark switch cases
    where we are expecting to fall through.

    Notice that in this particular case I replaced "Fall" with a proper
    "fall through" comment, which is what GCC is expecting to find.

    Signed-off-by: Gustavo A. R. Silva
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Gustavo A. R. Silva
     

17 Dec, 2017

2 commits

  • If handle_boot_enabled is set to 0, the watchdog driver module use
    counter will not be increased and kref_get() will not be called when
    registering the watchdog. Subsequently, on open, this does not happen
    either because the code believes that it was already done because the
    hardware watchdog is marked as running.

    We could introduce a state variable to indicate this state, but let's
    just increase the module use counter and call kref_get() unconditionally
    if the hardware watchdog is running when a driver is registering itself
    to keep the code simple.

    Fixes: 2501b015313fe ("watchdog: core: add option to avoid early ...")
    Cc: Sebastian Reichel
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     
  • If a watchdog driver's open function sets WDOG_HW_RUNNING with the
    expectation that the watchdog can not be stopped, but then stops the
    watchdog anyway in its stop function, kref_get() wil not be called in
    watchdog_open(). If the watchdog then stops on close, WDOG_HW_RUNNING
    will be cleared and kref_put() will be called, causing a kref imbalance.
    As result the character device data structure will be released, which in
    turn will cause the system to crash on the next call to watchdog_open().

    Fixes: ee142889e32f5 ("watchdog: Introduce WDOG_HW_RUNNING flag")
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     

18 Nov, 2017

1 commit

  • Save a bit of cleanup code by leveraging newly added
    devm_register_reboot_notifier().

    [akpm@linux-foundation.org: small cleanup: avoid 80-col tricks]
    Link: http://lkml.kernel.org/r/20170411160615.9784-1-andrew.smirnov@gmail.com
    Signed-off-by: Andrey Smirnov
    Acked-by: Guenter Roeck
    Cc: Chris Healy
    Cc: Wim Van Sebroeck
    Cc: Andy Shevchenko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrey Smirnov
     

03 Jul, 2017

1 commit


06 Jun, 2017

1 commit

  • On some systems its desirable to have watchdog reboot the system
    when it does not come up fast enough. This adds a kernel parameter
    to disable the auto-update of watchdog before userspace takes over
    and a kernel option to set the default. The info messages were
    added to shorten error searching on misconfigured systems.

    Signed-off-by: Sebastian Reichel
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Sebastian Reichel
     

25 Feb, 2017

1 commit

  • Many watchdog drivers explicitly stop the watchdog when unregistering it.
    While it is unclear if this is actually needed (the whatdog should not be
    running at that time if it can be stopped), introduce a helper to
    explicitly stop the watchdog in the watchdog core when unregistering it.
    This helps reducing driver code size while retaining functionality.

    Signed-off-by: Guenter Roeck

    Guenter Roeck
     

08 Oct, 2016

3 commits

  • The change adds an option to a user with CONFIG_WATCHDOG_SYSFS and
    CONFIG_WATCHDOG_PRETIMEOUT_GOV enabled to get information about all
    registered watchdog pretimeout governors by reading watchdog device
    attribute named "pretimeout_available_governors".

    Signed-off-by: Vladimir Zapolskiy
    Reviewed-by: Guenter Roeck
    Reviewed-by: Wolfram Sang
    Tested-by: Wolfram Sang
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Vladimir Zapolskiy
     
  • The change converts watchdog device attribute "pretimeout_governor" from
    read-only to read-write type to allow users to select a desirable
    watchdog pretimeout governor in runtime, e.g.

    % echo -n panic > /sys/..../watchdog/watchdog0/pretimeout

    To get this working a list of registered pretimeout governors is created
    and a new helper function watchdog_pretimeout_governor_set() is exported
    to watchdog_dev.c.

    If a selected governor is gone, a watchdog device pretimeout notification
    is delegated to a default built-in pretimeout governor.

    Signed-off-by: Vladimir Zapolskiy
    Reviewed-by: Guenter Roeck
    Reviewed-by: Wolfram Sang
    Tested-by: Wolfram Sang
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Vladimir Zapolskiy
     
  • The change adds a simple watchdog pretimeout framework infrastructure,
    its purpose is to allow users to select a desired handling of watchdog
    pretimeout events, which may be generated by some watchdog devices.

    A user selects a default watchdog pretimeout governor during
    compilation stage.

    Watchdogs with WDIOF_PRETIMEOUT capability now have one more device
    attribute in sysfs, pretimeout_governor attribute is intended to display
    the selected watchdog pretimeout governor.

    The framework has no impact at runtime on watchdog devices with no
    WDIOF_PRETIMEOUT capability set.

    Signed-off-by: Vladimir Zapolskiy
    Reviewed-by: Guenter Roeck
    Reviewed-by: Wolfram Sang
    Tested-by: Wolfram Sang
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Vladimir Zapolskiy
     

24 Sep, 2016

1 commit

  • Since the watchdog framework centrializes the IOCTL interfaces of device
    drivers now, SETPRETIMEOUT and GETPRETIMEOUT need to be added in the
    common code.

    Signed-off-by: Robin Gong
    Signed-off-by: Wolfram Sang
    [vzapolskiy: added conditional pretimeout sysfs attribute visibility]
    Signed-off-by: Vladimir Zapolskiy
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Wolfram Sang
     

25 Jul, 2016

2 commits

  • WDOG_HW_RUNNING indicates that the hardware watchdog is running while the
    watchdog device is closed. The flag may be set by the driver when it is
    instantiated to indicate that the watchdog is running, and that the
    watchdog core needs to send heartbeat requests to the driver until the
    watchdog device is opened.

    When the watchdog device is closed, the flag can be used by the driver's
    stop function to indicate to the watchdog core that it was unable to stop
    the watchdog, and that the watchdog core needs to send heartbeat requests.
    This only works if the flag is actually cleared when the watchdog is
    stopped. To avoid having to clear the flag in each driver's stop function,
    clear it in the watchdog core before calling the stop function.

    Reported-by: Rasmus Villemoes
    Fixes: ee142889e32f ("watchdog: Introduce WDOG_HW_RUNNING flag")
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     
  • Fix the error handling paths of watchdog_dev_init().

    Signed-off-by: Wei Yongjun
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Wei Yongjun
     

19 Jul, 2016

1 commit

  • Up to now, the watchdog status function called a driver function,
    which was supposed to return the watchdog status. All but one
    driver using the watchdog core did not implement this function,
    and the driver implementing it did not implement it correctly
    (the function is supposed to return WDIOF_ flags). At the same time,
    at least some of the status information can be provided by the watchdog
    core.

    Provide the available status bits directly from the watchdog driver core.
    Call the driver status function if it exists to get the boot status, but
    always provide WDIOF_MAGICCLOSE and WDIOF_KEEPALIVEPING internally.
    This patch makes the 'status' sysfs attribute always available.
    This attribute is now displayed as hex number with 0x prepended to be
    easier to decode.

    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     

18 Jul, 2016

1 commit

  • If the driver indicates that the watchdog is running, the framework
    should feed it until userspace opens the device, regardless of whether
    the driver has set max_hw_heartbeat_ms.

    This patch only affects the case where wdd->max_hw_heartbeat_ms is
    zero, wdd->timeout is non-zero, the watchdog is not active and the
    hardware device is running (*):

    - If wdd->timeout is zero, watchdog_need_worker() returns false both
    before and after this patch, and watchdog_next_keepalive() is not
    called.

    - If watchdog_active(wdd), the return value from watchdog_need_worker
    is also the same as before (namely, hm && t > hm). Hence in that case,
    watchdog_next_keepalive() is only called if hm == max_hw_heartbeat_ms
    is non-zero, so the change to min_not_zero there is a no-op.

    - If the watchdog is not active and the device is not running, we
    return false from watchdog_need_worker just as before.

    That leaves the watchdog_hw_running(wdd) && !watchdog_active(wdd) &&
    wdd->timeout case. Again, it's easy to see that if
    wdd->max_hw_heartbeat_ms is non-zero, we return true from
    watchdog_need_worker with and without this patch, and the logic in
    watchdog_next_keepalive is unchanged. Finally, if
    wdd->max_hw_heartbeat_ms is 0, we used to end up in the
    cancel_delayed_work branch, whereas with this patch we end up
    scheduling a ping timeout_ms/2 from now.

    (*) This should imply that no current kernel drivers are affected,
    since the only drivers which explicitly set WDOG_HW_RUNNING are
    imx2_wdt.c and dw_wdt.c, both of which also provide a non-zero value
    for max_hw_heartbeat_ms. The watchdog core also sets WDOG_HW_RUNNING,
    but only when the driver doesn't provide ->stop, in which case it
    must, according to Documentation/watchdog/watchdog-kernel-api.txt, set
    max_hw_heartbeat_ms.

    Signed-off-by: Rasmus Villemoes
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Rasmus Villemoes
     

14 May, 2016

1 commit

  • lockdep reports the following circular locking dependency.

    ======================================================
    INFO: possible circular locking dependency detected ]
    4.6.0-rc3-00191-gfabf418 #162 Not tainted
    -------------------------------------------------------
    systemd/1 is trying to acquire lock:
    ((&(&wd_data->work)->work)){+.+...}, at: [] flush_work+0x0/0x280

    but task is already holding lock:

    (&wd_data->lock){+.+...}, at: [] watchdog_release+0x18/0x190

    which lock already depends on the new lock.
    the existing dependency chain (in reverse order) is:

    -> #1 (&wd_data->lock){+.+...}:
    [] mutex_lock_nested+0x64/0x4a8
    [] watchdog_ping_work+0x18/0x4c
    [] process_one_work+0x1ac/0x500
    [] worker_thread+0x38/0x554
    [] kthread+0xf4/0x108
    [] ret_from_fork+0x14/0x24

    -> #0 ((&(&wd_data->work)->work)){+.+...}:
    [] lock_acquire+0x70/0x90
    [] flush_work+0x4c/0x280
    [] __cancel_work_timer+0x9c/0x1e0
    [] watchdog_release+0x3c/0x190
    [] __fput+0x80/0x1c8
    [] task_work_run+0x94/0xc8
    [] do_work_pending+0x8c/0xb4
    [] slow_work_pending+0xc/0x20

    other info that might help us debug this:
    Possible unsafe locking scenario:

    CPU0 CPU1
    ---- ----
    lock(&wd_data->lock);
    lock((&(&wd_data->work)->work));
    lock(&wd_data->lock);
    lock((&(&wd_data->work)->work));

    *** DEADLOCK ***

    1 lock held by systemd/1:

    stack backtrace:
    CPU: 2 PID: 1 Comm: systemd Not tainted 4.6.0-rc3-00191-gfabf418 #162
    Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
    [] (unwind_backtrace) from [] (show_stack+0x10/0x14)
    [] (show_stack) from [] (dump_stack+0xa8/0xd4)
    [] (dump_stack) from [] (print_circular_bug+0x214/0x334)
    [] (print_circular_bug) from [] (check_prevs_add+0x4dc/0x8e8)
    [] (check_prevs_add) from [] (__lock_acquire+0xc6c/0x14ec)
    [] (__lock_acquire) from [] (lock_acquire+0x70/0x90)
    [] (lock_acquire) from [] (flush_work+0x4c/0x280)
    [] (flush_work) from [] (__cancel_work_timer+0x9c/0x1e0)
    [] (__cancel_work_timer) from [] (watchdog_release+0x3c/0x190)
    [] (watchdog_release) from [] (__fput+0x80/0x1c8)
    [] (__fput) from [] (task_work_run+0x94/0xc8)
    [] (task_work_run) from [] (do_work_pending+0x8c/0xb4)
    [] (do_work_pending) from [] (slow_work_pending+0xc/0x20)

    Turns out the call to cancel_delayed_work_sync() in watchdog_release()
    is not necessary and can be dropped. If the worker is no longer necessary,
    the subsequent call to watchdog_update_worker() will cancel it. If it is
    already running, it won't do anything, since the worker function checks
    if it needs to ping the watchdog or not.

    Reported-by: Clemens Gruber
    Tested-by: Clemens Gruber
    Fixes: 11d7aba9ceb7 ("watchdog: imx2: Convert to use infrastructure triggered keepalives")
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck
    Cc: stable

    Guenter Roeck
     

17 Mar, 2016

6 commits

  • Smatch rightfully complains that wdd is dereferenced in the watchdog
    release function after being checked for NULL. Also make sure that it
    is not accessed outside mutex protection to avoid use-after-free problems.

    Fixes: e6c71e84e4c0 ("watchdog: Introduce WDOG_HW_RUNNING flag")
    Reported-by: Dan Carpenter
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     
  • Some watchdogs require a minimum time between heartbeats.
    Examples are the watchdogs in DA9062 and AT91SAM9x.

    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     
  • Not all hardware watchdogs can be stopped. The driver for
    such watchdogs would typically only set the WATCHDOG_HW_RUNNING
    flag in its stop function. Make the stop function optional and set
    WATCHDOG_HW_RUNNING in the watchdog core if it is not provided.

    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     
  • The WDOG_HW_RUNNING flag is expected to be set by watchdog drivers if
    the hardware watchdog is running. If the flag is set, the watchdog
    subsystem will ping the watchdog even if the watchdog device is closed.

    The watchdog driver stop function is now optional and may be omitted
    if the watchdog can not be stopped. If stopping the watchdog is not
    possible but the driver implements a stop function, it is responsible
    to set the WDOG_HW_RUNNING flag in its stop function.

    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     
  • Introduce an optional hardware maximum heartbeat in the watchdog core.
    The hardware maximum heartbeat can be lower than the maximum timeout.

    Drivers can set the maximum hardware heartbeat value in the watchdog data
    structure. If the configured timeout exceeds the maximum hardware heartbeat,
    the watchdog core enables a timer function to assist sending keepalive
    requests to the watchdog driver.

    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     
  • For some watchdogs, the watchdog driver handles timeout changes without
    explicitly setting any registers. In this situation, the watchdog driver
    might only set the 'timeout' variable but do nothing else.
    This can as well be handled by the infrastructure, so make the set_timeout
    callback optional. If WDIOF_SETTIMEOUT is configured but the .set_timeout
    callback is not available, update the timeout variable in the
    infrastructure code.

    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     

12 Jan, 2016

2 commits

  • The lifetime of the watchdog device pointer is different from the lifetime
    of its character device. Remove it entirely to avoid race conditions.

    Signed-off-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     
  • The Zodiac watchdog driver attaches additional sysfs attributes to the
    watchdog device. This has a number of problems: The watchdog device
    lifetime differs from the driver lifetime, and the device structure
    should therefore not be accessed from drivers. Also, creating sysfs
    attributes after driver registration results in a potential race condition
    if user space expects the attributes to exist but they don't exist yet.

    Add support for creating driver specific sysfs attributes to the watchdog
    core to solve the problems.

    Signed-off-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     

30 Dec, 2015

2 commits

  • All variables required by the watchdog core to manage a watchdog are
    currently stored in struct watchdog_device. The lifetime of those
    variables is determined by the watchdog driver. However, the lifetime
    of variables used by the watchdog core differs from the lifetime of
    struct watchdog_device. To remedy this situation, watchdog drivers
    can implement ref and unref callbacks, to be used by the watchdog
    core to lock struct watchdog_device in memory.

    While this solves the immediate problem, it depends on watchdog drivers
    to actually implement the ref/unref callbacks. This is error prone,
    often not implemented in the first place, or not implemented correctly.

    To solve the problem without requiring driver support, split the variables
    in struct watchdog_device into two data structures - one for variables
    associated with the watchdog driver, one for variables associated with
    the watchdog core. With this approach, the watchdog core can keep track
    of its variable lifetime and no longer depends on ref/unref callbacks
    in the driver. As a side effect, some of the variables originally in
    struct watchdog_driver are now private to the watchdog core and no longer
    visible in watchdog drivers.

    As a side effect of the changes made, an ioctl will now always fail
    with -ENODEV after a watchdog device was unregistered with the character
    device still open. Previously, it would only fail with -ENODEV in some
    situations. Also, ioctl operations are now atomic from driver perspective.
    With this change, it is now guaranteed that the driver will not unregister
    a watchdog between a timeout change and the subsequent ping.

    The 'ref' and 'unref' callbacks in struct watchdog_driver are no longer
    used and marked as deprecated.

    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     
  • The watchdog character device is currently created in watchdog_dev.c,
    and the watchdog device in watchdog_core.c. This results in
    cross-dependencies, since device creation needs to know the watchdog
    character device number as well as the watchdog class, both of which
    reside in watchdog_dev.c.

    Create the watchdog device in watchdog_dev.c to simplify the code.

    Inspired by earlier patch set from Damien Riegel.

    Cc: Damien Riegel
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Guenter Roeck
     

27 Dec, 2015

2 commits

  • This patch adds following attributes to watchdog device's sysfs interface
    to read its different status.

    * state - reads whether device is active or not
    * identity - reads Watchdog device's identity string.
    * timeout - reads current timeout.
    * timeleft - reads timeleft before watchdog generates a reset
    * bootstatus - reads status of the watchdog device at boot
    * status - reads watchdog device's internal status bits
    * nowayout - reads whether nowayout feature was set or not

    Testing with iTCO_wdt:
    # cd /sys/class/watchdog/watchdog1/
    # ls
    bootstatus dev device identity nowayout power state
    subsystem timeleft timeout uevent
    # cat identity
    iTCO_wdt
    # cat timeout
    30
    # cat state
    inactive
    # echo > /dev/watchdog1
    # cat timeleft
    26
    # cat state
    active
    # cat bootstatus
    0
    # cat nowayout
    0

    Signed-off-by: Pratyush Anand
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Pratyush Anand
     
  • We need few sysfs attributes to know different status of a watchdog device.
    To do that, we need to associate .dev_groups with watchdog_class. So
    convert it from pointer to static.
    Putting this static struct in watchdog_dev.c, so that static device
    attributes defined in that file can be attached to it.

    Signed-off-by: Pratyush Anand
    Suggested-by: Guenter Roeck
    Reviewed-by: Guenter Roeck
    Signed-off-by: Guenter Roeck
    Signed-off-by: Wim Van Sebroeck

    Pratyush Anand