From fb83c2354b32c8a5f41cd87359b78cd4cabcca37 Mon Sep 17 00:00:00 2001 From: Andrii Sultanov Date: Thu, 9 Jul 2026 12:00:09 +0000 Subject: [PATCH] tools/ocaml/xb: Fix handling of requests with len = 0 for socket connections Without this fix, the backend would be stuck waiting on the zero-sized body until the next request comes in. Instead return the request immediately after reading the header, there's no need to wait for another call to .has_more_input and .input Reported-by: George Dunlap Link: https://lore.kernel.org/xen-devel/CAFLBxZaeTMcF4tcV45MJdCVx4A6qbzQdjKei_Quh_iLrtARVFA@mail.gmail.com/ Signed-off-by: Andrii Sultanov Reviewed-by: Guillaume Thouvenin Release-Acked-by: Oleksii Kurochko (cherry picked from commit 7b98d94e759b5ec54c7380d63287119b3712785d) --- tools/ocaml/libs/xb/xb.ml | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/tools/ocaml/libs/xb/xb.ml b/tools/ocaml/libs/xb/xb.ml index 3e3ef2b29d..12ddb05c6d 100644 --- a/tools/ocaml/libs/xb/xb.ml +++ b/tools/ocaml/libs/xb/xb.ml @@ -249,6 +249,11 @@ let can_input con = Queue.can_push con.pkt_out CommandReply (* NB: can throw Reconnect *) let input con = + let reset_and_return partial_pkt = + let pkt = Packet.of_partialpkt partial_pkt in + con.partial_in <- init_partial_in (); + Some pkt + in if not (can_input con) then None else let to_read = to_read con in @@ -264,17 +269,25 @@ let input con = if sz > 0 then Partial.append partial_pkt (Bytes.to_string b) sz; if Partial.to_complete partial_pkt = 0 then ( - let pkt = Packet.of_partialpkt partial_pkt in - con.partial_in <- init_partial_in (); - Some pkt + reset_and_return partial_pkt ) else None | NoHdr (i, buf) -> (* we complete the partial header *) if sz > 0 then Bytes.blit b 0 buf (Partial.header_size () - i) sz; - con.partial_in <- if sz = i then - HaveHdr (Partial.of_string (Bytes.to_string buf)) else NoHdr (i - sz, buf); - None + if sz = i then + let partial_pkt = Partial.of_string (Bytes.to_string buf) in + (* If there is no body, we can return the full request immediately *) + if Partial.to_complete partial_pkt = 0 then + reset_and_return partial_pkt + else ( + con.partial_in <- HaveHdr partial_pkt; + None + ) + else ( + con.partial_in <- NoHdr (i - sz, buf); + None + ) ) let classify t =