1 /******************************************************************************
3 * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. All rights reserved.
5 ******************************************************************************/
7 #ifndef _SCSC_LOGRING_RING_H_
8 #define _SCSC_LOGRING_RING_H_
10 #include <linux/module.h>
11 #include <linux/sched.h>
12 #include <linux/smp.h>
13 #include <linux/hardirq.h>
14 #include <linux/wait.h>
15 #include <linux/slab.h>
16 #include <linux/smp.h>
17 #include <linux/errno.h>
18 #include <linux/spinlock.h>
19 #include <linux/jiffies.h>
20 #include <linux/time.h>
21 #include <linux/crc32.h>
23 #include <scsc/scsc_logring.h>
25 #include "scsc_logring_common.h"
27 #define SCSC_BINFO_LEN 32
28 #define SCSC_HBUF_LEN 128
29 /* A safe size to enforce on ingressing binary blobs; this accounts
30 * for possible binary expansion while reading, in order to fit the reader
31 * DEFAULT_TBUF_SZ in any possible case: this way we avoid to have truncated
32 * data also on read while dumping big binary blobs.
34 #define SCSC_MAX_BIN_BLOB_SZ 1920
36 * This spare area is used to prepare a logging entry before pushing it into
37 * the ring and so it's the maximum length allowed for a log entry.
38 * When this change (hugely) you should check the size of len field
39 * in the following struct scsc_ring_record.
41 #define BASE_SPARE_SZ 2048
43 #define DEFAULT_RING_BUFFER_SZ 1048576
44 #define DEFAULT_ENABLE_HEADER 1
45 #define DEFAULT_ENABLE_LOGRING 1
46 /* The default len, in bytes, of the binary blob to decode in ASCII
47 * Human readable form. -1 means DECODE EVERYTHING !
49 #define DEFAULT_BIN_DECODE_LEN -1
50 #define DEBUGFS_ROOT "/sys/kernel/debug"
51 #define DEBUGFS_RING0_ROOT "ring0"
54 * Our ring buffer is allocated simply as a bunch of contiguos bytes.
55 * Data is stored as a contiguos stream of concatenated records, each one
56 * starting with a record descriptor of type scsc_ring_record: data content
57 * is then appended to the record descriptor; in this way we can account
58 * for different types of content, pushing the TAG describing the content
59 * into the record descriptor itself, being then able to operate differently
60 * on read depending on the type of content.
61 * The tail and head references 'points' to the start of the first (oldest)
62 * and the last (newest) record: any write will happen after the end
63 * of the current head: these references in fact points to the starting byte
64 * of the record descriptor modulus the ring size (they're NOT abosolute
65 * pointers). Since our 'metadata' is embedded inside the ring itself (like
66 * printk does) we never write variable string content in place BUT use
67 * instead the spare area (allocated contiguosly at the end of the ring)
68 * to expand the provided format string and then memcpy the content to
69 * the final position after having properly updated the record descriptors
70 * and eventually moved away the tail when overwriting.
71 * Moreover we never wrap a record across the ring boundary: if there's NOT
72 * enough space at the end of the ring, we simply place it at the start.
73 * Moreover this structs holds a kcache reference to allocate temporary
74 * buffers to use when double buffering is needed, a spinlock_t for
75 * protection and a wait_queue_t for blocking I/O.
77 * @buf: the ring-buffer itself starts here
78 * @spare: start of spare area (buf[bsz])
79 * @name: a simple named identifier
81 * @ssz: size of spare (fixed at BASE_SPARE_SZ)
82 * @head: newest record written (first byte)...next write after it
83 * @tail: odelst record written (first byte)...full dump read will start
85 * @last: the last record before the end of the ring.
86 * @records: the number of records
87 * @written: a general progressive counter of total bytes written into
89 * @lock: a spinlock_t to protetc concurrent access
90 * @wq: a wait queue where to put sleeping processes waiting for input.
91 * They're woken up at the end os scsc_printk().
92 * @refc: a reference counter...currently unused.
93 * @private: useful to hold some user provided data (used to hold debugfs
94 * initdata related to this ring)
95 * @kcache: a reference to a kmem_cache created at initialization time
96 * to get fresh temporary buffers on the fly when copying to user and in
97 * need of a double buffer
99 struct scsc_ring_buffer
{
113 wait_queue_head_t wq
;
119 * Our ring buffer is now built concatenating entries prepended by a record
120 * that describes the content itself. This will allow us to store different
121 * types of data (NOT only string) and to interpret it.
122 * Each record is described by this struct that is laid out in front of the
125 * | SYNC | CRC | tag | len | lev | ctx | core | nsec | <buffer len - - |
127 * @SYNC: a fixed pattern to search for when re-syncing after a reader
129 * @CRC: CRC32 calculated, using kernel crc32_le, on the whole record header,
130 * taking care to substitute this field with the 32 LSB of this record
131 * relative starting position (relative to the absolute ring buffer
133 * @tag: type of this record...matters expecially to identify binary data
135 * @len: this is the length in bytes of buffer. All string content should
136 * be NULL terminated. This length will anyway NEVER exceed
137 * BASE_SPARE_SZ that's currently a few KB.
138 * @lev: the debuglevel associated to this message.
139 * @ctx: the execution context of the logged line:
140 * SoftIRQ / Interrupt / Process
141 * @core: the CPU core id
142 * @nsec: the timestamp in nanoseconds
144 struct scsc_ring_record
{
153 } __packed
; /* should NOT be needed */
155 #define SYNC_MAGIC 0xDEADBEEF
157 * Fill a scsc_ring_record descriptor
158 * local_clock() is from the same family of time-func used
159 * by printk returns nanoseconds
161 #define SCSC_FILL_RING_RECORD(r, tag, lev) \
163 (r)->sync = SYNC_MAGIC; \
165 (r)->nsec = local_clock(); \
169 (r)->ctx = ((in_interrupt()) ? \
170 ((in_softirq()) ? 'S' : 'I') : 'P'); \
171 (r)->core = smp_processor_id(); \
175 #define SCSC_RINGREC_SZ (sizeof(struct scsc_ring_record))
176 #define SCSC_CRC_RINGREC_SZ (SCSC_RINGREC_SZ - sizeof(SYNC_MAGIC))
178 #define SCSC_IS_RING_IN_USE(ring) \
179 ((atomic_read(&((struct scsc_ring_buffer *)(ring))->refc)) != 0)
181 #define SCSC_GET_RING_REFC(ring) \
182 atomic_inc(&((struct scsc_ring_buffer *)(ring))->refc)
184 #define SCSC_PUT_RING_REFC(ring) \
185 atomic_dec(&((struct scsc_ring_buffer *)(ring))->refc)
188 #define SCSC_GET_REC_BUF(p) (((char *)(p)) + SCSC_RINGREC_SZ)
190 #define SCSC_GET_REC_LEN(recp) (((struct scsc_ring_record *)(recp))->len)
192 #define SCSC_GET_REC_TAG(recp) (((struct scsc_ring_record *)(recp))->tag)
194 #define SCSC_GET_REC_CRC(recp) (((struct scsc_ring_record *)(recp))->crc)
196 #define SCSC_GET_PTR(ring, pos) ((ring)->buf + (pos))
198 #define SCSC_GET_REC(ring, pos) \
199 ((struct scsc_ring_record *)(SCSC_GET_PTR((ring), (pos))))
201 #define SCSC_IS_REC_SYNC_VALID(recp) ((recp)->sync == SYNC_MAGIC)
203 #define SCSC_GET_HEAD_PTR(ring) SCSC_GET_PTR((ring), (ring)->head)
205 #define SCSC_GET_NEXT_FREE_SLOT_PTR(ring) \
206 (SCSC_GET_HEAD_PTR((ring)) + SCSC_RINGREC_SZ + \
207 SCSC_GET_REC_LEN(SCSC_GET_HEAD_PTR(ring)))
209 #define SCSC_GET_SLOT_LEN(ring, pos) \
210 (((SCSC_GET_REC_LEN(SCSC_GET_PTR((ring), (pos)))) != 0) ? \
211 (SCSC_RINGREC_SZ + SCSC_GET_REC_LEN(SCSC_GET_PTR((ring), (pos)))) : 0)
213 #define SCSC_GET_NEXT_SLOT_POS(ring, pos) \
214 ((pos) + SCSC_GET_SLOT_LEN((ring), (pos)))
216 #define SCSC_RING_FREE_BYTES(rb) \
217 (((rb)->head >= (rb)->tail) ? \
218 ((rb)->bsz - SCSC_GET_NEXT_SLOT_POS(rb, rb->head)) : \
219 ((rb)->tail - SCSC_GET_NEXT_SLOT_POS(rb, rb->head)))
221 #define SCSC_USED_BYTES(rb) ((rb)->bsz - SCSC_RING_FREE_BYTES(rb))
223 #define SCSC_LOGGED_BYTES(rb) (SCSC_USED_BYTES(rb) - \
224 ((rb)->records * SCSC_RINGREC_SZ))
226 #define SCSC_GET_NEXT_REC_ENTRY_POS(ring, rpos) \
227 (rpos + SCSC_RINGREC_SZ + \
228 SCSC_GET_REC_LEN(SCSC_GET_PTR((ring), (rpos))))
230 /* Ring buffer API */
231 struct scsc_ring_buffer
*alloc_ring_buffer(size_t bsz
, size_t ssz
,
232 const char *name
) __init
;
233 void free_ring_buffer(struct scsc_ring_buffer
*rb
);
234 void scsc_ring_truncate(struct scsc_ring_buffer
*rb
);
235 int push_record_string(struct scsc_ring_buffer
*rb
, int tag
, int lev
,
236 int prepend_header
, const char *msg_head
, va_list args
);
237 int push_record_blob(struct scsc_ring_buffer
*rb
, int tag
, int lev
,
238 int prepend_header
, const void *start
, size_t len
);
239 size_t read_next_records(struct scsc_ring_buffer
*rb
, int max_recs
,
240 loff_t
*last_read_rec
, void *tbuf
, size_t tsz
);
241 struct scsc_ring_buffer
*scsc_ring_get_snapshot(const struct scsc_ring_buffer
*rb
,
242 void *snap_buf
, size_t snap_sz
,
244 #endif /* _SCSC_LOGRING_RING_H_ */