Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */ 2 : : /* 3 : : * linux/include/linux/relay.h 4 : : * 5 : : * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp 6 : : * Copyright (C) 1999, 2000, 2001, 2002 - Karim Yaghmour (karim@opersys.com) 7 : : * 8 : : * CONFIG_RELAY definitions and declarations 9 : : */ 10 : : 11 : : #ifndef _LINUX_RELAY_H 12 : : #define _LINUX_RELAY_H 13 : : 14 : : #include <linux/types.h> 15 : : #include <linux/sched.h> 16 : : #include <linux/timer.h> 17 : : #include <linux/wait.h> 18 : : #include <linux/list.h> 19 : : #include <linux/irq_work.h> 20 : : #include <linux/bug.h> 21 : : #include <linux/fs.h> 22 : : #include <linux/poll.h> 23 : : #include <linux/kref.h> 24 : : #include <linux/percpu.h> 25 : : 26 : : /* 27 : : * Tracks changes to rchan/rchan_buf structs 28 : : */ 29 : : #define RELAYFS_CHANNEL_VERSION 7 30 : : 31 : : /* 32 : : * Per-cpu relay channel buffer 33 : : */ 34 : : struct rchan_buf 35 : : { 36 : : void *start; /* start of channel buffer */ 37 : : void *data; /* start of current sub-buffer */ 38 : : size_t offset; /* current offset into sub-buffer */ 39 : : size_t subbufs_produced; /* count of sub-buffers produced */ 40 : : size_t subbufs_consumed; /* count of sub-buffers consumed */ 41 : : struct rchan *chan; /* associated channel */ 42 : : wait_queue_head_t read_wait; /* reader wait queue */ 43 : : struct irq_work wakeup_work; /* reader wakeup */ 44 : : struct dentry *dentry; /* channel file dentry */ 45 : : struct kref kref; /* channel buffer refcount */ 46 : : struct page **page_array; /* array of current buffer pages */ 47 : : unsigned int page_count; /* number of current buffer pages */ 48 : : unsigned int finalized; /* buffer has been finalized */ 49 : : size_t *padding; /* padding counts per sub-buffer */ 50 : : size_t prev_padding; /* temporary variable */ 51 : : size_t bytes_consumed; /* bytes consumed in cur read subbuf */ 52 : : size_t early_bytes; /* bytes consumed before VFS inited */ 53 : : unsigned int cpu; /* this buf's cpu */ 54 : : } ____cacheline_aligned; 55 : : 56 : : /* 57 : : * Relay channel data structure 58 : : */ 59 : : struct rchan 60 : : { 61 : : u32 version; /* the version of this struct */ 62 : : size_t subbuf_size; /* sub-buffer size */ 63 : : size_t n_subbufs; /* number of sub-buffers per buffer */ 64 : : size_t alloc_size; /* total buffer size allocated */ 65 : : struct rchan_callbacks *cb; /* client callbacks */ 66 : : struct kref kref; /* channel refcount */ 67 : : void *private_data; /* for user-defined data */ 68 : : size_t last_toobig; /* tried to log event > subbuf size */ 69 : : struct rchan_buf * __percpu *buf; /* per-cpu channel buffers */ 70 : : int is_global; /* One global buffer ? */ 71 : : struct list_head list; /* for channel list */ 72 : : struct dentry *parent; /* parent dentry passed to open */ 73 : : int has_base_filename; /* has a filename associated? */ 74 : : char base_filename[NAME_MAX]; /* saved base filename */ 75 : : }; 76 : : 77 : : /* 78 : : * Relay channel client callbacks 79 : : */ 80 : : struct rchan_callbacks 81 : : { 82 : : /* 83 : : * subbuf_start - called on buffer-switch to a new sub-buffer 84 : : * @buf: the channel buffer containing the new sub-buffer 85 : : * @subbuf: the start of the new sub-buffer 86 : : * @prev_subbuf: the start of the previous sub-buffer 87 : : * @prev_padding: unused space at the end of previous sub-buffer 88 : : * 89 : : * The client should return 1 to continue logging, 0 to stop 90 : : * logging. 91 : : * 92 : : * NOTE: subbuf_start will also be invoked when the buffer is 93 : : * created, so that the first sub-buffer can be initialized 94 : : * if necessary. In this case, prev_subbuf will be NULL. 95 : : * 96 : : * NOTE: the client can reserve bytes at the beginning of the new 97 : : * sub-buffer by calling subbuf_start_reserve() in this callback. 98 : : */ 99 : : int (*subbuf_start) (struct rchan_buf *buf, 100 : : void *subbuf, 101 : : void *prev_subbuf, 102 : : size_t prev_padding); 103 : : 104 : : /* 105 : : * buf_mapped - relay buffer mmap notification 106 : : * @buf: the channel buffer 107 : : * @filp: relay file pointer 108 : : * 109 : : * Called when a relay file is successfully mmapped 110 : : */ 111 : : void (*buf_mapped)(struct rchan_buf *buf, 112 : : struct file *filp); 113 : : 114 : : /* 115 : : * buf_unmapped - relay buffer unmap notification 116 : : * @buf: the channel buffer 117 : : * @filp: relay file pointer 118 : : * 119 : : * Called when a relay file is successfully unmapped 120 : : */ 121 : : void (*buf_unmapped)(struct rchan_buf *buf, 122 : : struct file *filp); 123 : : /* 124 : : * create_buf_file - create file to represent a relay channel buffer 125 : : * @filename: the name of the file to create 126 : : * @parent: the parent of the file to create 127 : : * @mode: the mode of the file to create 128 : : * @buf: the channel buffer 129 : : * @is_global: outparam - set non-zero if the buffer should be global 130 : : * 131 : : * Called during relay_open(), once for each per-cpu buffer, 132 : : * to allow the client to create a file to be used to 133 : : * represent the corresponding channel buffer. If the file is 134 : : * created outside of relay, the parent must also exist in 135 : : * that filesystem. 136 : : * 137 : : * The callback should return the dentry of the file created 138 : : * to represent the relay buffer. 139 : : * 140 : : * Setting the is_global outparam to a non-zero value will 141 : : * cause relay_open() to create a single global buffer rather 142 : : * than the default set of per-cpu buffers. 143 : : * 144 : : * See Documentation/filesystems/relay.txt for more info. 145 : : */ 146 : : struct dentry *(*create_buf_file)(const char *filename, 147 : : struct dentry *parent, 148 : : umode_t mode, 149 : : struct rchan_buf *buf, 150 : : int *is_global); 151 : : 152 : : /* 153 : : * remove_buf_file - remove file representing a relay channel buffer 154 : : * @dentry: the dentry of the file to remove 155 : : * 156 : : * Called during relay_close(), once for each per-cpu buffer, 157 : : * to allow the client to remove a file used to represent a 158 : : * channel buffer. 159 : : * 160 : : * The callback should return 0 if successful, negative if not. 161 : : */ 162 : : int (*remove_buf_file)(struct dentry *dentry); 163 : : }; 164 : : 165 : : /* 166 : : * CONFIG_RELAY kernel API, kernel/relay.c 167 : : */ 168 : : 169 : : struct rchan *relay_open(const char *base_filename, 170 : : struct dentry *parent, 171 : : size_t subbuf_size, 172 : : size_t n_subbufs, 173 : : struct rchan_callbacks *cb, 174 : : void *private_data); 175 : : extern int relay_late_setup_files(struct rchan *chan, 176 : : const char *base_filename, 177 : : struct dentry *parent); 178 : : extern void relay_close(struct rchan *chan); 179 : : extern void relay_flush(struct rchan *chan); 180 : : extern void relay_subbufs_consumed(struct rchan *chan, 181 : : unsigned int cpu, 182 : : size_t consumed); 183 : : extern void relay_reset(struct rchan *chan); 184 : : extern int relay_buf_full(struct rchan_buf *buf); 185 : : 186 : : extern size_t relay_switch_subbuf(struct rchan_buf *buf, 187 : : size_t length); 188 : : 189 : : /** 190 : : * relay_write - write data into the channel 191 : : * @chan: relay channel 192 : : * @data: data to be written 193 : : * @length: number of bytes to write 194 : : * 195 : : * Writes data into the current cpu's channel buffer. 196 : : * 197 : : * Protects the buffer by disabling interrupts. Use this 198 : : * if you might be logging from interrupt context. Try 199 : : * __relay_write() if you know you won't be logging from 200 : : * interrupt context. 201 : : */ 202 : : static inline void relay_write(struct rchan *chan, 203 : : const void *data, 204 : : size_t length) 205 : : { 206 : : unsigned long flags; 207 : : struct rchan_buf *buf; 208 : : 209 : : local_irq_save(flags); 210 : : buf = *this_cpu_ptr(chan->buf); 211 : : if (unlikely(buf->offset + length > chan->subbuf_size)) 212 : : length = relay_switch_subbuf(buf, length); 213 : : memcpy(buf->data + buf->offset, data, length); 214 : : buf->offset += length; 215 : : local_irq_restore(flags); 216 : : } 217 : : 218 : : /** 219 : : * __relay_write - write data into the channel 220 : : * @chan: relay channel 221 : : * @data: data to be written 222 : : * @length: number of bytes to write 223 : : * 224 : : * Writes data into the current cpu's channel buffer. 225 : : * 226 : : * Protects the buffer by disabling preemption. Use 227 : : * relay_write() if you might be logging from interrupt 228 : : * context. 229 : : */ 230 : : static inline void __relay_write(struct rchan *chan, 231 : : const void *data, 232 : : size_t length) 233 : : { 234 : : struct rchan_buf *buf; 235 : : 236 : : buf = *get_cpu_ptr(chan->buf); 237 : : if (unlikely(buf->offset + length > buf->chan->subbuf_size)) 238 : : length = relay_switch_subbuf(buf, length); 239 : : memcpy(buf->data + buf->offset, data, length); 240 : : buf->offset += length; 241 : : put_cpu_ptr(chan->buf); 242 : : } 243 : : 244 : : /** 245 : : * relay_reserve - reserve slot in channel buffer 246 : : * @chan: relay channel 247 : : * @length: number of bytes to reserve 248 : : * 249 : : * Returns pointer to reserved slot, NULL if full. 250 : : * 251 : : * Reserves a slot in the current cpu's channel buffer. 252 : : * Does not protect the buffer at all - caller must provide 253 : : * appropriate synchronization. 254 : : */ 255 : 0 : static inline void *relay_reserve(struct rchan *chan, size_t length) 256 : : { 257 : : void *reserved = NULL; 258 : 0 : struct rchan_buf *buf = *get_cpu_ptr(chan->buf); 259 : : 260 : 0 : if (unlikely(buf->offset + length > buf->chan->subbuf_size)) { 261 : 0 : length = relay_switch_subbuf(buf, length); 262 : 0 : if (!length) 263 : : goto end; 264 : : } 265 : 0 : reserved = buf->data + buf->offset; 266 : 0 : buf->offset += length; 267 : : 268 : : end: 269 : 0 : put_cpu_ptr(chan->buf); 270 : 0 : return reserved; 271 : : } 272 : : 273 : : /** 274 : : * subbuf_start_reserve - reserve bytes at the start of a sub-buffer 275 : : * @buf: relay channel buffer 276 : : * @length: number of bytes to reserve 277 : : * 278 : : * Helper function used to reserve bytes at the beginning of 279 : : * a sub-buffer in the subbuf_start() callback. 280 : : */ 281 : : static inline void subbuf_start_reserve(struct rchan_buf *buf, 282 : : size_t length) 283 : : { 284 : : BUG_ON(length >= buf->chan->subbuf_size - 1); 285 : : buf->offset = length; 286 : : } 287 : : 288 : : /* 289 : : * exported relay file operations, kernel/relay.c 290 : : */ 291 : : extern const struct file_operations relay_file_operations; 292 : : 293 : : #ifdef CONFIG_RELAY 294 : : int relay_prepare_cpu(unsigned int cpu); 295 : : #else 296 : : #define relay_prepare_cpu NULL 297 : : #endif 298 : : 299 : : #endif /* _LINUX_RELAY_H */ 300 : :