From: Matthew Dillon Date: Sun, 24 May 2009 03:02:50 +0000 (-0700) Subject: vkernel - more crit section work to avoid pthread reentrancy. X-Git-Tag: v2.3.2~237 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/941319553038bba25664cb804f0dc437d15a79e2 vkernel - more crit section work to avoid pthread reentrancy. --- diff --git a/sys/dev/virtual/disk/vdisk.c b/sys/dev/virtual/disk/vdisk.c index 7dc245f6e3..9a2b9e292c 100644 --- a/sys/dev/virtual/disk/vdisk.c +++ b/sys/dev/virtual/disk/vdisk.c @@ -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 diff --git a/sys/dev/virtual/net/if_vke.c b/sys/dev/virtual/net/if_vke.c index 401bdb09f5..92c2174543 100644 --- a/sys/dev/virtual/net/if_vke.c +++ b/sys/dev/virtual/net/if_vke.c @@ -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 diff --git a/sys/platform/vkernel/include/cothread.h b/sys/platform/vkernel/include/cothread.h index b5b784e967..7fd72a2dc7 100644 --- a/sys/platform/vkernel/include/cothread.h +++ b/sys/platform/vkernel/include/cothread.h @@ -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 diff --git a/sys/platform/vkernel/platform/console.c b/sys/platform/vkernel/platform/console.c index a61473c5ab..c7874701de 100644 --- a/sys/platform/vkernel/platform/console.c +++ b/sys/platform/vkernel/platform/console.c @@ -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 diff --git a/sys/platform/vkernel/platform/cothread.c b/sys/platform/vkernel/platform/cothread.c index fb06670c4f..c432de5a11 100644 --- a/sys/platform/vkernel/platform/cothread.c +++ b/sys/platform/vkernel/platform/cothread.c @@ -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(); + } }