msm_ipc_logging.txt 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. Introduction
  2. ============
  3. This module will be used to log the events by any module/driver which
  4. enables Inter Processor Communication (IPC). Some of the IPC drivers such
  5. as Message Routers, Multiplexers etc. which act as a passive pipe need
  6. some mechanism to log their events. Since all such IPC drivers handle a
  7. large amount of traffic/events, using kernel logs renders kernel logs
  8. unusable by other drivers and also degrades the performance of IPC
  9. drivers. This new module will help in logging such high frequency IPC
  10. driver events while keeping the standard kernel logging mechanism
  11. intact.
  12. Hardware description
  13. ====================
  14. This module does not drive any hardware resource and will only use the
  15. kernel memory-space to log the events.
  16. Software description
  17. ====================
  18. Design Goals
  19. ------------
  20. This module is designed to
  21. * support logging for drivers handling large amount of
  22. traffic/events
  23. * define & differentiate events/logs from different drivers
  24. * support both id-based and stream-based logging
  25. * support extracting the logs from both live target & memory dump
  26. IPC Log Context
  27. ----------------
  28. This module will support logging by multiple drivers. To differentiate
  29. between the multiple drivers that are using this logging mechanism, each
  30. driver will be assigned a unique context by this module. Associated with
  31. each context is the logging space, dynamically allocated from the kernel
  32. memory-space, specific to that context so that the events logged using that
  33. context will not interfere with other contexts.
  34. Event Logging
  35. --------------
  36. Every event will be logged as a <Type: Size: Value> combination. Type
  37. field identifies the type of the event that is logged. Size field represents
  38. the size of the log information. Value field represents the actual
  39. information being logged. This approach will support both id-based logging
  40. and stream-based logging. This approach will also support logging sub-events
  41. of an event. This module will provide helper routines to encode/decode the
  42. logs to/from this format.
  43. Encode Context
  44. ---------------
  45. Encode context is a temporary storage space that will be used by the client
  46. drivers to log the events in <Type: Size: Value> format. The client drivers
  47. will perform an encode start operation to initialize the encode context
  48. data structure. Then the client drivers will log their events into the
  49. encode context. Upon completion of event logging, the client drivers will
  50. perform an encode end operation to finalize the encode context data
  51. structure to be logged. Then this updated encode context data structure
  52. will be written into the client driver's IPC Log Context. The maximum
  53. event log size will be defined as 256 bytes.
  54. Log Space
  55. ----------
  56. Each context (Figure 1) has an associated log space, which is dynamically
  57. allocated from the kernel memory-space. The log space is organized as a list of
  58. 1 or more kernel memory pages. Each page (Figure 2) contains header information
  59. which is used to differentiate the log kernel page from the other kernel pages.
  60. 0 ---------------------------------
  61. | magic_no = 0x25874452 |
  62. ---------------------------------
  63. | nmagic_no = 0x52784425 |
  64. ---------------------------------
  65. | version |
  66. ---------------------------------
  67. | user_version |
  68. ---------------------------------
  69. | log_id |
  70. ---------------------------------
  71. | header_size |
  72. ---------------------------------
  73. | |
  74. | |
  75. | name [20 chars] |
  76. | |
  77. | |
  78. ---------------------------------
  79. | run-time data structures |
  80. ---------------------------------
  81. Figure 1 - Log Context Structure
  82. 31 0
  83. 0 ---------------------------------
  84. | magic_no = 0x52784425 |
  85. ---------------------------------
  86. | nmagic_no = 0xAD87BBDA |
  87. ---------------------------------
  88. |1| page_num |
  89. ---------------------------------
  90. | read_offset | write_offset |
  91. ---------------------------------
  92. | log_id |
  93. ---------------------------------
  94. | start_time low word |
  95. | start_time high word |
  96. ---------------------------------
  97. | end_time low word |
  98. | end_time high word |
  99. ---------------------------------
  100. | context offset |
  101. ---------------------------------
  102. | run-time data structures |
  103. . . . . .
  104. ---------------------------------
  105. | |
  106. | Log Data |
  107. . . .
  108. . . .
  109. | |
  110. --------------------------------- PAGE_SIZE - 1
  111. Figure 2 - Log Page Structure
  112. In addition to extracting logs at runtime through DebugFS, IPC Logging has been
  113. designed to allow extraction of logs from a memory dump. The magic numbers,
  114. timestamps, and context offset are all added to support the memory-dump
  115. extraction use case.
  116. Design
  117. ======
  118. Alternate solutions discussed include using kernel & SMEM logs which are
  119. limited in size and hence using them render them unusable by other drivers.
  120. Also kernel logging into serial console is slowing down the performance of
  121. the drivers by multiple times and sometimes lead to APPs watchdog bite.
  122. Power Management
  123. ================
  124. Not-Applicable
  125. SMP/multi-core
  126. ==============
  127. This module uses spinlocks & mutexes to handle multi-core safety.
  128. Security
  129. ========
  130. Not-Applicable
  131. Performance
  132. ===========
  133. This logging mechanism, based on experimental data, is not expected to
  134. cause a significant performance degradation. Under worst case, it can
  135. cause 1 - 2 percent degradation in the throughput of the IPC Drivers.
  136. Interface
  137. =========
  138. Exported Data Structures
  139. ------------------------
  140. struct encode_context {
  141. struct tsv_header hdr;
  142. char buff[MAX_MSG_SIZE];
  143. int offset;
  144. };
  145. struct decode_context {
  146. int output_format;
  147. char *buff;
  148. int size;
  149. };
  150. Kernel-Space Interface APIs
  151. ----------------------------
  152. /*
  153. * ipc_log_context_create: Create a ipc log context
  154. *
  155. * @max_num_pages: Number of pages of logging space required (max. 10)
  156. * @mod_name : Name of the directory entry under DEBUGFS
  157. * @user_version : Version number of user-defined message formats
  158. *
  159. * returns reference to context on success, NULL on failure
  160. */
  161. void * ipc_log_context_create(int max_num_pages,
  162. const char *mod_name);
  163. /*
  164. * msg_encode_start: Start encoding a log message
  165. *
  166. * @ectxt: Temporary storage to hold the encoded message
  167. * @type: Root event type defined by the module which is logging
  168. */
  169. void msg_encode_start(struct encode_context *ectxt, uint32_t type);
  170. /*
  171. * msg_encode_end: Complete the message encode process
  172. *
  173. * @ectxt: Temporary storage which holds the encoded message
  174. */
  175. void msg_encode_end(struct encode_context *ectxt);
  176. /*
  177. * tsv_timestamp_write: Writes the current timestamp count
  178. *
  179. * @ectxt: Context initialized by calling msg_encode_start()
  180. *
  181. * Returns 0 on success, -ve error code on failure
  182. */
  183. int tsv_timestamp_write(struct encode_context *ectxt);
  184. /*
  185. * tsv_pointer_write: Writes a data pointer
  186. *
  187. * @ectxt: Context initialized by calling msg_encode_start()
  188. * @pointer: Pointer value to write
  189. *
  190. * Returns 0 on success, -ve error code on failure
  191. */
  192. int tsv_pointer_write(struct encode_context *ectxt, void *pointer);
  193. /*
  194. * tsv_int32_write: Writes a 32-bit integer value
  195. *
  196. * @ectxt: Context initialized by calling msg_encode_start()
  197. * @n: Integer to write
  198. *
  199. * Returns 0 on success, -ve error code on failure
  200. */
  201. int tsv_int32_write(struct encode_context *ectxt, int32_t n);
  202. /*
  203. * tsv_byte_array_write: Writes a byte array
  204. *
  205. * @ectxt: Context initialized by calling msg_encode_start()
  206. * @data: Location of data
  207. * @data_size: Size of data to be written
  208. *
  209. * Returns 0 on success, -ve error code on failure
  210. */
  211. int tsv_byte_array_write(struct encode_context *ectxt,
  212. void *data, int data_size);
  213. /*
  214. * ipc_log_write: Write the encoded message into the log space
  215. *
  216. * @ctxt: IPC log context where the message has to be logged into
  217. * @ectxt: Temporary storage containing the encoded message
  218. */
  219. void ipc_log_write(unsigned long ctxt, struct encode_context *ectxt);
  220. /*
  221. * ipc_log_string: Helper function to log a string
  222. *
  223. * @dlctxt: IPC Log Context created using ipc_log_context_create()
  224. * @fmt: Data specified using format specifiers
  225. */
  226. int ipc_log_string(unsigned long dlctxt, const char *fmt, ...);
  227. /*
  228. * tsv_timestamp_read: Reads a timestamp
  229. *
  230. * @ectxt: Context retrieved by reading from log space
  231. * @dctxt: Temporary storage to hold the decoded message
  232. * @format: Output format while dumping through DEBUGFS
  233. */
  234. void tsv_timestamp_read(struct encode_context *ectxt,
  235. struct decode_context *dctxt, const char *format);
  236. /*
  237. * tsv_pointer_read: Reads a data pointer
  238. *
  239. * @ectxt: Context retrieved by reading from log space
  240. * @dctxt: Temporary storage to hold the decoded message
  241. * @format: Output format while dumping through DEBUGFS
  242. */
  243. void tsv_pointer_read(struct encode_context *ectxt,
  244. struct decode_context *dctxt, const char *format);
  245. /*
  246. * tsv_int32_read: Reads a 32-bit integer value
  247. *
  248. * @ectxt: Context retrieved by reading from log space
  249. * @dctxt: Temporary storage to hold the decoded message
  250. * @format: Output format while dumping through DEBUGFS
  251. */
  252. void tsv_int32_read(struct encode_context *ectxt,
  253. struct decode_context *dctxt, const char *format);
  254. /*
  255. * tsv_byte_array_read: Reads a byte array/string
  256. *
  257. * @ectxt: Context retrieved by reading from log space
  258. * @dctxt: Temporary storage to hold the decoded message
  259. * @format: Output format while dumping through DEBUGFS
  260. */
  261. void tsv_byte_array_read(struct encode_context *ectxt,
  262. struct decode_context *dctxt, const char *format);
  263. /*
  264. * add_deserialization_func: Register a deserialization function to
  265. * to unpack the subevents of a main event
  266. *
  267. * @ctxt: IPC log context to which the deserialization function has
  268. * to be registered
  269. * @type: Main/Root event, defined by the module which is logging, to
  270. * which this deserialization function has to be registered.
  271. * @dfune: Deserialization function to be registered
  272. *
  273. * return 0 on success, -ve value on FAILURE
  274. */
  275. int add_deserialization_func(unsigned long ctxt, int type,
  276. void (*dfunc)(struct encode_context *,
  277. struct decode_context *));
  278. Driver parameters
  279. =================
  280. Not-Applicable
  281. Config options
  282. ==============
  283. Not-Applicable
  284. Dependencies
  285. ============
  286. This module will partially depend on CONFIG_DEBUGFS, in order to dump the
  287. logs through debugfs. If CONFIG_DEBUGFS is disabled, the above mentioned
  288. helper functions will perform no operation and return appropriate error
  289. code if the return value is non void. Under such circumstances the logs can
  290. only be extracted through the memory dump.
  291. User space utilities
  292. ====================
  293. DEBUGFS
  294. Other
  295. =====
  296. Not-Applicable
  297. Known issues
  298. ============
  299. None
  300. To do
  301. =====
  302. None