All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-core] [PATCH] rtdm: add rtdm_printk_ratelimited
@ 2011-11-17 11:56 Wolfgang Grandegger
  2011-11-20 16:43 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 2+ messages in thread
From: Wolfgang Grandegger @ 2011-11-17 11:56 UTC (permalink / raw)
  To: xenomai-core

This patch implements a real-time safe rate-limited message printing
on kernel console similar to Linux's printk_ratelimited.

Signed-off-by: Wolfgang Grandegger <wg@domain.hid>
---
 include/rtdm/rtdm_driver.h |   31 +++++++++++++++++
 ksrc/skins/rtdm/drvlib.c   |   77 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+), 0 deletions(-)

diff --git a/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h
index 85624ed..4267bd7 100644
--- a/include/rtdm/rtdm_driver.h
+++ b/include/rtdm/rtdm_driver.h
@@ -1241,6 +1241,37 @@ static inline void rtdm_mutex_destroy(rtdm_mutex_t *mutex)
 
 #define rtdm_printk(format, ...)	printk(format, ##__VA_ARGS__)
 
+struct rtdm_ratelimit_state {
+	rtdm_lock_t	lock;		/* protect the state */
+	nanosecs_abs_t  interval;
+	int		burst;
+	int		printed;
+	int		missed;
+	nanosecs_abs_t	begin;
+};
+
+int rtdm_ratelimit(struct rtdm_ratelimit_state *rs, const char *func);
+
+#define DEFINE_RTDM_RATELIMIT_STATE(name, interval_init, burst_init)	\
+	struct rtdm_ratelimit_state name = {				\
+		.lock		= RTDM_LOCK_UNLOCKED,			\
+		.interval	= interval_init,			\
+		.burst		= burst_init,				\
+	}
+
+/* We use the Linux defaults */
+#define DEF_RTDM_RATELIMIT_INTERVAL	5000000000LL
+#define DEF_RTDM_RATELIMIT_BURST	10
+
+#define rtdm_printk_ratelimited(fmt, ...)  ({				\
+	static DEFINE_RTDM_RATELIMIT_STATE(_rs,				\
+					   DEF_RTDM_RATELIMIT_INTERVAL,	\
+					   DEF_RTDM_RATELIMIT_BURST);	\
+									\
+	if (rtdm_ratelimit(&_rs, __func__))				\
+		printk(fmt, ##__VA_ARGS__);				\
+})
+
 #ifndef DOXYGEN_CPP /* Avoid static inline tags for RTDM in doxygen */
 static inline void *rtdm_malloc(size_t size)
 {
diff --git a/ksrc/skins/rtdm/drvlib.c b/ksrc/skins/rtdm/drvlib.c
index 8c86705..06fa772 100644
--- a/ksrc/skins/rtdm/drvlib.c
+++ b/ksrc/skins/rtdm/drvlib.c
@@ -2111,9 +2111,86 @@ int rtdm_munmap(rtdm_user_info_t *user_info, void *ptr, size_t len)
 EXPORT_SYMBOL_GPL(rtdm_munmap);
 #endif /* CONFIG_XENO_OPT_PERVASIVE || DOXYGEN_CPP */
 
+/**
+ * @brief Enforces a rate limit
+ *
+ * This function enforces a rate limit: not more than @rs->burst callbacks
+ * in every @rs->interval.
+ *
+ * @param[in,out] rtdm_ratelimit_state data
+ * @param[in] name of calling function
+ *
+ * @return 0 means callback will be suppressed and 1 means go ahead and do it
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - Kernel-based task
+ * - User-space task (RT, non-RT)
+ *
+ * Rescheduling: possible.
+ */
+int rtdm_ratelimit(struct rtdm_ratelimit_state *rs, const char *func)
+{
+	rtdm_lockctx_t lock_ctx;
+	int ret;
+
+	if (!rs->interval)
+		return 1;
+
+	rtdm_lock_get_irqsave(&rs->lock, lock_ctx);
+
+	if (!rs->begin)
+		rs->begin = rtdm_clock_read();
+	if (rtdm_clock_read() >= 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;
+	}
+	rtdm_lock_put_irqrestore(&rs->lock, lock_ctx);
+
+	return ret;
+}
+EXPORT_SYMBOL(rtdm_ratelimit);
+
 #ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */
 
 /**
+ * Real-time safe rate-limited message printing on kernel console
+ *
+ * @param[in] format Format string (conforming standard @c printf())
+ * @param ... Arguments referred by @a format
+ *
+ * @return On success, this service returns the number of characters printed.
+ * Otherwise, a negative error code is returned.
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - Interrupt service routine (consider the overhead!)
+ * - Kernel-based task
+ * - User-space task (RT, non-RT)
+ *
+ * Rescheduling: never in real-time context, possible in non-real-time
+ * environments.
+ */
+void rtdm_printk_ratelimited(const char *format, ...);
+
+/**
  * Real-time safe message printing on kernel console
  *
  * @param[in] format Format string (conforming standard @c printf())
-- 
1.7.4.1



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Xenomai-core] [PATCH] rtdm: add rtdm_printk_ratelimited
  2011-11-17 11:56 [Xenomai-core] [PATCH] rtdm: add rtdm_printk_ratelimited Wolfgang Grandegger
@ 2011-11-20 16:43 ` Gilles Chanteperdrix
  0 siblings, 0 replies; 2+ messages in thread
From: Gilles Chanteperdrix @ 2011-11-20 16:43 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

On 11/17/2011 12:56 PM, Wolfgang Grandegger wrote:
> This patch implements a real-time safe rate-limited message printing
> on kernel console similar to Linux's printk_ratelimited.

Applied, thanks.

-- 
                                                                Gilles.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-11-20 16:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-17 11:56 [Xenomai-core] [PATCH] rtdm: add rtdm_printk_ratelimited Wolfgang Grandegger
2011-11-20 16:43 ` Gilles Chanteperdrix

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.