Our performance testing shows that batch sizes of 8 or 16 introduce stability fluctuations and higher CPU overhead, whereas a size of 32 delivers optimal, stable throughput.
Per NDIS architectural guidelines and driver best practices, a range of 32 to 64 is considered the optimal sweet spot for balancing framework overhead against system latency, making 32 our ideal baseline.
On 17/09/2026 17:43, david ambu wrote:
> Raise NblBatchMax default to 32 (max 64). Split batches at
> EtherType boundaries and set NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE per
> batch. Fix __ReceiverPushPackets: move KeMemoryBarrier before Returned/
> Indicated reads, and return early when queue is empty.
>
> Signed-off-by: david ambu <david.preetham@xxxxxxxxxx>
> ---
> src/xennet.inf | 6 +++
> src/xennet/adapter.c | 13 +++++
> src/xennet/adapter.h | 8 ++++
> src/xennet/receiver.c | 108 +++++++++++++++++++++++++++++++-----------
> 4 files changed, 108 insertions(+), 27 deletions(-)
>
> diff --git a/src/xennet.inf b/src/xennet.inf
> index 55e11a2..79730e8 100644
> --- a/src/xennet.inf
> +++ b/src/xennet.inf
> @@ -186,6 +186,11 @@ HKR, Ndi\params\*NumRSSQueues, Default, 0, "8"
> HKR, Ndi\params\*NumRSSQueues, Min, 0, "1"
> HKR, Ndi\params\*NumRSSQueues, Max, 0, "8"
>
> +HKR, Ndi\Params\NblBatchMax, ParamDesc, 0, %NblBatchMax%
> +HKR, Ndi\Params\NblBatchMax, Type, 0, "int"
> +HKR, Ndi\Params\NblBatchMax, Default, 0, "32"
> +HKR, Ndi\Params\NblBatchMax, Min, 0, "1"
> +HKR, Ndi\Params\NblBatchMax, Max, 0, "64"
> [XenNet_Inst.Services]
> AddService=xennet,0x02,XenNet_Service,XenNet_EventLog
>
> @@ -248,6 +253,7 @@ Enabled="Enabled"
> Enabled-Rx="Rx Enabled"
> Enabled-Tx="Tx Enabled"
> Enabled-TxRx="Rx & Tx Enabled"
> +NblBatchMax="Max Receive Indicate NBLS"
>
> SERVICE_BOOT_START=0x0
> SERVICE_SYSTEM_START=0x1
> diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c
> index f79c0c8..6e5a95a 100644
> --- a/src/xennet/adapter.c
> +++ b/src/xennet/adapter.c
> @@ -63,6 +63,7 @@ typedef struct _PROPERTIES {
> int lrov6;
> int rss;
> int numrssqueues;
> + int nblbatchmax;
> } PROPERTIES, *PPROPERTIES;
>
> typedef struct _XENNET_RSS {
> @@ -1480,6 +1481,17 @@ AdapterGetHandle(
> return Adapter->NdisAdapterHandle;
> }
>
> +ULONG
> +AdapterGetNblMaxBatchSize(
> + IN PXENNET_ADAPTER Adapter
> + )
> +{
> + ULONG val = (ULONG)Adapter->Properties.nblbatchmax;
> + if (val == 0 || val > NBL_BATCH_SIZE_MAX)
> + return NBL_BATCH_SIZE_DEFAULT;
> + return val;
> +}
> +
> PXENVIF_VIF_INTERFACE
> AdapterGetVifInterface(
> IN PXENNET_ADAPTER Adapter
> @@ -2939,6 +2951,7 @@ AdapterGetAdvancedSettings(
> READ_PROPERTY(Adapter->Properties.need_csum_value, L"NeedChecksumValue", 1, Handle);
> READ_PROPERTY(Adapter->Properties.rss, L"*RSS", 1, Handle);
> READ_PROPERTY(Adapter->Properties.numrssqueues, L"*NumRSSQueues", 8, Handle);
> + READ_PROPERTY(Adapter->Properties.nblbatchmax, L"NblBatchMax", NBL_BATCH_SIZE_DEFAULT, Handle);
>
> NdisCloseConfiguration(Handle);
>
> diff --git a/src/xennet/adapter.h b/src/xennet/adapter.h
> index 2ea0345..a54cb4d 100644
> --- a/src/xennet/adapter.h
> +++ b/src/xennet/adapter.h
> @@ -121,4 +121,12 @@ AdapterQueryInformation(
> IN PNDIS_OID_REQUEST Request
> );
>
> +#define NBL_BATCH_SIZE_DEFAULT 32
> +#define NBL_BATCH_SIZE_MAX 64
Is there a method to know what's the ideal NBL batching size?
--
Ngoc Tu Dinh | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web:
https://vates.tech