Page 1 of 2

Linux thread

Posted: 16 Oct 2025, 15:52
by agendarsky
sooo guys, sorry for that rmw post. turned out to be placebo. i was deep into ram tuning, trying different subtimings, and the fps boost on the 14700k just happened to line up with it. but fps are just fps — the core problem stayed.

so, back to the roots. i always return to the d875pbz, that board is my baseline. the one that never had the issue. i compare everything against it and move by elimination. i already ruled out ram behaviour, gpu power states, even pcie mapping. the only consistent difference left was in the chipset — the pch and how it changed everything once intel started merging functions into one chip.

the d875pbz was a clean design. agp slot, northbridge, southbridge, direct irq lines. predictable. the newer boards like i945gc brought acpi 2.0, the io-apic integrated into the chipset, and pci-e instead of agp. on paper it’s progress. in feel, it’s different.
some of you remember that on older Windows builds you could switch in Device Manager between ACPI Uniprocessor PC and Advanced Configuration and Power Interface (ACPI) PC. that wasn’t cosmetic — it changed how HAL routed interrupts. the uniprocessor HAL used simple static mapping, while the full ACPI HAL started sharing and dynamically assigning interrupts between devices. most of my boards from that time had half the system stacked on IRQ 16.
i tried to emulate that old static behaviour again. disabled Message Signaled Interrupts with

bcdedit /set msi ForceDisable

and also switched off MSI in BIOS. doesn’t really make logical sense, but input and that heavy car bug got noticeably better. not perfect, but more consistent.
at that point i had nothing left to try on Windows. i kept thinking — maybe the problem is deeper, maybe modern boards are just too dependent on ACPI tables. MADT, DSDT, FADT — those define device maps, irq routing, power domains, everything. they’re part of the firmware now. editing them by hand is technically possible, but a nightmare. one wrong offset or checksum and the board doesn’t boot. ACPI 2.0 added dynamic routing, power states, hotplug — and i think that’s when the system stopped being deterministic.

so i switched. installed Fedora with the Zen kernel just to see how far Linux gaming has come. tested CS2 on the RTX 4070 Super. fps were lower, around 450, dipping to 350 in 5v5, but the game stayed consistent. that got my attention but i moved to Arch based CachyOs
because i wanted full control over the kernel. The big things Linux allows you , is full control over a kernel and it comes with things disabling I/O-APIC and ACPI routing completely. my current GRUB looks like this:
nowatchdog nvme_load=YES zswap.enabled=0 splash loglevel=3 mitigations=off pcie_aspm=off processor.maxcstate=1 intel_idle.max_cstate=0 pcie_port_pm=off apm=off clk_ignore_unused clocksource=tsc tsc=perfect acpi=noirq noirqbalance nohz=off pci=noacpi noapic pnpbios=off

