diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2020-04-08 11:41:12 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2020-04-08 11:41:12 +0000 |
commit | 6b564a7014af2d4d9f000ed39a4fed77fd5245e0 (patch) | |
tree | 3805c7d1cab7ee8faf746ed3a1f0d1a448d4a8da | |
parent | 4fc8237742a380d4833394892fb148e1a34acb28 (diff) | |
parent | 62366fbbe8edca853fee6c14327d822239ba914f (diff) | |
download | illumos-joyent-6b564a7014af2d4d9f000ed39a4fed77fd5245e0.tar.gz |
[illumos-gate merge]release-20200409
commit 62366fbbe8edca853fee6c14327d822239ba914f
12466 Enable IPv6 TSO Support for vioif
commit d240edaf609c558d5a1f981b09a577823b54fae2
12465 vioif needs length for tso checksum
commit 425251fd07ab465313fb50dea0f1ac795be10e05
9059 Simplify SMAP relocations with krtld
commit 28e0ac9c914344194ef919b0271895d33f83d396
12433 efcode: NULL pointer errors
commit 31aa620247ae407b2bee2dccd71693d1938f54d6
12452 Want support for AMD Zen 2 CPC Events
Conflicts:
usr/src/uts/i86pc/os/machdep.c
usr/src/uts/common/io/dld/dld_proto.c
usr/src/uts/common/inet/ip/ip_if.c
32 files changed, 1385 insertions, 320 deletions
@@ -14623,7 +14623,8 @@ s usr/share/man/man3contract/ct_tmpl_set_cookie.3contract=ct_tmpl_activate.3cont s usr/share/man/man3contract/ct_tmpl_set_critical.3contract=ct_tmpl_activate.3contract s usr/share/man/man3contract/ct_tmpl_set_informative.3contract=ct_tmpl_activate.3contract d usr/share/man/man3cpc 0755 root bin -f usr/share/man/man3cpc/amd_f17h_events.3cpc 0444 root bin +f usr/share/man/man3cpc/amd_f17h_zen1_events.3cpc 0444 root bin +f usr/share/man/man3cpc/amd_f17h_zen2_events.3cpc 0444 root bin f usr/share/man/man3cpc/bdw_de_events.3cpc 0444 root bin f usr/share/man/man3cpc/bdw_events.3cpc 0444 root bin f usr/share/man/man3cpc/bdx_events.3cpc 0444 root bin diff --git a/usr/src/data/amdpmc/README b/usr/src/data/amdpmc/README index e7c4783950..53562ac107 100644 --- a/usr/src/data/amdpmc/README +++ b/usr/src/data/amdpmc/README @@ -7,5 +7,9 @@ that are used to implement the kernel performance monitoring interfaces. For more information, see the cpcgen tool. This data is derived from the following documents: -FAMILY DOCUMENT -17h OSRR for AMD Family 17h processors, Models 00h-2Fh (56255 Rev 3.03 - July, 2018) +FAMILY CORE DOCUMENT +17h Zen 1 OSRR for AMD Family 17h processors, Models 00h-2Fh (56255 Rev 3.03 - July, 2018) +17h Zen 2 Preliminary Processor Programming Reference (PPR) for AMD Family 17h + Model 31h, Revision B0 Processors (55803 Rev 0.54 - Sep 12, 2019) + Processor Programming Reference (PPR) for AMD Family 17h + Model 71h, Revision B0 Processors (56176 Rev 3.06 - Jul 17, 2019) diff --git a/usr/src/data/amdpmc/f17h_core.json b/usr/src/data/amdpmc/f17h_zen1_core.json index f200ee93a3..f200ee93a3 100644 --- a/usr/src/data/amdpmc/f17h_core.json +++ b/usr/src/data/amdpmc/f17h_zen1_core.json diff --git a/usr/src/data/amdpmc/f17h_zen2_core.json b/usr/src/data/amdpmc/f17h_zen2_core.json new file mode 100644 index 0000000000..05a20d4566 --- /dev/null +++ b/usr/src/data/amdpmc/f17h_zen2_core.json @@ -0,0 +1,940 @@ +[ +{ + "mnemonic": "Core::X86::Pmc::Core::FpRetSseAvxOps", + "name": "FpRetSseAvxOps", + "code": "0x003", + "summary": "Retired SSE/AVX FLOPs", + "description": "This is a retire-based event. The number of retired SSE/AVX FLOPs. The number of events logged per cycle can vary from 0 to 64. This event is a MergeEvent since it can count above 15.", + "units": [ { + "name": "MacFLOPs", + "bit": 3, + "rw": "Read-write", + "description": "MacFLOPs count as 2 FLOPs. Does not provide a useful count without use of the MergeEvent feature." + }, { + "name": "DivFLOPs", + "bit": 2, + "rw": "Read-write", + "description": "Divide/square root FLOPs. Does not provide a useful count without use of the MergeEvent feature." + }, { + "name": "MultFLOPs", + "bit": 1, + "rw": "Read-write", + "description": "Multiply FLOPs. Does not provide a useful count without use of the MergeEvent feature." + }, { + "name": "AddSubFLOPs", + "bit": 0, + "rw": "Read-write", + "description": "Add/subtract FLOPs. Does not provide a useful count without use of the MergeEvent feature." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::FpRetiredSerOps", + "name": "FpRetiredSerOps", + "code": "0x005", + "summary": "Retired Serializing Ops", + "description": "The number of serializing Ops retired.", + "units": [ { + "name": "SseBotRet", + "bit": 3, + "rw": "Read-write", + "description": "SSE bottom-executing uOps retired." + }, { + "name": "SseCtrlRet", + "bit": 2, + "rw": "Read-write", + "description": "SSE control word mispredict traps due to mispredictions in RC, FTZ or DAZ, or changes in mask bits." + }, { + "name": "X87BotRet", + "bit": 1, + "rw": "Read-write", + "description": "x87 bottom-executing uOps retired." + }, { + "name": "X87CtrlRet", + "bit": 0, + "rw": "Read-write", + "description": "x87 control word mispredict traps due to mispredictions in RC or PC, or changes in mask bits." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::FpDispFaults", + "name": "FpDispFaults", + "code": "0x00E", + "summary": "FP Dispatch Faults", + "description": "Floating Point Dispatch Faults.", + "units": [ { + "name": "YmmSpillFault", + "bit": 3, + "rw": "Read-write", + "description": "YMM Spill fault." + }, { + "name": "YmmFillFault", + "bit": 2, + "rw": "Read-write", + "description": "YMM Fill fault." + }, { + "name": "XmmFillFault", + "bit": 1, + "rw": "Read-write", + "description": "XMM Fill fault." + }, { + "name": "x87FillFault", + "bit": 0, + "rw": "Read-write", + "description": "x87 Fill fault." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsBadStatus2", + "name": "LsBadStatus2", + "code": "0x024", + "summary": "Bad Status 2", + "description": "Store To Load Interlock (STLI) are loads that were unable to complete because of a possible match with an older store, and the older store could not do STLF for some reason. There are a number of reasons why this occurs, and this perfmon organizes them into three major groups.", + "units": [ { + "name": "StliOther", + "bit": 1, + "rw": "Read-write", + "description": "Non-forwardable conflict; used to reduce STLI's via software. All reasons. The most common among these is that there is only a partial overlap between the store and the load, for example there's an 8B store to address A and a 16B load starting at address A. STLF can't be performed in this case because only some of the load's data is coming from the store, so the load gets StliOther. Another StliOther case is if the load hits a non-cacheable store that's sitting in the non-cacheable buffers (WCBs)." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsLocks", + "name": "LsLocks", + "code": "0x025", + "summary": "Retired Lock Instructions", + "unit_mode": "or", + "units": [ { + "name": "SpecLockHiSpec", + "bit": 3, + "rw": "Read-write", + "description": "High speculative cacheable lock speculation succeeded." + }, { + "name": "SpecLockLoSpec", + "bit": 2, + "rw": "Read-write", + "description": "Low speculative cacheable lock speculation succeeded." + }, { + "name": "NonSpecLock", + "bit": 1, + "rw": "Read-write" + }, { + "name": "BusLock", + "bit": 0, + "rw": "Read-write", + "description": "Comparable to legacy bus lock." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsRetClClush", + "name": "LsRetClClush", + "code": "0x026", + "summary": "Retired CLFLUSH Instructions", + "description": "The number of retired CLFLUSH instructions. This is a non-speculative event." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsRetCpuid", + "name": "LsRetCpuid", + "code": "0x027", + "summary": "Retired CPUID Instructions", + "description": "The number of CPUID instructions retired." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsDispatch", + "name": "LsDispatch", + "code": "0x029", + "summary": "LS Dispatch", + "description": "Counts the number of operations dispatched to the LS unit.", + "unit_mode": "add", + "units": [ { + "name": "LdStDispatch", + "bit": 2, + "rw": "Read-write", + "description": "Load-op-Store Dispatch. Dispatch of a single op that performs a load from and store to the same memory address." + }, { + "name": "StoreDispatch", + "bit": 1, + "rw": "Read-write" + }, { + "name": "LdDispatch", + "bit": 0, + "rw": "Read-write" + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsSmiRx", + "name": "LsSmiRx", + "code": "0x02B", + "summary": "SMIs Received", + "description": "Counts the number of SMIs received." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsIntTaken", + "name": "LsIntTaken", + "code": "0x02C", + "summary": "Interrupts Taken", + "description": "Counts the number of interrupts taken." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsRdTsc", + "name": "LsRdTsc", + "code": "0x02D", + "summary": "Time Stamp Counter Reads", + "description": "Counts the number of reads of the TSC (RDTSC instructions). The count is speculative." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsSTLF", + "name": "LsSTLF", + "code": "0x035", + "summary": "Store to Load Forward", + "description": "Number of STLF hits." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsStCommitCancel2", + "name": "LsStCommitCancel2", + "code": "0x037", + "summary": "Store Commit Cancels 2", + "units": [ { + "name": "StCommitCancelWcbFull", + "bit": 0, + "rw": "Read-write", + "description": "A non-cacheable store and the non-cacheable commit buffer is full." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsDcAccesses", + "name": "LsDcAccesses", + "code": "0x040", + "summary": "Data Cache Accesses", + "description": "The number of accesses to the data cache for load and store references. This may include certain microcode scratchpad accesses, although these are generally rare. Each increment represents an eight-byte access, although the instruction may only be accessing a portion of that. This event is a speculative event." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsMabAlloc", + "name": "LsMabAlloc", + "code": "0x041", + "summary": "DC Miss By Type", + "units": [ { + "name": "DcPrefetcher", + "bit": 3, + "rw": "Read-write" + }, { + "name": "Stores", + "bit": 1, + "rw": "Read-write" + }, { + "name": "Loads", + "bit": 0, + "rw": "Read-write" + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsRefillsFromSys", + "name": "LsRefillsFromSys", + "code": "0x043", + "summary": "Data Cache Refills from System", + "description": "Demand Data Cache Fills by Data Source.", + "units": [ { + "name": "LS_MABRESP_RMT_DRAM", + "bit": 6, + "rw": "Read-write", + "description": "DRAM or IO from different die." + }, { + "name": "LS_MABRESP_RMT_CACHE", + "bit": 4, + "rw": "Read-write", + "description": "Hit in cache; Remote CCX and the address's Home Node is on a different die." + }, { + "name": "LS_MABRESP_LCL_DRAM", + "bit": 3, + "rw": "Read-write", + "description": "DRAM or IO from this thread's die." + }, { + "name": "LS_MABRESP_LCL_CACHE", + "bit": 1, + "rw": "Read-write", + "description": "Hit in cache; local CCX (not Local L2), or Remote CCXand the address's Home Node is on this thread's die." + }, { + "name": "MABRESP_LCL_L2", + "bit": 0, + "rw": "Read-write", + "description": "Local L2 hit." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsL1DTlbMiss", + "name": "LsL1DTlbMiss", + "code": "0x045", + "summary": "L1 DTLB Miss", + "units": [ { + "name": "TlbReload1GL2Miss", + "bit": 7, + "rw": "Read-write", + "description": "DTLB reload to a 1G page that miss in the L2 TLB." + }, { + "name": "TlbReload2ML2Miss", + "bit": 6, + "rw": "Read-write", + "description": "DTLB reload to a 2M page that miss in the L2 TLB." + }, { + "name": "TlbReloadCoalescedPageMiss", + "bit": 5, + "rw": "Read-write" + }, { + "name": "TlbReload4KL2Miss", + "bit": 4, + "rw": "Read-write", + "description": "DTLB reload to a 4K page that miss the L2 TLB." + }, { + "name": "TlbReload1GL2Hit", + "bit": 3, + "rw": "Read-write", + "description": "DTLB reload to a 1G page that hit in the L2 TLB." + }, { + "name": "TlbReload2ML2Hit", + "bit": 2, + "rw": "Read-write", + "description": "DTLB reload to a 2M page that hit in the L2 TLB." + }, { + "name": "TlbReloadCoalescedPageHit", + "bit": 1, + "rw": "Read-write" + }, { + "name": "TlbReload4KL2Hit", + "bit": 0, + "rw": "Read-write", + "description": "DTLB reload to a 4K page that hit in the L2 TLB." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsMisalAccesses", + "name": "LsMisalAccesses", + "code": "0x047", + "summary": "Misaligned loads" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsPrefInstrDisp", + "name": "LsPrefInstrDisp", + "code": "0x04B", + "summary": "Prefetch Instructions Dispatched", + "description": "Software Prefetch Instructions Dispatched (Speculative).", + "units": [ { + "name": "PrefetchNTA", + "bit": 2, + "rw": "Read-write", + "description": "PrefetchNTA instruction. See AMD64 Architecture Programmer's Manual Volume 3: Instruction-Set Reference, order# 24594 PREFETCHlevel." + }, { + "name": "PrefetchW", + "bit": 1, + "rw": "Read-write", + "description": "PrefetchW instruction. See AMD64 Architecture Programmer's Manual Volume 3: Instruction-Set Reference, order# 24594 PREFETCHlevel." + }, { + "name": "Prefetch", + "bit": 0, + "rw": "Read-write", + "description": "PrefetchT0, T1 and T2 instructions. See AMD64 Architecture Programmer's Manual Volume 3: Instruction-Set Reference, order# 24594 PREFETCHlevel." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsInefSwPref", + "name": "LsInefSwPref", + "code": "0x052", + "summary": "Ineffective Software Prefetches", + "description": "The number of software prefetches that did not fetch data outside of the processor core.", + "units": [ { + "name": "MabMchCnt", + "bit": 1, + "rw": "Read-write", + "description": "Software PREFETCH instruction saw a match on an already-allocated miss request buffer." + }, { + "name": "DataPipeSwPfDcHit", + "bit": 0, + "rw": "Read-write", + "description": "Software PREFETCH instruction saw a DC hit." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsSwPfDcFills", + "name": "LsSwPfDcFills", + "code": "0x059", + "summary": "Software Prefetch Data Cache Fills", + "description": "Software Prefetch Data Cache Fills by Data Source.", + "units": [ { + "name": "LS_MABRESP_RMT_DRAM", + "bit": 6, + "rw": "Read-write", + "description": "DRAM or IO from different die." + }, { + "name": "LS_MABRESP_RMT_CACHE", + "bit": 4, + "rw": "Read-write", + "description": "Hit in cache; Remote CCX and the address's Home Node is on a different die." + }, { + "name": "LS_MABRESP_LCL_DRAM", + "bit": 3, + "rw": "Read-write", + "description": "DRAM or IO from this thread's die." + }, { + "name": "LS_MABRESP_LCL_CACHE", + "bit": 1, + "rw": "Read-write", + "description": "Hit in cache; local CCX (not Local L2), or Remote CCX and the address's Home Node is on this thread's die." + }, { + "name": "MABRESP_LCL_L2", + "bit": 0, + "rw": "Read-write", + "description": "Local L2 hit." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsHwPfDcFills", + "name": "LsHwPfDcFills", + "code": "0x05A", + "summary": "Hardware Prefetch Data Cache Fills", + "description": "Hardware Prefetch Data Cache Fills by Data Source.", + "units": [ { + "name": "LS_MABRESP_RMT_DRAM", + "bit": 6, + "rw": "Read-write", + "description": "DRAM or IO from different die." + }, { + "name": "LS_MABRESP_RMT_CACHE", + "bit": 4, + "rw": "Read-write", + "description": "Hit in cache; Remote CCX and the address's Home Nodeis on a different die." + }, { + "name": "LS_MABRESP_LCL_DRAM", + "bit": 3, + "rw": "Read-write", + "description": "DRAM or IO from this thread's die." + }, { + "name": "LS_MABRESP_LCL_CACHE", + "bit": 1, + "rw": "Read-write", + "description": "Hit in cache; local CCX (not Local L2), or Remote CCXand the address's Home Node is on this thread's die." + }, { + "name": "MABRESP_LCL_L2", + "bit": 0, + "rw": "Read-write", + "description": "Local L2 hit." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsNotHaltedCyc", + "name": "LsNotHaltedCyc", + "code": "0x076", + "summary": "Cycles not in Halt" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::LsTlbFlush", + "name": "LsTlbFlush", + "code": "0x078", + "summary": "All TLB Flushes" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::IcCacheFillL2", + "name": "IcCacheFillL2", + "code": "0x082", + "summary": "Instruction Cache Refills from L2", + "description": "The number of 64 byte instruction cache line was fulfilled from the L2 cache." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::IcCacheFillSys", + "name": "IcCacheFillSys", + "code": "0x083", + "summary": "Instruction Cache Refills from System", + "description": "The number of 64 byte instruction cache line fulfilled from system memory or another cache." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::BpL1TlbMissL2TlbHit", + "name": "BpL1TlbMissL2TlbHit", + "code": "0x084", + "summary": "L1 ITLB Miss, L2 ITLB Hit", + "description": "The number of instruction fetches that miss in the L1 ITLB but hit in the L2 ITLB." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::BpL1TlbMissL2TlbMiss", + "name": "BpL1TlbMissL2TlbMiss", + "code": "0x085", + "summary": "L1 ITLB Miss, L2 ITLB Miss", + "description": "The number of instruction fetches that miss in both the L1 and L2 TLBs.", + "units": [ { + "name": "IF1G", + "bit": 2, + "rw": "Read-write", + "description": "Instruction fetches to a 1 GB page." + }, { + "name": "IF2M", + "bit": 1, + "rw": "Read-write", + "description": "Instruction fetches to a 2 MB page." + }, { + "name": "IF4K", + "bit": 0, + "rw": "Read-write", + "description": "Instruction fetches to a 4 KB page." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::BpL1BTBCorrect", + "name": "BpL1BTBCorrect", + "code": "0x08A", + "summary": "L1 Branch Prediction Overrides Existing Prediction (speculative)" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::BpL2BTBCorrect", + "name": "BpL2BTBCorrect", + "code": "0x08B", + "summary": "L2 Branch Prediction Overrides Existing Prediction (speculative)" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::BpDynIndPred", + "name": "BpDynIndPred", + "code": "0x08E", + "summary": "Dynamic Indirect Predictions", + "description": "Indirect Branch Prediction for potential multi-target branch (speculative)" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::BpDeReDirect", + "name": "BpDeReDirect", + "code": "0x091", + "summary": "Decoder Overrides Existing Branch Prediction (speculative)" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::BpL1TlbFetchHit", + "name": "BpL1TlbFetchHit", + "code": "0x094", + "summary": "ITLB Instruction Fetch Hits", + "description": "The number of instruction fetches that hit in the L1 ITLB.", + "units": [ { + "name": "IF1G", + "bit": 2, + "rw": "Read-write", + "description": "Instruction fetches to a 1 GB page." + }, { + "name": "IF2M", + "bit": 1, + "rw": "Read-write", + "description": "Instruction fetches to a 2 MB page." + }, { + "name": "IF4K", + "bit": 0, + "rw": "Read-write", + "description": "Instruction fetches to a 4 KB page." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::DeDisUopQueueEmptyDi0", + "name": "DeDisUopQueueEmptyDi0", + "code": "0x0A9", + "summary": "Micro-Op Queue Empty", + "description": "Cycles where the Micro-Op Queue is empty." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::DeDisUopsFromDecoder", + "name": "DeDisUopsFromDecoder", + "code": "0x0AA", + "summary": "UOps Dispatched From Decoder", + "description": "Ops dispatched from either the decoders, OpCache or both.", + "units": [ { + "name": "OpCacheDispatched", + "bit": 1, + "rw": "Read-write", + "description": "Count of dispatched Ops from OpCache." + }, { + "name": "DecoderDispatched", + "bit": 0, + "rw": "Read-write", + "description": "Count of dispatched Ops from Decoder." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::DeDisDispatchTokenStalls1", + "name": "DeDisDispatchTokenStalls1", + "code": "0x0AE", + "summary": "Dispatch Resource Stall Cycles 1", + "description": "Cycles where a dispatch group is valid but does not get dispatched due to a Token Stall.", + "units": [ { + "name": "FPMiscRsrcStall", + "bit": 7, + "rw": "Read-write", + "description": "FP Miscellaneous resource unavailable. Applies to the recovery of mispredicts with FP ops." + }, { + "name": "FPSchRsrcStall", + "bit": 6, + "rw": "Read-write", + "description": "FP scheduler resource stall. Applies to ops that use the FP scheduler." + }, { + "name": "FpRegFileRsrcStall", + "bit": 5, + "rw": "Read-write", + "description": "floating point register file resource stall. Applies to all FP ops that have a destination register." + }, { + "name": "TakenBrnchBufferRsrc", + "bit": 4, + "rw": "Read-write", + "description": "taken branch buffer resource stall." + }, { + "name": "IntSchedulerMiscRsrcStall", + "bit": 3, + "rw": "Read-write", + "description": "Integer Scheduler miscellaneous resource stall." + }, { + "name": "StoreQueueRsrcStall", + "bit": 2, + "rw": "Read-write", + "description": "Store Queue resource stall. Applies to all ops with store semantics." + }, { + "name": "LoadQueueRsrcStall", + "bit": 1, + "rw": "Read-write", + "description": "Load Queue resource stall. Applies to all ops with load semantics." + }, { + "name": "IntPhyRegFileRsrcStall", + "bit": 0, + "rw": "Read-write", + "description": "Integer Physical Register File resource stall. Integer Physical Register File, applies to all ops that have an integer destination register." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::DeDisDispatchTokenStalls0", + "name": "DeDisDispatchTokenStalls0", + "code": "0x0AF", + "summary": "Dispatch Resource Stall Cycles 0", + "description": "Cycles where a dispatch group is valid but does not get dispatched due to a token stall.", + "units": [ { + "name": "ScAguDispatchStall", + "bit": 6, + "rw": "Read-write", + "description": "SC AGU dispatch stall." + }, { + "name": "RetireTokenStall", + "bit": 5, + "rw": "Read-write", + "description": "RETIRE Tokens unavailable." + }, { + "name": "AGSQTokenStall", + "bit": 4, + "rw": "Read-write", + "description": "AGSQ Tokens unavailable." + }, { + "name": "ALUTokenStall", + "bit": 3, + "rw": "Read-write", + "description": "ALU tokens total unavailable." + }, { + "name": "ALSQ3_0_TokenStall", + "bit": 2, + "rw": "Read-write" + }, { + "name": "ALSQ2RsrcStall", + "bit": 1, + "rw": "Read-write", + "description": "ALSQ 2 Resources unavailable." + }, { + "name": "ALSQ1RsrcStall", + "bit": 0, + "rw": "Read-write", + "description": "ALSQ 1 Resources unavailable." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetInstr", + "name": "ExRetInstr", + "code": "0x0C0", + "summary": "Retired Instructions" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetCops", + "name": "ExRetCops", + "code": "0x0C1", + "summary": "Retired Uops", + "description": "The number of micro-ops retired. This count includes all processor activity (instructions, exceptions, interrupts, microcode assists, etc.). The number of events logged per cycle can vary from 0 to 8." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetBrn", + "name": "ExRetBrn", + "code": "0x0C2", + "summary": "Retired Branch Instructions", + "description": "The number of branch instructions retired. This includes all types of architectural control flow changes, including exceptions and interrupts." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetBrnMisp", + "name": "ExRetBrnMisp", + "code": "0x0C3", + "summary": "Retired Branch Instructions Mispredicted", + "description": "The number of branch instructions retired, of any type, that were not correctly predicted. This includes those for which prediction is not attempted (far control transfers, exceptions and interrupts)." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetBrnTkn", + "name": "ExRetBrnTkn", + "code": "0x0C4", + "summary": "Retired Taken Branch Instructions", + "description": "The number of taken branches that were retired. This includes all types of architectural control flow changes, including exceptions and interrupts." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetBrnTknMisp", + "name": "ExRetBrnTknMisp", + "code": "0x0C5", + "summary": "Retired Taken Branch Instructions Mispredicted", + "description": "The number of retired taken branch instructions that were mispredicted." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetBrnFar", + "name": "ExRetBrnFar", + "code": "0x0C6", + "summary": "Retired Far Control Transfers", + "description": "The number of far control transfers retired including far call/jump/return, IRET, SYSCALL and SYSRET, plus exceptions and interrupts. Far control transfers are not subject to branch prediction." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetNearRet", + "name": "ExRetNearRet", + "code": "0x0C8", + "summary": "Retired Near Returns", + "description": "The number of near return instructions (RET or RET Iw) retired." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetNearRetMispred", + "name": "ExRetNearRetMispred", + "code": "0x0C9", + "summary": "Retired Near Returns Mispredicted", + "description": "The number of near returns retired that were not correctly predicted by the return address predictor. Each such mispredictincurs the same penalty as a mispredicted conditional branch instruction." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetBrnIndMisp", + "name": "ExRetBrnIndMisp", + "code": "0x0CA", + "summary": "Retired Indirect Branch Instructions Mispredicted", + "description": "The number of indirect branches retired that were not correctly predicted. Each such mispredict incurs the same penalty as a mispredicted conditional branch instruction. Note that only EX mispredicts are counted." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetMmxFpInstr", + "name": "ExRetMmxFpInstr", + "code": "0x0CB", + "summary": "Retired MMX/FP Instructions", + "description": "The number of MMX, SSE or x87 instructions retired. The UnitMask allows the selection of the individual classes of instructions as given in the table. Each increment represents one complete instruction. Since this event includes non-numeric instructions it is not suitable for measuring MFLOPs.", + "units": [ { + "name": "SseInstr", + "bit": 2, + "rw": "Read-write", + "description": "SSE instructions (SSE, SSE2, SSE3, SSSE3, SSE4A, SSE41, SSE42, AVX)." + }, { + "name": "MmxInstr", + "bit": 1, + "rw": "Read-write", + "description": "MMX instructions." + }, { + "name": "X87Instr", + "bit": 0, + "rw": "Read-write", + "description": "x87 instructions." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetCond", + "name": "ExRetCond", + "code": "0x0D1", + "summary": "Retired Conditional Branch Instructions" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExDivBusy", + "name": "ExDivBusy", + "code": "0x0D3", + "summary": "Div Cycles Busy count" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExDivCount", + "name": "ExDivCount", + "code": "0x0D4", + "summary": "Div Op Count" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExTaggedIbsOps", + "name": "ExTaggedIbsOps", + "code": "0x1CF", + "summary": "Tagged IBS Ops", + "units": [ { + "name": "IbsCountRollover", + "bit": 2, + "rw": "Read-write", + "description": "Number of times an op could not be tagged by IBS because of a previous tagged op that has not retired." + }, { + "name": "IbsTaggedOpsRet", + "bit": 1, + "rw": "Read-write", + "description": "Number of Ops tagged by IBS that retired." + }, { + "name": "IbsTaggedOps", + "bit": 0, + "rw": "Read-write", + "description": "Number of Ops tagged by IBS." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::ExRetFusBrnchInst", + "name": "ExRetFusBrnchInst", + "code": "0x1D0", + "summary": "Retired Fused Branch Instructions", + "description": "The number of fuse-branch instructions retired per cycle. The number of events logged per cycle can vary from 0-8." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::L2RequestG1", + "name": "L2RequestG1", + "code": "0x060", + "summary": "Requests to L2 Group1", + "description": "All L2 Cache Requests (Breakdown 1 - Common).", + "units": [ { + "name": "RdBlkL", + "bit": 7, + "rw": "Read-write", + "description": "Data Cache Reads (including hardware and software prefetch)." + }, { + "name": "RdBlkX", + "bit": 6, + "rw": "Read-write", + "description": "Data Cache Stores." + }, { + "name": "LsRdBlkC_S", + "bit": 5, + "rw": "Read-write", + "description": "Data Cache Shared Reads." + }, { + "name": "CacheableIcRead", + "bit": 4, + "rw": "Read-write", + "description": "Instruction Cache Reads." + }, { + "name": "ChangeToX", + "bit": 3, + "rw": "Read-write", + "description": "Data Cache State Change Requests. Request change to writable, check L2 for current state." + }, { + "name": "PrefetchL2Cmd", + "bit": 2, + "rw": "Read-write" + }, { + "name": "L2HwPf", + "bit": 1, + "rw": "Read-write", + "description": "L2 Prefetcher. All prefetches accepted by L2 pipeline, hit or miss. Types of PF and L2 hit/miss broken out in a separate perfmon event." + }, { + "name": "Group2", + "bit": 0, + "rw": "Read-write", + "description": "Miscellaneous events covered in more detail by Core::X86::Pmc::Core::L2RequestG2 (PMCx061)." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::L2RequestG2", + "name": "L2RequestG2", + "code": "0x061", + "summary": "Requests to L2 Group2", + "description": "All L2 Cache Requests (Breakdown 2 - Rare). ", + "units": [ { + "name": "Group1", + "bit": 7, + "rw": "Read-write", + "description": "Miscellaneous events covered in more detail by Core::X86::Pmc::Core::L2RequestG1 (PMCx060)." + }, { + "name": "LsRdSized", + "bit": 6, + "rw": "Read-write", + "description": "Data cache read sized." + }, { + "name": "LsRdSizedNC", + "bit": 5, + "rw": "Read-write", + "description": "Data cache read sized non-cacheable." + }, { + "name": "IcRdSized", + "bit": 4, + "rw": "Read-write", + "description": "Instruction cache read sized." + }, { + "name": "IcRdSizedNC", + "bit": 3, + "rw": "Read-write", + "description": "Instruction cache read sized non-cacheable." + }, { + "name": "SmcInval", + "bit": 2, + "rw": "Read-write", + "description": "Self-modifying code invalidates." + }, { + "name": "BusLocksOriginator", + "bit": 1, + "rw": "Read-write", + "description": "Bus locks." + }, { + "name": "BusLocksResponses", + "bit": 0, + "rw": "Read-write", + "description": "Bus Lock Response." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::L2CacheReqStat", + "name": "L2CacheReqStat", + "code": "0x064", + "summary": "Core to L2 Cacheable Request Access Status", + "description": "L2 Cache Request Outcomes (not including L2 Prefetch).", + "units": [ { + "name": "LsRdBlkCS", + "bit": 7, + "rw": "Read-write", + "description": "Data Cache Shared Read Hit in L2." + }, { + "name": "LsRdBlkLHitX", + "bit": 6, + "rw": "Read-write", + "description": "Data Cache Read Hit in L2." + }, { + "name": "LsRdBlkLHitS", + "bit": 5, + "rw": "Read-write", + "description": "Data Cache Read Hit on Shared Line in L2." + }, { + "name": "LsRdBlkX", + "bit": 4, + "rw": "Read-write", + "description": "Data Cache Store or State Change Hit in L2." + }, { + "name": "LsRdBlkC", + "bit": 3, + "rw": "Read-write", + "description": "Data Cache Req Miss in L2 (all types)." + }, { + "name": "IcFillHitX", + "bit": 2, + "rw": "Read-write", + "description": "Instruction Cache Hit Modifiable Line in L2." + }, { + "name": "IcFillHitS", + "bit": 1, + "rw": "Read-write", + "description": "Instruction Cache Hit Clean Line in L2." + }, { + "name": "IcFillMiss", + "bit": 0, + "rw": "Read-write", + "description": "Instruction Cache Req Miss in L2." + } ] +}, +{ + "mnemonic": "Core::X86::Pmc::Core::L2PfHitL2", + "name": "L2PfHitL2", + "code": "0x070", + "summary": "L2 Prefetch Hit in L2" +}, +{ + "mnemonic": "Core::X86::Pmc::Core::L2PfMissL2HitL2", + "name": "L2PfMissL2HitL2", + "code": "0x071", + "summary": "L2 Prefetcher Hits in L3", + "description": "Counts all L2 prefetches accepted by the L2 pipeline which miss the L2 cache and hit the L3." +}, +{ + "mnemonic": "Core::X86::Pmc::Core::L2PfMissL2L3", + "name": "L2PfMissL2L3", + "code": "0x072", + "summary": "L2 Prefetcher Misses in L3", + "description": "Counts all L2 prefetches accepted by the L2 pipeline which miss the L2 and the L3 caches." +} +] diff --git a/usr/src/lib/efcode/engine/env.c b/usr/src/lib/efcode/engine/env.c index 0fe815baed..16431b21dd 100644 --- a/usr/src/lib/efcode/engine/env.c +++ b/usr/src/lib/efcode/engine/env.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <ctype.h> #include <stdio.h> #include <unistd.h> @@ -230,7 +228,7 @@ typedef struct CMN_MSG_T cmn_msg_t; struct CMN_MSG_T { char buf[CMN_MSG_SIZE]; int level; - int len; + int len; cmn_msg_t *prev; cmn_msg_t *next; }; @@ -243,7 +241,7 @@ struct CMN_FMT_T { char format; /* format type */ }; -static cmn_msg_t *root = NULL; +static cmn_msg_t *root = NULL; static int cmn_msg_level = 0; /* @@ -271,7 +269,7 @@ static int cmn_msg_level = 0; * For valid formatting, caller's supplied cmn_fmt_t elements are * filled in: * fwidth: - * > 0 - returned value is the field width + * > 0 - returned value is the field width * < 0 - returned value is negation of field width for * 64 bit data formats * cwidth: @@ -296,7 +294,7 @@ validfmt(char *fmt, cmn_fmt_t *cfstr) cwidth = &cfstr->cwidth; format = &cfstr->format; *fwidth = *cwidth = 0; - *format = NULL; + *format = '\0'; dig1 = dig2 = NULL; /* check for left justification character */ @@ -361,7 +359,7 @@ validfmt(char *fmt, cmn_fmt_t *cfstr) (*fwidth)++; break; case 'p': - isll = 1; /* uses 64 bit format */ + isll = 1; /* uses 64 bit format */ *format = *fmt; (*fwidth)++; break; @@ -392,7 +390,7 @@ validfmt(char *fmt, cmn_fmt_t *cfstr) static void fmt_args(fcode_env_t *env, int cw, int fw, char format, long *arg, - long long *llarg) + long long *llarg) { char *cbuf; char snf[3]; @@ -423,8 +421,8 @@ fmt_args(fcode_env_t *env, int cw, int fw, char format, long *arg, return; default: log_message(MSG_ERROR, - "fmt_args:invalid format type! (%s)\n", - &format); + "fmt_args:invalid format type! (%s)\n", + &format); return; } @@ -436,9 +434,9 @@ fmt_args(fcode_env_t *env, int cw, int fw, char format, long *arg, if (snprintf(cbuf, cbsize, snf, *arg) < 0) log_message(MSG_ERROR, - "fmt_args: snprintf output error\n"); - while ((cbuf[ndigits] != NULL) && - (ndigits < cbsize)) + "fmt_args: snprintf output error\n"); + while ((cbuf[ndigits] != '\0') && + (ndigits < cbsize)) ndigits++; /* if truncation is necessary, do it */ @@ -449,8 +447,7 @@ fmt_args(fcode_env_t *env, int cw, int fw, char format, long *arg, str = (char *)*arg; str[cw] = 0; } else - *arg = strtol(cbuf, - (char **)NULL, cnv); + *arg = strtol(cbuf, (char **)NULL, cnv); } free(cbuf); } @@ -470,7 +467,7 @@ fmt_args(fcode_env_t *env, int cw, int fw, char format, long *arg, cnv = 16; if (snprintf(cbuf, cbsize, "%p", *llarg) < 0) log_message(MSG_ERROR, - "fmt_args: snprintf error\n"); + "fmt_args: snprintf error\n"); break; case 'x': cnv = 16; @@ -481,17 +478,17 @@ fmt_args(fcode_env_t *env, int cw, int fw, char format, long *arg, case 'd': if (snprintf(cbuf, cbsize, "%ld", *llarg) < 0) log_message(MSG_ERROR, - "fmt_args: snprintf error\n"); + "fmt_args: snprintf error\n"); break; default: log_message(MSG_ERROR, "invalid long format type! (l%s)\n", - &format); + &format); free(cbuf); return; } - while ((cbuf[ndigits] != NULL) && - (ndigits < cbsize)) { + while ((cbuf[ndigits] != '\0') && + (ndigits < cbsize)) { ndigits++; } /* if truncation is necessary, do it */ @@ -561,8 +558,8 @@ fmt_str(fcode_env_t *env, char *fmt, char *fmtbuf, int bsize) tbuf[bytes] = 0; log_message(MSG_ERROR, - "fmt_str: invalid format type! (%s)\n", - tbuf+bytes-3); + "fmt_str: invalid format type! (%s)\n", + tbuf+bytes-3); strncpy(fmtbuf, tbuf, bsize); return; @@ -589,8 +586,8 @@ fmt_str(fcode_env_t *env, char *fmt, char *fmtbuf, int bsize) /* if more input buffer to process, recurse */ if ((l - abs(fw)) != 0) { - fmt_str(env, pct+abs(fw), (tbuf + strlen(tbuf)), - CMN_MSG_SIZE - strlen(tbuf)); + fmt_str(env, pct+abs(fw), (tbuf + strlen(tbuf)), + CMN_MSG_SIZE - strlen(tbuf)); } /* call to extract args for snprintf() calls below */ @@ -611,7 +608,7 @@ fmt_str(fcode_env_t *env, char *fmt, char *fmtbuf, int bsize) default: log_message(MSG_ERROR, "fmt_str: invalid format (%s)\n", - fmptr); + fmptr); return; } @@ -642,7 +639,7 @@ fc_cmn_append(fcode_env_t *env) if (root == NULL) { log_message(MSG_ERROR, - "fc_cmn_append: no message context for append\n"); + "fc_cmn_append: no message context for append\n"); return; } @@ -651,11 +648,11 @@ fc_cmn_append(fcode_env_t *env) if ((root->len + len) < CMN_MSG_SIZE) { fmt_str(env, str, root->buf+root->len, CMN_MSG_SIZE - - root->len); + root->len); root->len += len; } else log_message(MSG_ERROR, - "fc_cmn_append: append exceeds max msg size\n"); + "fc_cmn_append: append exceeds max msg size\n"); } /* diff --git a/usr/src/lib/efcode/engine/mcookie.c b/usr/src/lib/efcode/engine/mcookie.c index 7f25a321cd..2bcc02af1a 100644 --- a/usr/src/lib/efcode/engine/mcookie.c +++ b/usr/src/lib/efcode/engine/mcookie.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -116,7 +114,7 @@ delete_mapping(fstack_t mcookie) } } log_message(MSG_WARN, "Warning: delete_mapping: invalid" - " mcookie: %llx\n", (uint64_t)mcookie); + " mcookie: %llx\n", (uint64_t)mcookie); } int @@ -209,7 +207,7 @@ add_map(fcode_env_t *env) size = POP(DS); addr = POP(DS); - addr = mapping_to_mcookie(addr, size, NULL, NULL); + addr = mapping_to_mcookie(addr, size, 0, 0); PUSH(DS, addr); } diff --git a/usr/src/lib/efcode/fcdriver/build_tree.c b/usr/src/lib/efcode/fcdriver/build_tree.c index 9abcbe9fbc..6882b7ba0a 100644 --- a/usr/src/lib/efcode/fcdriver/build_tree.c +++ b/usr/src/lib/efcode/fcdriver/build_tree.c @@ -24,8 +24,6 @@ * All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> @@ -47,7 +45,7 @@ fc_nodeop(common_data_t *cdp, fc_phandle_t node, char *svc) error = fc_run_priv(cdp, svc, 1, 1, fc_phandle2cell(node), &hcell); if (error) - return (NULL); + return (0); return (fc_cell2phandle(hcell)); } @@ -85,7 +83,7 @@ get_prom_nodeid(fcode_env_t *env, device_t *d) name = get_package_name(env, d); debug_msg(DEBUG_UPLOAD, "Node %s: %p (%p)\n", name, d, pd); if (d->parent) { - private_data_t *ppd = (private_data_t *) d->parent->private; + private_data_t *ppd = (private_data_t *)d->parent->private; fc_phandle_t thisnode; if (os_get_prop_common(cdp, ppd->node, "name", @@ -94,7 +92,7 @@ get_prom_nodeid(fcode_env_t *env, device_t *d) debug_msg(DEBUG_UPLOAD, "Parent: %p (%p) %s = %p\n", d->parent, ppd, namebuf, ppd->node); for (thisnode = fc_nodeop(cdp, ppd->node, FC_CHILD_FCODE); - thisnode != NULL; + thisnode != 0; thisnode = fc_nodeop(cdp, thisnode, FC_PEER_FCODE)) { int status; diff --git a/usr/src/lib/efcode/fcdriver/get_req.c b/usr/src/lib/efcode/fcdriver/get_req.c index 1423524a5d..2fd07e4fec 100644 --- a/usr/src/lib/efcode/fcdriver/get_req.c +++ b/usr/src/lib/efcode/fcdriver/get_req.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <fcntl.h> #include <unistd.h> #include <stdlib.h> @@ -81,7 +79,7 @@ fc_get_request(common_data_t *cdp) return (0); } - if ((cdp->attach = fc_get_ap(cdp)) == NULL) + if ((cdp->attach = fc_get_ap(cdp)) == 0) return (0); return (1); @@ -355,7 +353,7 @@ get_efdaemon_request(fcode_env_t *env) exit(1); } - if ((cdp->attach = fc_get_ap(cdp)) == NULL) + if ((cdp->attach = fc_get_ap(cdp)) == 0) exit(1); get_my_args(env); diff --git a/usr/src/lib/efcode/fcdriver/property.c b/usr/src/lib/efcode/fcdriver/property.c index 5634d1407d..97a9f5ea0d 100644 --- a/usr/src/lib/efcode/fcdriver/property.c +++ b/usr/src/lib/efcode/fcdriver/property.c @@ -24,8 +24,6 @@ * All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <unistd.h> #include <stdlib.h> @@ -129,7 +127,7 @@ os_get_prop(fcode_env_t *env, int inherit, device_t *dev) name = pop_a_string(env, &len); node = pd->node; - if (node == NULL) { + if (node == 0) { log_message(MSG_ERROR, "os_get_prop: NULL node: %s\n", get_path(env, dev)); PUSH(DS, TRUE); diff --git a/usr/src/lib/efcode/gp2/gp2.c b/usr/src/lib/efcode/gp2/gp2.c index 8832230f76..bdc8f2d72f 100644 --- a/usr/src/lib/efcode/gp2/gp2.c +++ b/usr/src/lib/efcode/gp2/gp2.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <strings.h> @@ -40,7 +38,7 @@ mem_map_in(fcode_env_t *env, fstack_t hi, fstack_t lo, fstack_t len) { private_data_t *pdp = DEVICE_PRIVATE(env); fc_cell_t virt; - fstack_t mcookie = NULL; + fstack_t mcookie = 0; char *service = "map-in"; int error; int offset = 0; @@ -60,9 +58,9 @@ mem_map_in(fcode_env_t *env, fstack_t hi, fstack_t lo, fstack_t len) if (error) throw_from_fclib(env, 1, "gp2:%s: failed\n", service); - mcookie = mapping_to_mcookie(virt, len, NULL, NULL); + mcookie = mapping_to_mcookie(virt, len, 0, 0); - if (mcookie == NULL) + if (mcookie == 0) throw_from_fclib(env, 1, "gp2:%s: mapping_to_mcookie failed\n", service); @@ -294,7 +292,7 @@ do_device_id(fcode_env_t *env) /* Try to read the wci_id register */ rc = fc_run_priv(pdp->common, "rx@", 1, 1, virtaddr + 0xe0, - &wci_id_reg); + &wci_id_reg); mem_map_out(env, addr, 0x100); diff --git a/usr/src/lib/efcode/jupiter/jupiter.c b/usr/src/lib/efcode/jupiter/jupiter.c index 821a24656a..823cbe1b5f 100644 --- a/usr/src/lib/efcode/jupiter/jupiter.c +++ b/usr/src/lib/efcode/jupiter/jupiter.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <strings.h> @@ -52,7 +50,7 @@ mem_map_in(fcode_env_t *env, fstack_t hi, fstack_t lo, fstack_t len) { private_data_t *pdp = DEVICE_PRIVATE(env); fc_cell_t virt; - fstack_t mcookie = NULL; + fstack_t mcookie = 0; char *service = "map-in"; int error; int offset = 0; @@ -72,9 +70,9 @@ mem_map_in(fcode_env_t *env, fstack_t hi, fstack_t lo, fstack_t len) if (error) throw_from_fclib(env, 1, "jupiter:%s: failed\n", service); - mcookie = mapping_to_mcookie(virt, len, NULL, NULL); + mcookie = mapping_to_mcookie(virt, len, 0, 0); - if (mcookie == NULL) + if (mcookie == 0) throw_from_fclib(env, 1, "jupiter:%s: mapping_to_mcookie failed\n", service); @@ -420,7 +418,7 @@ do_get_interrupt_target(fcode_env_t *env) PUSH(DS, mid); debug_msg(DEBUG_REG_ACCESS, - "jupiter:get-interrupt-target ( ) -> %x\n", mid); + "jupiter:get-interrupt-target ( ) -> %x\n", mid); } diff --git a/usr/src/lib/efcode/packages/memalloc.c b/usr/src/lib/efcode/packages/memalloc.c index 5e8d365d17..b32b1e5228 100644 --- a/usr/src/lib/efcode/packages/memalloc.c +++ b/usr/src/lib/efcode/packages/memalloc.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <strings.h> @@ -55,7 +53,7 @@ claim(fcode_env_t *env) fc_int2cell(align), fc_size2cell(size), fc_ptr2cell(hint), &vaddr); if (error) throw_from_fclib(env, 1, "client-services/claim failed\n"); - vaddr = mapping_to_mcookie(vaddr, size, NULL, NULL); + vaddr = mapping_to_mcookie(vaddr, size, 0, 0); PUSH(DS, (fstack_t)vaddr); } diff --git a/usr/src/lib/efcode/pci/pci.c b/usr/src/lib/efcode/pci/pci.c index 53aa22cdf9..2ee4fc02c2 100644 --- a/usr/src/lib/efcode/pci/pci.c +++ b/usr/src/lib/efcode/pci/pci.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <strings.h> @@ -43,7 +41,7 @@ mem_map_in(fcode_env_t *env, fstack_t hi, fstack_t mid, fstack_t lo, int error; fc_cell_t requested_virt, adjusted_virt; char *service = "map-in"; - fstack_t mcookie = NULL; + fstack_t mcookie = 0; int pa_offset = 0, va_offset = 0; fstack_t adjusted_len = 0; @@ -83,7 +81,7 @@ mem_map_in(fcode_env_t *env, fstack_t hi, fstack_t mid, fstack_t lo, mcookie = mapping_to_mcookie(requested_virt, requested_len, adjusted_virt, adjusted_len); - if (mcookie == NULL) + if (mcookie == 0) throw_from_fclib(env, 1, "pci-mapin-> pci:%s:" " mapping_to_mcookie failed\n", service); /* diff --git a/usr/src/man/man3cpc/cpc.3cpc b/usr/src/man/man3cpc/cpc.3cpc index d25dc393f8..3a4e86819f 100644 --- a/usr/src/man/man3cpc/cpc.3cpc +++ b/usr/src/man/man3cpc/cpc.3cpc @@ -3,7 +3,7 @@ .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] .\" Copyright (c) 2019, Joyent, Inc. -.Dd March 25, 2019 +.Dd March 27, 2020 .Dt CPC 3CPC .Os .Sh NAME @@ -131,8 +131,11 @@ The following manual pages provide more detailed information on the events available for the specific AMD processor models. The covered processor families are listed in hexadecimal. .Bl -tag -width Xr -.It Xr amd_f17h_events 3CPC -AMD Family 17h processors, including models 00-2fh. +.It Xr amd_f17h_zen1_events 3CPC +AMD Family 17h Zen 1 processors, including models 00-2fh. +Include Ryzen, ThreadRipper, and EPYC branded processors. +.It Xr amd_f17h_zen2_events 3CPC +AMD Family 17h Zen 2 processors, including models 30-7fh. Include Ryzen, ThreadRipper, and EPYC branded processors. .El .Ss Using Attributes diff --git a/usr/src/pkg/manifests/diagnostic-cpu-counters.mf b/usr/src/pkg/manifests/diagnostic-cpu-counters.mf index 8f6934cfd3..3c4f3cb233 100644 --- a/usr/src/pkg/manifests/diagnostic-cpu-counters.mf +++ b/usr/src/pkg/manifests/diagnostic-cpu-counters.mf @@ -66,7 +66,8 @@ file path=usr/lib/libpctx.so.1 file path=usr/sbin/cpustat mode=0555 file path=usr/share/man/man1/cputrack.1 file path=usr/share/man/man1m/cpustat.1m -$(i386_ONLY)file path=usr/share/man/man3cpc/amd_f17h_events.3cpc +$(i386_ONLY)file path=usr/share/man/man3cpc/amd_f17h_zen1_events.3cpc +$(i386_ONLY)file path=usr/share/man/man3cpc/amd_f17h_zen2_events.3cpc $(i386_ONLY)file path=usr/share/man/man3cpc/bdw_de_events.3cpc $(i386_ONLY)file path=usr/share/man/man3cpc/bdw_events.3cpc $(i386_ONLY)file path=usr/share/man/man3cpc/bdx_events.3cpc diff --git a/usr/src/tools/cpcgen/cpcgen.c b/usr/src/tools/cpcgen/cpcgen.c index 43bc016a70..4934fda015 100644 --- a/usr/src/tools/cpcgen/cpcgen.c +++ b/usr/src/tools/cpcgen/cpcgen.c @@ -332,11 +332,11 @@ static const char *cpcgen_manual_amd_header = "" ".Os\n" ".Sh NAME\n" ".Nm amd_%s_events\n" -".Nd AMD family %s processor performance monitoring events\n" +".Nd AMD Family %s processor performance monitoring events\n" ".Sh DESCRIPTION\n" -"This manual page describes events specfic to AMD family %s processors.\n" +"This manual page describes events specfic to AMD Family %s processors.\n" "For more information, please consult the appropriate AMD BIOS and Kernel\n" -"Developer's guide or Open-Source Register Reference manual.\n" +"Developer's guide or Open-Source Register Reference.\n" ".Pp\n" "Each of the events listed below includes the AMD mnemonic which matches\n" "the name found in the AMD manual and a brief summary of the event.\n" @@ -630,7 +630,7 @@ cpcgen_determine_vendor(const char *datadir) * Read in all the data files that exist for AMD. * * Our family names for AMD systems are based on the family and type so a given - * name will look like f17h_core.json. + * name will look like f17h_<core>_core.json. */ static void cpcgen_read_amd(const char *datadir, const char *platform) @@ -660,16 +660,26 @@ cpcgen_read_amd(const char *datadir, const char *platform) continue; } + /* + * Chop off the .json. Next, make sure we have both _ present. + */ if (*(c + slen) != '\0') { free(name); continue; } - *c = '\0'; + c = strchr(name, '_'); if (c == NULL) { - free(name); - continue; + errx(EXIT_FAILURE, "unexpected AMD JSON file name: %s", + d->d_name); + } + + c++; + c = strchr(c, '_'); + if (c == NULL) { + errx(EXIT_FAILURE, "unexpected AMD JSON file name: %s", + d->d_name); } *c = '\0'; c++; @@ -1408,29 +1418,42 @@ static boolean_t cpcgen_manual_amd_file_before(FILE *f, cpc_map_t *map) { size_t i; - char *upper; - const char *family; + char *upper, *desc, *c; if ((upper = strdup(map->cmap_name)) == NULL) { warn("failed to duplicate manual name for %s", map->cmap_name); return (B_FALSE); } + if ((desc = strdup(map->cmap_name)) == NULL) { + warn("failed to duplicate manual name for %s", map->cmap_name); + free(upper); + return (B_FALSE); + } + for (i = 0; upper[i] != '\0'; i++) { upper[i] = toupper(upper[i]); } - family = map->cmap_name + 1; + desc++; + c = strchr(desc, '_'); + if (c != NULL) { + *c = ' '; + c++; + *c = toupper(*c); + } if (fprintf(f, cpcgen_manual_amd_header, map->cmap_path, upper, - family, family, family) == -1) { + map->cmap_name, desc, desc) == -1) { warn("failed to write out manual header for %s", map->cmap_name); free(upper); + free(desc); return (B_FALSE); } free(upper); + free(desc); return (B_TRUE); } diff --git a/usr/src/uts/common/inet/ip.h b/usr/src/uts/common/inet/ip.h index 89574da71f..81801b3dad 100644 --- a/usr/src/uts/common/inet/ip.h +++ b/usr/src/uts/common/inet/ip.h @@ -1596,7 +1596,8 @@ struct ill_zerocopy_capab_s { struct ill_lso_capab_s { uint_t ill_lso_flags; /* capabilities */ - uint_t ill_lso_max; /* maximum size of payload */ + uint_t ill_lso_max_tcpv4; /* maximum size of payload */ + uint_t ill_lso_max_tcpv6; /* maximum size of payload */ }; /* diff --git a/usr/src/uts/common/inet/ip/ip_if.c b/usr/src/uts/common/inet/ip/ip_if.c index a2ddcb3547..638a5e4b21 100644 --- a/usr/src/uts/common/inet/ip/ip_if.c +++ b/usr/src/uts/common/inet/ip/ip_if.c @@ -2112,7 +2112,7 @@ ill_capability_lso_enable(ill_t *ill) dld_capab_lso_t lso; int rc; - ASSERT(!ill->ill_isv6 && IAM_WRITER_ILL(ill)); + ASSERT(IAM_WRITER_ILL(ill)); if (ill->ill_lso_capab == NULL) { ill->ill_lso_capab = kmem_zalloc(sizeof (ill_lso_capab_t), @@ -2129,7 +2129,8 @@ ill_capability_lso_enable(ill_t *ill) if ((rc = idc->idc_capab_df(idc->idc_capab_dh, DLD_CAPAB_LSO, &lso, DLD_ENABLE)) == 0) { ill->ill_lso_capab->ill_lso_flags = lso.lso_flags; - ill->ill_lso_capab->ill_lso_max = lso.lso_max; + ill->ill_lso_capab->ill_lso_max_tcpv4 = lso.lso_max_tcpv4; + ill->ill_lso_capab->ill_lso_max_tcpv6 = lso.lso_max_tcpv6; ill->ill_capabilities |= ILL_CAPAB_LSO; ip1dbg(("ill_capability_lso_enable: interface %s " "has enabled LSO\n ", ill->ill_name)); @@ -2194,11 +2195,10 @@ ill_capability_dld_enable(ill_t *ill) if (!ill->ill_isv6) { ill_capability_direct_enable(ill); ill_capability_poll_enable(ill); - ill_capability_lso_enable(ill); } ill_capability_ipcheck_enable(ill); - + ill_capability_lso_enable(ill); ill->ill_capabilities |= ILL_CAPAB_DLD; ill_mac_perim_exit(ill, mph); } diff --git a/usr/src/uts/common/inet/ip/ip_output.c b/usr/src/uts/common/inet/ip/ip_output.c index a6ca2aabd5..a0157d3c48 100644 --- a/usr/src/uts/common/inet/ip/ip_output.c +++ b/usr/src/uts/common/inet/ip/ip_output.c @@ -673,7 +673,8 @@ ip_verify_lso(ill_t *ill, ip_xmit_attr_t *ixa) /* * Capability has changed, refresh the copy in ixa. */ - if (lsoc->ill_lso_max != new_lsoc->ill_lso_max) { + if (lsoc->ill_lso_max_tcpv4 != new_lsoc->ill_lso_max_tcpv4 || + lsoc->ill_lso_max_tcpv6 != new_lsoc->ill_lso_max_tcpv6) { *lsoc = *new_lsoc; return (B_FALSE); diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c index ef4c96db1c..554fe8b78f 100644 --- a/usr/src/uts/common/inet/tcp/tcp.c +++ b/usr/src/uts/common/inet/tcp/tcp.c @@ -3332,9 +3332,11 @@ tcp_update_lso(tcp_t *tcp, ip_xmit_attr_t *ixa) */ if (ixa->ixa_flags & IXAF_LSO_CAPAB) { ill_lso_capab_t *lsoc = &ixa->ixa_lso_capab; + uint_t lso_max = (ixa->ixa_flags & IXAF_IS_IPV4) ? + lsoc->ill_lso_max_tcpv4 : lsoc->ill_lso_max_tcpv6; - ASSERT(lsoc->ill_lso_max > 0); - tcp->tcp_lso_max = MIN(TCP_MAX_LSO_LENGTH, lsoc->ill_lso_max); + ASSERT3U(lso_max, >, 0); + tcp->tcp_lso_max = MIN(TCP_MAX_LSO_LENGTH, lso_max); DTRACE_PROBE3(tcp_update_lso, boolean_t, tcp->tcp_lso, boolean_t, B_TRUE, uint32_t, tcp->tcp_lso_max); diff --git a/usr/src/uts/common/io/dld/dld_proto.c b/usr/src/uts/common/io/dld/dld_proto.c index 1371fa47c0..596147f4e9 100644 --- a/usr/src/uts/common/io/dld/dld_proto.c +++ b/usr/src/uts/common/io/dld/dld_proto.c @@ -1537,13 +1537,23 @@ dld_capab_lso(dld_str_t *dsp, void *data, uint_t flags) * accordingly. */ if (mac_capab_get(dsp->ds_mh, MAC_CAPAB_LSO, &mac_lso)) { - lso->lso_max = mac_lso.lso_basic_tcp_ipv4.lso_max; + lso->lso_max_tcpv4 = mac_lso.lso_basic_tcp_ipv4.lso_max; + lso->lso_max_tcpv6 = mac_lso.lso_basic_tcp_ipv6.lso_max; lso->lso_flags = 0; /* translate the flag for mac clients */ if ((mac_lso.lso_flags & LSO_TX_BASIC_TCP_IPV4) != 0) lso->lso_flags |= DLD_LSO_BASIC_TCP_IPV4; - dsp->ds_lso = B_TRUE; - dsp->ds_lso_max = lso->lso_max; + if ((mac_lso.lso_flags & LSO_TX_BASIC_TCP_IPV6) != 0) + lso->lso_flags |= DLD_LSO_BASIC_TCP_IPV6; + dsp->ds_lso = lso->lso_flags != 0; + /* + * DLS uses this to try and make sure that a raw ioctl + * doesn't send too much data, but doesn't currently + * check the actual SAP that is sending this (or that + * it's TCP). So for now, just use the max value here. + */ + dsp->ds_lso_max = MAX(lso->lso_max_tcpv4, + lso->lso_max_tcpv6); } else { dsp->ds_lso = B_FALSE; dsp->ds_lso_max = 0; @@ -1581,10 +1591,18 @@ dld_capab(dld_str_t *dsp, uint_t type, void *data, uint_t flags) switch (type) { case DLD_CAPAB_DIRECT: + if (dsp->ds_sap == ETHERTYPE_IPV6) { + err = ENOTSUP; + break; + } err = dld_capab_direct(dsp, data, flags); break; case DLD_CAPAB_POLL: + if (dsp->ds_sap == ETHERTYPE_IPV6) { + err = ENOTSUP; + break; + } err = dld_capab_poll(dsp, data, flags); break; diff --git a/usr/src/uts/common/io/i40e/i40e_transceiver.c b/usr/src/uts/common/io/i40e/i40e_transceiver.c index caafa3e102..9662cb58f5 100644 --- a/usr/src/uts/common/io/i40e/i40e_transceiver.c +++ b/usr/src/uts/common/io/i40e/i40e_transceiver.c @@ -1663,186 +1663,6 @@ i40e_ring_rx_poll(void *arg, int poll_bytes) } /* - * This is a structure I wish someone would fill out for me for dorking with the - * checksums. When we get some more experience with this, we should go ahead and - * consider adding this to MAC. - */ -typedef enum mac_ether_offload_flags { - MEOI_L2INFO_SET = 0x01, - MEOI_VLAN_TAGGED = 0x02, - MEOI_L3INFO_SET = 0x04, - MEOI_L3CKSUM_SET = 0x08, - MEOI_L4INFO_SET = 0x10, - MEOI_L4CKSUM_SET = 0x20 -} mac_ether_offload_flags_t; - -typedef struct mac_ether_offload_info { - mac_ether_offload_flags_t meoi_flags; - uint8_t meoi_l2hlen; /* How long is the Ethernet header? */ - uint16_t meoi_l3proto; /* What's the Ethertype */ - uint8_t meoi_l3hlen; /* How long is the header? */ - uint8_t meoi_l4proto; /* What is the payload type? */ - uint8_t meoi_l4hlen; /* How long is the L4 header */ - mblk_t *meoi_l3ckmp; /* Which mblk has the l3 checksum */ - off_t meoi_l3ckoff; /* What's the offset to it */ - mblk_t *meoi_l4ckmp; /* Which mblk has the L4 checksum */ - off_t meoi_l4off; /* What is the offset to it? */ -} mac_ether_offload_info_t; - -/* - * This is something that we'd like to make a general MAC function. Before we do - * that, we should add support for TSO. - * - * We should really keep track of our offset and not walk everything every - * time. I can't imagine that this will be kind to us at high packet rates; - * however, for the moment, let's leave that. - * - * This walks a message block chain without pulling up to fill in the context - * information. Note that the data we care about could be hidden across more - * than one mblk_t. - */ -static int -i40e_meoi_get_uint8(mblk_t *mp, off_t off, uint8_t *out) -{ - size_t mpsize; - uint8_t *bp; - - mpsize = msgsize(mp); - /* Check for overflow */ - if (off + sizeof (uint16_t) > mpsize) - return (-1); - - mpsize = MBLKL(mp); - while (off >= mpsize) { - mp = mp->b_cont; - off -= mpsize; - mpsize = MBLKL(mp); - } - - bp = mp->b_rptr + off; - *out = *bp; - return (0); - -} - -static int -i40e_meoi_get_uint16(mblk_t *mp, off_t off, uint16_t *out) -{ - size_t mpsize; - uint8_t *bp; - - mpsize = msgsize(mp); - /* Check for overflow */ - if (off + sizeof (uint16_t) > mpsize) - return (-1); - - mpsize = MBLKL(mp); - while (off >= mpsize) { - mp = mp->b_cont; - off -= mpsize; - mpsize = MBLKL(mp); - } - - /* - * Data is in network order. Note the second byte of data might be in - * the next mp. - */ - bp = mp->b_rptr + off; - *out = *bp << 8; - if (off + 1 == mpsize) { - mp = mp->b_cont; - bp = mp->b_rptr; - } else { - bp++; - } - - *out |= *bp; - return (0); - -} - -static int -mac_ether_offload_info(mblk_t *mp, mac_ether_offload_info_t *meoi) -{ - size_t off; - uint16_t ether; - uint8_t ipproto, iplen, l4len, maclen; - - bzero(meoi, sizeof (mac_ether_offload_info_t)); - - off = offsetof(struct ether_header, ether_type); - if (i40e_meoi_get_uint16(mp, off, ðer) != 0) - return (-1); - - if (ether == ETHERTYPE_VLAN) { - off = offsetof(struct ether_vlan_header, ether_type); - if (i40e_meoi_get_uint16(mp, off, ðer) != 0) - return (-1); - meoi->meoi_flags |= MEOI_VLAN_TAGGED; - maclen = sizeof (struct ether_vlan_header); - } else { - maclen = sizeof (struct ether_header); - } - meoi->meoi_flags |= MEOI_L2INFO_SET; - meoi->meoi_l2hlen = maclen; - meoi->meoi_l3proto = ether; - - switch (ether) { - case ETHERTYPE_IP: - /* - * For IPv4 we need to get the length of the header, as it can - * be variable. - */ - off = offsetof(ipha_t, ipha_version_and_hdr_length) + maclen; - if (i40e_meoi_get_uint8(mp, off, &iplen) != 0) - return (-1); - iplen &= 0x0f; - if (iplen < 5 || iplen > 0x0f) - return (-1); - iplen *= 4; - off = offsetof(ipha_t, ipha_protocol) + maclen; - if (i40e_meoi_get_uint8(mp, off, &ipproto) == -1) - return (-1); - break; - case ETHERTYPE_IPV6: - iplen = 40; - off = offsetof(ip6_t, ip6_nxt) + maclen; - if (i40e_meoi_get_uint8(mp, off, &ipproto) == -1) - return (-1); - break; - default: - return (0); - } - meoi->meoi_l3hlen = iplen; - meoi->meoi_l4proto = ipproto; - meoi->meoi_flags |= MEOI_L3INFO_SET; - - switch (ipproto) { - case IPPROTO_TCP: - off = offsetof(tcph_t, th_offset_and_rsrvd) + maclen + iplen; - if (i40e_meoi_get_uint8(mp, off, &l4len) == -1) - return (-1); - l4len = (l4len & 0xf0) >> 4; - if (l4len < 5 || l4len > 0xf) - return (-1); - l4len *= 4; - break; - case IPPROTO_UDP: - l4len = sizeof (struct udphdr); - break; - case IPPROTO_SCTP: - l4len = sizeof (sctp_hdr_t); - break; - default: - return (0); - } - - meoi->meoi_l4hlen = l4len; - meoi->meoi_flags |= MEOI_L4INFO_SET; - return (0); -} - -/* * Attempt to put togther the information we'll need to feed into a descriptor * to properly program the hardware for checksum offload as well as the * generally required flags. diff --git a/usr/src/uts/common/io/mac/mac_provider.c b/usr/src/uts/common/io/mac/mac_provider.c index 0f917cd8ca..7f193f68eb 100644 --- a/usr/src/uts/common/io/mac/mac_provider.c +++ b/usr/src/uts/common/io/mac/mac_provider.c @@ -58,6 +58,10 @@ #include <sys/pattr.h> #include <sys/strsun.h> #include <sys/vlan.h> +#include <inet/ip.h> +#include <inet/tcp.h> +#include <netinet/udp.h> +#include <netinet/sctp.h> /* * MAC Provider Interface. @@ -1653,3 +1657,155 @@ mac_transceiver_info_set_usable(mac_transceiver_info_t *infop, { infop->mti_usable = usable; } + +/* + * We should really keep track of our offset and not walk everything every + * time. I can't imagine that this will be kind to us at high packet rates; + * however, for the moment, let's leave that. + * + * This walks a message block chain without pulling up to fill in the context + * information. Note that the data we care about could be hidden across more + * than one mblk_t. + */ +static int +mac_meoi_get_uint8(mblk_t *mp, off_t off, uint8_t *out) +{ + size_t mpsize; + uint8_t *bp; + + mpsize = msgsize(mp); + /* Check for overflow */ + if (off + sizeof (uint16_t) > mpsize) + return (-1); + + mpsize = MBLKL(mp); + while (off >= mpsize) { + mp = mp->b_cont; + off -= mpsize; + mpsize = MBLKL(mp); + } + + bp = mp->b_rptr + off; + *out = *bp; + return (0); + +} + +static int +mac_meoi_get_uint16(mblk_t *mp, off_t off, uint16_t *out) +{ + size_t mpsize; + uint8_t *bp; + + mpsize = msgsize(mp); + /* Check for overflow */ + if (off + sizeof (uint16_t) > mpsize) + return (-1); + + mpsize = MBLKL(mp); + while (off >= mpsize) { + mp = mp->b_cont; + off -= mpsize; + mpsize = MBLKL(mp); + } + + /* + * Data is in network order. Note the second byte of data might be in + * the next mp. + */ + bp = mp->b_rptr + off; + *out = *bp << 8; + if (off + 1 == mpsize) { + mp = mp->b_cont; + bp = mp->b_rptr; + } else { + bp++; + } + + *out |= *bp; + return (0); + +} + + +int +mac_ether_offload_info(mblk_t *mp, mac_ether_offload_info_t *meoi) +{ + size_t off; + uint16_t ether; + uint8_t ipproto, iplen, l4len, maclen; + + bzero(meoi, sizeof (mac_ether_offload_info_t)); + + meoi->meoi_len = msgsize(mp); + off = offsetof(struct ether_header, ether_type); + if (mac_meoi_get_uint16(mp, off, ðer) != 0) + return (-1); + + if (ether == ETHERTYPE_VLAN) { + off = offsetof(struct ether_vlan_header, ether_type); + if (mac_meoi_get_uint16(mp, off, ðer) != 0) + return (-1); + meoi->meoi_flags |= MEOI_VLAN_TAGGED; + maclen = sizeof (struct ether_vlan_header); + } else { + maclen = sizeof (struct ether_header); + } + meoi->meoi_flags |= MEOI_L2INFO_SET; + meoi->meoi_l2hlen = maclen; + meoi->meoi_l3proto = ether; + + switch (ether) { + case ETHERTYPE_IP: + /* + * For IPv4 we need to get the length of the header, as it can + * be variable. + */ + off = offsetof(ipha_t, ipha_version_and_hdr_length) + maclen; + if (mac_meoi_get_uint8(mp, off, &iplen) != 0) + return (-1); + iplen &= 0x0f; + if (iplen < 5 || iplen > 0x0f) + return (-1); + iplen *= 4; + off = offsetof(ipha_t, ipha_protocol) + maclen; + if (mac_meoi_get_uint8(mp, off, &ipproto) == -1) + return (-1); + break; + case ETHERTYPE_IPV6: + iplen = 40; + off = offsetof(ip6_t, ip6_nxt) + maclen; + if (mac_meoi_get_uint8(mp, off, &ipproto) == -1) + return (-1); + break; + default: + return (0); + } + meoi->meoi_l3hlen = iplen; + meoi->meoi_l4proto = ipproto; + meoi->meoi_flags |= MEOI_L3INFO_SET; + + switch (ipproto) { + case IPPROTO_TCP: + off = offsetof(tcph_t, th_offset_and_rsrvd) + maclen + iplen; + if (mac_meoi_get_uint8(mp, off, &l4len) == -1) + return (-1); + l4len = (l4len & 0xf0) >> 4; + if (l4len < 5 || l4len > 0xf) + return (-1); + l4len *= 4; + break; + case IPPROTO_UDP: + l4len = sizeof (struct udphdr); + break; + case IPPROTO_SCTP: + l4len = sizeof (sctp_hdr_t); + break; + default: + return (0); + } + + meoi->meoi_l4hlen = l4len; + meoi->meoi_flags |= MEOI_L4INFO_SET; + return (0); +} diff --git a/usr/src/uts/common/io/vioif/vioif.c b/usr/src/uts/common/io/vioif/vioif.c index e1535182b3..cac90d3073 100644 --- a/usr/src/uts/common/io/vioif/vioif.c +++ b/usr/src/uts/common/io/vioif/vioif.c @@ -74,6 +74,7 @@ #include <sys/random.h> #include <sys/containerof.h> #include <sys/stream.h> +#include <inet/tcp.h> #include <sys/mac.h> #include <sys/mac_provider.h> @@ -1018,7 +1019,7 @@ vioif_send(vioif_t *vif, mblk_t *mp) for (nmp = mp; nmp; nmp = nmp->b_cont) msg_size += MBLKL(nmp); - if (vif->vif_tx_tso4) { + if (vif->vif_tx_tso4 || vif->vif_tx_tso6) { mac_lso_get(mp, &lso_mss, &lso_flags); lso_required = (lso_flags & HW_LSO) != 0; } @@ -1084,8 +1085,70 @@ vioif_send(vioif_t *vif, mblk_t *mp) * Setup LSO fields if required. */ if (lso_required) { - vnh->vnh_gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + mac_ether_offload_flags_t needed; + mac_ether_offload_info_t meo; + uint32_t cksum; + size_t len; + mblk_t *pullmp = NULL; + tcpha_t *tcpha; + + if (mac_ether_offload_info(mp, &meo) != 0) { + goto fail; + } + + needed = MEOI_L2INFO_SET | MEOI_L3INFO_SET | MEOI_L4INFO_SET; + if ((meo.meoi_flags & needed) != needed) { + goto fail; + } + + if (meo.meoi_l4proto != IPPROTO_TCP) { + goto fail; + } + + if (meo.meoi_l3proto == ETHERTYPE_IP && vif->vif_tx_tso4) { + vnh->vnh_gso_type = VIRTIO_NET_HDR_GSO_TCPV4; + } else if (meo.meoi_l3proto == ETHERTYPE_IPV6 && + vif->vif_tx_tso6) { + vnh->vnh_gso_type = VIRTIO_NET_HDR_GSO_TCPV6; + } else { + goto fail; + } + + /* + * The TCP stack does not include the length in the TCP + * pseudo-header when it is performing LSO since hardware + * generally asks for it to be removed (as it'll change). + * Unfortunately, for virtio, we actually need it. This means we + * need to go through and calculate the actual length and fix + * things up. Because the virtio spec cares about the ECN flag + * and indicating that, at least this means we'll have that + * available as well. + */ + if (MBLKL(mp) < vnh->vnh_hdr_len) { + pullmp = msgpullup(mp, vnh->vnh_hdr_len); + if (pullmp == NULL) + goto fail; + tcpha = (tcpha_t *)(pullmp->b_rptr + meo.meoi_l2hlen + + meo.meoi_l3hlen); + } else { + tcpha = (tcpha_t *)(mp->b_rptr + meo.meoi_l2hlen + + meo.meoi_l3hlen); + } + + len = meo.meoi_len - meo.meoi_l2hlen - meo.meoi_l3hlen; + cksum = ntohs(tcpha->tha_sum) + len; + cksum = (cksum >> 16) + (cksum & 0xffff); + cksum = (cksum >> 16) + (cksum & 0xffff); + tcpha->tha_sum = htons(cksum); + + if (tcpha->tha_flags & TH_CWR) { + vnh->vnh_gso_type |= VIRTIO_NET_HDR_GSO_ECN; + } vnh->vnh_gso_size = (uint16_t)lso_mss; + vnh->vnh_hdr_len = meo.meoi_l2hlen + meo.meoi_l3hlen + + meo.meoi_l4hlen; + + freemsg(pullmp); } /* @@ -1453,8 +1516,9 @@ vioif_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) } mac_capab_lso_t *lso = cap_data; - lso->lso_flags = LSO_TX_BASIC_TCP_IPV4; + lso->lso_flags = LSO_TX_BASIC_TCP_IPV4 | LSO_TX_BASIC_TCP_IPV6; lso->lso_basic_tcp_ipv4.lso_max = VIOIF_RX_DATA_SIZE; + lso->lso_basic_tcp_ipv6.lso_max = VIOIF_RX_DATA_SIZE; return (B_TRUE); } @@ -1556,6 +1620,7 @@ vioif_check_features(vioif_t *vif) vif->vif_tx_csum = 0; vif->vif_tx_tso4 = 0; + vif->vif_tx_tso6 = 0; if (vioif_has_feature(vif, VIRTIO_NET_F_CSUM)) { /* @@ -1569,6 +1634,7 @@ vioif_check_features(vioif_t *vif) */ boolean_t gso = vioif_has_feature(vif, VIRTIO_NET_F_GSO); boolean_t tso4 = vioif_has_feature(vif, VIRTIO_NET_F_HOST_TSO4); + boolean_t tso6 = vioif_has_feature(vif, VIRTIO_NET_F_HOST_TSO6); boolean_t ecn = vioif_has_feature(vif, VIRTIO_NET_F_HOST_ECN); /* @@ -1578,8 +1644,15 @@ vioif_check_features(vioif_t *vif) * we require the device to support the combination of * segmentation offload and ECN support. */ - if (gso || (tso4 && ecn)) { + if (gso) { vif->vif_tx_tso4 = 1; + vif->vif_tx_tso6 = 1; + } + if (tso4 && ecn) { + vif->vif_tx_tso4 = 1; + } + if (tso6 && ecn) { + vif->vif_tx_tso6 = 1; } } } diff --git a/usr/src/uts/common/io/vioif/vioif.h b/usr/src/uts/common/io/vioif/vioif.h index 19d8965bd4..9f750c9b8a 100644 --- a/usr/src/uts/common/io/vioif/vioif.h +++ b/usr/src/uts/common/io/vioif/vioif.h @@ -164,6 +164,7 @@ extern "C" { #define VIRTIO_NET_WANTED_FEATURES (VIRTIO_NET_F_CSUM | \ VIRTIO_NET_F_GSO | \ VIRTIO_NET_F_HOST_TSO4 | \ + VIRTIO_NET_F_HOST_TSO6 | \ VIRTIO_NET_F_HOST_ECN | \ VIRTIO_NET_F_MAC | \ VIRTIO_NET_F_MTU) @@ -356,6 +357,7 @@ struct vioif { */ unsigned int vif_tx_csum:1; unsigned int vif_tx_tso4:1; + unsigned int vif_tx_tso6:1; /* * For debugging, it is useful to know whether the MAC address we diff --git a/usr/src/uts/common/mapfiles/mac.mapfile b/usr/src/uts/common/mapfiles/mac.mapfile index d40c09b311..d5ba3ae2e5 100644 --- a/usr/src/uts/common/mapfiles/mac.mapfile +++ b/usr/src/uts/common/mapfiles/mac.mapfile @@ -32,6 +32,7 @@ $mapfile_version 2 SYMBOL_SCOPE { global: mac_alloc { FLAGS = EXTERN }; + mac_ether_offload_info { FLAGS = EXTERN }; mac_fini_ops { FLAGS = EXTERN }; mac_free { FLAGS = EXTERN }; mac_hcksum_get { FLAGS = EXTERN }; diff --git a/usr/src/uts/common/sys/dld.h b/usr/src/uts/common/sys/dld.h index 5be223ce93..6921960160 100644 --- a/usr/src/uts/common/sys/dld.h +++ b/usr/src/uts/common/sys/dld.h @@ -446,7 +446,8 @@ typedef struct dld_capab_poll_s { typedef struct dld_capab_lso_s { uint_t lso_flags; /* capability flags */ - uint_t lso_max; /* maximum payload */ + uint_t lso_max_tcpv4; /* maximum TCPv4 payload */ + uint_t lso_max_tcpv6; /* maximum TCPv6 payload */ } dld_capab_lso_t; int dld_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); diff --git a/usr/src/uts/common/sys/mac_provider.h b/usr/src/uts/common/sys/mac_provider.h index fc3b3892bd..04c20d6aac 100644 --- a/usr/src/uts/common/sys/mac_provider.h +++ b/usr/src/uts/common/sys/mac_provider.h @@ -120,10 +120,15 @@ typedef struct lso_basic_tcp_ipv4_s { t_uscalar_t lso_max; /* maximum payload */ } lso_basic_tcp_ipv4_t; +typedef struct lso_basic_tcp_ipv6_s { + t_uscalar_t lso_max; /* maximum payload */ +} lso_basic_tcp_ipv6_t; + /* * Currently supported flags for LSO. */ -#define LSO_TX_BASIC_TCP_IPV4 0x01 /* TCP LSO capability */ +#define LSO_TX_BASIC_TCP_IPV4 0x01 /* TCPv4 LSO capability */ +#define LSO_TX_BASIC_TCP_IPV6 0x02 /* TCPv6 LSO capability */ /* * Future LSO capabilities can be added at the end of the mac_capab_lso_t. @@ -136,6 +141,7 @@ typedef struct lso_basic_tcp_ipv4_s { typedef struct mac_capab_lso_s { t_uscalar_t lso_flags; lso_basic_tcp_ipv4_t lso_basic_tcp_ipv4; + lso_basic_tcp_ipv6_t lso_basic_tcp_ipv6; /* Add future lso capabilities here */ } mac_capab_lso_t; @@ -647,6 +653,31 @@ extern void mac_transceiver_info_set_usable( mac_transceiver_info_t *, boolean_t); +/* + * This represents a provisional set of currently illumos-private APIs to get + * information about a mblk_t chain's type. This is an evolving interface. + */ +typedef enum mac_ether_offload_flags { + MEOI_L2INFO_SET = 1 << 0, + MEOI_VLAN_TAGGED = 1 << 1, + MEOI_L3INFO_SET = 1 << 2, + MEOI_L4INFO_SET = 1 << 3 +} mac_ether_offload_flags_t; + +typedef struct mac_ether_offload_info { + mac_ether_offload_flags_t meoi_flags; /* What's valid? */ + size_t meoi_len; /* Total message length */ + uint8_t meoi_l2hlen; /* How long is the Ethernet header? */ + uint16_t meoi_l3proto; /* What's the Ethertype */ + uint8_t meoi_l3hlen; /* How long is the header? */ + uint8_t meoi_l4proto; /* What is the payload type? */ + uint8_t meoi_l4hlen; /* How long is the L4 header */ +} mac_ether_offload_info_t; + +extern int mac_ether_offload_info(mblk_t *, + mac_ether_offload_info_t *); + + #endif /* _KERNEL */ #ifdef __cplusplus diff --git a/usr/src/uts/i86pc/os/machdep.c b/usr/src/uts/i86pc/os/machdep.c index 45e4d41aad..7dbf63e2c7 100644 --- a/usr/src/uts/i86pc/os/machdep.c +++ b/usr/src/uts/i86pc/os/machdep.c @@ -21,7 +21,7 @@ /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2017, Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ /* * Copyright (c) 2010, Intel Corporation. @@ -1472,14 +1472,6 @@ hotinline_smap(hotinline_desc_t *hid) if (is_x86_feature(x86_featureset, X86FSET_SMAP) == B_FALSE) return; -/* - * We should never hit this since SMAP feature detection is behind - * an AMD64 header guard. - */ -#if defined(__i386) - panic("illumos only suppports SMAP on the AMD64 architecture."); -#endif - if (strcmp(hid->hid_symname, "smap_enable") == 0) { bcopy(clac_instr, (void *)hid->hid_instr_offset, sizeof (clac_instr)); diff --git a/usr/src/uts/intel/ia32/ml/copy.s b/usr/src/uts/intel/ia32/ml/copy.s index 8c23d794f9..5e5f822518 100644 --- a/usr/src/uts/intel/ia32/ml/copy.s +++ b/usr/src/uts/intel/ia32/ml/copy.s @@ -36,7 +36,7 @@ /* All Rights Reserved */ /* - * Copyright 2019 Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ #include <sys/errno.h> @@ -66,11 +66,10 @@ * * Rules and Constraints: * - * 1. For anything that's not in copy.s, we have it do explicit calls to the - * smap related code. It usually is in a position where it is able to. This is - * restricted to the following three places: DTrace, resume() in swtch.s and - * on_fault/no_fault. If you want to add it somewhere else, we should be - * thinking twice. + * 1. For anything that's not in copy.s, we have it do explicit smap_disable() + * or smap_enable() calls. This is restricted to the following three places: + * DTrace, resume() in swtch.s and on_fault/no_fault. If you want to add it + * somewhere else, we should be thinking twice. * * 2. We try to toggle this at the smallest window possible. This means that if * we take a fault, need to try to use a copyop in copyin() or copyout(), or any @@ -81,33 +80,25 @@ * explicitly only allowed to be called while in an on_fault()/no_fault() handler, * which already takes care of ensuring that SMAP is enabled and disabled. Note * this means that when under an on_fault()/no_fault() handler, one must not - * call the non-*_noeer() routines. + * call the non-*_noerr() routines. * * 4. The first thing we should do after coming out of an lofault handler is to - * make sure that we call smap_enable again to ensure that we are safely + * make sure that we call smap_enable() again to ensure that we are safely * protected, as more often than not, we will have disabled smap to get there. * - * 5. The SMAP functions, smap_enable and smap_disable may not touch any - * registers beyond those done by the call and ret. These routines may be called - * from arbitrary contexts in copy.s where we have slightly more special ABIs in - * place. + * 5. smap_enable() and smap_disable() don't exist: calls to these functions + * generate runtime relocations, that are then processed into the necessary + * clac/stac, via the krtld hotinlines mechanism and hotinline_smap(). * * 6. For any inline user of SMAP, the appropriate SMAP_ENABLE_INSTR and - * SMAP_DISABLE_INSTR macro should be used (except for smap_enable() and - * smap_disable()). If the number of these is changed, you must update the - * constants SMAP_ENABLE_COUNT and SMAP_DISABLE_COUNT below. + * SMAP_DISABLE_INSTR macro should be used. If the number of these is changed, + * you must update the constants SMAP_ENABLE_COUNT and SMAP_DISABLE_COUNT below. * - * 7. Note, at this time SMAP is not implemented for the 32-bit kernel. There is - * no known technical reason preventing it from being enabled. - * - * 8. Generally this .s file is processed by a K&R style cpp. This means that it + * 7. Generally this .s file is processed by a K&R style cpp. This means that it * really has a lot of feelings about whitespace. In particular, if you have a * macro FOO with the arguments FOO(1, 3), the second argument is in fact ' 3'. * - * 9. The smap_enable and smap_disable functions should not generally be called. - * They exist such that DTrace and on_trap() may use them, that's it. - * - * 10. In general, the kernel has its own value for rflags that gets used. This + * 8. In general, the kernel has its own value for rflags that gets used. This * is maintained in a few different places which vary based on how the thread * comes into existence and whether it's a user thread. In general, when the * kernel takes a trap, it always will set ourselves to a known set of flags, diff --git a/usr/src/uts/intel/opteron_pcbe/Makefile b/usr/src/uts/intel/opteron_pcbe/Makefile index 2d45ea3801..16cb0f41e5 100644 --- a/usr/src/uts/intel/opteron_pcbe/Makefile +++ b/usr/src/uts/intel/opteron_pcbe/Makefile @@ -33,7 +33,8 @@ UTSBASE = ../.. # The following objects are autogenerated by cpcgen. # CPCGEN_OBJS = \ - opteron_pcbe_f17h.o + opteron_pcbe_f17h_zen1.o \ + opteron_pcbe_f17h_zen2.o CPCGEN_COMMON = opteron_pcbe_cpcgen.h CPCGEN_CMD = $(CPCGEN) -d $(SRC)/data/amdpmc -o . @@ -100,7 +101,7 @@ opteron_pcbe_cpcgen.h: opteron_pcbe_%.c: $(CPCGEN_COMMON) $(CPCGEN_CMD) -c -p \ $$(echo $@ | \ - $(SED) -e 's/opteron_pcbe_//g' -e 's/_/-/g' -e 's/.c$$//g') + $(SED) -e 's/opteron_pcbe_//g' -e 's/.c$$//g') $(OBJS_DIR)/%.o: %.c $(COMPILE.c) -I$(SRC)/uts/intel/pcbe/ -o $@ $< diff --git a/usr/src/uts/intel/pcbe/opteron_pcbe.c b/usr/src/uts/intel/pcbe/opteron_pcbe.c index 6a875ec681..c4496bf8ca 100644 --- a/usr/src/uts/intel/pcbe/opteron_pcbe.c +++ b/usr/src/uts/intel/pcbe/opteron_pcbe.c @@ -449,11 +449,11 @@ static const amd_generic_event_t family_10h_generic_events[] = { /* * For Family 17h, the cpcgen utility generates all of our events including ones * that need specific unit codes, therefore we leave all unit codes out of - * these. + * these. Zen 1 and Zen 2 have different event sets that they support. */ -static const amd_generic_event_t family_17h_papi_events[] = { +static const amd_generic_event_t family_17h_zen1_papi_events[] = { { "PAPI_br_cn", "ExRetCond" }, - { "PAPI_br_ins", "ExRetBrnMis" }, + { "PAPI_br_ins", "ExRetBrn" }, { "PAPI_fpu_idl", "FpSchedEmpty" }, { "PAPI_tot_cyc", "LsNotHaltedCyc" }, { "PAPI_tot_ins", "ExRetInstr" }, @@ -463,6 +463,18 @@ static const amd_generic_event_t family_17h_papi_events[] = { GEN_EV_END }; +static const amd_generic_event_t family_17h_zen2_papi_events[] = { + { "PAPI_br_cn", "ExRetCond" }, + { "PAPI_br_ins", "ExRetBrn" }, + { "PAPI_tot_cyc", "LsNotHaltedCyc" }, + { "PAPI_tot_ins", "ExRetInstr" }, + { "PAPI_tlb_dm", "LsL1DTlbMiss" }, + { "PAPI_tlb_im", "BpL1TlbMissL2Miss" }, + { "PAPI_tot_cyc", "LsNotHaltedCyc" }, + GEN_EV_END +}; + + static char *evlist; static size_t evlist_sz; static const amd_event_t *amd_events = NULL; @@ -477,9 +489,14 @@ static char amd_fam_10h_bkdg[] = "See \"BIOS and Kernel Developer's Guide " "(BKDG) For AMD Family 10h Processors\" (AMD publication 31116)"; static char amd_fam_11h_bkdg[] = "See \"BIOS and Kernel Developer's Guide " "(BKDG) For AMD Family 11h Processors\" (AMD publication 41256)"; -static char amd_fam_17h_reg[] = "See \"Open-Source Register Reference For " +static char amd_fam_17h_zen1_reg[] = "See \"Open-Source Register Reference For " "AMD Family 17h Processors Models 00h-2Fh\" (AMD publication 56255) and " -"amd_f17h_events(3CPC)"; +"amd_f17h_zen1_events(3CPC)"; +static char amd_fam_17h_zen2_reg[] = "See \"Preliminary Processor Programming " +"Reference (PPR) for AMD Family 17h Model 31h, Revision B0 Processors\" " +"(AMD publication 55803), \"Processor Programming Reference (PPR) for AMD " +"Family 17h Model 71h, Revision B0 Processors\" (AMD publication 56176), and " +"amd_f17h_zen2_events(3CPC)"; static char amd_pcbe_impl_name[64]; static char *amd_pcbe_cpuref; @@ -582,9 +599,14 @@ opt_pcbe_init(void) amd_events = family_11h_events; amd_generic_events = opt_generic_events; } else if (amd_family == 0x17 && amd_model <= 0x2f) { - amd_pcbe_cpuref = amd_fam_17h_reg; - amd_events = opteron_pcbe_f17h_events; - amd_generic_events = family_17h_papi_events; + amd_pcbe_cpuref = amd_fam_17h_zen1_reg; + amd_events = opteron_pcbe_f17h_zen1_events; + amd_generic_events = family_17h_zen1_papi_events; + } else if (amd_family == 0x17 && amd_model >= 0x30 && + amd_model <= 0x7f) { + amd_pcbe_cpuref = amd_fam_17h_zen2_reg; + amd_events = opteron_pcbe_f17h_zen2_events; + amd_generic_events = family_17h_zen2_papi_events; } else { /* * Different families have different meanings on events and even |