# Per-process hardware prefetcher control for Linux (x86 / Intel)

Adds `/proc/<pid>/prefetch_disable/` — per-task control of the four Intel
hardware prefetchers via `MSR_MISC_FEATURE_CONTROL` (0x1A4), applied at context
switch, OR'd across SMT siblings, and per-core cached so it costs nothing when
idle. Written for performance and cache side-channel experiments; see
https://adamdeprince.com/blog/posts/what-if-the-prefetcher-is-wrong-for-my-code/

## Contents
- `0001-x86-prefetch-*.patch` — the kernel patch (base: Linux v7.3-rc1, commit 88405f0)
- `prefetchctl.c` — small userspace helper (show / enable / disable / exec)

## Apply and build
    git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
    cd linux && git checkout v7.3-rc1
    git am /path/to/0001-x86-prefetch-*.patch      # or: patch -p1 < ...
    ./scripts/config --enable X86_PREFETCH_CTL       # (default y under Processor type and features)
    make -j"$(nproc)" && sudo make modules_install install
    # reboot into the new kernel; confirm with:
    dmesg | grep prefetch_ctl                        # "... enabled (MSR 0x1a4, per-core cached)"

## Flip the switches (1 = that prefetcher disabled, 0 = enabled)
    echo 1 > /proc/self/prefetch_disable/l2_stream   # disable, this process only
    echo 0 > /proc/self/prefetch_disable/l2_stream   # re-enable
    grep . /proc/<pid>/prefetch_disable/*            # read another process (needs ptrace perms)

    gcc -O2 -o prefetchctl prefetchctl.c
    ./prefetchctl show
    ./prefetchctl disable l2_stream <pid>
    ./prefetchctl exec l2_stream,l1_ip -- ./mybench  # run a benchmark with those off

## The four knobs
| file          | prefetcher                                   |
|---------------|----------------------------------------------|
| `l2_stream`   | L2 hardware stream prefetcher                |
| `l2_adjacent` | L2 adjacent cache-line (128-byte pair)       |
| `l1_stream`   | L1 data-cache next-line (DCU)                |
| `l1_ip`       | L1 data-cache IP-history (DCU)               |

## Notes
- Intel only; probed at boot. On unsupported hardware writes return -ENODEV.
- Per-thread; NOT inherited across fork; preserved across exec (so
  `prefetchctl exec ... -- cmd` carries the mask into the benchmark).
- MSR 0x1A4 is core-scoped: a prefetcher is off on the core if EITHER SMT
  sibling asks for it off.
