Module Name: src Committed By: nonaka Date: Wed Mar 20 13:34:51 UTC 2019
Modified Files: src/sys/arch/x86/pci: if_vmx.c Log Message: PR/54058: vmx(4): Fix device enable command failure when the number of vCPUs is not a power of two. Make the size of the vmx(4) TX/RX queue a power of two not exceeding the number of vCPUs. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/sys/arch/x86/pci/if_vmx.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/pci/if_vmx.c diff -u src/sys/arch/x86/pci/if_vmx.c:1.26 src/sys/arch/x86/pci/if_vmx.c:1.27 --- src/sys/arch/x86/pci/if_vmx.c:1.26 Tue Jun 26 06:48:00 2018 +++ src/sys/arch/x86/pci/if_vmx.c Wed Mar 20 13:34:51 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_vmx.c,v 1.26 2018/06/26 06:48:00 msaitoh Exp $ */ +/* $NetBSD: if_vmx.c,v 1.27 2019/03/20 13:34:51 nonaka Exp $ */ /* $OpenBSD: if_vmx.c,v 1.16 2014/01/22 06:04:17 brad Exp $ */ /* @@ -19,7 +19,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_vmx.c,v 1.26 2018/06/26 06:48:00 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_vmx.c,v 1.27 2019/03/20 13:34:51 nonaka Exp $"); #include <sys/param.h> #include <sys/cpu.h> @@ -395,6 +395,29 @@ void vmxnet3_dma_free(struct vmxnet3_sof CFATTACH_DECL3_NEW(vmx, sizeof(struct vmxnet3_softc), vmxnet3_match, vmxnet3_attach, vmxnet3_detach, NULL, NULL, NULL, 0); +/* round down to the nearest power of 2 */ +static int +vmxnet3_calc_queue_size(int n) +{ + int v, q; + + v = n; + while (v != 0) { + if (powerof2(n) != 0) + break; + v /= 2; + q = rounddown2(n, v); + if (q != 0) { + n = q; + break; + } + } + if (n == 0) + n = 1; + + return n; +} + static inline void vmxnet3_write_bar0(struct vmxnet3_softc *sc, bus_size_t r, uint32_t v) { @@ -520,8 +543,10 @@ vmxnet3_attach(device_t parent, device_t sc->vmx_mtx = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); callout_init(&sc->vmx_tick, CALLOUT_MPSAFE); - sc->vmx_max_ntxqueues = ncpu; - sc->vmx_max_nrxqueues = ncpu; + sc->vmx_max_ntxqueues = + vmxnet3_calc_queue_size(MIN(VMXNET3_MAX_TX_QUEUES, ncpu)); + sc->vmx_max_nrxqueues = + vmxnet3_calc_queue_size(MIN(VMXNET3_MAX_RX_QUEUES, ncpu)); sc->vmx_ntxdescs = 512; sc->vmx_nrxdescs = 256; sc->vmx_max_rxsegs = VMXNET3_MAX_RX_SEGS;