vkernel - more crit section work to avoid pthread reentrancy.
authorMatthew Dillon <dillon@apollo.backplane.com>
Sun, 24 May 2009 03:02:50 +0000 (20:02 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sun, 24 May 2009 03:02:50 +0000 (20:02 -0700)
sys/dev/virtual/disk/vdisk.c
sys/dev/virtual/net/if_vke.c
sys/platform/vkernel/include/cothread.h
sys/platform/vkernel/platform/console.c
sys/platform/vkernel/platform/cothread.c

index 7dc245f..9a2b9e2 100644 (file)
@@ -160,10 +160,10 @@ vkdstrategy(struct dev_strategy_args *ap)
        sc = dev->si_drv1;
 
        devstat_start_transaction(&sc->stats);
-       cothread_lock(sc->cotd);
+       cothread_lock(sc->cotd, 0);
        TAILQ_INSERT_TAIL(&sc->cotd_queue, bio, bio_act);
        cothread_signal(sc->cotd);
-       cothread_unlock(sc->cotd);
+       cothread_unlock(sc->cotd, 0);
 
        return(0);
 }
@@ -177,14 +177,14 @@ vkd_io_intr(cothread_t cotd)
 
        sc = cotd->arg;
 
-       cothread_lock(cotd);
+       cothread_lock(cotd, 0);
        while (!TAILQ_EMPTY(&sc->cotd_done)) {
                bio = TAILQ_FIRST(&sc->cotd_done);
                TAILQ_REMOVE(&sc->cotd_done, bio, bio_act);
                devstat_end_transaction_buf(&sc->stats, bio->bio_buf);
                biodone(bio);
        }
-       cothread_unlock(sc->cotd);
+       cothread_unlock(sc->cotd, 0);
 }
 
 /*
@@ -202,14 +202,14 @@ vkd_io_thread(cothread_t cotd)
        struct vkd_softc *sc = cotd->arg;
        int count;
 
-       cothread_lock(cotd);
+       cothread_lock(cotd, 1);
        for (;;) {
                count = 0;
                while ((bio = TAILQ_FIRST(&sc->cotd_queue)) != NULL) {
                        TAILQ_REMOVE(&sc->cotd_queue, bio, bio_act);
-                       cothread_unlock(cotd);
+                       cothread_unlock(cotd, 1);
                        vkd_doio(sc, bio);
-                       cothread_lock(cotd);
+                       cothread_lock(cotd, 1);
                        TAILQ_INSERT_TAIL(&sc->cotd_done, bio, bio_act);
                        if (++count == 8) {
                                cothread_intr(cotd);
@@ -221,7 +221,7 @@ vkd_io_thread(cothread_t cotd)
                cothread_wait(cotd);    /* interlocks cothread lock */
        }
        /* NOT REACHED */
-       cothread_unlock(cotd);
+       cothread_unlock(cotd, 1);
 }
 
 static
index 401bdb0..92c2174 100644 (file)
@@ -323,7 +323,7 @@ vke_start(struct ifnet *ifp)
        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                return;
 
-       cothread_lock(cotd);
+       cothread_lock(cotd, 0);
        count = 0;
 
        while ((m = ifq_dequeue(&ifp->if_snd, NULL)) != NULL) {
@@ -341,7 +341,7 @@ vke_start(struct ifnet *ifp)
                cothread_signal(cotd);
        }
 
-       cothread_unlock(cotd);
+       cothread_unlock(cotd, 0);
 }
 
 static int
