WHEAService, WHEA errors suppressor

Discussion in 'Processors and motherboards AMD' started by mannix, May 16, 2021.

Tags:
  1. mannix

    mannix Active Member

    Messages:
    70
    Likes Received:
    17
    GPU:
    MSI GTX1070 ArmorOC
    Due to the high number of WHEA errors clogging the system, running a Ryzen with high FCLK incurs in a performance penalty.

    WHEAService will disable the WHEA error reporting; please be careful and check system stability.

    System should become stable and smooth once the error sources are disabled.

    It's a non-destructive and low risk solution; you can always disable the service or uninstall it and go back to the previous state.

    Ver. 1.2.0.0 Release

    You can download it form GitHub:


    https://github.com/mann1x/WHEAService/releases/tag/v1.2.0.0


    Use the MSI installer and reboot.


    Please check the README on GitHub.
     
    Last edited: May 21, 2021
  2. mbk1969

    mbk1969 Ancient Guru

    Messages:
    10,801
    Likes Received:
    8,048
    GPU:
    GF RTX 2070 Super
    Smooth source files.

    PS
    One note:

    Code:
    public (int,int) GetSourceInfo(ManagementScope scope, int esType)
    {
        try
        {
            ManagementObject obj = new ManagementObject();
            ManagementPath path = new ManagementPath(scope.Path + ":WHEAErrorSourceMethods.InstanceName='WHEA_WMI_PROVIDER0'");
            obj.Path = path;
            obj.Get();
            ...
    
    I would assume that obj instance needs a disposal
    Code:
    public (int,int) GetSourceInfo(ManagementScope scope, int esType)
    {
        try
        {
            using(ManagementObject obj = new ManagementObject())
            {
                 ManagementPath path = new ManagementPath(scope.Path + ":WHEAErrorSourceMethods.InstanceName='WHEA_WMI_PROVIDER0'");
                 obj.Path = path;
                 obj.Get();
                 ...
    
    (Same goes for DisableSource method.)

    PSS
    And second note (more curiosity):
    why "if (Type.ToString() == esType.ToString())" instead of "if (Type == esType)" seeing that both variables are of the same type?
     
    Last edited: May 16, 2021
  3. Astyanax

    Astyanax Ancient Guru

    Messages:
    10,590
    Likes Received:
    3,877
    GPU:
    GTX 1080ti
    Don't disable WHEA errors

    Fix your computer instead.
     
  4. mannix

    mannix Active Member

    Messages:
    70
    Likes Received:
    17
    GPU:
    MSI GTX1070 ArmorOC
    Programming is not my best skill :)

    I don't think C# needs disposal, should be handled by the GC. But I may be wrong.

    The Type is probably a typo eheh
     

  5. mannix

    mannix Active Member

    Messages:
    70
    Likes Received:
    17
    GPU:
    MSI GTX1070 ArmorOC
    You are right but there's nothing to fix in this case :)
    At least, not the high flow which is caused by the Realtek EFI.
    Unfortunately if there are also other legitimate WHEA errors you will not see it.
    It's a workaround not a fix.
    So test the stability with OCCT & Co and brace yourself.
     
  6. Astyanax

    Astyanax Ancient Guru

    Messages:
    10,590
    Likes Received:
    3,877
    GPU:
    GTX 1080ti
    WHEA errors are errors that need to be addressed, doesn't matter if they are being corrected, sometimes corrected errors become uncorrected under load.
     
  7. mbk1969

    mbk1969 Ancient Guru

    Messages:
    10,801
    Likes Received:
    8,048
    GPU:
    GF RTX 2070 Super
    C# does not need disposal for managed objects - types native to .Net Framework. In case of WMI you deal with unmanaged COM-objects wrapped in C#-objects. In such cases Garbage Collector can dispose managed object-wrapper but leave unmanaged object orphaned. It is a "best practice" approach to dispose objects which implement IDisposable:
    Inheritance -> Object -> MarshalByRefObject -> Component -> ManagementBaseObject -> ManagementObject
    where
    public class Component : MarshalByRefObject, IDisposable, System.ComponentModel.IComponent

    "Type" is not a typo, that name can be used for variable despite being used by .Net Framework type "Type".
    I was simply pointing out that since both variables are of the same type "int" you can compare them without converting to strings.

    Upd: I went to see a .Net source code of ManagementObject and found that you indeed do not have to call Dispose directly, because it will release COM-object when GarbageCollected. But still it is "a best practice" to do - to call Dispose directly on objects which implement IDisposable.
     
    Last edited: May 16, 2021
  8. mannix

    mannix Active Member

    Messages:
    70
    Likes Received:
    17
    GPU:
    MSI GTX1070 ArmorOC
    Thanks a lot for the info, I had no idea even that was best practice :p
    Honestly I never considered to check if they implement IDisposable.

    It was a joke. Type&Typo, I got it eheh
    Didn't thought about naming collision either, I was doing something different and changed it in a hurry.
    Will definitely use something else.
     
  9. mannix

    mannix Active Member

    Messages:
    70
    Likes Received:
    17
    GPU:
    MSI GTX1070 ArmorOC
    Just a bit of background:

    When you run a high FCLK on Vermeer you get a steady flow of dozens to hundreds of errors per second.
    This massive flow, which is not reflected in any real issue or performance degradation, has been tracked down to the
    Realtek EFI
    by @Veii
    We'll try to confirm if running a custom BIOS without the EFI in question inside.

    My experience is telling me that these errors are a total fake; my 3800x would crash in a matter of seconds with a much less flow of WHEA.
    Same as my 5950x when I do something really stupid, it's not that tolerant.
    I've spent months benching and testing at 1900+ with scaling results in performances and zero issues, at least till 2033 MHz.
    Now I took the big step to use FCLK 2033 MHz also on my main install and it's rock solid and fast.

    If you have performance degradation then there's something else wrong and you should not disable error reporting and not use a high FCLK.

    Otherwise, bearing the risks, you can silence the errors and verify stability like in the old times when WHEA was not a thing.
    Unless you are too young for this kind of stuff :)

    Pick you chances.
     
    Last edited: May 16, 2021
  10. mannix

    mannix Active Member

    Messages:
    70
    Likes Received:
    17
    GPU:
    MSI GTX1070 ArmorOC

  11. mannix

    mannix Active Member

    Messages:
    70
    Likes Received:
    17
    GPU:
    MSI GTX1070 ArmorOC
  12. mbk1969

    mbk1969 Ancient Guru

    Messages:
    10,801
    Likes Received:
    8,048
    GPU:
    GF RTX 2070 Super
    You do not need to specify "17" as array length with direct immediate initialization (when array does not need to grow). Compiler will count the number of intializers
    Code:
    eslist = new EventSource[17]
    {
    new EventSource(0,"WheaErrSrcTypeMCE = 0x00, Machine Check Exception"),
    new EventSource(1,"WheaErrSrcTypeCMC = 0x01, Corrected Machine Check"),
    new EventSource(2,"WheaErrSrcTypeCPE = 0x02, Corrected Platform Error"),
    new EventSource(3,"WheaErrSrcTypeNMI = 0x03, Non-Maskable Interrupt"),
    new EventSource(4,"WheaErrSrcTypePCIe = 0x04, PCI Express Error"),
    new EventSource(5,"WheaErrSrcTypeGeneric = 0x05, Other types of error sources"),
    new EventSource(6,"WheaErrSrcTypeINIT = 0x06, IA64 INIT Error Source"),
    new EventSource(7,"WheaErrSrcTypeBOOT = 0x07, BOOT Error Source"),
    new EventSource(8,"WheaErrSrcTypeSCIGeneric = 0x08, SCI-based generic error source"),
    new EventSource(9,"WheaErrSrcTypeIPFMCA = 0x09, Itanium Machine Check Abort"),
    new EventSource(10,"WheaErrSrcTypeIPFCMC = 0x0a, Itanium Machine check"),
    new EventSource(11,"WheaErrSrcTypeIPFCPE = 0x0b, Itanium Corrected Platform Error"),
    new EventSource(12,"WheaErrSrcTypeGenericV2 = 0x0c, Other types of error sources v2"),
    new EventSource(13,"WheaErrSrcTypeSCIGenericV2 = 0x0d, SCI-based GHESv2"),
    new EventSource(14,"WheaErrSrcTypeBMC = 0x0e, BMC error info"),
    new EventSource(15,"WheaErrSrcTypePMEM = 0x0f, ARS PMEM Error Source"),
    new EventSource(16,"WheaErrSrcTypeDeviceDriver = 0x10, Device Driver Error Source"),
    };
    
     
    mannix likes this.
  13. mbk1969

    mbk1969 Ancient Guru

    Messages:
    10,801
    Likes Received:
    8,048
    GPU:
    GF RTX 2070 Super
    You forgot to use logName and logSource in EventErr method.

    Code:
    public static void EventMsg(string msg)
    {
        eventLog2 = new EventLog();
        eventLog2.Source = logName;
        eventLog2.Log = logSource;
        eventLog2.WriteEntry(msg);
        Console.WriteLine("INFO " + msg);
    }
    
    public static void EventErr(string msg)
    {
        eventLog2 = new EventLog();
        eventLog2.Source = "WHEAService";
        eventLog2.Log = "WHEAServiceLog";
        eventLog2.WriteEntry(msg, EventLogEntryType.Error);
        Console.WriteLine("ERROR " + msg);
    }
    
    And why do you create eventLog2 with each call in these methods? You can check whether eventLog2 is null and then create it (one time).

    PS
    And in case of many fields to assign after the creation of object you can use this syntax:
    Code:
        eventLog2 = new EventLog()
        {
            Source = logName,
            Log = logSource
        };
    
    PPS
    Instead of concatenating the strings in Console.WriteLine you can do

    Code:
        Console.Write("INFO ");
        Console.WriteLine(msg)
    
    or
    Code:
        Console.WriteLine("INFO {0}", msg);
    
    or
    Code:
        Console.WriteLine($"INFO {msg}");
    
     
    Last edited: May 21, 2021
    mannix likes this.
  14. mbk1969

    mbk1969 Ancient Guru

    Messages:
    10,801
    Likes Received:
    8,048
    GPU:
    GF RTX 2070 Super
    In GetSourceInfo method you can save space
    Code:
    ...
    int Length;
    int Version;
    int TypeEs;
    int State;
    int MaxRawDataLength;
    int NumRecordsToPreallocate;
    int MaxSectionsPerRecord;
    int ErrorSourceId;
    int PlatformErrorSourceId;
    int Flags;
    byte[] Info;
    int InfoSeek;
    ...
    
    using (BinaryReader reader = new System.IO.BinaryReader(ms))
    {
        for (int i = 0; i < sCount; i++)
        {
            Length = reader.ReadInt32();
            InfoSeek = int.Parse(Length.ToString()) - 40;
            Version = reader.ReadInt32();
            TypeEs = reader.ReadInt32();
            State = reader.ReadInt32();
            MaxRawDataLength = reader.ReadInt32();
            NumRecordsToPreallocate = reader.ReadInt32();
            MaxSectionsPerRecord = reader.ReadInt32();
            ErrorSourceId = reader.ReadInt32();
            PlatformErrorSourceId = reader.ReadInt32();
            Flags = reader.ReadInt32();
            Info = reader.ReadBytes(InfoSeek);
    
    =>
    Code:
    using (BinaryReader reader = new System.IO.BinaryReader(ms))
    {
       for (int i = 0; i < sCount; i++)
       {
           int Length = reader.ReadInt32();
           int InfoSeek = int.Parse(Length.ToString()) - 40;
           int Version = reader.ReadInt32();
           int TypeEs = reader.ReadInt32();
           int State = reader.ReadInt32();
           int MaxRawDataLength = reader.ReadInt32();
           int NumRecordsToPreallocate = reader.ReadInt32();
           int MaxSectionsPerRecord = reader.ReadInt32();
           int ErrorSourceId = reader.ReadInt32();
           int PlatformErrorSourceId = reader.ReadInt32();
           int Flags = reader.ReadInt32();
           byte[] Info = reader.ReadBytes(InfoSeek);
    
    - declare the local variable right where it is intialized
     
    mannix likes this.
  15. Astyanax

    Astyanax Ancient Guru

    Messages:
    10,590
    Likes Received:
    3,877
    GPU:
    GTX 1080ti
    there is no such thing as fake errors,

    theres errors, or theres no errors.
    theres critical uncorrectable errors and there benign uncorrectable errors errors
     

  16. mannix

    mannix Active Member

    Messages:
    70
    Likes Received:
    17
    GPU:
    MSI GTX1070 ArmorOC
    thanks @mbk1969, I appreciate it!

    BTW I know there are other methods but I like to concatenate strings like that, feels more natural to me

    I may be wrong of course :p
    But benign uncorrectable errors I don't know... maybe more benign correctable errors
    So far running with these WHEA 19 flow in the background was a positive experience
    System is butter smooth and I don't have USB issues anymore
    But things could change...
     
  17. mbk1969

    mbk1969 Ancient Guru

    Messages:
    10,801
    Likes Received:
    8,048
    GPU:
    GF RTX 2070 Super
    Not on the memory side of things: each concatenation leads to new string allocation. It is ok to do so only outside of loops.
    And if you concatenate two strings the syntax is ok, but what if you want to insert 10 things into the string? Syntax would be silly.
     
  18. mannix

    mannix Active Member

    Messages:
    70
    Likes Received:
    17
    GPU:
    MSI GTX1070 ArmorOC
    Ah jeez... you are damn good, I'll have to change habits :p
     
    mbk1969 likes this.
  19. mbk1969

    mbk1969 Ancient Guru

    Messages:
    10,801
    Likes Received:
    8,048
    GPU:
    GF RTX 2070 Super
    Btw, why do use Console at all? It is not visible when used from a system service.
     
  20. mannix

    mannix Active Member

    Messages:
    70
    Likes Received:
    17
    GPU:
    MSI GTX1070 ArmorOC
    Cause of this in Program.cs:

    Code:
           static void Main()
            {
                #if (!DEBUG)
                            ServiceBase[] ServicesToRun;
                            ServicesToRun = new ServiceBase[]
                            {
                                new WHEAService()
                            };
                            ServiceBase.Run(ServicesToRun);
                #else
                            WHEAService myServ = new WHEAService();
                            myServ.StartDbg();
                #endif
            }
    I can run it in Debug mode directly from Visual Studio and watch the console output, otherwise I would have to change the registered service to the Debug binary and look at the event log
     

Share This Page