Source-Changes-HG archive

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

[src/sommerfeld_i386mp_1]: src/sys/arch/i386/i386 Add a spinlock around softi...



details:   https://anonhg.NetBSD.org/src/rev/7d8153a51f8d
branches:  sommerfeld_i386mp_1
changeset: 482558:7d8153a51f8d
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Tue Jun 25 01:08:49 2002 +0000

description:
Add a spinlock around softintr queue management. Use a lock prefix to
protect manipulation of the 'ipending' variable. Fixes 'softclock
stops being called' AKA 'processes entering nanosleep do not return'
problem.

diffstat:

 sys/arch/i386/i386/softintr.c |  174 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 174 insertions(+), 0 deletions(-)

diffs (178 lines):

diff -r 5421c0bf7dda -r 7d8153a51f8d sys/arch/i386/i386/softintr.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/i386/i386/softintr.c     Tue Jun 25 01:08:49 2002 +0000
@@ -0,0 +1,174 @@
+/*     $NetBSD: softintr.c,v 1.2.2.2 2002/06/25 01:08:49 fvdl Exp $    */
+
+/*-
+ * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the NetBSD
+ *     Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Generic soft interrupt implementation for NetBSD/i386.
+ *
+ * Note: This code is expected to go away when the i386-MP
+ * branch is merged.
+ *
+ * Also note: the netisr processing is left in i386/isa/icu.s
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: softintr.c,v 1.2.2.2 2002/06/25 01:08:49 fvdl Exp $");
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+
+#include <machine/intr.h>
+
+#include <uvm/uvm_extern.h>
+
+struct i386_soft_intr i386_soft_intrs[I386_NSOFTINTR];
+
+const int i386_soft_intr_to_ssir[I386_NSOFTINTR] = {
+       SIR_CLOCK,
+       SIR_NET,
+       SIR_SERIAL,
+};
+
+/*
+ * softintr_init:
+ *
+ *     Initialize the software interrupt system.
+ */
+void
+softintr_init(void)
+{
+       struct i386_soft_intr *si;
+       int i;
+
+       for (i = 0; i < I386_NSOFTINTR; i++) {
+               si = &i386_soft_intrs[i];
+               TAILQ_INIT(&si->softintr_q);
+               simple_lock_init(&si->softintr_slock);
+               si->softintr_ssir = i386_soft_intr_to_ssir[i];
+       }
+}
+
+/*
+ * softintr_dispatch:
+ *
+ *     Process pending software interrupts.
+ */
+void
+softintr_dispatch(int which)
+{
+       struct i386_soft_intr *si = &i386_soft_intrs[which];
+       struct i386_soft_intrhand *sih;
+       int s;
+
+       for (;;) {
+               i386_softintr_lock(si, s);
+               sih = TAILQ_FIRST(&si->softintr_q);
+               if (sih == NULL) {
+                       i386_softintr_unlock(si, s);
+                       break;
+               }
+               TAILQ_REMOVE(&si->softintr_q, sih, sih_q);
+               sih->sih_pending = 0;
+               i386_softintr_unlock(si, s);
+
+               uvmexp.softs++;
+               (*sih->sih_fn)(sih->sih_arg);
+       }
+}
+
+/*
+ * softintr_establish:         [interface]
+ *
+ *     Register a software interrupt handler.
+ */
+void *
+softintr_establish(int ipl, void (*func)(void *), void *arg)
+{
+       struct i386_soft_intr *si;
+       struct i386_soft_intrhand *sih;
+       int which;
+
+       switch (ipl) {
+       case IPL_SOFTCLOCK:
+               which = I386_SOFTINTR_SOFTCLOCK;
+               break;
+
+       case IPL_SOFTNET:
+               which = I386_SOFTINTR_SOFTNET;
+               break;
+
+       case IPL_SOFTSERIAL:
+               which = I386_SOFTINTR_SOFTSERIAL;
+               break;
+
+       default:
+               panic("softintr_establish");
+       }
+
+       si = &i386_soft_intrs[which];
+
+       sih = malloc(sizeof(*sih), M_DEVBUF, M_NOWAIT);
+       if (__predict_true(sih != NULL)) {
+               sih->sih_intrhead = si;
+               sih->sih_fn = func;
+               sih->sih_arg = arg;
+               sih->sih_pending = 0;
+       }
+       return (sih);
+}
+
+/*
+ * softintr_disestablish:      [interface]
+ *
+ *     Unregister a software interrupt handler.
+ */
+void
+softintr_disestablish(void *arg)
+{
+       struct i386_soft_intrhand *sih = arg;
+       struct i386_soft_intr *si = sih->sih_intrhead;
+       int s;
+
+       i386_softintr_lock(si, s);
+       if (sih->sih_pending) {
+               TAILQ_REMOVE(&si->softintr_q, sih, sih_q);
+               sih->sih_pending = 0;
+       }
+       i386_softintr_unlock(si, s);
+
+       free(sih, M_DEVBUF);
+}



Home | Main Index | Thread Index | Old Index