@@ -408,19 +408,19 @@ vke_stop(struct vke_softc *sc)
 
        if (sc) {
                if (sc->cotd_tx) {
-                       cothread_lock(sc->cotd_tx);
+                       cothread_lock(sc->cotd_tx, 0);
                        if (sc->cotd_tx_exit == VKE_COTD_RUN)
                                sc->cotd_tx_exit = VKE_COTD_EXIT;
                        cothread_signal(sc->cotd_tx);
-                       cothread_unlock(sc->cotd_tx);
+                       cothread_unlock(sc->cotd_tx, 0);
                        cothread_delete(&sc->cotd_tx);
                }
                if (sc->cotd_rx) {
-                       cothread_lock(sc->cotd_rx);
+                       cothread_lock(sc->cotd_rx, 0);
                        if (sc->cotd_rx_exit == VKE_COTD_RUN)
                                sc->cotd_rx_exit = VKE_COTD_EXIT;
                        cothread_signal(sc->cotd_rx);
-                       cothread_unlock(sc->cotd_rx);
+                       cothread_unlock(sc->cotd_rx, 0);
                        cothread_delete(&sc->cotd_rx);
                }
 
@@ -472,10 +472,10 @@ vke_rx_intr(cothread_t cotd)
        static int count = 0;
 
        ifnet_serialize_all(ifp);
-       cothread_lock(cotd);
+       cothread_lock(cotd, 0);
 
        if (sc->cotd_rx_exit != VKE_COTD_RUN) {
-               cothread_unlock(cotd);
+               cothread_unlock(cotd, 0);
                ifnet_deserialize_all(ifp);
                return;
        }
@@ -497,7 +497,7 @@ vke_rx_intr(cothread_t cotd)
        if (count)
                cothread_signal(cotd);
 
-       cothread_unlock(cotd);
+       cothread_unlock(cotd, 0);
        ifnet_deserialize_all(ifp);
 }
 
@@ -513,10 +513,10 @@ vke_tx_intr(cothread_t cotd)
        struct mbuf *m;
 
        ifnet_serialize_all(ifp);
-       cothread_lock(cotd);
+       cothread_lock(cotd, 0);
 
        if (sc->cotd_tx_exit != VKE_COTD_RUN) {
-               cothread_unlock(cotd);
+               cothread_unlock(cotd, 0);
                ifnet_deserialize_all(ifp);
                return;
        }
@@ -529,7 +529,7 @@ vke_tx_intr(cothread_t cotd)
                m_freem(m);
        }
 
-       cothread_unlock(cotd);
+       cothread_unlock(cotd, 0);
 
        ifnet_deserialize_all(ifp);
 }
@@ -556,7 +556,7 @@ vke_rx_thread(cothread_t cotd)
 
        FD_ZERO(&fdset);
 
-       cothread_lock(cotd);
+       cothread_lock(cotd, 1);
 
        for (;;) {
                int n;
@@ -570,9 +570,9 @@ vke_rx_thread(cothread_t cotd)
 
                        if ((m = fifo->array[NETFIFOINDEX(fifo->windex)]) !=
                                        NULL) {
-                               cothread_unlock(cotd);
+                               cothread_unlock(cotd, 1);
                                n = read(sc->sc_fd, mtod(m, void *), MCLBYTES);
-                               cothread_lock(cotd);
+                               cothread_lock(cotd, 1);
                                if (n <= 0)
                                        break;
                                ifp->if_ipackets++;
@@ -594,7 +594,7 @@ vke_rx_thread(cothread_t cotd)
                if (sc->cotd_rx_exit != VKE_COTD_RUN)
                        break;
 
-               cothread_unlock(cotd);
+               cothread_unlock(cotd, 1);
 
                /* Set up data for select() call */
                FD_SET(sc->sc_fd, &fdset);
@@ -602,11 +602,11 @@ vke_rx_thread(cothread_t cotd)
                if (select(sc->sc_fd + 1, &fdset, NULL, NULL, &tv) == -1)
                        kprintf(VKE_DEVNAME "%d: select failed for TAP device\n", sc->sc_unit);
 
-               cothread_lock(cotd);
+               cothread_lock(cotd, 1);
        }
 
        sc->cotd_rx_exit = VKE_COTD_DEAD;
-       cothread_unlock(cotd);
+       cothread_unlock(cotd, 1);
 }
 
 /*
@@ -620,7 +620,7 @@ vke_tx_thread(cothread_t cotd)
        struct ifnet *ifp = &sc->arpcom.ac_if;
        int count = 0;
 
-       cothread_lock(cotd);
+       cothread_lock(cotd, 1);
 
        while (sc->cotd_tx_exit == VKE_COTD_RUN) {
                /* Write outgoing packets to the TAP interface */
