Re: [PATCH] sched: Further restrict the preemption modes

Ilya Leoshkevich
2026-02-25T02:30:35Z

On 2/24/26 16:45, Ciunas Bennett wrote:
>
>
> On 19/12/2025 10:15, Peter Zijlstra wrote:
>
>
> Hi Peter,
> We are observing a performance regression on s390 since enabling
> PREEMPT_LAZY.
> Test Environment
> Architecture: s390
> Setup:
>
> Single KVM host running two identical guests
> Guests are connected virtually via Open vSwitch
> Workload: uperf streaming read test with 50 parallel connections
> One guest acts as the uperf client, the other as the server
>
> Open vSwitch configuration:
>
> OVS bridge with two ports
> Guests attached via virtio‑net
> Each guest configured with 4 vhost‑queues
>
> Problem Description
> When comparing PREEMPT_LAZY against full PREEMPT, we see a substantial
> drop in throughput—on some systems up to 50%.
>
> Observed Behaviour
> By tracing packets inside Open vSwitch (ovs_do_execute_action), we see:
> Packet drops
> Retransmissions
> Reductions in packet size (from 64K down to 32K)
>
> Capturing traffic inside the VM and inspecting it in Wireshark shows
> the following TCP‑level differences between PREEMPT_FULL and
> PREEMPT_LAZY:
> |--------------------------------------+--------------+--------------+------------------|
>
> | Wireshark Warning / Note             | PREEMPT_FULL | PREEMPT_LAZY |
> (lazy vs full)   |
> |--------------------------------------+--------------+--------------+------------------|
>
> | D-SACK Sequence                      |          309 | 2603 |
> ×8.4             |
> | Partial Acknowledgement of a segment |           54 | 279 |
> ×5.2             |
> | Ambiguous ACK (Karn)                 |           32 | 747 |
> ×23              |
> | (Suspected) spurious retransmission  |          205 | 857 |
> ×4.2             |
> | (Suspected) fast retransmission      |           54 | 1622 |
> ×30              |
> | Duplicate ACK                        |          504 | 3446 |
> ×6.8             |
> | Packet length exceeds MSS (TSO/GRO)  |        13172 | 34790 |
> ×2.6             |
> | Previous segment(s) not captured     |         9205 | 6730 |
> -27%             |
> | ACKed segment that wasn't captured   |         7022 | 8272 |
> +18%             |
> | (Suspected) out-of-order segment     |          436 | 303 |
> -31%             |
> |--------------------------------------+--------------+--------------+------------------|
>
> This pattern indicates reordering, loss, or scheduling‑related delays,
> but it is still unclear why PREEMPT_LAZY is causing this behaviour in
> this workload.
>
> Additional observations:
>
> Monitoring the guest CPU run time shows that it drops from 16% with
> PREEMPT_FULL to 9% with PREEMPT_LAZY.
>
> The workload is dominated by voluntary preemption (schedule()), and
> PREEMPT_LAZY is, as far as I understand, mainly concerned with forced
> preemption.
> It is therefore not obvious why PREEMPT_LAZY has an impact here.
>
> Changing guest configuration to disable mergeable RX buffers:
>       <host mrg_rxbuf="off"/>
>       had a clear effect on throughput:
>       PREEMPT_LAZY: throughput improved from 40 Gb/s → 60 Gb/s

When I look at top sched_switch kstacks on s390 with this workload, 20%
of them are worker_thread() -> schedule(), both with CONFIG_PREEMPT and
CONFIG_PREEMPT_LAZY. The others are vhost and idle.

On x86 I see only vhost and idle, but not worker_thread().

According to runqlat.bt, average run queue latency goes up from 4us to
18us when switching from CONFIG_PREEMPT to CONFIG_PREEMPT_LAZY.

I modified the script to show per-comm latencies, and it shows
that worker_thread() is disproportionately penalized: the latency
increases from 2us to 60us!

For vhost it's better: 5us -> 2us, and for KVM it's better too: 8us -> 2us.

Finally, what is the worker doing? I looked at __queue_work() kstacks,
and they all come from irqfd_wakeup().

irqfd_wakeup() calls arch-specific kvm_arch_set_irq_inatomic(), which is
implemented on x86 and not implemented on s390.

This may explain why we on s390 are the first to see this.

Christian, do you think if it would make sense to
implement kvm_arch_set_irq_inatomic() on s390?