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;

Reply via email to