Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Jul 2015 08:06:41 +0000 (UTC)
From:      Navdeep Parhar <np@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r285650 - projects/cxl_iscsi/sys/dev/cxgbe/cxgbei
Message-ID:  <201507170806.t6H86f2u064093@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: np
Date: Fri Jul 17 08:06:40 2015
New Revision: 285650
URL: https://svnweb.freebsd.org/changeset/base/285650

Log:
  Create some worker threads.  These will be used instead of the driver's
  ithreads to dispatch received PDUs.

Modified:
  projects/cxl_iscsi/sys/dev/cxgbe/cxgbei/cxgbei.c

Modified: projects/cxl_iscsi/sys/dev/cxgbe/cxgbei/cxgbei.c
==============================================================================
--- projects/cxl_iscsi/sys/dev/cxgbe/cxgbei/cxgbei.c	Fri Jul 17 07:30:00 2015	(r285649)
+++ projects/cxl_iscsi/sys/dev/cxgbe/cxgbei/cxgbei.c	Fri Jul 17 08:06:40 2015	(r285650)
@@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/errno.h>
 #include <sys/param.h>
 #include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/smp.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/mbuf.h>
@@ -1204,6 +1206,114 @@ static struct uld_info cxgbei_uld_info =
 	.deactivate = cxgbei_deactivate,
 };
 
+enum {
+	CWT_RUNNING = 1,
+	CWT_STOP = 2,
+	CWT_STOPPED = 3,
+};
+
+struct cxgbei_worker_thread_softc {
+	struct mtx	cwt_lock;
+	struct cv	cwt_cv;
+	volatile int	cwt_state;
+} __aligned(CACHE_LINE_SIZE);
+
+int worker_thread_count;
+static struct cxgbei_worker_thread_softc *cwt_softc;
+static struct proc *cxgbei_proc;
+
+static void
+cwt_main(void *arg)
+{
+	struct cxgbei_worker_thread_softc *cwt = arg;
+
+	MPASS(cwt != NULL);
+
+	mtx_lock(&cwt->cwt_lock);
+	MPASS(cwt->cwt_state == 0);
+	cwt->cwt_state = CWT_RUNNING;
+	cv_signal(&cwt->cwt_cv);
+	for (;;) {
+		cv_wait(&cwt->cwt_cv, &cwt->cwt_lock);
+		if (cwt->cwt_state == CWT_STOP)
+			break;
+	}
+
+	mtx_assert(&cwt->cwt_lock, MA_OWNED);
+	cwt->cwt_state = CWT_STOPPED;
+	cv_signal(&cwt->cwt_cv);
+	mtx_unlock(&cwt->cwt_lock);
+	kthread_exit();
+}
+
+static int
+start_worker_threads(void)
+{
+	int i, rc;
+	struct cxgbei_worker_thread_softc *cwt;
+
+	worker_thread_count = min(mp_ncpus, 32);
+	cwt_softc = malloc(worker_thread_count * sizeof(*cwt), M_CXGBE,
+	    M_WAITOK | M_ZERO);
+
+	MPASS(cxgbei_proc == NULL);
+	for (i = 0, cwt = &cwt_softc[0]; i < worker_thread_count; i++, cwt++) {
+		mtx_init(&cwt->cwt_lock, "cwt lock", NULL, MTX_DEF);
+		cv_init(&cwt->cwt_cv, "cwt cv");
+		rc = kproc_kthread_add(cwt_main, cwt, &cxgbei_proc, NULL, 0, 0,
+		    "cxgbei", "%d", i);
+		if (rc != 0) {
+			printf("cxgbei: failed to start thread #%d/%d (%d)\n",
+			    i + 1, worker_thread_count, rc);
+			mtx_destroy(&cwt->cwt_lock);
+			cv_destroy(&cwt->cwt_cv);
+			bzero(&cwt, sizeof(*cwt));
+			if (i == 0) {
+				free(cwt_softc, M_CXGBE);
+				worker_thread_count = 0;
+
+				return (rc);
+			}
+
+			/* Not fatal, carry on with fewer threads. */
+			worker_thread_count = i;
+			rc = 0;
+			break;
+		}
+
+		/* Wait for thread to start before moving on to the next one. */
+		mtx_lock(&cwt->cwt_lock);
+		while (cwt->cwt_state != CWT_RUNNING)
+			cv_wait(&cwt->cwt_cv, &cwt->cwt_lock);
+		mtx_unlock(&cwt->cwt_lock);
+	}
+
+	MPASS(cwt_softc != NULL);
+	MPASS(worker_thread_count > 0);
+	return (0);
+}
+
+static void
+stop_worker_threads(void)
+{
+	int i;
+	struct cxgbei_worker_thread_softc *cwt = &cwt_softc[0];
+
+	MPASS(worker_thread_count >= 0);
+
+	for (i = 0, cwt = &cwt_softc[0]; i < worker_thread_count; i++, cwt++) {
+		mtx_lock(&cwt->cwt_lock);
+		MPASS(cwt->cwt_state == CWT_RUNNING);
+		cwt->cwt_state = CWT_STOP;
+		cv_signal(&cwt->cwt_cv);
+		do {
+			cv_wait(&cwt->cwt_cv, &cwt->cwt_lock);
+		} while (cwt->cwt_state != CWT_STOPPED);
+		mtx_unlock(&cwt->cwt_lock);
+	}
+	free(cwt_softc, M_CXGBE);
+}
+
 extern void (*cxgbei_fw4_ack)(struct toepcb *, int);
 extern void (*cxgbei_rx_data_ddp)(struct toepcb *,
     const struct cpl_rx_data_ddp *);
@@ -1220,10 +1330,16 @@ cxgbei_mod_load(void)
 	cxgbei_writeq_len = get_writeq_len;
 	cxgbei_writeq_next = do_writeq_next;
 
-	rc = t4_register_uld(&cxgbei_uld_info);
+	rc = start_worker_threads();
 	if (rc != 0)
 		return (rc);
 
+	rc = t4_register_uld(&cxgbei_uld_info);
+	if (rc != 0) {
+		stop_worker_threads();
+		return (rc);
+	}
+
 	t4_iterate(cxgbei_activate_all, NULL);
 
 	return (rc);
@@ -1238,6 +1354,8 @@ cxgbei_mod_unload(void)
 	if (t4_unregister_uld(&cxgbei_uld_info) == EBUSY)
 		return (EBUSY);
 
+	stop_worker_threads();
+
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507170806.t6H86f2u064093>