Dhoat Harpal | f76b236 | 2018-03-22 20:37:38 +0530 | [diff] [blame] | 1 | /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. |
Karthikeyan Ramasubramanian | 44dc770 | 2016-09-16 15:39:37 -0600 | [diff] [blame] | 2 | * |
| 3 | * This program is free software; you can redistribute it and/or modify |
| 4 | * it under the terms of the GNU General Public License version 2 and |
| 5 | * only version 2 as published by the Free Software Foundation. |
| 6 | * |
| 7 | * This program is distributed in the hope that it will be useful, |
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 10 | * GNU General Public License for more details. |
| 11 | * |
| 12 | */ |
| 13 | #ifndef _IPC_LOGGING_PRIVATE_H |
| 14 | #define _IPC_LOGGING_PRIVATE_H |
| 15 | |
| 16 | #include <linux/ipc_logging.h> |
| 17 | |
| 18 | #define IPC_LOG_VERSION 0x0003 |
| 19 | #define IPC_LOG_MAX_CONTEXT_NAME_LEN 32 |
| 20 | |
| 21 | /** |
| 22 | * struct ipc_log_page_header - Individual log page header |
| 23 | * |
| 24 | * @magic: Magic number (used for log extraction) |
| 25 | * @nmagic: Inverse of magic number (used for log extraction) |
| 26 | * @page_num: Index of page (0.. N - 1) (note top bit is always set) |
| 27 | * @read_offset: Read offset in page |
| 28 | * @write_offset: Write offset in page (or 0xFFFF if full) |
| 29 | * @log_id: ID of logging context that owns this page |
| 30 | * @start_time: Scheduler clock for first write time in page |
| 31 | * @end_time: Scheduler clock for last write time in page |
| 32 | * @ctx_offset: Signed offset from page to the logging context. Used to |
| 33 | * optimize ram-dump extraction. |
| 34 | * |
| 35 | * @list: Linked list of pages that make up a log |
| 36 | * @nd_read_offset: Non-destructive read offset used for debugfs |
| 37 | * |
| 38 | * The first part of the structure defines data that is used to extract the |
| 39 | * logs from a memory dump and elements in this section should not be changed |
| 40 | * or re-ordered. New local data structures can be added to the end of the |
| 41 | * structure since they will be ignored by the extraction tool. |
| 42 | */ |
| 43 | struct ipc_log_page_header { |
| 44 | uint32_t magic; |
| 45 | uint32_t nmagic; |
| 46 | uint32_t page_num; |
| 47 | uint16_t read_offset; |
| 48 | uint16_t write_offset; |
| 49 | uint64_t log_id; |
| 50 | uint64_t start_time; |
| 51 | uint64_t end_time; |
| 52 | int64_t ctx_offset; |
| 53 | |
| 54 | /* add local data structures after this point */ |
| 55 | struct list_head list; |
| 56 | uint16_t nd_read_offset; |
| 57 | }; |
| 58 | |
| 59 | /** |
| 60 | * struct ipc_log_page - Individual log page |
| 61 | * |
| 62 | * @hdr: Log page header |
| 63 | * @data: Log data |
| 64 | * |
| 65 | * Each log consists of 1 to N log pages. Data size is adjusted to always fit |
| 66 | * the structure into a single kernel page. |
| 67 | */ |
| 68 | struct ipc_log_page { |
| 69 | struct ipc_log_page_header hdr; |
| 70 | char data[PAGE_SIZE - sizeof(struct ipc_log_page_header)]; |
| 71 | }; |
| 72 | |
| 73 | /** |
| 74 | * struct ipc_log_context - main logging context |
| 75 | * |
| 76 | * @magic: Magic number (used for log extraction) |
| 77 | * @nmagic: Inverse of magic number (used for log extraction) |
| 78 | * @version: IPC Logging version of log format |
| 79 | * @user_version: Version number for user-defined messages |
| 80 | * @header_size: Size of the log header which is used to determine the offset |
| 81 | * of ipc_log_page::data |
| 82 | * @log_id: Log ID (assigned when log is created) |
| 83 | * @name: Name of the log used to uniquely identify the log during extraction |
| 84 | * |
| 85 | * @list: List of log contexts (struct ipc_log_context) |
| 86 | * @page_list: List of log pages (struct ipc_log_page) |
| 87 | * @first_page: First page in list of logging pages |
| 88 | * @last_page: Last page in list of logging pages |
| 89 | * @write_page: Current write page |
| 90 | * @read_page: Current read page (for internal reads) |
| 91 | * @nd_read_page: Current debugfs extraction page (non-destructive) |
| 92 | * |
| 93 | * @write_avail: Number of bytes available to write in all pages |
| 94 | * @dent: Debugfs node for run-time log extraction |
| 95 | * @dfunc_info_list: List of deserialization functions |
| 96 | * @context_lock_lhb1: Lock for entire structure |
| 97 | * @read_avail: Completed when new data is added to the log |
| 98 | */ |
| 99 | struct ipc_log_context { |
| 100 | uint32_t magic; |
| 101 | uint32_t nmagic; |
| 102 | uint32_t version; |
| 103 | uint16_t user_version; |
| 104 | uint16_t header_size; |
| 105 | uint64_t log_id; |
| 106 | char name[IPC_LOG_MAX_CONTEXT_NAME_LEN]; |
| 107 | |
| 108 | /* add local data structures after this point */ |
| 109 | struct list_head list; |
| 110 | struct list_head page_list; |
| 111 | struct ipc_log_page *first_page; |
| 112 | struct ipc_log_page *last_page; |
| 113 | struct ipc_log_page *write_page; |
| 114 | struct ipc_log_page *read_page; |
| 115 | struct ipc_log_page *nd_read_page; |
| 116 | |
| 117 | uint32_t write_avail; |
| 118 | struct dentry *dent; |
| 119 | struct list_head dfunc_info_list; |
| 120 | spinlock_t context_lock_lhb1; |
| 121 | struct completion read_avail; |
Lynus Vaz | 802d738 | 2017-06-30 15:10:26 +0530 | [diff] [blame] | 122 | struct kref refcount; |
| 123 | bool destroyed; |
Dhoat Harpal | f76b236 | 2018-03-22 20:37:38 +0530 | [diff] [blame] | 124 | bool disabled; |
Karthikeyan Ramasubramanian | 44dc770 | 2016-09-16 15:39:37 -0600 | [diff] [blame] | 125 | }; |
| 126 | |
| 127 | struct dfunc_info { |
| 128 | struct list_head list; |
| 129 | int type; |
| 130 | void (*dfunc)(struct encode_context *, struct decode_context *); |
| 131 | }; |
| 132 | |
| 133 | enum { |
| 134 | TSV_TYPE_INVALID, |
| 135 | TSV_TYPE_TIMESTAMP, |
| 136 | TSV_TYPE_POINTER, |
| 137 | TSV_TYPE_INT32, |
| 138 | TSV_TYPE_BYTE_ARRAY, |
| 139 | TSV_TYPE_QTIMER, |
| 140 | }; |
| 141 | |
| 142 | enum { |
| 143 | OUTPUT_DEBUGFS, |
| 144 | }; |
| 145 | |
| 146 | #define IPC_LOG_CONTEXT_MAGIC_NUM 0x25874452 |
| 147 | #define IPC_LOGGING_MAGIC_NUM 0x52784425 |
| 148 | #define MIN(x, y) ((x) < (y) ? (x) : (y)) |
| 149 | #define IS_MSG_TYPE(x) (((x) > TSV_TYPE_MSG_START) && \ |
| 150 | ((x) < TSV_TYPE_MSG_END)) |
| 151 | #define MAX_MSG_DECODED_SIZE (MAX_MSG_SIZE*4) |
| 152 | |
Lynus Vaz | 802d738 | 2017-06-30 15:10:26 +0530 | [diff] [blame] | 153 | void ipc_log_context_free(struct kref *kref); |
| 154 | |
| 155 | static inline void ipc_log_context_put(struct ipc_log_context *ilctxt) |
| 156 | { |
| 157 | kref_put(&ilctxt->refcount, ipc_log_context_free); |
| 158 | } |
| 159 | |
Karthikeyan Ramasubramanian | 44dc770 | 2016-09-16 15:39:37 -0600 | [diff] [blame] | 160 | #if (defined(CONFIG_DEBUG_FS)) |
| 161 | void check_and_create_debugfs(void); |
| 162 | |
| 163 | void create_ctx_debugfs(struct ipc_log_context *ctxt, |
| 164 | const char *mod_name); |
| 165 | #else |
| 166 | void check_and_create_debugfs(void) |
| 167 | { |
| 168 | } |
| 169 | |
| 170 | void create_ctx_debugfs(struct ipc_log_context *ctxt, const char *mod_name) |
| 171 | { |
| 172 | } |
| 173 | #endif |
| 174 | |
| 175 | #endif |