From owner-p4-projects@FreeBSD.ORG Wed Jul 23 12:04:00 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3E73837B404; Wed, 23 Jul 2003 12:04:00 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E471D37B401 for ; Wed, 23 Jul 2003 12:03:59 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 43BA843F75 for ; Wed, 23 Jul 2003 12:03:59 -0700 (PDT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h6NJ3x0U020893 for ; Wed, 23 Jul 2003 12:03:59 -0700 (PDT) (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h6NJ3wnG020890 for perforce@freebsd.org; Wed, 23 Jul 2003 12:03:58 -0700 (PDT) Date: Wed, 23 Jul 2003 12:03:58 -0700 (PDT) Message-Id: <200307231903.h6NJ3wnG020890@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 34889 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Jul 2003 19:04:01 -0000 http://perforce.freebsd.org/chv.cgi?CH=34889 Change 34889 by sam@sam_ebb on 2003/07/23 12:03:44 lock and remove giant Affected files ... .. //depot/projects/netperf/sys/dev/em/if_em.c#2 edit .. //depot/projects/netperf/sys/dev/em/if_em.h#2 edit Differences ... ==== //depot/projects/netperf/sys/dev/em/if_em.c#2 (text+ko) ==== @@ -113,6 +113,7 @@ static int em_ioctl(struct ifnet *, u_long, caddr_t); static void em_watchdog(struct ifnet *); static void em_init(void *); +static void em_init_locked(struct adapter *); static void em_stop(void *); static void em_media_status(struct ifnet *, struct ifmediareq *); static int em_media_change(struct ifnet *); @@ -252,23 +253,22 @@ em_attach(device_t dev) { struct adapter * adapter; - int s; int tsize, rsize; int error = 0; INIT_DEBUGOUT("em_attach: begin"); - s = splimp(); /* Allocate, clear, and link in our adapter structure */ if (!(adapter = device_get_softc(dev))) { printf("em: adapter structure allocation failed\n"); - splx(s); return(ENOMEM); } bzero(adapter, sizeof(struct adapter )); adapter->dev = dev; adapter->osdep.dev = dev; adapter->unit = device_get_unit(dev); + mtx_init(&adapter->mtx, device_get_nameunit(dev), + MTX_NETWORK_LOCK, MTX_DEF); if (em_adapter_list != NULL) em_adapter_list->prev = adapter; @@ -300,8 +300,8 @@ (void *)adapter, 0, em_sysctl_stats, "I", "Statistics"); - callout_handle_init(&adapter->timer_handle); - callout_handle_init(&adapter->tx_fifo_timer_handle); + callout_init(&adapter->timer, CALLOUT_MPSAFE); + callout_init(&adapter->tx_fifo_timer, CALLOUT_MPSAFE); /* Determine hardware revision */ em_identify_hardware(adapter); @@ -429,7 +429,6 @@ printf("em%d: Speed:N/A Duplex:N/A\n", adapter->unit); INIT_DEBUGOUT("em_attach: end"); - splx(s); return(0); err_mac_addr: @@ -442,7 +441,6 @@ em_free_pci_resources(adapter); sysctl_ctx_free(&adapter->sysctl_ctx); err_sysctl: - splx(s); return(error); } @@ -462,13 +460,13 @@ { struct adapter * adapter = device_get_softc(dev); struct ifnet *ifp = &adapter->interface_data.ac_if; - int s; INIT_DEBUGOUT("em_detach: begin"); - s = splimp(); + EM_LOCK(adapter); em_stop(adapter); em_phy_hw_reset(&adapter->hw); + EM_UNLOCK(adapter); #if __FreeBSD_version < 500000 ether_ifdetach(&adapter->interface_data.ac_if, ETHER_BPF_SUPPORTED); #else @@ -499,7 +497,6 @@ ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); ifp->if_timer = 0; - splx(s); return(0); } @@ -513,7 +510,9 @@ em_shutdown(device_t dev) { struct adapter *adapter = device_get_softc(dev); + EM_LOCK(adapter); em_stop(adapter); + EM_UNLOCK(adapter); return(0); } @@ -529,16 +528,16 @@ **********************************************************************/ static void -em_start(struct ifnet *ifp) +em_start_locked(struct ifnet *ifp) { - int s; struct mbuf *m_head; struct adapter *adapter = ifp->if_softc; + mtx_assert(&adapter->mtx, MA_OWNED); + if (!adapter->link_active) return; - s = splimp(); while (ifp->if_snd.ifq_head != NULL) { IF_DEQUEUE(&ifp->if_snd, m_head); @@ -563,10 +562,20 @@ ifp->if_timer = EM_TX_TIMEOUT; } - splx(s); return; } +static void +em_start(struct ifnet *ifp) +{ + struct adapter *adapter = ifp->if_softc; + + EM_LOCK(adapter); + em_start_locked(ifp); + EM_UNLOCK(adapter); + return; +} + /********************************************************************* * Ioctl entry point * @@ -579,11 +588,10 @@ static int em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { - int s, mask, error = 0; + int mask, error = 0; struct ifreq *ifr = (struct ifreq *) data; struct adapter * adapter = ifp->if_softc; - s = splimp(); switch (command) { case SIOCSIFADDR: case SIOCGIFADDR: @@ -595,17 +603,20 @@ if (ifr->ifr_mtu > MAX_JUMBO_FRAME_SIZE - ETHER_HDR_LEN) { error = EINVAL; } else { + EM_LOCK(adapter); ifp->if_mtu = ifr->ifr_mtu; adapter->hw.max_frame_size = ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; - em_init(adapter); + em_init_locked(adapter); + EM_UNLOCK(adapter); } break; case SIOCSIFFLAGS: IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)"); + EM_LOCK(adapter); if (ifp->if_flags & IFF_UP) { if (!(ifp->if_flags & IFF_RUNNING)) - em_init(adapter); + em_init_locked(adapter); em_disable_promisc(adapter); em_set_promisc(adapter); @@ -614,11 +625,13 @@ em_stop(adapter); } } + EM_UNLOCK(adapter); break; case SIOCADDMULTI: case SIOCDELMULTI: IOCTL_DEBUGOUT("ioctl rcv'd: SIOC(ADD|DEL)MULTI"); if (ifp->if_flags & IFF_RUNNING) { + EM_LOCK(adapter); em_disable_intr(adapter); em_set_multi(adapter); if (adapter->hw.mac_type == em_82542_rev2_0) { @@ -628,6 +641,7 @@ if (!(ifp->if_ipending & IFF_POLLING)) #endif em_enable_intr(adapter); + EM_UNLOCK(adapter); } break; case SIOCSIFMEDIA: @@ -652,7 +666,6 @@ error = EINVAL; } - splx(s); return(error); } @@ -700,15 +713,13 @@ **********************************************************************/ static void -em_init(void *arg) +em_init_locked(struct adapter * adapter) { - int s; struct ifnet *ifp; - struct adapter * adapter = arg; INIT_DEBUGOUT("em_init: begin"); - s = splimp(); + mtx_assert(&adapter->mtx, MA_OWNED); em_stop(adapter); @@ -716,7 +727,6 @@ if (em_hardware_init(adapter)) { printf("em%d: Unable to initialize the hardware\n", adapter->unit); - splx(s); return; } @@ -727,7 +737,6 @@ printf("em%d: Could not setup transmit structures\n", adapter->unit); em_stop(adapter); - splx(s); return; } em_initialize_transmit_unit(adapter); @@ -740,7 +749,6 @@ printf("em%d: Could not setup receive structures\n", adapter->unit); em_stop(adapter); - splx(s); return; } em_initialize_receive_unit(adapter); @@ -756,7 +764,7 @@ ifp->if_hwassist = 0; } - adapter->timer_handle = timeout(em_local_timer, adapter, 2*hz); + callout_reset(&adapter->timer, 2*hz, em_local_timer, adapter); em_clear_hw_cntrs(&adapter->hw); #ifdef DEVICE_POLLING /* @@ -769,7 +777,17 @@ #endif /* DEVICE_POLLING */ em_enable_intr(adapter); - splx(s); + return; +} + +static void +em_init(void *arg) +{ + struct adapter * adapter = arg; + + EM_LOCK(adapter); + em_init_locked(adapter); + EM_UNLOCK(adapter); return; } @@ -778,11 +796,13 @@ static poll_handler_t em_poll; static void -em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +em_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct adapter *adapter = ifp->if_softc; u_int32_t reg_icr; + mtx_assert(&adapter->mtx, MA_OWNED); + if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */ em_enable_intr(adapter); return; @@ -790,11 +810,11 @@ if (cmd == POLL_AND_CHECK_STATUS) { reg_icr = E1000_READ_REG(&adapter->hw, ICR); if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - untimeout(em_local_timer, adapter, adapter->timer_handle); + callout_stop(&adapter->timer); adapter->hw.get_link_status = 1; em_check_for_link(&adapter->hw); em_print_link_status(adapter); - adapter->timer_handle = timeout(em_local_timer, adapter, 2*hz); + callout_reset(&adapter->timer, 2*hz, em_local_timer, adapter); } } if (ifp->if_flags & IFF_RUNNING) { @@ -803,7 +823,17 @@ } if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) - em_start(ifp); + em_start_locked(ifp); +} + +static void +em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct adapter *adapter = ifp->if_softc; + + EM_LOCK(adapter); + em_poll_locked(ifp, cmd, count); + EM_UNLOCK(adapter); } #endif /* DEVICE_POLLING */ @@ -820,33 +850,37 @@ struct ifnet *ifp; struct adapter *adapter = arg; + EM_LOCK(adapter); + ifp = &adapter->interface_data.ac_if; #ifdef DEVICE_POLLING - if (ifp->if_ipending & IFF_POLLING) + if (ifp->if_ipending & IFF_POLLING) { + EM_UNLOCK(adapter); return; + } if (ether_poll_register(em_poll, ifp)) { em_disable_intr(adapter); em_poll(ifp, 0, 1); + EM_UNLOCK(adapter); return; } #endif /* DEVICE_POLLING */ reg_icr = E1000_READ_REG(&adapter->hw, ICR); if (!reg_icr) { + EM_UNLOCK(adapter); return; } /* Link status change */ if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { - untimeout(em_local_timer, adapter, - adapter->timer_handle); + callout_stop(&adapter->timer); adapter->hw.get_link_status = 1; em_check_for_link(&adapter->hw); em_print_link_status(adapter); - adapter->timer_handle = - timeout(em_local_timer, adapter, 2*hz); + callout_reset(&adapter->timer, 2*hz, em_local_timer, adapter); } while (loop_cnt > 0) { @@ -858,8 +892,9 @@ } if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) - em_start(ifp); + em_start_locked(ifp); + EM_UNLOCK(adapter); return; } @@ -1150,7 +1185,6 @@ static void em_82547_move_tail(void *arg) { - int s; struct adapter *adapter = arg; uint16_t hw_tdt; uint16_t sw_tdt; @@ -1158,7 +1192,7 @@ uint16_t length = 0; boolean_t eop = 0; - s = splimp(); + EM_LOCK(adapter); hw_tdt = E1000_READ_REG(&adapter->hw, TDT); sw_tdt = adapter->next_avail_tx_desc; @@ -1172,20 +1206,16 @@ if(eop) { if (em_82547_fifo_workaround(adapter, length)) { adapter->tx_fifo_wrk++; - adapter->tx_fifo_timer_handle = - timeout(em_82547_move_tail, - adapter, 1); - splx(s); - return; + callout_reset(&adapter->tx_fifo_timer, 1, + em_82547_move_tail, adapter); + break; } - else { - E1000_WRITE_REG(&adapter->hw, TDT, hw_tdt); - em_82547_update_fifo_head(adapter, length); - length = 0; - } + E1000_WRITE_REG(&adapter->hw, TDT, hw_tdt); + em_82547_update_fifo_head(adapter, length); + length = 0; } } - splx(s); + EM_UNLOCK(adapter); return; } @@ -1374,12 +1404,11 @@ static void em_local_timer(void *arg) { - int s; struct ifnet *ifp; struct adapter * adapter = arg; ifp = &adapter->interface_data.ac_if; - s = splimp(); + EM_LOCK(adapter); em_check_for_link(&adapter->hw); em_print_link_status(adapter); @@ -1389,9 +1418,9 @@ } em_smartspeed(adapter); - adapter->timer_handle = timeout(em_local_timer, adapter, 2*hz); + callout_reset(&adapter->timer, 2*hz, em_local_timer, adapter); - splx(s); + EM_UNLOCK(adapter); return; } @@ -1437,12 +1466,13 @@ struct adapter * adapter = arg; ifp = &adapter->interface_data.ac_if; + mtx_assert(&adapter->mtx, MA_OWNED); + INIT_DEBUGOUT("em_stop: begin\n"); em_disable_intr(adapter); em_reset_hw(&adapter->hw); - untimeout(em_local_timer, adapter, adapter->timer_handle); - untimeout(em_82547_move_tail, adapter, - adapter->tx_fifo_timer_handle); + callout_stop(&adapter->timer); + callout_stop(&adapter->tx_fifo_timer); em_free_transmit_structures(adapter); em_free_receive_structures(adapter); @@ -1545,7 +1575,8 @@ adapter->unit); return(ENXIO); } - if (bus_setup_intr(dev, adapter->res_interrupt, INTR_TYPE_NET, + if (bus_setup_intr(dev, adapter->res_interrupt, + INTR_TYPE_NET | INTR_MPSAFE, (void (*)(void *)) em_intr, adapter, &adapter->int_handler_tag)) { printf("em%d: Error registering interrupt handler!\n", @@ -2136,16 +2167,16 @@ static void em_clean_transmit_interrupts(struct adapter * adapter) { - int s; int i, num_avail; struct em_buffer *tx_buffer; struct em_tx_desc *tx_desc; struct ifnet *ifp = &adapter->interface_data.ac_if; + mtx_assert(&adapter->mtx, MA_OWNED); + if (adapter->num_tx_desc_avail == adapter->num_tx_desc) return; - s = splimp(); #ifdef DBG_STATS adapter->clean_tx_interrupts++; #endif @@ -2194,7 +2225,6 @@ ifp->if_timer = EM_TX_TIMEOUT; } adapter->num_tx_desc_avail = num_avail; - splx(s); return; } @@ -2495,6 +2525,8 @@ /* Pointer to the receive descriptor being examined. */ struct em_rx_desc *current_desc; + mtx_assert(&adapter->mtx, MA_OWNED); + ifp = &adapter->interface_data.ac_if; i = adapter->next_rx_desc_to_check; current_desc = &adapter->rx_desc_base[i]; @@ -2599,8 +2631,11 @@ E1000_RXD_SPC_VLAN_MASK), adapter->fmp = NULL); - if (adapter->fmp != NULL) + if (adapter->fmp != NULL) { + EM_UNLOCK(adapter); (*ifp->if_input)(ifp, adapter->fmp); + EM_LOCK(adapter); + } #endif adapter->fmp = NULL; adapter->lmp = NULL; ==== //depot/projects/netperf/sys/dev/em/if_em.h#2 (text+ko) ==== @@ -309,10 +309,11 @@ struct resource *res_interrupt; void *int_handler_tag; struct ifmedia media; - struct callout_handle timer_handle; - struct callout_handle tx_fifo_timer_handle; + struct callout timer; + struct callout tx_fifo_timer; int io_rid; u_int8_t unit; + struct mtx mtx; /* Info about the board itself */ u_int32_t part_num; @@ -390,4 +391,7 @@ struct em_hw_stats stats; }; +#define EM_LOCK(_sc) mtx_lock(&(_sc)->mtx) +#define EM_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) + #endif /* _EM_H_DEFINED_ */