summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0006-printk-rb-add-blocking-reader-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/0006-printk-rb-add-blocking-reader-support.patch')
-rw-r--r--debian/patches-rt/0006-printk-rb-add-blocking-reader-support.patch162
1 files changed, 0 insertions, 162 deletions
diff --git a/debian/patches-rt/0006-printk-rb-add-blocking-reader-support.patch b/debian/patches-rt/0006-printk-rb-add-blocking-reader-support.patch
deleted file mode 100644
index f3ab52e2a..000000000
--- a/debian/patches-rt/0006-printk-rb-add-blocking-reader-support.patch
+++ /dev/null
@@ -1,162 +0,0 @@
-From: John Ogness <john.ogness@linutronix.de>
-Date: Tue, 12 Feb 2019 15:29:44 +0100
-Subject: [PATCH 06/25] printk-rb: add blocking reader support
-Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.9/older/patches-5.9-rt16.tar.xz
-
-Add a blocking read function for readers. An irq_work function is
-used to signal the wait queue so that write notification can
-be triggered from any context.
-
-Signed-off-by: John Ogness <john.ogness@linutronix.de>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
----
- include/linux/printk_ringbuffer.h | 20 +++++++++++++
- lib/printk_ringbuffer.c | 55 ++++++++++++++++++++++++++++++++++++++
- 2 files changed, 75 insertions(+)
-
---- a/include/linux/printk_ringbuffer.h
-+++ b/include/linux/printk_ringbuffer.h
-@@ -2,8 +2,10 @@
- #ifndef _LINUX_PRINTK_RINGBUFFER_H
- #define _LINUX_PRINTK_RINGBUFFER_H
-
-+#include <linux/irq_work.h>
- #include <linux/atomic.h>
- #include <linux/percpu.h>
-+#include <linux/wait.h>
-
- struct prb_cpulock {
- atomic_t owner;
-@@ -22,6 +24,10 @@ struct printk_ringbuffer {
-
- struct prb_cpulock *cpulock;
- atomic_t ctx;
-+
-+ struct wait_queue_head *wq;
-+ atomic_long_t wq_counter;
-+ struct irq_work *wq_work;
- };
-
- struct prb_entry {
-@@ -59,6 +65,15 @@ struct prb_iterator {
- #define DECLARE_STATIC_PRINTKRB(name, szbits, cpulockptr) \
- static char _##name##_buffer[1 << (szbits)] \
- __aligned(__alignof__(long)); \
-+static DECLARE_WAIT_QUEUE_HEAD(_##name##_wait); \
-+static void _##name##_wake_work_func(struct irq_work *irq_work) \
-+{ \
-+ wake_up_interruptible_all(&_##name##_wait); \
-+} \
-+static struct irq_work _##name##_wake_work = { \
-+ .func = _##name##_wake_work_func, \
-+ .flags = ATOMIC_INIT(IRQ_WORK_LAZY), \
-+}; \
- static struct printk_ringbuffer name = { \
- .buffer = &_##name##_buffer[0], \
- .size_bits = szbits, \
-@@ -68,6 +83,9 @@ static struct printk_ringbuffer name = {
- .reserve = ATOMIC_LONG_INIT(-111 * sizeof(long)), \
- .cpulock = cpulockptr, \
- .ctx = ATOMIC_INIT(0), \
-+ .wq = &_##name##_wait, \
-+ .wq_counter = ATOMIC_LONG_INIT(0), \
-+ .wq_work = &_##name##_wake_work, \
- }
-
- /* writer interface */
-@@ -80,6 +98,8 @@ void prb_iter_init(struct prb_iterator *
- u64 *seq);
- void prb_iter_copy(struct prb_iterator *dest, struct prb_iterator *src);
- int prb_iter_next(struct prb_iterator *iter, char *buf, int size, u64 *seq);
-+int prb_iter_wait_next(struct prb_iterator *iter, char *buf, int size,
-+ u64 *seq);
- int prb_iter_data(struct prb_iterator *iter, char *buf, int size, u64 *seq);
-
- /* utility functions */
---- a/lib/printk_ringbuffer.c
-+++ b/lib/printk_ringbuffer.c
-@@ -1,4 +1,5 @@
- // SPDX-License-Identifier: GPL-2.0
-+#include <linux/sched.h>
- #include <linux/smp.h>
- #include <linux/string.h>
- #include <linux/errno.h>
-@@ -154,6 +155,7 @@ static bool push_tail(struct printk_ring
- void prb_commit(struct prb_handle *h)
- {
- struct printk_ringbuffer *rb = h->rb;
-+ bool changed = false;
- struct prb_entry *e;
- unsigned long head;
- unsigned long res;
-@@ -175,6 +177,7 @@ void prb_commit(struct prb_handle *h)
- }
- e->seq = ++rb->seq;
- head += e->size;
-+ changed = true;
- }
- atomic_long_set_release(&rb->head, res);
- atomic_dec(&rb->ctx);
-@@ -185,6 +188,18 @@ void prb_commit(struct prb_handle *h)
- }
-
- prb_unlock(rb->cpulock, h->cpu);
-+
-+ if (changed) {
-+ atomic_long_inc(&rb->wq_counter);
-+ if (wq_has_sleeper(rb->wq)) {
-+#ifdef CONFIG_IRQ_WORK
-+ irq_work_queue(rb->wq_work);
-+#else
-+ if (!in_nmi())
-+ wake_up_interruptible_all(rb->wq);
-+#endif
-+ }
-+ }
- }
-
- /*
-@@ -437,3 +452,43 @@ int prb_iter_next(struct prb_iterator *i
-
- return 1;
- }
-+
-+/*
-+ * prb_iter_wait_next: Advance to the next record, blocking if none available.
-+ * @iter: Iterator tracking the current position.
-+ * @buf: A buffer to store the data of the next record. May be NULL.
-+ * @size: The size of @buf. (Ignored if @buf is NULL.)
-+ * @seq: The sequence number of the next record. May be NULL.
-+ *
-+ * If a next record is already available, this function works like
-+ * prb_iter_next(). Otherwise block interruptible until a next record is
-+ * available.
-+ *
-+ * When a next record is available, @iter is advanced and (if specified)
-+ * the data and/or sequence number of that record are provided.
-+ *
-+ * This function might sleep.
-+ *
-+ * Returns 1 if @iter was advanced, -EINVAL if @iter is now invalid, or
-+ * -ERESTARTSYS if interrupted by a signal.
-+ */
-+int prb_iter_wait_next(struct prb_iterator *iter, char *buf, int size, u64 *seq)
-+{
-+ unsigned long last_seen;
-+ int ret;
-+
-+ for (;;) {
-+ last_seen = atomic_long_read(&iter->rb->wq_counter);
-+
-+ ret = prb_iter_next(iter, buf, size, seq);
-+ if (ret != 0)
-+ break;
-+
-+ ret = wait_event_interruptible(*iter->rb->wq,
-+ last_seen != atomic_long_read(&iter->rb->wq_counter));
-+ if (ret < 0)
-+ break;
-+ }
-+
-+ return ret;
-+}