Changes from John Baldwin adding to last commit,
change rxeof api for poll friendliness, and eliminate unnecessary link tasklet use. Thanks John!
This commit is contained in:
parent
1c0174e29a
commit
73fa18d121
@ -231,7 +231,7 @@ static void em_enable_intr(struct adapter *);
|
||||
static void em_disable_intr(struct adapter *);
|
||||
static void em_update_stats_counters(struct adapter *);
|
||||
static bool em_txeof(struct tx_ring *);
|
||||
static int em_rxeof(struct rx_ring *, int);
|
||||
static bool em_rxeof(struct rx_ring *, int, int *);
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
static int em_fixup_rx(struct rx_ring *);
|
||||
#endif
|
||||
@ -1356,12 +1356,13 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
struct adapter *adapter = ifp->if_softc;
|
||||
struct tx_ring *txr = adapter->tx_rings;
|
||||
struct rx_ring *rxr = adapter->rx_rings;
|
||||
u32 reg_icr, rx_done = 0;
|
||||
u32 reg_icr;
|
||||
int rx_done;
|
||||
|
||||
EM_CORE_LOCK(adapter);
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
|
||||
EM_CORE_UNLOCK(adapter);
|
||||
return (rx_done);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (cmd == POLL_AND_CHECK_STATUS) {
|
||||
@ -1376,7 +1377,7 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
}
|
||||
EM_CORE_UNLOCK(adapter);
|
||||
|
||||
rx_done = em_rxeof(rxr, count);
|
||||
em_rxeof(rxr, count, &rx_done);
|
||||
|
||||
EM_TX_LOCK(txr);
|
||||
em_txeof(txr);
|
||||
@ -1448,14 +1449,15 @@ em_handle_que(void *context, int pending)
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
struct tx_ring *txr = adapter->tx_rings;
|
||||
struct rx_ring *rxr = adapter->rx_rings;
|
||||
bool more_rx;
|
||||
bool more;
|
||||
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
more_rx = em_rxeof(rxr, adapter->rx_process_limit);
|
||||
more = em_rxeof(rxr, adapter->rx_process_limit, NULL);
|
||||
|
||||
EM_TX_LOCK(txr);
|
||||
em_txeof(txr);
|
||||
if (em_txeof(txr))
|
||||
more = TRUE;
|
||||
#ifdef EM_MULTIQUEUE
|
||||
if (!drbr_empty(ifp, txr->br))
|
||||
em_mq_start_locked(ifp, txr, NULL);
|
||||
@ -1464,7 +1466,7 @@ em_handle_que(void *context, int pending)
|
||||
em_start_locked(ifp, txr);
|
||||
#endif
|
||||
EM_TX_UNLOCK(txr);
|
||||
if (more_rx) {
|
||||
if (more) {
|
||||
taskqueue_enqueue(adapter->tq, &adapter->que_task);
|
||||
return;
|
||||
}
|
||||
@ -1513,7 +1515,7 @@ em_msix_rx(void *arg)
|
||||
bool more;
|
||||
|
||||
++rxr->rx_irq;
|
||||
more = em_rxeof(rxr, adapter->rx_process_limit);
|
||||
more = em_rxeof(rxr, adapter->rx_process_limit, NULL);
|
||||
if (more)
|
||||
taskqueue_enqueue(rxr->tq, &rxr->rx_task);
|
||||
else
|
||||
@ -1538,7 +1540,7 @@ em_msix_link(void *arg)
|
||||
|
||||
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
|
||||
adapter->hw.mac.get_link_status = 1;
|
||||
taskqueue_enqueue(taskqueue_fast, &adapter->link_task);
|
||||
em_handle_link(adapter, 0);
|
||||
} else
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_IMS,
|
||||
EM_MSIX_LINK | E1000_IMS_LSC);
|
||||
@ -1552,7 +1554,7 @@ em_handle_rx(void *context, int pending)
|
||||
struct adapter *adapter = rxr->adapter;
|
||||
bool more;
|
||||
|
||||
more = em_rxeof(rxr, adapter->rx_process_limit);
|
||||
more = em_rxeof(rxr, adapter->rx_process_limit, NULL);
|
||||
if (more)
|
||||
taskqueue_enqueue(rxr->tq, &rxr->rx_task);
|
||||
else
|
||||
@ -2428,11 +2430,6 @@ em_allocate_msix(struct adapter *adapter)
|
||||
adapter->linkvec = vector;
|
||||
adapter->ivars |= (8 | vector) << 16;
|
||||
adapter->ivars |= 0x80000000;
|
||||
TASK_INIT(&adapter->link_task, 0, em_handle_link, adapter);
|
||||
adapter->tq = taskqueue_create_fast("em_link", M_NOWAIT,
|
||||
taskqueue_thread_enqueue, &adapter->tq);
|
||||
taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s linkq",
|
||||
device_get_nameunit(adapter->dev));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -4087,8 +4084,8 @@ em_initialize_receive_unit(struct adapter *adapter)
|
||||
*
|
||||
* For polling we also now return the number of cleaned packets
|
||||
*********************************************************************/
|
||||
static int
|
||||
em_rxeof(struct rx_ring *rxr, int count)
|
||||
static bool
|
||||
em_rxeof(struct rx_ring *rxr, int count, int *done)
|
||||
{
|
||||
struct adapter *adapter = rxr->adapter;
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
@ -4215,13 +4212,11 @@ skip:
|
||||
}
|
||||
|
||||
rxr->next_to_check = i;
|
||||
if (done != NULL)
|
||||
*done = rxdone;
|
||||
EM_RX_UNLOCK(rxr);
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
return (rxdone);
|
||||
#else
|
||||
return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
|
@ -205,7 +205,7 @@ static __inline void igb_rx_discard(struct rx_ring *, int);
|
||||
static __inline void igb_rx_input(struct rx_ring *,
|
||||
struct ifnet *, struct mbuf *, u32);
|
||||
|
||||
static bool igb_rxeof(struct igb_queue *, int);
|
||||
static bool igb_rxeof(struct igb_queue *, int, int *);
|
||||
static void igb_rx_checksum(u32, struct mbuf *, u32);
|
||||
static int igb_tx_ctx_setup(struct tx_ring *, struct mbuf *);
|
||||
static bool igb_tso_setup(struct tx_ring *, struct mbuf *, u32 *);
|
||||
@ -1234,13 +1234,15 @@ igb_handle_que(void *context, int pending)
|
||||
struct adapter *adapter = que->adapter;
|
||||
struct tx_ring *txr = que->txr;
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
bool more;
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
more = igb_rxeof(que, -1);
|
||||
bool more;
|
||||
|
||||
more = igb_rxeof(que, -1, NULL);
|
||||
|
||||
IGB_TX_LOCK(txr);
|
||||
igb_txeof(txr);
|
||||
if (igb_txeof(txr))
|
||||
more = TRUE;
|
||||
#if __FreeBSD_version >= 800000
|
||||
if (!drbr_empty(ifp, txr->br))
|
||||
igb_mq_start_locked(ifp, txr, NULL);
|
||||
@ -1353,15 +1355,14 @@ igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
|
||||
/* Link status change */
|
||||
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))
|
||||
taskqueue_enqueue(que->tq, &adapter->link_task);
|
||||
igb_handle_link(adapter, 0);
|
||||
|
||||
if (reg_icr & E1000_ICR_RXO)
|
||||
adapter->rx_overruns++;
|
||||
}
|
||||
IGB_CORE_UNLOCK(adapter);
|
||||
|
||||
/* TODO: rx_count */
|
||||
rx_done = igb_rxeof(que, count) ? 1 : 0;
|
||||
igb_rxeof(que, count, &rx_done);
|
||||
|
||||
IGB_TX_LOCK(txr);
|
||||
do {
|
||||
@ -1401,7 +1402,7 @@ igb_msix_que(void *arg)
|
||||
more_tx = igb_txeof(txr);
|
||||
IGB_TX_UNLOCK(txr);
|
||||
|
||||
more_rx = igb_rxeof(que, adapter->rx_process_limit);
|
||||
more_rx = igb_rxeof(que, adapter->rx_process_limit, NULL);
|
||||
|
||||
if (igb_enable_aim == FALSE)
|
||||
goto no_calc;
|
||||
@ -1481,7 +1482,7 @@ igb_msix_link(void *arg)
|
||||
icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
|
||||
if (!(icr & E1000_ICR_LSC))
|
||||
goto spurious;
|
||||
taskqueue_enqueue(adapter->tq, &adapter->link_task);
|
||||
igb_handle_link(adapter, 0);
|
||||
|
||||
spurious:
|
||||
/* Rearm */
|
||||
@ -2212,13 +2213,6 @@ igb_allocate_msix(struct adapter *adapter)
|
||||
#endif
|
||||
adapter->linkvec = vector;
|
||||
|
||||
/* Make tasklet for deferred handling */
|
||||
TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter);
|
||||
adapter->tq = taskqueue_create_fast("igb_link", M_NOWAIT,
|
||||
taskqueue_thread_enqueue, &adapter->tq);
|
||||
taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s link",
|
||||
device_get_nameunit(adapter->dev));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -4199,14 +4193,14 @@ igb_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype)
|
||||
* Return TRUE if more to clean, FALSE otherwise
|
||||
*********************************************************************/
|
||||
static bool
|
||||
igb_rxeof(struct igb_queue *que, int count)
|
||||
igb_rxeof(struct igb_queue *que, int count, int *done)
|
||||
{
|
||||
struct adapter *adapter = que->adapter;
|
||||
struct rx_ring *rxr = que->rxr;
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
struct lro_ctrl *lro = &rxr->lro;
|
||||
struct lro_entry *queued;
|
||||
int i, processed = 0;
|
||||
int i, processed = 0, rxdone = 0;
|
||||
u32 ptype, staterr = 0;
|
||||
union e1000_adv_rx_desc *cur;
|
||||
|
||||
@ -4359,6 +4353,7 @@ next_desc:
|
||||
rxr->next_to_check = i;
|
||||
igb_rx_input(rxr, ifp, sendmp, ptype);
|
||||
i = rxr->next_to_check;
|
||||
rxdone++;
|
||||
}
|
||||
|
||||
/* Every 8 descriptors we go to refresh mbufs */
|
||||
@ -4386,6 +4381,9 @@ next_desc:
|
||||
|
||||
IGB_RX_UNLOCK(rxr);
|
||||
|
||||
if (done != NULL)
|
||||
*done = rxdone;
|
||||
|
||||
/*
|
||||
** We still have cleaning to do?
|
||||
** Schedule another interrupt if so.
|
||||
|
@ -382,7 +382,6 @@ struct adapter {
|
||||
int min_frame_size;
|
||||
struct mtx core_mtx;
|
||||
int igb_insert_vlan_header;
|
||||
struct taskqueue *tq; /* adapter task queue */
|
||||
u16 num_queues;
|
||||
|
||||
eventhandler_tag vlan_attach;
|
||||
|
@ -200,7 +200,7 @@ static void lem_txeof(struct adapter *);
|
||||
static void lem_tx_purge(struct adapter *);
|
||||
static int lem_allocate_receive_structures(struct adapter *);
|
||||
static int lem_allocate_transmit_structures(struct adapter *);
|
||||
static int lem_rxeof(struct adapter *, int);
|
||||
static bool lem_rxeof(struct adapter *, int, int *);
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
static int lem_fixup_rx(struct adapter *);
|
||||
#endif
|
||||
@ -1255,7 +1255,7 @@ lem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
}
|
||||
EM_CORE_UNLOCK(adapter);
|
||||
|
||||
rx_done = lem_rxeof(adapter, count);
|
||||
lem_rxeof(adapter, count, &rx_done);
|
||||
|
||||
EM_TX_LOCK(adapter);
|
||||
lem_txeof(adapter);
|
||||
@ -1308,7 +1308,7 @@ lem_intr(void *arg)
|
||||
|
||||
EM_TX_LOCK(adapter);
|
||||
lem_txeof(adapter);
|
||||
lem_rxeof(adapter, -1);
|
||||
lem_rxeof(adapter, -1, NULL);
|
||||
lem_txeof(adapter);
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
|
||||
!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
@ -1350,7 +1350,7 @@ lem_handle_rxtx(void *context, int pending)
|
||||
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
if (lem_rxeof(adapter, adapter->rx_process_limit) != 0)
|
||||
if (lem_rxeof(adapter, adapter->rx_process_limit, NULL) != 0)
|
||||
taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
|
||||
EM_TX_LOCK(adapter);
|
||||
lem_txeof(adapter);
|
||||
@ -3449,8 +3449,8 @@ lem_free_receive_structures(struct adapter *adapter)
|
||||
*
|
||||
* For polling we also now return the number of cleaned packets
|
||||
*********************************************************************/
|
||||
static int
|
||||
lem_rxeof(struct adapter *adapter, int count)
|
||||
static bool
|
||||
lem_rxeof(struct adapter *adapter, int count, int *done)
|
||||
{
|
||||
struct ifnet *ifp = adapter->ifp;;
|
||||
struct mbuf *mp;
|
||||
@ -3466,8 +3466,10 @@ lem_rxeof(struct adapter *adapter, int count)
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
|
||||
if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
|
||||
if (done != NULL)
|
||||
*done = rx_sent;
|
||||
EM_RX_UNLOCK(adapter);
|
||||
return (rx_sent);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
while ((current_desc->status & E1000_RXD_STAT_DD) &&
|
||||
@ -3626,8 +3628,10 @@ discard:
|
||||
if (--i < 0)
|
||||
i = adapter->num_rx_desc - 1;
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
|
||||
if (done != NULL)
|
||||
*done = rx_sent;
|
||||
EM_RX_UNLOCK(adapter);
|
||||
return (rx_sent);
|
||||
return (current_desc->status & E1000_RXD_STAT_DD);
|
||||
}
|
||||
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
|
Loading…
x
Reference in New Issue
Block a user