]> git.ipfire.org Git - thirdparty/linux.git/blobdiff - kernel/printk/printk_ringbuffer.h
Merge tag 'printk-for-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/printk...
[thirdparty/linux.git] / kernel / printk / printk_ringbuffer.h
index 18cd25e489b8935225c1ca9292c109af71941eb1..52626d0f1fa37815d0473a879c7a8413a0eec15f 100644 (file)
@@ -75,7 +75,7 @@ struct prb_desc_ring {
        struct printk_info      *infos;
        atomic_long_t           head_id;
        atomic_long_t           tail_id;
-       atomic_long_t           last_finalized_id;
+       atomic_long_t           last_finalized_seq;
 };
 
 /*
@@ -127,8 +127,22 @@ enum desc_state {
 #define DESC_SV(id, state)     (((unsigned long)state << DESC_FLAGS_SHIFT) | id)
 #define DESC_ID_MASK           (~DESC_FLAGS_MASK)
 #define DESC_ID(sv)            ((sv) & DESC_ID_MASK)
+
+/*
+ * Special data block logical position values (for fields of
+ * @prb_desc.text_blk_lpos).
+ *
+ * - Bit0 is used to identify if the record has no data block. (Implemented in
+ *   the LPOS_DATALESS() macro.)
+ *
+ * - Bit1 specifies the reason for not having a data block.
+ *
+ * These special values could never be real lpos values because of the
+ * meta data and alignment padding of data blocks. (See to_blk_size() for
+ * details.)
+ */
 #define FAILED_LPOS            0x1
-#define NO_LPOS                        0x3
+#define EMPTY_LINE_LPOS                0x3
 
 #define FAILED_BLK_LPOS        \
 {                              \
@@ -259,7 +273,7 @@ static struct printk_ringbuffer name = {                                                    \
                .infos          = &_##name##_infos[0],                                          \
                .head_id        = ATOMIC_INIT(DESC0_ID(descbits)),                              \
                .tail_id        = ATOMIC_INIT(DESC0_ID(descbits)),                              \
-               .last_finalized_id = ATOMIC_INIT(DESC0_ID(descbits)),                           \
+               .last_finalized_seq = ATOMIC_INIT(0),                                           \
        },                                                                                      \
        .text_data_ring = {                                                                     \
                .size_bits      = (avgtextbits) + (descbits),                                   \
@@ -378,7 +392,41 @@ bool prb_read_valid(struct printk_ringbuffer *rb, u64 seq,
 bool prb_read_valid_info(struct printk_ringbuffer *rb, u64 seq,
                         struct printk_info *info, unsigned int *line_count);
 
+u64 prb_first_seq(struct printk_ringbuffer *rb);
 u64 prb_first_valid_seq(struct printk_ringbuffer *rb);
 u64 prb_next_seq(struct printk_ringbuffer *rb);
+u64 prb_next_reserve_seq(struct printk_ringbuffer *rb);
+
+#ifdef CONFIG_64BIT
+
+#define __u64seq_to_ulseq(u64seq) (u64seq)
+#define __ulseq_to_u64seq(rb, ulseq) (ulseq)
+
+#else /* CONFIG_64BIT */
+
+#define __u64seq_to_ulseq(u64seq) ((u32)u64seq)
+
+static inline u64 __ulseq_to_u64seq(struct printk_ringbuffer *rb, u32 ulseq)
+{
+       u64 rb_first_seq = prb_first_seq(rb);
+       u64 seq;
+
+       /*
+        * The provided sequence is only the lower 32 bits of the ringbuffer
+        * sequence. It needs to be expanded to 64bit. Get the first sequence
+        * number from the ringbuffer and fold it.
+        *
+        * Having a 32bit representation in the console is sufficient.
+        * If a console ever gets more than 2^31 records behind
+        * the ringbuffer then this is the least of the problems.
+        *
+        * Also the access to the ring buffer is always safe.
+        */
+       seq = rb_first_seq - (s32)((u32)rb_first_seq - ulseq);
+
+       return seq;
+}
+
+#endif /* CONFIG_64BIT */
 
 #endif /* _KERNEL_PRINTK_RINGBUFFER_H */