Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * linux/include/linux/relay.h
0004  *
0005  * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp
0006  * Copyright (C) 1999, 2000, 2001, 2002 - Karim Yaghmour (karim@opersys.com)
0007  *
0008  * CONFIG_RELAY definitions and declarations
0009  */
0010 
0011 #ifndef _LINUX_RELAY_H
0012 #define _LINUX_RELAY_H
0013 
0014 #include <linux/types.h>
0015 #include <linux/sched.h>
0016 #include <linux/timer.h>
0017 #include <linux/wait.h>
0018 #include <linux/list.h>
0019 #include <linux/irq_work.h>
0020 #include <linux/bug.h>
0021 #include <linux/fs.h>
0022 #include <linux/poll.h>
0023 #include <linux/kref.h>
0024 #include <linux/percpu.h>
0025 
0026 /*
0027  * Tracks changes to rchan/rchan_buf structs
0028  */
0029 #define RELAYFS_CHANNEL_VERSION     7
0030 
0031 /*
0032  * Per-cpu relay channel buffer
0033  */
0034 struct rchan_buf
0035 {
0036     void *start;            /* start of channel buffer */
0037     void *data;         /* start of current sub-buffer */
0038     size_t offset;          /* current offset into sub-buffer */
0039     size_t subbufs_produced;    /* count of sub-buffers produced */
0040     size_t subbufs_consumed;    /* count of sub-buffers consumed */
0041     struct rchan *chan;     /* associated channel */
0042     wait_queue_head_t read_wait;    /* reader wait queue */
0043     struct irq_work wakeup_work;    /* reader wakeup */
0044     struct dentry *dentry;      /* channel file dentry */
0045     struct kref kref;       /* channel buffer refcount */
0046     struct page **page_array;   /* array of current buffer pages */
0047     unsigned int page_count;    /* number of current buffer pages */
0048     unsigned int finalized;     /* buffer has been finalized */
0049     size_t *padding;        /* padding counts per sub-buffer */
0050     size_t prev_padding;        /* temporary variable */
0051     size_t bytes_consumed;      /* bytes consumed in cur read subbuf */
0052     size_t early_bytes;     /* bytes consumed before VFS inited */
0053     unsigned int cpu;       /* this buf's cpu */
0054 } ____cacheline_aligned;
0055 
0056 /*
0057  * Relay channel data structure
0058  */
0059 struct rchan
0060 {
0061     u32 version;            /* the version of this struct */
0062     size_t subbuf_size;     /* sub-buffer size */
0063     size_t n_subbufs;       /* number of sub-buffers per buffer */
0064     size_t alloc_size;      /* total buffer size allocated */
0065     const struct rchan_callbacks *cb; /* client callbacks */
0066     struct kref kref;       /* channel refcount */
0067     void *private_data;     /* for user-defined data */
0068     size_t last_toobig;     /* tried to log event > subbuf size */
0069     struct rchan_buf * __percpu *buf; /* per-cpu channel buffers */
0070     int is_global;          /* One global buffer ? */
0071     struct list_head list;      /* for channel list */
0072     struct dentry *parent;      /* parent dentry passed to open */
0073     int has_base_filename;      /* has a filename associated? */
0074     char base_filename[NAME_MAX];   /* saved base filename */
0075 };
0076 
0077 /*
0078  * Relay channel client callbacks
0079  */
0080 struct rchan_callbacks
0081 {
0082     /*
0083      * subbuf_start - called on buffer-switch to a new sub-buffer
0084      * @buf: the channel buffer containing the new sub-buffer
0085      * @subbuf: the start of the new sub-buffer
0086      * @prev_subbuf: the start of the previous sub-buffer
0087      * @prev_padding: unused space at the end of previous sub-buffer
0088      *
0089      * The client should return 1 to continue logging, 0 to stop
0090      * logging.
0091      *
0092      * This callback is optional.
0093      *
0094      * NOTE: subbuf_start will also be invoked when the buffer is
0095      *       created, so that the first sub-buffer can be initialized
0096      *       if necessary.  In this case, prev_subbuf will be NULL.
0097      *
0098      * NOTE: the client can reserve bytes at the beginning of the new
0099      *       sub-buffer by calling subbuf_start_reserve() in this callback.
0100      */
0101     int (*subbuf_start) (struct rchan_buf *buf,
0102                  void *subbuf,
0103                  void *prev_subbuf,
0104                  size_t prev_padding);
0105 
0106     /*
0107      * create_buf_file - create file to represent a relay channel buffer
0108      * @filename: the name of the file to create
0109      * @parent: the parent of the file to create
0110      * @mode: the mode of the file to create
0111      * @buf: the channel buffer
0112      * @is_global: outparam - set non-zero if the buffer should be global
0113      *
0114      * Called during relay_open(), once for each per-cpu buffer,
0115      * to allow the client to create a file to be used to
0116      * represent the corresponding channel buffer.  If the file is
0117      * created outside of relay, the parent must also exist in
0118      * that filesystem.
0119      *
0120      * The callback should return the dentry of the file created
0121      * to represent the relay buffer.
0122      *
0123      * Setting the is_global outparam to a non-zero value will
0124      * cause relay_open() to create a single global buffer rather
0125      * than the default set of per-cpu buffers.
0126      *
0127      * This callback is mandatory.
0128      *
0129      * See Documentation/filesystems/relay.rst for more info.
0130      */
0131     struct dentry *(*create_buf_file)(const char *filename,
0132                       struct dentry *parent,
0133                       umode_t mode,
0134                       struct rchan_buf *buf,
0135                       int *is_global);
0136 
0137     /*
0138      * remove_buf_file - remove file representing a relay channel buffer
0139      * @dentry: the dentry of the file to remove
0140      *
0141      * Called during relay_close(), once for each per-cpu buffer,
0142      * to allow the client to remove a file used to represent a
0143      * channel buffer.
0144      *
0145      * The callback should return 0 if successful, negative if not.
0146      *
0147      * This callback is mandatory.
0148      */
0149     int (*remove_buf_file)(struct dentry *dentry);
0150 };
0151 
0152 /*
0153  * CONFIG_RELAY kernel API, kernel/relay.c
0154  */
0155 
0156 struct rchan *relay_open(const char *base_filename,
0157              struct dentry *parent,
0158              size_t subbuf_size,
0159              size_t n_subbufs,
0160              const struct rchan_callbacks *cb,
0161              void *private_data);
0162 extern int relay_late_setup_files(struct rchan *chan,
0163                   const char *base_filename,
0164                   struct dentry *parent);
0165 extern void relay_close(struct rchan *chan);
0166 extern void relay_flush(struct rchan *chan);
0167 extern void relay_subbufs_consumed(struct rchan *chan,
0168                    unsigned int cpu,
0169                    size_t consumed);
0170 extern void relay_reset(struct rchan *chan);
0171 extern int relay_buf_full(struct rchan_buf *buf);
0172 
0173 extern size_t relay_switch_subbuf(struct rchan_buf *buf,
0174                   size_t length);
0175 
0176 /**
0177  *  relay_write - write data into the channel
0178  *  @chan: relay channel
0179  *  @data: data to be written
0180  *  @length: number of bytes to write
0181  *
0182  *  Writes data into the current cpu's channel buffer.
0183  *
0184  *  Protects the buffer by disabling interrupts.  Use this
0185  *  if you might be logging from interrupt context.  Try
0186  *  __relay_write() if you know you won't be logging from
0187  *  interrupt context.
0188  */
0189 static inline void relay_write(struct rchan *chan,
0190                    const void *data,
0191                    size_t length)
0192 {
0193     unsigned long flags;
0194     struct rchan_buf *buf;
0195 
0196     local_irq_save(flags);
0197     buf = *this_cpu_ptr(chan->buf);
0198     if (unlikely(buf->offset + length > chan->subbuf_size))
0199         length = relay_switch_subbuf(buf, length);
0200     memcpy(buf->data + buf->offset, data, length);
0201     buf->offset += length;
0202     local_irq_restore(flags);
0203 }
0204 
0205 /**
0206  *  __relay_write - write data into the channel
0207  *  @chan: relay channel
0208  *  @data: data to be written
0209  *  @length: number of bytes to write
0210  *
0211  *  Writes data into the current cpu's channel buffer.
0212  *
0213  *  Protects the buffer by disabling preemption.  Use
0214  *  relay_write() if you might be logging from interrupt
0215  *  context.
0216  */
0217 static inline void __relay_write(struct rchan *chan,
0218                  const void *data,
0219                  size_t length)
0220 {
0221     struct rchan_buf *buf;
0222 
0223     buf = *get_cpu_ptr(chan->buf);
0224     if (unlikely(buf->offset + length > buf->chan->subbuf_size))
0225         length = relay_switch_subbuf(buf, length);
0226     memcpy(buf->data + buf->offset, data, length);
0227     buf->offset += length;
0228     put_cpu_ptr(chan->buf);
0229 }
0230 
0231 /**
0232  *  relay_reserve - reserve slot in channel buffer
0233  *  @chan: relay channel
0234  *  @length: number of bytes to reserve
0235  *
0236  *  Returns pointer to reserved slot, NULL if full.
0237  *
0238  *  Reserves a slot in the current cpu's channel buffer.
0239  *  Does not protect the buffer at all - caller must provide
0240  *  appropriate synchronization.
0241  */
0242 static inline void *relay_reserve(struct rchan *chan, size_t length)
0243 {
0244     void *reserved = NULL;
0245     struct rchan_buf *buf = *get_cpu_ptr(chan->buf);
0246 
0247     if (unlikely(buf->offset + length > buf->chan->subbuf_size)) {
0248         length = relay_switch_subbuf(buf, length);
0249         if (!length)
0250             goto end;
0251     }
0252     reserved = buf->data + buf->offset;
0253     buf->offset += length;
0254 
0255 end:
0256     put_cpu_ptr(chan->buf);
0257     return reserved;
0258 }
0259 
0260 /**
0261  *  subbuf_start_reserve - reserve bytes at the start of a sub-buffer
0262  *  @buf: relay channel buffer
0263  *  @length: number of bytes to reserve
0264  *
0265  *  Helper function used to reserve bytes at the beginning of
0266  *  a sub-buffer in the subbuf_start() callback.
0267  */
0268 static inline void subbuf_start_reserve(struct rchan_buf *buf,
0269                     size_t length)
0270 {
0271     BUG_ON(length >= buf->chan->subbuf_size - 1);
0272     buf->offset = length;
0273 }
0274 
0275 /*
0276  * exported relay file operations, kernel/relay.c
0277  */
0278 extern const struct file_operations relay_file_operations;
0279 
0280 #ifdef CONFIG_RELAY
0281 int relay_prepare_cpu(unsigned int cpu);
0282 #else
0283 #define relay_prepare_cpu     NULL
0284 #endif
0285 
0286 #endif /* _LINUX_RELAY_H */
0287