@@ -628,13 +628,13 @@ vke_tx_thread(cothread_t cotd)
                        if (m->m_pkthdr.len <= MCLBYTES) {
                                m_copydata(m, 0, m->m_pkthdr.len, sc->sc_txbuf);
                                sc->sc_txbuf_len = m->m_pkthdr.len;
-                               cothread_unlock(cotd);
+                               cothread_unlock(cotd, 1);
 
                                if (write(sc->sc_fd, sc->sc_txbuf, sc->sc_txbuf_len) < 0) {
-                                       cothread_lock(cotd);
+                                       cothread_lock(cotd, 1);
                                        ifp->if_oerrors++;
                                } else {
-                                       cothread_lock(cotd);
+                                       cothread_lock(cotd, 1);
                                        vke_txfifo_done_enqueue(sc, m);
                                        ifp->if_opackets++;
                                        if (count++ == VKE_CHUNK) {
@@ -653,7 +653,7 @@ vke_tx_thread(cothread_t cotd)
        }
        /* NOT REACHED */
        sc->cotd_tx_exit = VKE_COTD_DEAD;
-       cothread_unlock(cotd);
+       cothread_unlock(cotd, 1);
 }
 
 static int
index b5b784e..7fd72a2 100644 (file)
@@ -59,7 +59,7 @@ void cothread_delete(cothread_t *cotdp);
 void cothread_intr(cothread_t cotd);
 void cothread_signal(cothread_t cotd);
 void cothread_wait(cothread_t cotd);
-void cothread_lock(cothread_t cotd);
-void cothread_unlock(cothread_t cotd);
+void cothread_lock(cothread_t cotd, int is_cotd);
+void cothread_unlock(cothread_t cotd, int is_cotd);
 
 #endif
index a61473c..c787470 100644 (file)
@@ -183,9 +183,7 @@ vcons_tty_start(struct tty *tp)
                 * Dummy up ttyv1, etc.
                 */
                if (minor(tp->t_dev) == 0) {
-                       crit_enter();
-                       write(1, buf, n);
-                       crit_exit();
+                       pwrite(1, buf, n, -1);
                }
        }
        tp->t_state &= ~TS_BUSY;
@@ -373,9 +371,7 @@ vconsgetc(void *private)
 
        console_stolen_by_kernel = 1;
        for (;;) {
-               crit_enter();
-               n = read(0, &c, 1);
-               crit_exit();
+               n = pread(0, &c, 1, -1);
                if (n == 1)
                        break;
                if (n < 0 && errno == EINTR)
@@ -401,9 +397,7 @@ vconsputc(void *private, int c)
 {
        char cc = c;
 
-       crit_enter();
-       write(1, &cc, 1);
-       crit_exit();
+       pwrite(1, &cc, 1, -1);
 }
 
 void
index fb06670..c432de5 100644 (file)
@@ -172,18 +172,26 @@ cothread_wait(cothread_t cotd)
  * Typically called by kernel thread or cothread
  */
 void
-cothread_lock(cothread_t cotd)
+cothread_lock(cothread_t cotd, int is_cotd)
 {
-       crit_enter();
-       pthread_mutex_lock(&cotd->mutex);
-       crit_exit();
+       if (is_cotd) {
+               pthread_mutex_lock(&cotd->mutex);
+       } else {
+               crit_enter();
+               pthread_mutex_lock(&cotd->mutex);
+               crit_exit();
+       }
 }
 
 void
-cothread_unlock(cothread_t cotd)
+cothread_unlock(cothread_t cotd, int is_cotd)
 {
-       crit_enter();
-       pthread_mutex_unlock(&cotd->mutex);
-       crit_exit();
+       if (is_cotd) {
+               pthread_mutex_unlock(&cotd->mutex);
+       } else {
+               crit_enter();
+               pthread_mutex_unlock(&cotd->mutex);
+               crit_exit();
+       }
 }