ipc_logging.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2012-2015,2017-2021 The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #ifndef _IPC_LOGGING_H
  7. #define _IPC_LOGGING_H
  8. #include <linux/errno.h>
  9. #include <linux/types.h>
  10. #define MAX_MSG_SIZE 255
  11. enum {
  12. TSV_TYPE_MSG_START = 1,
  13. TSV_TYPE_SKB = TSV_TYPE_MSG_START,
  14. TSV_TYPE_STRING,
  15. TSV_TYPE_MSG_END = TSV_TYPE_STRING,
  16. };
  17. struct tsv_header {
  18. unsigned char type;
  19. unsigned char size; /* size of data field */
  20. };
  21. struct encode_context {
  22. struct tsv_header hdr;
  23. char buff[MAX_MSG_SIZE];
  24. int offset;
  25. };
  26. struct decode_context {
  27. int output_format; /* 0 = debugfs */
  28. char *buff; /* output buffer */
  29. int size; /* size of output buffer */
  30. };
  31. #if IS_ENABLED(CONFIG_IPC_LOGGING)
  32. /*
  33. * ipc_log_context_create: Create a debug log context
  34. * Should not be called from atomic context
  35. *
  36. * @max_num_pages: Number of pages of logging space required (max. 10)
  37. * @mod_name : Name of the directory entry under DEBUGFS
  38. * @feature_version : First 16 bit for version number of user-defined message
  39. * formats and next 16 bit for enabling minidump
  40. *
  41. * returns context id on success, NULL on failure
  42. */
  43. void *ipc_log_context_create(int max_num_pages, const char *modname,
  44. uint32_t feature_version);
  45. /*
  46. * msg_encode_start: Start encoding a log message
  47. *
  48. * @ectxt: Temporary storage to hold the encoded message
  49. * @type: Root event type defined by the module which is logging
  50. */
  51. void msg_encode_start(struct encode_context *ectxt, uint32_t type);
  52. /*
  53. * tsv_timestamp_write: Writes the current timestamp count
  54. *
  55. * @ectxt: Context initialized by calling msg_encode_start()
  56. */
  57. int tsv_timestamp_write(struct encode_context *ectxt);
  58. /*
  59. * tsv_qtimer_write: Writes the current QTimer timestamp count
  60. *
  61. * @ectxt: Context initialized by calling msg_encode_start()
  62. */
  63. int tsv_qtimer_write(struct encode_context *ectxt);
  64. /*
  65. * tsv_pointer_write: Writes a data pointer
  66. *
  67. * @ectxt: Context initialized by calling msg_encode_start()
  68. * @pointer: Pointer value to write
  69. */
  70. int tsv_pointer_write(struct encode_context *ectxt, void *pointer);
  71. /*
  72. * tsv_int32_write: Writes a 32-bit integer value
  73. *
  74. * @ectxt: Context initialized by calling msg_encode_start()
  75. * @n: Integer to write
  76. */
  77. int tsv_int32_write(struct encode_context *ectxt, int32_t n);
  78. /*
  79. * tsv_byte_array_write: Writes a byte array
  80. *
  81. * @ectxt: Context initialized by calling msg_encode_start()
  82. * @data: Pointer to byte array
  83. * @data_size: Size of byte array
  84. */
  85. int tsv_byte_array_write(struct encode_context *ectxt,
  86. void *data, int data_size);
  87. /*
  88. * msg_encode_end: Complete the message encode process
  89. *
  90. * @ectxt: Temporary storage which holds the encoded message
  91. */
  92. void msg_encode_end(struct encode_context *ectxt);
  93. /*
  94. * ipc_log_write: Commits message to logging ring buffer
  95. *
  96. * @ctxt: Logging context
  97. * @ectxt: Temporary storage which holds the encoded message
  98. */
  99. void ipc_log_write(void *ctxt, struct encode_context *ectxt);
  100. /*
  101. * ipc_log_string: Helper function to log a string
  102. *
  103. * @ilctxt: Debug Log Context created using ipc_log_context_create()
  104. * @fmt: Data specified using format specifiers
  105. */
  106. int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3);
  107. /**
  108. * ipc_log_extract - Reads and deserializes log
  109. *
  110. * @ilctxt: logging context
  111. * @buff: buffer to receive the data
  112. * @size: size of the buffer
  113. * @returns: 0 if no data read; >0 number of bytes read; < 0 error
  114. *
  115. * If no data is available to be read, then the ilctxt::read_avail
  116. * completion is reinitialized. This allows clients to block
  117. * until new log data is save.
  118. */
  119. int ipc_log_extract(void *ilctxt, char *buff, int size);
  120. /*
  121. * Print a string to decode context.
  122. * @dctxt Decode context
  123. * @args printf args
  124. */
  125. #define IPC_SPRINTF_DECODE(dctxt, args...) \
  126. do { \
  127. int i; \
  128. i = scnprintf(dctxt->buff, dctxt->size, args); \
  129. dctxt->buff += i; \
  130. dctxt->size -= i; \
  131. } while (0)
  132. /*
  133. * tsv_timestamp_read: Reads a timestamp
  134. *
  135. * @ectxt: Context retrieved by reading from log space
  136. * @dctxt: Temporary storage to hold the decoded message
  137. * @format: Output format while dumping through DEBUGFS
  138. */
  139. void tsv_timestamp_read(struct encode_context *ectxt,
  140. struct decode_context *dctxt, const char *format);
  141. /*
  142. * tsv_qtimer_read: Reads a QTimer timestamp
  143. *
  144. * @ectxt: Context retrieved by reading from log space
  145. * @dctxt: Temporary storage to hold the decoded message
  146. * @format: Output format while dumping through DEBUGFS
  147. */
  148. void tsv_qtimer_read(struct encode_context *ectxt,
  149. struct decode_context *dctxt, const char *format);
  150. /*
  151. * tsv_pointer_read: Reads a data pointer
  152. *
  153. * @ectxt: Context retrieved by reading from log space
  154. * @dctxt: Temporary storage to hold the decoded message
  155. * @format: Output format while dumping through DEBUGFS
  156. */
  157. void tsv_pointer_read(struct encode_context *ectxt,
  158. struct decode_context *dctxt, const char *format);
  159. /*
  160. * tsv_int32_read: Reads a 32-bit integer value
  161. *
  162. * @ectxt: Context retrieved by reading from log space
  163. * @dctxt: Temporary storage to hold the decoded message
  164. * @format: Output format while dumping through DEBUGFS
  165. */
  166. int32_t tsv_int32_read(struct encode_context *ectxt,
  167. struct decode_context *dctxt, const char *format);
  168. /*
  169. * tsv_byte_array_read: Reads a byte array
  170. *
  171. * @ectxt: Context retrieved by reading from log space
  172. * @dctxt: Temporary storage to hold the decoded message
  173. * @format: Output format while dumping through DEBUGFS
  174. */
  175. void tsv_byte_array_read(struct encode_context *ectxt,
  176. struct decode_context *dctxt, const char *format);
  177. /*
  178. * add_deserialization_func: Register a deserialization function to
  179. * unpack the subevents of a main event
  180. *
  181. * @ctxt: Debug log context to which the deserialization function has
  182. * to be registered
  183. * @type: Main/Root event, defined by the module which is logging, to
  184. * which this deserialization function has to be registered.
  185. * @dfune: Deserialization function to be registered
  186. *
  187. * return 0 on success, -ve value on FAILURE
  188. */
  189. int add_deserialization_func(void *ctxt, int type,
  190. void (*dfunc)(struct encode_context *,
  191. struct decode_context *));
  192. /*
  193. * ipc_log_context_destroy: Destroy debug log context
  194. *
  195. * @ctxt: debug log context created by calling ipc_log_context_create API.
  196. */
  197. int ipc_log_context_destroy(void *ctxt);
  198. /*
  199. * netlog
  200. */
  201. void net_log(const char *fmt, ...);
  202. #else
  203. static inline void net_log(const char *fmt, ...) { }
  204. static inline void *ipc_log_context_create(int max_num_pages,
  205. const char *modname, uint32_t feature_version)
  206. { return NULL; }
  207. static inline void msg_encode_start(struct encode_context *ectxt,
  208. uint32_t type) { }
  209. static inline int tsv_timestamp_write(struct encode_context *ectxt)
  210. { return -EINVAL; }
  211. static inline int tsv_qtimer_write(struct encode_context *ectxt)
  212. { return -EINVAL; }
  213. static inline int tsv_pointer_write(struct encode_context *ectxt, void *pointer)
  214. { return -EINVAL; }
  215. static inline int tsv_int32_write(struct encode_context *ectxt, int32_t n)
  216. { return -EINVAL; }
  217. static inline int tsv_byte_array_write(struct encode_context *ectxt,
  218. void *data, int data_size)
  219. { return -EINVAL; }
  220. static inline void msg_encode_end(struct encode_context *ectxt) { }
  221. static inline void ipc_log_write(void *ctxt, struct encode_context *ectxt) { }
  222. static inline int ipc_log_string(void *ilctxt, const char *fmt, ...)
  223. { return -EINVAL; }
  224. static inline int ipc_log_extract(void *ilctxt, char *buff, int size)
  225. { return -EINVAL; }
  226. #define IPC_SPRINTF_DECODE(dctxt, args...) do { } while (0)
  227. static inline void tsv_timestamp_read(struct encode_context *ectxt,
  228. struct decode_context *dctxt, const char *format) { }
  229. static inline void tsv_qtimer_read(struct encode_context *ectxt,
  230. struct decode_context *dctxt, const char *format) { }
  231. static inline void tsv_pointer_read(struct encode_context *ectxt,
  232. struct decode_context *dctxt, const char *format) { }
  233. static inline int32_t tsv_int32_read(struct encode_context *ectxt,
  234. struct decode_context *dctxt, const char *format)
  235. { return 0; }
  236. static inline void tsv_byte_array_read(struct encode_context *ectxt,
  237. struct decode_context *dctxt, const char *format) { }
  238. static inline int add_deserialization_func(void *ctxt, int type,
  239. void (*dfunc)(struct encode_context *,
  240. struct decode_context *))
  241. { return 0; }
  242. static inline int ipc_log_context_destroy(void *ctxt)
  243. { return 0; }
  244. #endif
  245. #endif