Code change:
I see that the custom CPU scheduler, zen's main feature is disabled: This raises a question: does nixpkgs' zen actually differs from the default kernel or nixpkgs disables all the customizations by applying the same config as to the default kernel? Moreover, nixpkgs provides the -lqx variant with the same config but the main difference between -zen and -lqx variants is the config: liquorix provides a pre-defined config with its Debian/Arch packages and when I see lqx in the repos, I expect nixpkgs to use it as well as there's no source code difference. The -lqx variant seem to be poorly maintained in nixpkgs in general, it lags behind -zen variant (6.4.1 vs 6.3.11 in current nixos-unstable). Steps to reproduce the behavior: -zen should have its features enabled more or less, the -lqx variant MUST use (and probably be available only for x86_64). See the for example. Would be nice to have variants with different schedulers like the AUR package allows, preferably pre-built on Hydra (well, I don't have a powerful enough hardware to build kernels).
It might be a good idea to also have a xanmod variant built with .
I created a PR that should fix this: I took a look at the Arch config for -zen and it looks like it is basically the vanilla kernel with and some tweaks to the RCU/Preempt/tick. So this is what I did above. For the -lqx variation, I activated the PDS process scheduler, BBR2 and other tricks that seems to make Liquorix kernel (according to the site: ). This is not exactly true, the release of the -lqx variant generally lags between major kernel releases, so while -zen gets to X.Y.Z, -lqx will stay in X.Y-1.Z for some weeks (I imagine for stability purposes, but I am not familiar with upstream). This will be difficult, because we can't simply take its configuration as-is. If the current approach in the PR above is not acceptable, I would say it is better to just remove the -lqx from nixpkgs. We already don't seem to have that many users of the current variants considering you're the first person to note that we are compiling the packages without the customizations. So unless there is really a strong demand I would say let's not do so and just keep 2 variations of this kernel that should be enough for most users.
It's acceptable as a first step but why can't we?
I guess only the minority checks actually? I periodically see in Arch groups how people try -zen thinking they get all the features for better responsiveness but don't see a difference and don't even think about checking what scheduler they run actually.
It would be really difficult to use upstream configuration as-is. I mean, I don't think it is impossible, but I definitely don't want to be the person to do so. What I mean is mostly that I don't think most people care anyway. Even users of those custom kernels doesn't seems to care too much if they're actually using a custom scheduler it seems, considering again you're the first person to note this issue and this kernel is in nixpkgs for a long time already. So considering that nobody is that interested in the first place I think adding another variation of those kernels is too much. We definitely can do in the future if there is enough people that wants those though.
What I mean is they do care, it's just they don't know how to check. They see -zen and believe they get all the features out of the box.

Related discussion:
text: inherit sha256; }; <ins> # This is based on the following sources: # - zen: https://gitlab.archlinux.org/archlinux/packaging/packages/linux-zen/-/blob/main/config # - lqx: https://github.com/damentz/liquorix-package/blob/6.4/master/linux-liquorix/debian/config/kernelarch-x86/config-arch-64 # - Liquorix features: https://liquorix.net/ # The list below is not exhaustive, so the kernels probably doesn't match # the upstream, but should bring most of the improvements that will be # expected by users structuredExtraConfig = with lib.kernel; { # Zen Interactive tuning ZEN_INTERACTIVE = yes; # FQ-Codel Packet Scheduling NET_SCH_DEFAULT = yes; DEFAULT_FQ_CODEL = yes; DEFAULT_NET_SCH = freeform "fq_codel"; # Preempt (low-latency) PREEMPT = lib.mkOverride 60 yes; PREEMPT_VOLUNTARY = lib.mkOverride 60 no; # Preemptible tree-based hierarchical RCU TREE_RCU = yes; PREEMPT_RCU = yes; RCU_EXPERT = yes; TREE_SRCU = yes; TASKS_RCU_GENERIC = yes; TASKS_RCU = yes; TASKS_RUDE_RCU = yes; TASKS_TRACE_RCU = yes; RCU_STALL_COMMON = yes; RCU_NEED_SEGCBLIST = yes; RCU_FANOUT = freeform "64"; RCU_FANOUT_LEAF = freeform "16"; RCU_BOOST = yes; RCU_BOOST_DELAY = freeform "500"; RCU_NOCB_CPU = yes; RCU_LAZY = yes; # Futex WAIT_MULTIPLE implementation for Wine / Proton Fsync. FUTEX = yes; FUTEX_PI = yes; # Preemptive Full Tickless Kernel at 1000Hz HZ = freeform "1000"; HZ_1000 = yes; } // lib.optionalAttrs (isLqx) { # Google's BBRv2 TCP congestion Control TCP_CONG_BBR2 = yes; DEFAULT_BBR2 = yes; DEFAULT_TCP_CONG = freeform "bbr2"; # PDS Process Scheduler SCHED_ALT = yes; SCHED_PDS = yes; # Swap storage is compressed with LZ4 using zswap ZSWAP_COMPRESSOR_DEFAULT_LZ4 = yes; ZSWAP_COMPRESSOR_DEFAULT = freeform "lz4"; # Fix error: unused option: XXX. CFS_BANDWIDTH = lib.mkForce (option no); PSI = lib.mkForce (option no); RT_GROUP_SCHED = lib.mkForce (option no); SCHED_AUTOGROUP = lib.mkForce (option no); SCHED_CORE = lib.mkForce (option no); # ERROR: modpost: "sched_numa_hop_mask" [drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko] undefined! MLX5_CORE = no; }; </ins> passthru.updateScript = [ ./update-zen.py (if isLqx then "lqx" else "zen") ]; extraMeta = { branch = lib.versions.majorMinor version + "/master"; <del> maintainers = with lib.maintainers; [ ]; </del> <ins> maintainers = with lib.maintainers; [ thiagokokada ]; </ins> description = "Built using the best configuration and kernel sources for desktop, multimedia, and gaming workloads." + <del> lib.optionalString isLqx " (Same as linux_zen but less aggressive release schedule)"; </del> <ins> lib.optionalString isLqx " (Same as linux_zen, but less aggressive release schedule and additional extra config)"; broken = stdenv.isAarch64; </ins> }; } // (args.argsOverride or { }));