From 9b562f1928fb5506dd95a9d8705ef2921d07e233 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 19 Dec 2010 17:24:29 -0800 Subject: [PATCH] kernel - Implement POLLING support for if_igb, change token->lockmgr lock * Clean up the polling code so it works. * Use a lockmgr lock instead of a token, the original driver writer expected a normal lock. --- sys/dev/netif/e1000/if_igb.c | 50 +++++++++++------------------------- sys/dev/netif/e1000/if_igb.h | 38 +++++++++++++-------------- 2 files changed, 34 insertions(+), 54 deletions(-) diff --git a/sys/dev/netif/e1000/if_igb.c b/sys/dev/netif/e1000/if_igb.c index 76df3a70ff..f71c3ad994 100644 --- a/sys/dev/netif/e1000/if_igb.c +++ b/sys/dev/netif/e1000/if_igb.c @@ -32,11 +32,8 @@ ******************************************************************************/ -#ifdef HAVE_KERNEL_OPTION_HEADERS -#include "opt_device_polling.h" +#include "opt_polling.h" #include "opt_inet.h" -#include "opt_altq.h" -#endif #include #include @@ -45,6 +42,7 @@ #endif #include #include +#include #include #include #include @@ -642,11 +640,6 @@ igb_detach(device_t dev) return (EBUSY); } -#ifdef DEVICE_POLLING - if (adapter->ifp->if_capenable & IFCAP_POLLING) - ether_poll_deregister(adapter->ifp); -#endif - IGB_CORE_LOCK(adapter); adapter->in_detach = 1; igb_stop(adapter); @@ -1003,7 +996,7 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cred) igb_disable_intr(adapter); igb_set_multi(adapter); #ifdef DEVICE_POLLING - if (!(ifp->if_capenable & IFCAP_POLLING)) + if ((ifp->if_flags & IFF_POLLING) == 0) #endif igb_enable_intr(adapter); IGB_CORE_UNLOCK(adapter); @@ -1032,23 +1025,10 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cred) reinit = 0; mask = ifr->ifr_reqcap ^ ifp->if_capenable; #ifdef DEVICE_POLLING - if (mask & IFCAP_POLLING) { - if (ifr->ifr_reqcap & IFCAP_POLLING) { - error = ether_poll_register(igb_poll, ifp); - if (error) - return (error); - IGB_CORE_LOCK(adapter); - igb_disable_intr(adapter); - ifp->if_capenable |= IFCAP_POLLING; - IGB_CORE_UNLOCK(adapter); - } else { - error = ether_poll_deregister(ifp); - /* Enable interrupt even in error case */ - IGB_CORE_LOCK(adapter); - igb_enable_intr(adapter); - ifp->if_capenable &= ~IFCAP_POLLING; - IGB_CORE_UNLOCK(adapter); - } + if (ifp->if_flags & IFF_POLLING) { + IGB_CORE_LOCK(adapter); + igb_disable_intr(adapter); + IGB_CORE_UNLOCK(adapter); } #endif if (mask & IFCAP_HWCSUM) { @@ -1187,7 +1167,7 @@ igb_init_locked(struct adapter *adapter) * Only enable interrupts if we are not polling, make sure * they are off otherwise. */ - if (ifp->if_capenable & IFCAP_POLLING) + if (ifp->if_flags & IFF_POLLING) igb_disable_intr(adapter); else #endif /* DEVICE_POLLING */ @@ -1272,9 +1252,9 @@ igb_handle_que(void *context, int pending) /* Reenable this interrupt */ #ifdef DEVICE_POLLING - if (!(ifp->if_capenable & IFCAP_POLLING)) + if ((ifp->if_flags & IFF_POLLING) == 0) #endif - E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims); + E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims); } /* Deal with link in a sleepable context */ @@ -1927,9 +1907,9 @@ igb_local_timer(void *arg) /* Trigger an RX interrupt on all queues */ #ifdef DEVICE_POLLING - if (!(ifp->if_capenable & IFCAP_POLLING)) + if ((ifp->if_flags & IFF_POLLING) == 0) #endif - E1000_WRITE_REG(&adapter->hw, E1000_EICS, adapter->rx_mask); + E1000_WRITE_REG(&adapter->hw, E1000_EICS, adapter->rx_mask); callout_reset(&adapter->timer, hz, igb_local_timer, adapter); IGB_CORE_UNLOCK(adapter); return; @@ -2677,6 +2657,9 @@ igb_setup_interface(device_t dev, struct adapter *adapter) ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = igb_ioctl; ifp->if_start = igb_start; +#ifdef DEVICE_POLLING + ifp->if_poll = igb_poll; +#endif #if __FreeBSD_version >= 800000 ifp->if_transmit = igb_mq_start; ifp->if_qflush = igb_qflush; @@ -2699,9 +2682,6 @@ igb_setup_interface(device_t dev, struct adapter *adapter) #endif ifp->if_capenable = ifp->if_capabilities; -#ifdef DEVICE_POLLING - ifp->if_capabilities |= IFCAP_POLLING; -#endif /* * Tell the upper layer(s) we support long frames. diff --git a/sys/dev/netif/e1000/if_igb.h b/sys/dev/netif/e1000/if_igb.h index 5bae9671f7..403bb0728e 100644 --- a/sys/dev/netif/e1000/if_igb.h +++ b/sys/dev/netif/e1000/if_igb.h @@ -297,7 +297,7 @@ struct igb_queue { struct tx_ring { struct adapter *adapter; u32 me; - struct lwkt_token tx_token; + struct lock tx_lock; char spin_name[16]; struct igb_dma_alloc txdma; struct e1000_tx_desc *tx_base; @@ -333,7 +333,7 @@ struct rx_ring { bool lro_enabled; bool hdr_split; bool discard; - struct lwkt_token rx_token; + struct lock rx_lock; char spin_name[16]; u32 last_cleaned; u32 next_to_check; @@ -384,7 +384,7 @@ struct adapter { int if_flags; int max_frame_size; int min_frame_size; - struct lwkt_token core_token; + struct lock core_lock; int igb_insert_vlan_header; struct task rxtx_task; struct taskqueue *tq; /* adapter task queue */ @@ -479,26 +479,26 @@ struct igb_rx_buf { bus_dmamap_t pack_map; /* bus_dma map for packet */ }; -#define IGB_CORE_LOCK_INIT(_sc, _name) lwkt_token_init(&(_sc)->core_token, \ - 1, "igb") -#define IGB_CORE_LOCK_DESTROY(_sc) lwkt_token_uninit(&(_sc)->core_token) -#define IGB_CORE_LOCK(_sc) lwkt_gettoken(&(_sc)->core_token) -#define IGB_CORE_UNLOCK(_sc) lwkt_reltoken(&(_sc)->core_token) +#define IGB_CORE_LOCK_INIT(_sc, _name) lockinit(&(_sc)->core_lock, \ + "igb", 0, 0) +#define IGB_CORE_LOCK_DESTROY(_sc) lockuninit(&(_sc)->core_lock) +#define IGB_CORE_LOCK(_sc) lockmgr(&(_sc)->core_lock, LK_EXCLUSIVE) +#define IGB_CORE_UNLOCK(_sc) lockmgr(&(_sc)->core_lock, LK_RELEASE) #define IGB_CORE_LOCK_ASSERT(_sc) -#define IGB_TX_LOCK_INIT(_sc) lwkt_token_init(&(_sc)->tx_token, \ - 1, "igbtx") -#define IGB_TX_LOCK_DESTROY(_sc) lwkt_token_uninit(&(_sc)->tx_token) -#define IGB_TX_LOCK(_sc) lwkt_gettoken(&(_sc)->tx_token) -#define IGB_TX_UNLOCK(_sc) lwkt_reltoken(&(_sc)->tx_token) -#define IGB_TX_TRYLOCK(_sc) lwkt_trytoken(&(_sc)->tx_token) +#define IGB_TX_LOCK_INIT(_sc) lockinit(&(_sc)->tx_lock, \ + "igbtx", 0, 0) +#define IGB_TX_LOCK_DESTROY(_sc) lockuninit(&(_sc)->tx_lock) +#define IGB_TX_LOCK(_sc) lockmgr(&(_sc)->tx_lock, LK_EXCLUSIVE) +#define IGB_TX_UNLOCK(_sc) lockmgr(&(_sc)->tx_lock, LK_RELEASE) +#define IGB_TX_TRYLOCK(_sc) lockmgr(&(_sc)->tx_lock, LK_EXCLUSIVE|LK_NOWAIT) #define IGB_TX_LOCK_ASSERT(_sc) -#define IGB_RX_LOCK_INIT(_sc) lwkt_token_init(&(_sc)->rx_token, \ - 1, "igbrx") -#define IGB_RX_LOCK_DESTROY(_sc) lwkt_token_uninit(&(_sc)->rx_token) -#define IGB_RX_LOCK(_sc) lwkt_gettoken(&(_sc)->rx_token) -#define IGB_RX_UNLOCK(_sc) lwkt_reltoken(&(_sc)->rx_token) +#define IGB_RX_LOCK_INIT(_sc) lockinit(&(_sc)->rx_lock, \ + "igbrx", 0, 0) +#define IGB_RX_LOCK_DESTROY(_sc) lockuninit(&(_sc)->rx_lock) +#define IGB_RX_LOCK(_sc) lockmgr(&(_sc)->rx_lock, LK_EXCLUSIVE) +#define IGB_RX_UNLOCK(_sc) lockmgr(&(_sc)->rx_lock, LK_RELEASE) #define IGB_TX_LOCK_ASSERT(_sc) #endif /* _IGB_H_DEFINED_ */ -- 2.41.0