Module Name:    src
Committed By:   knakahara
Date:           Fri Mar  2 10:21:01 UTC 2018

Modified Files:
        src/sys/dev/pci/ixgbe: ixv.c

Log Message:
ixv(4) also supports workqueue poll mode, but not enabled by default yet, 
either.

ok by msaitoh@n.o.


To generate a diff of this commit:
cvs rdiff -u -r1.83 -r1.84 src/sys/dev/pci/ixgbe/ixv.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/dev/pci/ixgbe/ixv.c
diff -u src/sys/dev/pci/ixgbe/ixv.c:1.83 src/sys/dev/pci/ixgbe/ixv.c:1.84
--- src/sys/dev/pci/ixgbe/ixv.c:1.83	Tue Feb 27 04:58:27 2018
+++ src/sys/dev/pci/ixgbe/ixv.c	Fri Mar  2 10:21:01 2018
@@ -1,4 +1,4 @@
-/*$NetBSD: ixv.c,v 1.83 2018/02/27 04:58:27 msaitoh Exp $*/
+/*$NetBSD: ixv.c,v 1.84 2018/03/02 10:21:01 knakahara Exp $*/
 
 /******************************************************************************
 
@@ -150,6 +150,9 @@ static int	ixv_msix_mbx(void *);
 static void	ixv_handle_que(void *);
 static void     ixv_handle_link(void *);
 
+/* Workqueue handler for deferred work */
+static void	ixv_handle_que_work(struct work *, void *);
+
 const struct sysctlnode *ixv_sysctl_instance(struct adapter *);
 static ixgbe_vendor_info_t *ixv_lookup(const struct pci_attach_args *);
 
@@ -200,6 +203,9 @@ TUNABLE_INT("hw.ixv.rx_process_limit", &
 static int ixv_tx_process_limit = 256;
 TUNABLE_INT("hw.ixv.tx_process_limit", &ixv_tx_process_limit);
 
+/* Which pakcet processing uses workqueue or softint */
+static bool ixv_txrx_workqueue = false;
+
 /*
  * Number of TX descriptors per ring,
  * setting higher than RX as this seems
@@ -220,10 +226,13 @@ TUNABLE_INT("hw.ixv.enable_legacy_tx", &
 #define IXGBE_MPSAFE		1
 #define IXGBE_CALLOUT_FLAGS	CALLOUT_MPSAFE
 #define IXGBE_SOFTINFT_FLAGS	SOFTINT_MPSAFE
+#define IXGBE_WORKQUEUE_FLAGS	WQ_PERCPU | WQ_MPSAFE
 #else
 #define IXGBE_CALLOUT_FLAGS	0
 #define IXGBE_SOFTINFT_FLAGS	0
+#define IXGBE_WORKQUEUE_FLAGS	WQ_PERCPU
 #endif
+#define IXGBE_WORKQUEUE_PRI PRI_SOFTNET
 
 #if 0
 static int (*ixv_start_locked)(struct ifnet *, struct tx_ring *);
@@ -508,6 +517,8 @@ ixv_attach(device_t parent, device_t dev
 	/* hw.ix defaults init */
 	adapter->enable_aim = ixv_enable_aim;
 
+	adapter->txrx_use_workqueue = ixv_txrx_workqueue;
+
 	error = ixv_allocate_msix(adapter, pa);
 	if (error) {
 		device_printf(dev, "ixv_allocate_msix() failed!\n");
@@ -597,6 +608,12 @@ ixv_detach(device_t dev, int flags)
 			softint_disestablish(txr->txr_si);
 		softint_disestablish(que->que_si);
 	}
+	if (adapter->txr_wq != NULL)
+		workqueue_destroy(adapter->txr_wq);
+	if (adapter->txr_wq_enqueued != NULL)
+		percpu_free(adapter->txr_wq_enqueued, sizeof(u_int));
+	if (adapter->que_wq != NULL)
+		workqueue_destroy(adapter->que_wq);
 
 	/* Drain the Mailbox(link) queue */
 	softint_disestablish(adapter->link_si);
@@ -2300,6 +2317,12 @@ ixv_add_device_sysctls(struct adapter *a
 	    "enable_aim", SYSCTL_DESCR("Interrupt Moderation"),
 	    NULL, 0, &adapter->enable_aim, 0, CTL_CREATE, CTL_EOL) != 0)
 		aprint_error_dev(dev, "could not create sysctl\n");
