Commit 28ac8219 authored by Jan Kiszka's avatar Jan Kiszka

cobalt/kernel/xnclock: Introduce xnclock_ratelimit()

This will service as an internal building block for RT-safe rate-limited
printk (printk_ratelimit() is not suited). It's derived from the RTDM
variant, but simplied (central lock, static parameters). We will switch
rtdm_printk_ratelimited to this implementation later on.
Signed-off-by: Jan Kiszka's avatarJan Kiszka <jan.kiszka@siemens.com>
parent 2edc126b
......@@ -92,6 +92,14 @@ struct xnclock {
#endif
};
struct xnclock_ratelimit_state {
xnticks_t interval;
xnticks_t begin;
int burst;
int printed;
int missed;
};
extern struct xnclock nkclock;
extern unsigned long nktimerlat;
......@@ -125,6 +133,20 @@ static inline xnticks_t xnclock_core_read_raw(void)
return t;
}
/* We use the Linux defaults */
#define XN_RATELIMIT_INTERVAL 5000000000LL
#define XN_RATELIMIT_BURST 10
int __xnclock_ratelimit(struct xnclock_ratelimit_state *rs, const char *func);
#define xnclock_ratelimit() ({ \
static struct xnclock_ratelimit_state __state = { \
.interval = XN_RATELIMIT_INTERVAL, \
.burst = XN_RATELIMIT_BURST, \
}; \
__xnclock_ratelimit(&__state, __func__); \
})
#ifdef CONFIG_XENO_OPT_EXTCLOCK
static inline void xnclock_program_shot(struct xnclock *clock,
......
......@@ -120,6 +120,41 @@ EXPORT_SYMBOL_GPL(xnclock_core_ticks_to_ns_rounded);
EXPORT_SYMBOL_GPL(xnclock_core_ns_to_ticks);
EXPORT_SYMBOL_GPL(xnclock_divrem_billion);
DEFINE_PRIVATE_XNLOCK(ratelimit_lock);
int __xnclock_ratelimit(struct xnclock_ratelimit_state *rs, const char *func)
{
spl_t s;
int ret;
if (!rs->interval)
return 1;
xnlock_get_irqsave(&ratelimit_lock, s);
if (!rs->begin)
rs->begin = xnclock_read_realtime(&nkclock);
if (xnclock_read_realtime(&nkclock) >= rs->begin + rs->interval) {
if (rs->missed)
printk(KERN_WARNING "%s: %d callbacks suppressed\n",
func, rs->missed);
rs->begin = 0;
rs->printed = 0;
rs->missed = 0;
}
if (rs->burst && rs->burst > rs->printed) {
rs->printed++;
ret = 1;
} else {
rs->missed++;
ret = 0;
}
xnlock_put_irqrestore(&ratelimit_lock, s);
return ret;
}
EXPORT_SYMBOL_GPL(__xnclock_ratelimit);
void xnclock_core_local_shot(struct xnsched *sched)
{
struct xntimerdata *tmd;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment