/* SPDX-License-Identifier: GPL-2.0 */ /* * C implementation of Buchi automaton, automatically generated by * tools/verification/rvgen from the linear temporal logic specification. * For further information, see kernel documentation: * Documentation/trace/rv/linear_temporal_logic.rst */ #include #define MONITOR_NAME sleep enum ltl_atom { LTL_ABORT_SLEEP, LTL_BLOCK_ON_RT_MUTEX, LTL_CLOCK_NANOSLEEP, LTL_FUTEX_LOCK_PI, LTL_FUTEX_WAIT, LTL_KERNEL_THREAD, LTL_KTHREAD_SHOULD_STOP, LTL_NANOSLEEP_CLOCK_MONOTONIC, LTL_NANOSLEEP_CLOCK_TAI, LTL_NANOSLEEP_TIMER_ABSTIME, LTL_RT, LTL_SLEEP, LTL_TASK_IS_MIGRATION, LTL_TASK_IS_RCU, LTL_WAKE, LTL_WOKEN_BY_EQUAL_OR_HIGHER_PRIO, LTL_WOKEN_BY_HARDIRQ, LTL_WOKEN_BY_NMI, LTL_NUM_ATOM }; static_assert(LTL_NUM_ATOM <= RV_MAX_LTL_ATOM); static const char *ltl_atom_str(enum ltl_atom atom) { static const char *const names[] = { "ab_sl", "bl_on_rt_mu", "cl_na", "fu_lo_pi", "fu_wa", "ker_th", "kth_sh_st", "na_cl_mo", "na_cl_ta", "na_ti_ab", "rt", "sl", "ta_mi", "ta_rc", "wak", "wo_eq_hi_pr", "wo_ha", "wo_nm", }; return names[atom]; } enum ltl_buchi_state { S0, S1, S2, S3, S4, S5, S6, S7, RV_NUM_BA_STATES }; static_assert(RV_NUM_BA_STATES <= RV_MAX_BA_STATES); static void ltl_start(struct task_struct *task, struct ltl_monitor *mon) { bool task_is_migration = test_bit(LTL_TASK_IS_MIGRATION, mon->atoms); bool task_is_rcu = test_bit(LTL_TASK_IS_RCU, mon->atoms); bool val40 = task_is_rcu || task_is_migration; bool futex_lock_pi = test_bit(LTL_FUTEX_LOCK_PI, mon->atoms); bool val41 = futex_lock_pi || val40; bool block_on_rt_mutex = test_bit(LTL_BLOCK_ON_RT_MUTEX, mon->atoms); bool val5 = block_on_rt_mutex || val41; bool kthread_should_stop = test_bit(LTL_KTHREAD_SHOULD_STOP, mon->atoms); bool abort_sleep = test_bit(LTL_ABORT_SLEEP, mon->atoms); bool val32 = abort_sleep || kthread_should_stop; bool woken_by_nmi = test_bit(LTL_WOKEN_BY_NMI, mon->atoms); bool val33 = woken_by_nmi || val32; bool woken_by_hardirq = test_bit(LTL_WOKEN_BY_HARDIRQ, mon->atoms); bool val34 = woken_by_hardirq || val33; bool woken_by_equal_or_higher_prio = test_bit(LTL_WOKEN_BY_EQUAL_OR_HIGHER_PRIO, mon->atoms); bool val14 = woken_by_equal_or_higher_prio || val34; bool wake = test_bit(LTL_WAKE, mon->atoms); bool val13 = !wake; bool kernel_thread = test_bit(LTL_KERNEL_THREAD, mon->atoms); bool nanosleep_clock_tai = test_bit(LTL_NANOSLEEP_CLOCK_TAI, mon->atoms); bool nanosleep_clock_monotonic = test_bit(LTL_NANOSLEEP_CLOCK_MONOTONIC, mon->atoms); bool val24 = nanosleep_clock_monotonic || nanosleep_clock_tai; bool nanosleep_timer_abstime = test_bit(LTL_NANOSLEEP_TIMER_ABSTIME, mon->atoms); bool val25 = nanosleep_timer_abstime && val24; bool clock_nanosleep = test_bit(LTL_CLOCK_NANOSLEEP, mon->atoms); bool val18 = clock_nanosleep && val25; bool futex_wait = test_bit(LTL_FUTEX_WAIT, mon->atoms); bool val9 = futex_wait || val18; bool val11 = val9 || kernel_thread; bool sleep = test_bit(LTL_SLEEP, mon->atoms); bool val2 = !sleep; bool rt = test_bit(LTL_RT, mon->atoms); bool val1 = !rt; bool val3 = val1 || val2; if (val3) __set_bit(S0, mon->states); if (val11 && val13) __set_bit(S1, mon->states); if (val11 && val14) __set_bit(S4, mon->states); if (val5) __set_bit(S5, mon->states); } static void ltl_possible_next_states(struct ltl_monitor *mon, unsigned int state, unsigned long *next) { bool task_is_migration = test_bit(LTL_TASK_IS_MIGRATION, mon->atoms); bool task_is_rcu = test_bit(LTL_TASK_IS_RCU, mon->atoms); bool val40 = task_is_rcu || task_is_migration; bool futex_lock_pi = test_bit(LTL_FUTEX_LOCK_PI, mon->atoms); bool val41 = futex_lock_pi || val40; bool block_on_rt_mutex = test_bit(LTL_BLOCK_ON_RT_MUTEX, mon->atoms); bool val5 = block_on_rt_mutex || val41; bool kthread_should_stop = test_bit(LTL_KTHREAD_SHOULD_STOP, mon->atoms); bool abort_sleep = test_bit(LTL_ABORT_SLEEP, mon->atoms); bool val32 = abort_sleep || kthread_should_stop; bool woken_by_nmi = test_bit(LTL_WOKEN_BY_NMI, mon->atoms); bool val33 = woken_by_nmi || val32; bool woken_by_hardirq = test_bit(LTL_WOKEN_BY_HARDIRQ, mon->atoms); bool val34 = woken_by_hardirq || val33; bool woken_by_equal_or_higher_prio = test_bit(LTL_WOKEN_BY_EQUAL_OR_HIGHER_PRIO, mon->atoms); bool val14 = woken_by_equal_or_higher_prio || val34; bool wake = test_bit(LTL_WAKE, mon->atoms); bool val13 = !wake; bool kernel_thread = test_bit(LTL_KERNEL_THREAD, mon->atoms); bool nanosleep_clock_tai = test_bit(LTL_NANOSLEEP_CLOCK_TAI, mon->atoms); bool nanosleep_clock_monotonic = test_bit(LTL_NANOSLEEP_CLOCK_MONOTONIC, mon->atoms); bool val24 = nanosleep_clock_monotonic || nanosleep_clock_tai; bool nanosleep_timer_abstime = test_bit(LTL_NANOSLEEP_TIMER_ABSTIME, mon->atoms); bool val25 = nanosleep_timer_abstime && val24; bool clock_nanosleep = test_bit(LTL_CLOCK_NANOSLEEP, mon->atoms); bool val18 = clock_nanosleep && val25; bool futex_wait = test_bit(LTL_FUTEX_WAIT, mon->atoms); bool val9 = futex_wait || val18; bool val11 = val9 || kernel_thread; bool sleep = test_bit(LTL_SLEEP, mon->atoms); bool val2 = !sleep; bool rt = test_bit(LTL_RT, mon->atoms); bool val1 = !rt; bool val3 = val1 || val2; switch (state) { case S0: if (val3) __set_bit(S0, next); if (val11 && val13) __set_bit(S1, next); if (val11 && val14) __set_bit(S4, next); if (val5) __set_bit(S5, next); break; case S1: if (val11 && val13) __set_bit(S1, next); if (val13 && val3) __set_bit(S2, next); if (val14 && val3) __set_bit(S3, next); if (val11 && val14) __set_bit(S4, next); if (val13 && val5) __set_bit(S6, next); if (val14 && val5) __set_bit(S7, next); break; case S2: if (val11 && val13) __set_bit(S1, next); if (val13 && val3) __set_bit(S2, next); if (val14 && val3) __set_bit(S3, next); if (val11 && val14) __set_bit(S4, next); if (val13 && val5) __set_bit(S6, next); if (val14 && val5) __set_bit(S7, next); break; case S3: if (val3) __set_bit(S0, next); if (val11 && val13) __set_bit(S1, next); if (val11 && val14) __set_bit(S4, next); if (val5) __set_bit(S5, next); break; case S4: if (val3) __set_bit(S0, next); if (val11 && val13) __set_bit(S1, next); if (val11 && val14) __set_bit(S4, next); if (val5) __set_bit(S5, next); break; case S5: if (val3) __set_bit(S0, next); if (val11 && val13) __set_bit(S1, next); if (val11 && val14) __set_bit(S4, next); if (val5) __set_bit(S5, next); break; case S6: if (val11 && val13) __set_bit(S1, next); if (val13 && val3) __set_bit(S2, next); if (val14 && val3) __set_bit(S3, next); if (val11 && val14) __set_bit(S4, next); if (val13 && val5) __set_bit(S6, next); if (val14 && val5) __set_bit(S7, next); break; case S7: if (val3) __set_bit(S0, next); if (val11 && val13) __set_bit(S1, next); if (val11 && val14) __set_bit(S4, next); if (val5) __set_bit(S5, next); break; } }