pcie_aspm=off and pcie_port_pm=off stop the link from retraining mid-load. maxcstate=1 and intel_idle.max_cstate=0 keep cores awake. clocksource=tsc tsc=perfect locks the kernel timer to cpu tsc — no interpolation. acpi=noirq pci=noacpi noapic cut the system off from the firmware’s irq routing, reverting to old PIC-style static interrupts. noirqbalance freezes them in place, so kernel can’t shuffle them around.
PIC-style basically means how interrupts worked before APIC even existed. back in the 90s every device line was hardwired to one of 15 interrupt numbers on a small chip called the Programmable Interrupt Controller (Intel 8259). there was no dynamic balancing, no tables, nothing smart — each device fired its signal directly and the cpu handled it in the same strict order every time. it wasn’t scalable, but it was deterministic.
when APIC came, Intel replaced that simple 8259 logic with a two-layer system: IO-APIC inside the chipset and LAPIC on each core. the IO-APIC collects external device interrupts, translates them into vectors, and sends them to LAPICs over the system bus. LAPICs then deliver them to the cores. that design gave us more IRQs and multicore support, but it also added one more layer of logic between the device and the cpu.
so when you disable IO-APIC and ACPI routing, the kernel falls back to that old PIC mode — every device gets a fixed line, nothing gets remapped, and interrupts go straight to the CPU through LAPIC’s compatibility mode. it’s less “smart,” but there’s no dynamic firmware in the middle deciding where to send each signal. that’s why it feels steadier. LAPIC can still do its own job — handle MSI, timers, per-core stuff — without being told by the chipset how to distribute external events.
in other words, you strip the system down to the bare electrical path: device → lapic → core. no acpi tables, no io-apic translations.
so yeah, a few people asked how the system even boots if i kill acpi like that. the thing is, it doesn’t completely disappear. when you use acpi=noirq pci=noacpi noapic, you’re not removing acpi as a whole — you’re just cutting off the part that handles interrupt routing and pci mapping. the rest of it (like basic cpu info, power tables, thermal zones) still exists, it just stops controlling irq logic.
when linux boots in that state, it falls back to legacy 8259 PIC mode or what’s called lapic compatibility mode. the old MP tables (MultiProcessor spec tables) inside the bios kick in before the kernel even starts, and those define the minimal irq layout — basically a backup routing map that existed before acpi took over. it’s not smart, but it’s enough.
so the chain looks like this: bios posts → fills those old mp or pci routing tables → kernel reads them → sets up 15 fixed irq lines → newer devices that support msi talk straight to the lapic, bypassing all that old chipset routing.
so you end up with a hybrid setup. stuff like sata or some usb controllers go through the old pic style fixed irqs, but gpu, nvme, soundcard, those send interrupts as messages straight to lapic. that’s why it still boots and works fine. the firmware still provides the minimal mapping, linux just ignores the fancy acpi layer and does it the old deterministic way.
basically, i cut the “brain” but kept the “wires”. bios and the kernel handle it like it’s 2003 again — fewer layers, less guessing, and no firmware trying to optimize what doesn’t need optimizing. I don't want to promote any fix but i would love to see more people trying this combo. Stop being lazy or scared of Linux , no one will fix it for you , every post about magical "scaling " trick is bullshit.
AND now the very interesting thing i found is this post from 2009 https://forums.virtualbox.org/viewtopic.php?t=21480 he literally says " After installing Windows 7 I noticed that IO APIC was enabled. This is known to cause slowdown etc. I believe that it has been causing problems with my system (slow mouse response, window interaction, etc).
I was able to force it to be disabled on my guest and the system seems to be much more responsive at this point." Sadly u cant do that on win10/win11 anymore. But if you dont mind about faceit or some games with strict kernel anti-cheat trust me, you won't miss a Windows and you can still use dual boot. Oh , and there is my little fps bench , cachy vs 25h2.https://www.youtube.com/watch?v=u-zVidz9DRM thoose 1% lows are super high if you consider its fucking raptor lake cpu. Rtx was fine but amd drivers are super-b on linux and often match or beat Windows performance in games that have vulkan support or native linux build (but proton is fucking awesome too, for example Mafia Definitive Edition runs through proton and i have few more fps on Linux than on Windows ). So .... yeah, fiddling in device manager wont help you , Linux can be our saviour and if its not , the control you get is making him best OS to test low level hardware control.

Re: I/O Apic off / Lapic on - Only possible on linux

Posted: 16 Oct 2025, 19:43
by Hyote
Very cool post, I'm going to try it later.

Re: I/O Apic off / Lapic on - Only possible on linux

Posted: 16 Oct 2025, 20:41
by ablemor
Hello, please check and answer yt comments, thank you!

Re: I/O Apic off / Lapic on - Only possible on linux

Posted: 17 Oct 2025, 00:32
by Hyote
noirqbalance doesn't do anything

I updated this list with a few other settings:
GRUB_CMDLINE_LINUX_DEFAULT="nowatchdog nvme_load=YES zswap.enabled=0 splash loglevel=3 mitigations=off pcie_aspm=off processor.maxcstate=1 isolcpus=0 rcu_nocbs=0 intel_idle.max_cstate=0 intel_pstate=disable pcie_port_pm=off apm=off clk_ignore_unused clocksource=tsc tsc=perfect acpi=noirq nohz=off pci=noacpi noapic pnpbios=off"

Also a few more because no one asked:

sudo find /sys/devices/system/cpu -name scaling_governor -exec sh -c 'echo performance > {}' ';'

sudo sysctl -w net.ipv4.tcp_low_latency=1

sudo find /sys/devices/virtual/workqueue -name cpumask -exec sh -c 'echo 1 > {}' ';'

sudo sysctl vm.stat_interval=120

sudo swapoff -a

echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag

sudo sysctl -w vm.nr_hugepages=0

echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

echo 'on' | sudo tee /sys/bus/usb/devices/*/power/control

echo performance | sudo tee /sys/bus/pci/devices/*/power/control

echo -1 | sudo tee /sys/module/usbcore/parameters/autosuspend

echo max_performance | sudo tee /sys/class/scsi_host/host*/link_power_management_policy

Re: I/O Apic off / Lapic on - Only possible on linux

Posted: 19 Oct 2025, 03:05
by agendarsky
thanks for sharing
testing more

GRUB_CMDLINE_LINUX_DEFAULT='nowatchdog nvme_load=YES zswap.enabled=0 splash loglevel=3 mitigations=off clk_ignore_unused clocksource=tsc tsc=perfect processor.maxcstate=1 x2apic_phys intel_idle.max_cstate=0 apm=off nohz=off pci=notph,ecrc=off,pcie_port_pm=off,pcie_bus_tune_off writecombine=off acpi_irq_nobalance'
there is a list of kernel options:
https://www.kernel.org/doc/Documentatio ... meters.txt
be aware of syntax
Everything that belongs to the same subsystem (like PCI) stays after one single pci= and each option inside that group is separated by commas with no spaces. When you move to another subsystem or flag, you break the chain with a space. Commas mean “same family,” spaces mean “new family.” Leaving a comma at the end makes the kernel read the next part as part of the previous group, so never end with one.

guys, the great thing about Linux is , it let us strip things that motherboard offers and u cant disable it in windows, bios or is not present in hidden bios too. Actually im now fully convicted that it works better for benching " that broken feel that we cant measure" , timing or whatever you call it, dual boot only for scewin

Re: Linux thread

Posted: 19 Oct 2025, 11:23
by agendarsky
GRUB_CMDLINE_LINUX_DEFAULT="nowatchdog nvme_load=YES zswap.enabled=0 loglevel=3 mitigations=off \
clk_ignore_unused clocksource=tsc processor.max_cstate=1 \
tsc=nowatchdog tsc=reliable x2apic intel_idle.max_cstate=0 apm=off nohz=off \
pci=ecrc=off,pcie_port_pm=off,aspm=off,nocrs,skip_isa_align,realloc=on,pm_async=off,nobar,pcie_ports=compat,pcie_bus_safe,norom,noaer,conf1,nobios \
writecombine=on lapic lapic=notscdeadline hpet=disable cpuidle.off=1 no_timer_check nospectre_bhb nospectre_v1 nospectre_v2 nosgx"

i've been experimenting with more settings, especially related to pci-e. can u try thoose?

ecrc=off disables packet-level CRC checking. / no PCIe layer error correction, slightly less overhead.
pcie_port_pm=off disables PCIe port power management. / ports never enter low-power states, link stays awake.
aspm=off disables Active State Power Management. / removes latency spikes from power transitions.
nocrs ignores ACPI _CRS resource tables. / kernel maps PCI space itself instead of trusting firmware.
skip_isa_align skips legacy I/O address alignment. / tighter and cleaner resource layout, no old ISA padding.
realloc=on allows kernel to reassign PCI address space. / fixes any broken BIOS resource allocations.
pm_async=off disables asynchronous device power-up. / all PCI devices initialize sequentially, deterministic order.
nobar stops kernel from reassigning BAR registers. / keeps memory regions exactly as BIOS configured.
pcie_ports=compat forces legacy PCIe port mode. / disables advanced hotplug and service features.
pcie_bus_safe sets all devices to smallest shared MPS (aka maximum payload size u can find in bios). / slightly lower throughput, but more consistent DMA timing. <- this one is really interesting , theoretically prevents race condition on pci-e lanes
norom skips mapping unused expansion ROMs. / avoids extra MMIO clutter and potential address conflicts.
noaer disables Advanced Error Reporting. / prevents kernel from logging or handling PCIe error interrupts.
conf1 forces Configuration Access Mechanism 1. / uses classic I/O ports (0xCF8/0xCFC) for PCI config access.
nobios disables PCI BIOS calls. / kernel interacts directly with hardware, no firmware mediation.

+ more spectre mitigations disabled / i'm not sure if mitigations=off handles them all , so just in case.

Re: Linux thread

Posted: 19 Oct 2025, 12:40
by Hyote
agendarsky wrote:
19 Oct 2025, 11:23
GRUB_CMDLINE_LINUX_DEFAULT="nowatchdog nvme_load=YES zswap.enabled=0 loglevel=3 mitigations=off \
clk_ignore_unused clocksource=tsc processor.max_cstate=1 \
tsc=nowatchdog tsc=reliable x2apic intel_idle.max_cstate=0 apm=off nohz=off \
pci=ecrc=off,pcie_port_pm=off,aspm=off,nocrs,skip_isa_align,realloc=on,pm_async=off,nobar,pcie_ports=compat,pcie_bus_safe,norom,noaer,conf1,nobios \
writecombine=on lapic lapic=notscdeadline hpet=disable cpuidle.off=1 no_timer_check nospectre_bhb nospectre_v1 nospectre_v2 nosgx"

i've been experimenting with more settings, especially related to pci-e. can u try thoose?

ecrc=off disables packet-level CRC checking. / no PCIe layer error correction, slightly less overhead.
pcie_port_pm=off disables PCIe port power management. / ports never enter low-power states, link stays awake.
aspm=off disables Active State Power Management. / removes latency spikes from power transitions.
nocrs ignores ACPI _CRS resource tables. / kernel maps PCI space itself instead of trusting firmware.
skip_isa_align skips legacy I/O address alignment. / tighter and cleaner resource layout, no old ISA padding.
realloc=on allows kernel to reassign PCI address space. / fixes any broken BIOS resource allocations.
pm_async=off disables asynchronous device power-up. / all PCI devices initialize sequentially, deterministic order.
nobar stops kernel from reassigning BAR registers. / keeps memory regions exactly as BIOS configured.
pcie_ports=compat forces legacy PCIe port mode. / disables advanced hotplug and service features.
pcie_bus_safe sets all devices to smallest shared MPS (aka maximum payload size u can find in bios). / slightly lower throughput, but more consistent DMA timing. <- this one is really interesting , theoretically prevents race condition on pci-e lanes
norom skips mapping unused expansion ROMs. / avoids extra MMIO clutter and potential address conflicts.
noaer disables Advanced Error Reporting. / prevents kernel from logging or handling PCIe error interrupts.
conf1 forces Configuration Access Mechanism 1. / uses classic I/O ports (0xCF8/0xCFC) for PCI config access.
nobios disables PCI BIOS calls. / kernel interacts directly with hardware, no firmware mediation.

+ more spectre mitigations disabled / i'm not sure if mitigations=off handles them all , so just in case.
I'm going to try them soon. Unfortunately Linux kind of shits itself after a few days on my PC and everything becomes laggy.

Re: Linux thread

Posted: 19 Oct 2025, 15:42
by agendarsky
https://www.youtube.com/watch?v=C7LMA2L_1Ks my system is super reactive atm, very enjoyable to play and browse , however my fps are reduced, gonna be testing more but it takes much time because usually i do one or two settings -reboot-> play a little dm to see how it feels and how render looks + fps map bench and casually checking lsirq for conflicts (most of mine devices are in msi-x atm)

Re: Linux thread

Posted: 20 Oct 2025, 09:49
by kosmicSeven
Hyote wrote:
19 Oct 2025, 12:40
agendarsky wrote:
19 Oct 2025, 11:23
GRUB_CMDLINE_LINUX_DEFAULT="nowatchdog nvme_load=YES zswap.enabled=0 loglevel=3 mitigations=off \
clk_ignore_unused clocksource=tsc processor.max_cstate=1 \
tsc=nowatchdog tsc=reliable x2apic intel_idle.max_cstate=0 apm=off nohz=off \
pci=ecrc=off,pcie_port_pm=off,aspm=off,nocrs,skip_isa_align,realloc=on,pm_async=off,nobar,pcie_ports=compat,pcie_bus_safe,norom,noaer,conf1,nobios \
writecombine=on lapic lapic=notscdeadline hpet=disable cpuidle.off=1 no_timer_check nospectre_bhb nospectre_v1 nospectre_v2 nosgx"

i've been experimenting with more settings, especially related to pci-e. can u try thoose?

ecrc=off disables packet-level CRC checking. / no PCIe layer error correction, slightly less overhead.
pcie_port_pm=off disables PCIe port power management. / ports never enter low-power states, link stays awake.
aspm=off disables Active State Power Management. / removes latency spikes from power transitions.
nocrs ignores ACPI _CRS resource tables. / kernel maps PCI space itself instead of trusting firmware.
skip_isa_align skips legacy I/O address alignment. / tighter and cleaner resource layout, no old ISA padding.
realloc=on allows kernel to reassign PCI address space. / fixes any broken BIOS resource allocations.
pm_async=off disables asynchronous device power-up. / all PCI devices initialize sequentially, deterministic order.
nobar stops kernel from reassigning BAR registers. / keeps memory regions exactly as BIOS configured.
pcie_ports=compat forces legacy PCIe port mode. / disables advanced hotplug and service features.
pcie_bus_safe sets all devices to smallest shared MPS (aka maximum payload size u can find in bios). / slightly lower throughput, but more consistent DMA timing. <- this one is really interesting , theoretically prevents race condition on pci-e lanes
norom skips mapping unused expansion ROMs. / avoids extra MMIO clutter and potential address conflicts.
noaer disables Advanced Error Reporting. / prevents kernel from logging or handling PCIe error interrupts.
conf1 forces Configuration Access Mechanism 1. / uses classic I/O ports (0xCF8/0xCFC) for PCI config access.
nobios disables PCI BIOS calls. / kernel interacts directly with hardware, no firmware mediation.

+ more spectre mitigations disabled / i'm not sure if mitigations=off handles them all , so just in case.
I'm going to try them soon. Unfortunately Linux kind of shits itself after a few days on my PC and everything becomes laggy.
Hey Hyote,

I’ve been following your posts closely while dialing in my 600Hz monitor/setup (RTX 4090, 9800X3D, 2×32GB 6000MHz CL30, Intel P5801X, OP1 8K, Wooting 60HE). I might’ve found something worth sharing.

Restarting DWM has always given me an instant bump in responsiveness input feels snappier, frametimes feel smoother but that effect fades as DWM's memory usage climbs. Without intervention, it typically grows to 500–800MB, and things start to feel sluggish again.

Using System Informer, I started experimenting with keeping DWM’s memory usage low. The trick: regularly flush the compositor and trim its working set. Keeping both around ~100MB preserves that fresh, just restarted feel indefinitely. Frame jitter and animation inconsistencies are noticeably reduced.

I’m no developer, just a power user, so this could probably be done cleaner but I’ve been running two simple tools:
  • One flushes DWM’s buffer (keeps private bytes low)
  • One trims its working set (RAM usage)
It may sound like placebo, but after 6 months of scripting DWM restarts every 30 minutes to deal with creeping latency, I feel pretty confident this is doing something real.

Here's the code and how to compile it yourself into an exe if you want to try it (There are no install dependencies. Native windows CMD should be able to create an exe for you by running this command)

Run EXE as admin and change priority to realtime and I/O Priority to high.

Name file FlushDWM.cs this reduce private bytes

Place script in C:\FM or create your own (Forum can't post url it is microsoft(dot)net)
"%WINDIR%\Microsoft^NET\Framework64\v4.0.30319\csc.exe" /nologo /platform:x64 ^
/target:exe /r:System.dll ^
/out:"C:\FM\FlushDWM.exe" "C:\FM\FlushDWM.cs"

Code: Select all

using System;
using System.Runtime.InteropServices;
using System.Threading;

static class Program
{
    [DllImport("dwmapi.dll")] static extern int DwmFlush();

    // Optional: keep a single instance
    static Mutex _mx;

    static int _intervalSec = 3;   // default cadence
    static int _bursts = 3;         // call DwmFlush() this many times each tick

    static void Main(string[] args)
    {
        ParseArgs(args);

        bool created = false;
        _mx = new Mutex(true, "FlushDWM_SingleInstance", out created);
        if (!created) return; // already running

        // Headless timer (no message pump, no windows)
        using (var timer = new System.Threading.Timer(Tick, null,
                   _intervalSec * 1000, _intervalSec * 1000))
        {
            // Keep the process alive forever
            Thread.Sleep(Timeout.Infinite);
        }
    }

    static void Tick(object _)
    {
        // Minimal “touch”: just call DwmFlush a few times
        for (int i = 0; i < _bursts; i++)
        {
            try { DwmFlush(); } catch { }
            // tiny yield so we don't hog a core if bursts>1
            Thread.Sleep(1);
        }
    }

    static void ParseArgs(string[] args)
    {
        foreach (var a in args)
        {
            var kv = a.Split(new[] { '=' }, 2);
            if (kv.Length == 2)
            {
                if (kv[0].Equals("/intervalSec", StringComparison.OrdinalIgnoreCase))
                {
                    int s; if (int.TryParse(kv[1], out s) && s > 0) _intervalSec = s;
                }
                else if (kv[0].Equals("/bursts", StringComparison.OrdinalIgnoreCase))
                {
                    int b; if (int.TryParse(kv[1], out b) && b > 0) _bursts = b;
                }
            }
        }
    }
}
Name file WSetDWM.cs this reduces the working set

Place script in C:\FM or create your own
"%WINDIR%\Microsoft^NET\Framework64\v4.0.30319\csc.exe" /nologo /platform:x64 ^
/target:exe /r:System.dll ^
/out:"C:\FM\WSetDWM.exe" "C:\FM\WSetDWM.cs"

Code: Select all

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

static class Program
{
    [DllImport("dwmapi.dll")] static extern int DwmFlush();
    [DllImport("psapi.dll")]  static extern bool EmptyWorkingSet(IntPtr hProcess);

    // single instance
    static Mutex _mx;

    // fixed cadence + knobs for how hard to nudge
    const int IntervalSec  = 1;  // always every 1s
    const int FlushBursts  = 3;  // DwmFlush calls per tick
    const int TrimBursts   = 1;  // EmptyWorkingSet calls per tick
    const int YieldMs      = 1;  // tiny sleep between calls

    static void Main(string[] args)
    {
        bool created;
        _mx = new Mutex(true, "FlushDWM_Always1s_v1", out created);
        if (!created) return;

        using (var timer = new System.Threading.Timer(Tick, null, IntervalSec*1000, IntervalSec*1000))
        {
            Thread.Sleep(Timeout.Infinite);
        }
    }

    static void Tick(object _)
    {
        // 1) Gentle compositor flushes
        for (int i = 0; i < FlushBursts; i++)
        {
            try { DwmFlush(); } catch { }
            if (YieldMs > 0) Thread.Sleep(YieldMs);
        }

        // 2) Always trim the DWM working set (no size check)
        try
        {
            var procs = Process.GetProcessesByName("dwm");
            if (procs != null && procs.Length > 0)
            {
                Process p = null;
                int curSession = Process.GetCurrentProcess().SessionId;
                foreach (var cand in procs) { if (cand.SessionId == curSession) { p = cand; break; } }
                if (p == null) p = procs[0];

                for (int i = 0; i < TrimBursts; i++)
                {
                    try { EmptyWorkingSet(p.Handle); } catch { }
                    if (YieldMs > 0) Thread.Sleep(YieldMs);
                }
            }
        }
        catch { /* ignore */ }
    }
}

Re: Linux thread

Posted: 20 Oct 2025, 15:30
by ablemor
Don't look for the solution on Linux, it's completely unnecessary.
If u have floaty mouse, etc, then its EMI/RFI, bad grounding, and return noise from neutral wire