kern/155030: [igb] igb(4) DEVICE_POLLING does not work with
carp(4)
Mark Johnston
markjdb at gmail.com
Fri Jun 22 01:40:05 UTC 2012
The following reply was made to PR kern/155030; it has been noted by GNATS.
From: Mark Johnston <markjdb at gmail.com>
To: bug-followup at FreeBSD.org, mm at FreeBSD.org
Cc:
Subject: Re: kern/155030: [igb] igb(4) DEVICE_POLLING does not work with
carp(4)
Date: Thu, 21 Jun 2012 21:38:36 -0400
--+HP7ph2BbKc20aGI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Another way to go is just to fix igb(4)'s polling routine to work with
multiple queues. That's what I've done in the src tree at my work; the
patch is attached.
Can you test it and let me know if it solves your problem? If so, I'll
bug jfv@ to commit it. =)
Thanks,
-Mark
--+HP7ph2BbKc20aGI
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="igb_polling.patch"
diff --git a/share/man/man4/polling.4 b/share/man/man4/polling.4
index 2c711cc..6abc37c 100644
--- a/share/man/man4/polling.4
+++ b/share/man/man4/polling.4
@@ -184,6 +184,7 @@ As of this writing, the
.Xr fwe 4 ,
.Xr fwip 4 ,
.Xr fxp 4 ,
+.Xr igb 4 ,
.Xr ixgb 4 ,
.Xr nfe 4 ,
.Xr nge 4 ,
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index cb6c63f..7a92b9a 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -1482,12 +1482,6 @@ igb_irq_fast(void *arg)
}
#ifdef DEVICE_POLLING
-/*********************************************************************
- *
- * Legacy polling routine : if using this code you MUST be sure that
- * multiqueue is not defined, ie, set igb_num_queues to 1.
- *
- *********************************************************************/
#if __FreeBSD_version >= 800000
#define POLL_RETURN_COUNT(a) (a)
static int
@@ -1498,11 +1492,12 @@ static void
igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
{
struct adapter *adapter = ifp->if_softc;
- struct igb_queue *que = adapter->queues;
- struct tx_ring *txr = adapter->tx_rings;
+ struct igb_queue *que;
+ struct tx_ring *txr;
u32 reg_icr, rx_done = 0;
u32 loop = IGB_MAX_LOOP;
bool more;
+ int i;
IGB_CORE_LOCK(adapter);
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
@@ -1521,20 +1516,26 @@ igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
}
IGB_CORE_UNLOCK(adapter);
- igb_rxeof(que, count, &rx_done);
+ for (i = 0; i < adapter->num_queues; i++) {
+ que = &adapter->queues[i];
+ txr = que->txr;
+
+ igb_rxeof(que, count, &rx_done);
- IGB_TX_LOCK(txr);
- do {
- more = igb_txeof(txr);
- } while (loop-- && more);
+ IGB_TX_LOCK(txr);
+ do {
+ more = igb_txeof(txr);
+ } while (loop-- && more);
#if __FreeBSD_version >= 800000
- if (!drbr_empty(ifp, txr->br))
- igb_mq_start_locked(ifp, txr, NULL);
+ if (!drbr_empty(ifp, txr->br))
+ igb_mq_start_locked(ifp, txr, NULL);
#else
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- igb_start_locked(txr, ifp);
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ igb_start_locked(txr, ifp);
#endif
- IGB_TX_UNLOCK(txr);
+ IGB_TX_UNLOCK(txr);
+ }
+
return POLL_RETURN_COUNT(rx_done);
}
#endif /* DEVICE_POLLING */
@@ -4846,7 +4847,7 @@ next_desc:
}
if (done != NULL)
- *done = rxdone;
+ *done += rxdone;
IGB_RX_UNLOCK(rxr);
return ((staterr & E1000_RXD_STAT_DD) ? TRUE : FALSE);
--+HP7ph2BbKc20aGI--
More information about the freebsd-net
mailing list