diff --git a/sys/compat/linuxkpi/common/src/linux_work.c b/sys/compat/linuxkpi/common/src/linux_work.c --- a/sys/compat/linuxkpi/common/src/linux_work.c +++ b/sys/compat/linuxkpi/common/src/linux_work.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2017-2019 Hans Petter Selasky + * Copyright (c) 2017-2021 Hans Petter Selasky * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -433,15 +433,20 @@ }; struct taskqueue *tq; +retry: switch (linux_update_state(&dwork->work.state, states)) { case WORK_ST_TIMER: - case WORK_ST_CANCEL: if (linux_cancel_timer(dwork, 0)) { atomic_cmpxchg(&dwork->work.state, WORK_ST_CANCEL, WORK_ST_IDLE); return (true); } - /* FALLTHROUGH */ + /* + * If the timer was not stopped, it means it has just + * elapsed and the state needs to be checked again: + */ + goto retry; + case WORK_ST_CANCEL: case WORK_ST_TASK: tq = dwork->work.work_queue->taskqueue; if (taskqueue_cancel(tq, &dwork->work.work_task, NULL) == 0) {