Date: Sat, 14 Jul 2007 13:26:26 +0900 From: Pyun YongHyeon <pyunyh@gmail.com> To: Li-Lun Leland Wang <llwang@infor.org> Cc: freebsd-current@freebsd.org Subject: Re: threadlock and msk watchdog timeout Message-ID: <20070714042626.GA22511@cdnetworks.co.kr> In-Reply-To: <b680ed60707130727r1d25ed11s9d2db1293ae0b4cb@mail.gmail.com> References: <20070713084325.GA47351@Athena.infor.org> <20070713100829.GC17801@cdnetworks.co.kr> <b680ed60707130727r1d25ed11s9d2db1293ae0b4cb@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--Nq2Wo0NMKNjxTN9z Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Jul 13, 2007 at 09:27:00AM -0500, Li-Lun Leland Wang wrote: > On 7/13/07, Pyun YongHyeon <pyunyh@gmail.com> wrote: > >Does msk(4) use shared interrupt? > >Show me the output of "vmstat -i". > > Here is the output of vmstat -i. > > interrupt total rate > irq1: atkbd0 677 1 > irq16: mskc0 uhci0 9423 15 > irq18: ehci0 uhci+ 9444 15 > irq19: atapci0++ 14362 22 > irq22: pcm0 15 0 > cpu0: timer 1251072 1995 > cpu1: timer 1251206 1995 > Total 2536199 4044 > > One thing I forgot to mention is that I've already disabled MSI on this > system. > Ok, try attached patch after adding 'hw.msk.legacy_intr="1"' to /boot/loader.conf. If you use msk(4) kernel module use kenv(1) to set the tunable. -- Regards, Pyun YongHyeon --Nq2Wo0NMKNjxTN9z Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="if_msk.legacy_intr.patch" Index: if_msk.c =================================================================== RCS file: /home/ncvs/src/sys/dev/msk/if_msk.c,v retrieving revision 1.17 diff -u -r1.17 if_msk.c --- if_msk.c 11 Jun 2007 02:00:50 -0000 1.17 +++ if_msk.c 14 Jul 2007 04:20:39 -0000 @@ -154,6 +154,8 @@ /* Tunables. */ static int msi_disable = 0; TUNABLE_INT("hw.msk.msi_disable", &msi_disable); +static int legacy_intr = 0; +TUNABLE_INT("hw.msk.legacy_intr", &legacy_intr); #define MSK_CSUM_FEATURES (CSUM_TCP | CSUM_UDP) @@ -229,6 +231,7 @@ static int msk_detach(device_t); static void msk_tick(void *); +static void msk_legacy_intr(void *); static int msk_intr(void *); static void msk_int_task(void *, int); static void msk_intr_phy(struct msk_if_softc *); @@ -1709,6 +1712,8 @@ * port cards with separate MSI messages, so for now I disable MSI * on dual port cards. */ + if (legacy_intr != 0) + msi_disable = 1; if (msic == 2 && msi_disable == 0 && sc->msk_num_port == 1 && pci_alloc_msi(dev, &msic) == 0) { if (msic == 2) { @@ -1778,18 +1783,25 @@ goto fail; } - TASK_INIT(&sc->msk_int_task, 0, msk_int_task, sc); - sc->msk_tq = taskqueue_create_fast("msk_taskq", M_WAITOK, - taskqueue_thread_enqueue, &sc->msk_tq); - taskqueue_start_threads(&sc->msk_tq, 1, PI_NET, "%s taskq", - device_get_nameunit(sc->msk_dev)); /* Hook interrupt last to avoid having to lock softc. */ - error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET | - INTR_MPSAFE, msk_intr, NULL, sc, &sc->msk_intrhand[0]); + if (legacy_intr) + error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET | + INTR_MPSAFE, NULL, msk_legacy_intr, sc, + &sc->msk_intrhand[0]); + else { + TASK_INIT(&sc->msk_int_task, 0, msk_int_task, sc); + sc->msk_tq = taskqueue_create_fast("msk_taskq", M_WAITOK, + taskqueue_thread_enqueue, &sc->msk_tq); + taskqueue_start_threads(&sc->msk_tq, 1, PI_NET, "%s taskq", + device_get_nameunit(sc->msk_dev)); + error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET | + INTR_MPSAFE, msk_intr, NULL, sc, &sc->msk_intrhand[0]); + } if (error != 0) { device_printf(dev, "couldn't set up interrupt handler\n"); - taskqueue_free(sc->msk_tq); + if (legacy_intr == 0) + taskqueue_free(sc->msk_tq); sc->msk_tq = NULL; goto fail; } @@ -1892,7 +1904,7 @@ msk_status_dma_free(sc); - if (sc->msk_tq != NULL) { + if (legacy_intr == 0 && sc->msk_tq != NULL) { taskqueue_drain(sc->msk_tq, &sc->msk_int_task); taskqueue_free(sc->msk_tq); sc->msk_tq = NULL; @@ -3503,6 +3515,75 @@ return (sc->msk_stat_cons != CSR_READ_2(sc, STAT_PUT_IDX)); } +/* Legacy interrupt handler for shared interrupt. */ +static void +msk_legacy_intr(void *xsc) +{ + struct msk_softc *sc; + struct msk_if_softc *sc_if0, *sc_if1; + struct ifnet *ifp0, *ifp1; + uint32_t status; + + sc = xsc; + MSK_LOCK(sc); + + /* Reading B0_Y2_SP_ISRC2 masks further interrupts. */ + status = CSR_READ_4(sc, B0_Y2_SP_ISRC2); + if (status == 0 || status == 0xffffffff || sc->msk_suspended != 0 || + (status & sc->msk_intrmask) == 0) { + CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2); + return; + } + + sc_if0 = sc->msk_if[MSK_PORT_A]; + sc_if1 = sc->msk_if[MSK_PORT_B]; + ifp0 = ifp1 = NULL; + if (sc_if0 != NULL) + ifp0 = sc_if0->msk_ifp; + if (sc_if1 != NULL) + ifp1 = sc_if1->msk_ifp; + + if ((status & Y2_IS_IRQ_PHY1) != 0 && sc_if0 != NULL) + msk_intr_phy(sc_if0); + if ((status & Y2_IS_IRQ_PHY2) != 0 && sc_if1 != NULL) + msk_intr_phy(sc_if1); + if ((status & Y2_IS_IRQ_MAC1) != 0 && sc_if0 != NULL) + msk_intr_gmac(sc_if0); + if ((status & Y2_IS_IRQ_MAC2) != 0 && sc_if1 != NULL) + msk_intr_gmac(sc_if1); + if ((status & (Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2)) != 0) { + device_printf(sc->msk_dev, "Rx descriptor error\n"); + sc->msk_intrmask &= ~(Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2); + CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask); + CSR_READ_4(sc, B0_IMSK); + } + if ((status & (Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXA2)) != 0) { + device_printf(sc->msk_dev, "Tx descriptor error\n"); + sc->msk_intrmask &= ~(Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXA2); + CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask); + CSR_READ_4(sc, B0_IMSK); + } + if ((status & Y2_IS_HW_ERR) != 0) + msk_intr_hwerr(sc); + + while (msk_handle_events(sc) != 0) + ; + if ((status & Y2_IS_STAT_BMU) != 0) + CSR_WRITE_4(sc, STAT_CTRL, SC_STAT_CLR_IRQ); + + /* Reenable interrupts. */ + CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2); + + if (ifp0 != NULL && (ifp0->if_drv_flags & IFF_DRV_RUNNING) != 0 && + !IFQ_DRV_IS_EMPTY(&ifp0->if_snd)) + taskqueue_enqueue(taskqueue_fast, &sc_if0->msk_tx_task); + if (ifp1 != NULL && (ifp1->if_drv_flags & IFF_DRV_RUNNING) != 0 && + !IFQ_DRV_IS_EMPTY(&ifp1->if_snd)) + taskqueue_enqueue(taskqueue_fast, &sc_if1->msk_tx_task); + + MSK_UNLOCK(sc); +} + static int msk_intr(void *xsc) { --Nq2Wo0NMKNjxTN9z--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070714042626.GA22511>