1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 * SPDX-License-Identifier: MIT 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 #ifndef LOGDECODE_H_ 25 #define LOGDECODE_H_ 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 #ifdef NVRM 32 33 # define LIBOS_LOG_DECODE_ENABLE 1 34 35 # define LIBOS_LOG_TO_NVLOG 1 36 37 # define LIBOS_LOG_MAX_LOGS 5 // Max logs per GPU 38 39 #elif defined(LIBOS_LOG_OFFLINE_DECODER) 40 # include "nvlog_decoder.h" 41 42 # define LIBOS_LOG_DECODE_ENABLE 1 43 # define LIBOS_LOG_TO_NVLOG 0 44 45 # define LIBOS_LOG_MAX_LOGS 160 // Max logs for all GPUs for offline decoder 46 47 #else 48 # error "Need to define either NVRM or LIBOS_LOG_OFFLINE_DECODER." 49 #endif // NVRM 50 51 #define LIBOS_LOG_ENABLE (LIBOS_LOG_TO_NVLOG || LIBOS_LOG_DECODE_ENABLE) 52 53 #if LIBOS_LOG_DECODE_ENABLE 54 # include "../include/libos_log.h" 55 # include "libdwarf.h" 56 #endif 57 58 // Forward declarations. 59 struct LIBOS_LOG_DECODE_LOG; 60 typedef struct LIBOS_LOG_DECODE_LOG LIBOS_LOG_DECODE_LOG; 61 62 #define LIBOS_LOG_LINE_BUFFER_SIZE 128 63 #define LIBOS_LOG_MAX_ARGS 20 64 65 #if LIBOS_LOG_DECODE_ENABLE 66 67 # include "nvctassert.h" 68 69 typedef struct 70 { 71 NV_DECLARE_ALIGNED(LIBOS_LOG_DECODE_LOG *log, 8); 72 NV_DECLARE_ALIGNED(LIBOS_LOG_DECODE_LOG *logSymbolResolver, 8); 73 NV_DECLARE_ALIGNED(libosLogMetadata *meta, 8); 74 NV_DECLARE_ALIGNED(NvU64 timeStamp, 8); 75 NvU64 args[LIBOS_LOG_MAX_ARGS]; 76 } LIBOS_LOG_DECODE_RECORD; 77 78 // Size of LIBOS_LOG_DECODE_RECORD without args, in number of NvU64 entries. 79 # define LIBOS_LOG_DECODE_RECORD_BASE 4 80 81 // Ensure that the size matches up (no padding in the struct) 82 ct_assert((LIBOS_LOG_DECODE_RECORD_BASE * sizeof(NvU64)) == (sizeof(LIBOS_LOG_DECODE_RECORD) - sizeof(((LIBOS_LOG_DECODE_RECORD*)NULL)->args))); 83 84 #endif // LIBOS_LOG_DECODE_ENABLE 85 86 #define TASK_NAME_MAX_LENGTH (8) 87 #define SOURCE_NAME_MAX_LENGTH (4) 88 89 #define ELF_SECTION_NAME_MAX (32) // In bytes 90 91 // NvLog buffer 92 typedef struct 93 { 94 NvU32 gpuArch; 95 NvU32 gpuImpl; 96 NvU32 rsvd1; 97 NvU32 rsvd2; 98 char taskPrefix[TASK_NAME_MAX_LENGTH]; // Prefix string printed before each line. 99 NvU8 data[0]; 100 } LIBOS_LOG_NVLOG_BUFFER; 101 102 #define LIBOS_LOG_NVLOG_BUFFER_SIZE(dataSize) (NV_OFFSETOF(LIBOS_LOG_NVLOG_BUFFER, data) + (dataSize)) 103 104 struct LIBOS_LOG_DECODE_LOG 105 { 106 volatile NvU64 *physicLogBuffer; 107 NvU64 logBufferSize; // Includes put pointer located in first 8 bytes. 108 NvU64 previousPut; // Keeps track of records already printed. 109 NvU64 putCopy; // End pointer for this batch. 110 NvU64 putIter; // Iterator for this batch. 111 NvU32 gpuInstance; // GPU that this log is associated with. 112 char taskPrefix[TASK_NAME_MAX_LENGTH]; // Prefix string printed before each line. 113 char elfSectionName[ELF_SECTION_NAME_MAX]; // Task section name in container logging ELF serving as ID. 114 115 #if LIBOS_LOG_TO_NVLOG 116 NvU32 hNvLogNoWrap; // No wrap buffer captures first records. 117 NvU32 hNvLogWrap; // Wrap buffer captures last records. 118 NvBool bNvLogNoWrap; // NV_TRUE if no wrap buffer not full. 119 120 NvBool bDidPush; // NV_TRUE if this buffer was ever pushed to 121 NvU64 preservedNoWrapPos; // Position in preserved nvlog buffer 122 #endif 123 124 #if LIBOS_LOG_DECODE_ENABLE 125 LibosElf64Header *elf; 126 LibosElfImage elfImage; 127 LibosDebugResolver resolver; 128 LIBOS_LOG_DECODE_RECORD record; 129 #endif 130 }; 131 132 typedef struct 133 { 134 char sourceName[SOURCE_NAME_MAX_LENGTH]; // GSP, PMU etc 135 136 NvU64 numLogBuffers; 137 LIBOS_LOG_DECODE_LOG log[LIBOS_LOG_MAX_LOGS]; 138 139 #if LIBOS_LOG_DECODE_ENABLE 140 NvBool bIsDecodable; // True if a logging ELF is provided, False on NULL 141 NvU64 *scratchBuffer; // Sorted by timestamp. 142 NvU64 scratchBufferSize; // Sum of logBufferSize. 143 char *curLineBufPtr; // Current position in lineBuffer. 144 // Decodes into lineBuffer, then prints as a string. 145 char lineBuffer[LIBOS_LOG_LINE_BUFFER_SIZE]; 146 NvBool bSynchronousBuffer; 147 NvBool bPtrSymbolResolve; 148 NvU8 lineLogLevel; 149 150 // Fall back to SHDR when a PDHR with %s argument is not found. 151 NvBool bDecodeStrShdr; 152 #endif // LIBOS_LOG_DECODE_ENABLE 153 154 #if defined(LIBOS_LOG_OFFLINE_DECODER) 155 LogPrinter *pLogPrinter; 156 #endif 157 158 } LIBOS_LOG_DECODE; 159 160 #if defined(LIBOS_LOG_OFFLINE_DECODER) 161 void libosLogCreate(LIBOS_LOG_DECODE *logDecode, LogPrinter *pLogPrinter); 162 void libosLogCreateEx(LIBOS_LOG_DECODE *logDecode, const char *pSourceName, LogPrinter *pLogPrinter); 163 #else 164 void libosLogCreate(LIBOS_LOG_DECODE *logDecode); 165 void libosLogCreateEx(LIBOS_LOG_DECODE *logDecode, const char *pSourceName); 166 #endif 167 168 void libosLogAddLogEx(LIBOS_LOG_DECODE *logDecode, void *buffer, NvU64 bufferSize, NvU32 gpuInstance, NvU32 gpuArch, NvU32 gpuImpl, const char *name, const char *elfSectionName); 169 void libosLogAddLog(LIBOS_LOG_DECODE *logDecode, void *buffer, NvU64 bufferSize, NvU32 gpuInstance, const char *name, const char *elfSectionName); 170 171 #if LIBOS_LOG_DECODE_ENABLE 172 void libosLogInit(LIBOS_LOG_DECODE *logDecode, LibosElf64Header *elf, NvU64 elfSize); 173 void libosLogInitEx( 174 LIBOS_LOG_DECODE *logDecode, LibosElf64Header *elf, NvBool bSynchronousBuffer, 175 NvBool bPtrSymbolResolve, NvBool bDecodeStrFmt, NvU64 elfSize); 176 #else 177 void libosLogInit(LIBOS_LOG_DECODE *logDecode, void *elf, NvU64 elfSize); 178 void libosLogInitEx( 179 LIBOS_LOG_DECODE *logDecode, void *elf, NvBool bSynchronousBuffer, NvBool bPtrSymbolResolve, 180 NvBool bDecodeStrFmt, NvU64 elfSize); 181 #endif // LIBOS_LOG_DECODE_ENABLE 182 183 NvBool libosLogSymbolicateAddress(LIBOS_LOG_DECODE *logDecode, char *decodedLine, NvLength decodedLineSize, NvUPtr addr); 184 185 void libosLogDestroy(LIBOS_LOG_DECODE *logDecode); 186 187 void libosExtractLogs(LIBOS_LOG_DECODE *logDecode, NvBool bSyncNvLog); 188 189 void libosPreserveLogs(LIBOS_LOG_DECODE *pLogDecode); 190 191 #ifdef __cplusplus 192 } 193 #endif 194 195 #endif // LOGDECODE_H_ 196