0
  $   ˆÃÂ„Âm¿¿a–Ü4ý()¨‰P@ŠåÀº¦-ÿÁ ?÷     /* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2019-2022 Red Hat, Inc. Daniel Bristot de Oliveira <bristot@kernel.org>
 *
 * Deterministic automata (DA) monitor functions, to be used together
 * with automata models in C generated by the dot2k tool.
 *
 * The dot2k tool is available at tools/verification/dot2k/
 *
 * For further information, see:
 *   Documentation/trace/rv/da_monitor_synthesis.rst
 */

#include <rv/automata.h>
#include <linux/rv.h>
#include <linux/bug.h>
#include <linux/sched.h>

#ifdef CONFIG_RV_REACTORS

#define DECLARE_RV_REACTING_HELPERS(name, type)							\
static void cond_react_##name(type curr_state, type event)					\
{												\
	if (!rv_reacting_on() || !rv_##name.react)						\
		return;										\
	rv_##name.react("rv: monitor %s does not allow event %s on state %s\n",			\
			#name,									\
			model_get_event_name_##name(event),					\
			model_get_state_name_##name(curr_state));				\
}

#else /* CONFIG_RV_REACTOR */

#define DECLARE_RV_REACTING_HELPERS(name, type)							\
static void cond_react_##name(type curr_state, type event)					\
{												\
	return;											\
}
#endif

/*
 * Generic helpers for all types of deterministic automata monitors.
 */
#define DECLARE_DA_MON_GENERIC_HELPERS(name, type)						\
												\
DECLARE_RV_REACTING_HELPERS(name, type)								\
												\
/*												\
 * da_monitor_reset_##name - reset a monitor and setting it to init state			\
 */												\
static inline void da_monitor_reset_##name(struct da_monitor *da_mon)				\
{												\
	da_mon->monitoring = 0;									\
	da_mon->curr_state = model_get_initial_state_##name();					\
}												\
												\
/*												\
 * da_monitor_start_##name - start monitoring							\
 *												\
 * The monitor will ignore all events until monitoring is set to true. This			\
 * function needs to be called to tell the monitor to start monitoring.				\
 */												\
static inline void da_monitor_start_##name(struct da_monitor *da_mon)				\
{												\
	da_mon->curr_state = model_get_initial_state_##name();					\
	da_mon->monitoring = 1;									\
}												\
												\
/*												\
 * da_monitoring_##name - returns true if the monitor is processing events			\
 */												\
static inline bool da_monitoring_##name(struct da_monitor *da_mon)				\
{												\
	return da_mon->monitoring;								\
}												\
												\
/*												\
 * da_monitor_enabled_##name - checks if the monitor is enabled					\
 */												\
static inline bool da_monitor_enabled_##name(void)						\
{												\
	/* global switch */									\
	if (unlikely(!rv_monitoring_on()))							\
		return 0;									\
												\
	/* monitor enabled */									\
	if (unlikely(!rv_##name.enabled))							\
		return 0;									\
												\
	return 1;										\
}												\
												\
/*												\
 * da_monitor_handling_event_##name - checks if the monitor is ready to handle events		\
 */												\
static inline bool da_monitor_handling_event_##name(struct da_monitor *da_mon)			\
{												\
												\
	if (!da_monitor_enabled_##name())							\
		return 0;									\
												\
	/* monitor is actually monitoring */							\
	if (unlikely(!da_monitoring_##name(da_mon)))						\
		return 0;									\
												\
	return 1;										\
}

/*
 * Event handler for implicit monitors. Implicit monitor is the one which the
 * handler does not need to specify which da_monitor to manipulate. Examples
 * of implicit monitor are the per_cpu or the global ones.
 *
 * Retry in case there is a race between getting and setting the next state,
 * warn and reset the monitor if it runs out of retries. The monitor should be
 * able to handle various orders.
 */
#define DECLARE_DA_MON_MODEL_HANDLER_IMPLICIT(name, type)					\
												\
static inline bool										\
da_event_##name(struct da_monitor *da_mon, enum events_##name event)				\
{												\
	enum states_##name curr_state, next_state;						\
												\
	curr_state = READ_