+
+	if (sysctl_createv(log, 0, &rnode, &cnode,
+	    CTLFLAG_READWRITE, CTLTYPE_BOOL,
+	    "txrx_workqueue", SYSCTL_DESCR("Use workqueue for packet processing"),
+		NULL, 0, &adapter->txrx_use_workqueue, 0, CTL_CREATE, CTL_EOL) != 0)
+		aprint_error_dev(dev, "could not create sysctl\n");
 }
 
 /************************************************************************
@@ -2769,7 +2792,6 @@ ixv_init(struct ifnet *ifp)
 	return 0;
 } /* ixv_init */
 
-
 /************************************************************************
  * ixv_handle_que
  ************************************************************************/
@@ -2799,7 +2821,15 @@ ixv_handle_que(void *context)
 		IXGBE_TX_UNLOCK(txr);
 		if (more) {
 			adapter->req.ev_count++;
-			softint_schedule(que->que_si);
+			if (adapter->txrx_use_workqueue) {
+				/*
+				 * "enqueued flag" is not required here
+				 * the same as ixg(4). See ixgbe_msix_que().
+				 */
+				workqueue_enqueue(adapter->que_wq,
+				    &que->wq_cookie, curcpu());
+			} else
+				  softint_schedule(que->que_si);
 			return;
 		}
 	}
@@ -2811,6 +2841,21 @@ ixv_handle_que(void *context)
 } /* ixv_handle_que */
 
 /************************************************************************
+ * ixv_handle_que_work
+ ************************************************************************/
+static void
+ixv_handle_que_work(struct work *wk, void *context)
+{
+	struct ix_queue *que = container_of(wk, struct ix_queue, wq_cookie);
+
+	/*
+	 * "enqueued flag" is not required here the same as ixg(4).
+	 * See ixgbe_msix_que().
+	 */
+	ixv_handle_que(que);
+}
+
+/************************************************************************
  * ixv_allocate_msix - Setup MSI-X Interrupt resources and handlers
  ************************************************************************/
 static int
@@ -2823,6 +2868,7 @@ ixv_allocate_msix(struct adapter *adapte
 	pci_chipset_tag_t pc;
 	pcitag_t	tag;
 	char		intrbuf[PCI_INTRSTR_LEN];
+	char		wqname[MAXCOMLEN];
 	char		intr_xname[32];
 	const char	*intrstr = NULL;
 	kcpuset_t	*affinity;
@@ -2891,6 +2937,23 @@ ixv_allocate_msix(struct adapter *adapte
 			    "could not establish software interrupt\n"); 
 		}
 	}
+	snprintf(wqname, sizeof(wqname), "%sdeferTx", device_xname(dev));
+	error = workqueue_create(&adapter->txr_wq, wqname,
+	    ixgbe_deferred_mq_start_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
+	    IXGBE_WORKQUEUE_FLAGS);
+	if (error) {
+		aprint_error_dev(dev, "couldn't create workqueue for deferred Tx\n");
+	}
+	adapter->txr_wq_enqueued = percpu_alloc(sizeof(u_int));
+
+	snprintf(wqname, sizeof(wqname), "%sTxRx", device_xname(dev));
+	error = workqueue_create(&adapter->que_wq, wqname,
+	    ixv_handle_que_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
+	    IXGBE_WORKQUEUE_FLAGS);
+	if (error) {
+		aprint_error_dev(dev,
+		    "couldn't create workqueue\n");
+	}
 
 	/* and Mailbox */
 	cpu_id++;

Reply via email to