Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/rump/librump/rumpkern Defer softint thread creation to f...



details:   https://anonhg.NetBSD.org/src/rev/1868046ea50e
branches:  trunk
changeset: 791284:1868046ea50e
user:      pooka <pooka%NetBSD.org@localhost>
date:      Mon Nov 11 23:06:40 2013 +0000

description:
Defer softint thread creation to first softint_establish() for that level.
Speeds up rump kernel bootstrap and saves memory -- very rarely are all
softint levels in a rump kernel used.

diffstat:

 sys/rump/librump/rumpkern/intr.c |  80 +++++++++++++++++++++++++++++++--------
 1 files changed, 63 insertions(+), 17 deletions(-)

diffs (143 lines):

diff -r 4cab2812f27e -r 1868046ea50e sys/rump/librump/rumpkern/intr.c
--- a/sys/rump/librump/rumpkern/intr.c  Mon Nov 11 17:04:06 2013 +0000
+++ b/sys/rump/librump/rumpkern/intr.c  Mon Nov 11 23:06:40 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: intr.c,v 1.40 2013/05/02 21:45:28 pooka Exp $  */
+/*     $NetBSD: intr.c,v 1.41 2013/11/11 23:06:40 pooka Exp $  */
 
 /*
  * Copyright (c) 2008-2010 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.40 2013/05/02 21:45:28 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.41 2013/11/11 23:06:40 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -188,11 +188,52 @@
        panic("sithread unreachable");
 }
 
+static kmutex_t sithr_emtx;
+static unsigned int sithr_est;
+static int sithr_canest;
+
+/*
+ * Create softint handler threads when the softint for each respective
+ * level is established for the first time.  Most rump kernels don't
+ * need at least half of the softint levels, so on-demand saves bootstrap
+ * time and memory resources.  Note, though, that this routine may be
+ * called before it's possible to call kthread_create().  Creation of
+ * those softints (SOFTINT_CLOCK, as of writing this) will be deferred
+ * to until softint_init() is called for the main CPU.
+ */
+static void
+sithread_establish(int level)
+{
+       int docreate, rv;
+       int lvlbit = 1<<level;
+       int i;
+
+       KASSERT((level & ~SOFTINT_LVLMASK) == 0);
+       if (__predict_true(sithr_est & lvlbit))
+               return;
+
+       mutex_enter(&sithr_emtx);
+       docreate = (sithr_est & lvlbit) == 0 && sithr_canest;
+       sithr_est |= lvlbit;
+       mutex_exit(&sithr_emtx);
+
+       if (docreate) {
+               for (i = 0; i < ncpu_final; i++) {
+                       if ((rv = kthread_create(PRI_NONE,
+                           KTHREAD_MPSAFE | KTHREAD_INTR,
+                           cpu_lookup(i), sithread, (void *)(uintptr_t)level,
+                           NULL, "rsi%d/%d", i, level)) != 0)
+                               panic("softint thread create failed: %d", rv);
+               }
+       }
+}
+
 void
 rump_intr_init(int numcpu)
 {
 
        cv_init(&lbolt, "oh kath ra");
+       mutex_init(&sithr_emtx, MUTEX_DEFAULT, IPL_NONE);
        ncpu_final = numcpu;
 }
 
@@ -206,10 +247,23 @@
        if (!rump_threads)
                return;
 
-       /* XXX */
+       /* overloaded global init ... */
        if (ci->ci_index == 0) {
+               int sithr_swap;
+
                rumptc.tc_frequency = hz;
                tc_init(&rumptc);
+
+               /* create deferred softint threads */
+               mutex_enter(&sithr_emtx);
+               sithr_swap = sithr_est;
+               sithr_est = 0;
+               sithr_canest = 1;
+               mutex_exit(&sithr_emtx);
+               for (i = 0; i < SOFTINT_COUNT; i++) {
+                       if (sithr_swap & (1<<i))
+                               sithread_establish(i);
+               }
        }
 
        slev = kmem_alloc(sizeof(struct softint_lev) * SOFTINT_COUNT, KM_SLEEP);
@@ -219,19 +273,9 @@
        }
        cd->cpu_softcpu = slev;
 
-       /* softint might run on different physical CPU */
-       membar_sync();
-
-       for (i = 0; i < SOFTINT_COUNT; i++) {
-               rv = kthread_create(PRI_NONE,
-                   KTHREAD_MPSAFE | KTHREAD_INTR, ci,
-                   sithread, (void *)(uintptr_t)i,
-                   NULL, "rsi%d/%d", ci->ci_index, i);
-       }
-
-       rv = kthread_create(PRI_NONE, KTHREAD_MPSAFE,
-           ci, doclock, NULL, NULL, "rumpclk%d", ci->ci_index);
-       if (rv)
+       /* well, not really a "soft" interrupt ... */
+       if ((rv = kthread_create(PRI_NONE, KTHREAD_MPSAFE,
+           ci, doclock, NULL, NULL, "rumpclk%d", ci->ci_index)) != 0)
                panic("clock thread creation failed: %d", rv);
 }
 
@@ -240,13 +284,14 @@
 {
        struct softint *si;
        struct softint_percpu *sip;
+       int level = flags & SOFTINT_LVLMASK;
        int i;
 
        si = malloc(sizeof(*si), M_TEMP, M_WAITOK);
        si->si_func = func;
        si->si_arg = arg;
        si->si_flags = flags & SOFTINT_MPSAFE ? SI_MPSAFE : 0;
-       si->si_level = flags & SOFTINT_LVLMASK;
+       si->si_level = level;
        KASSERT(si->si_level < SOFTINT_COUNT);
        si->si_entry = malloc(sizeof(*si->si_entry) * ncpu_final,
            M_TEMP, M_WAITOK | M_ZERO);
@@ -254,6 +299,7 @@
                sip = &si->si_entry[i];
                sip->sip_parent = si;
        }
+       sithread_establish(level);
 
        return si;
 }



Home | Main Index | Thread Index | Old Index