Skip to content

Commit

Permalink
[TG3]: Remove status block access in tg3_msi() and add prefetches
Browse files Browse the repository at this point in the history
Remove unnecessary status block accesses in tg3_msi(). Since MSI is
not shared, it is unnecessary to read the status block to determine if
there are any new events in the MSI handler. It is also unnecessary to
clear the updated bit in the status block.

Since the poll list is per-cpu, tg3_poll() will be scheduled to run on
the same CPU that received the MSI. Prefetches for the status block
and the next rx descriptors are added in tg3_msi() to improve their
access times when tg3_poll() runs.

In the non-MSI irq handlers, we need to check the status block because
interrupts may be shared. Only prefetches for the next rx descriptors
are added.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Michael Chan authored and David S. Miller committed Sep 6, 2005
1 parent 9f40dea commit 6148748
Showing 1 changed file with 11 additions and 17 deletions.
28 changes: 11 additions & 17 deletions drivers/net/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/workqueue.h>
#include <linux/prefetch.h>

#include <net/checksum.h>

Expand Down Expand Up @@ -3278,8 +3279,9 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
struct tg3 *tp = netdev_priv(dev);
struct tg3_hw_status *sblk = tp->hw_status;

prefetch(tp->hw_status);
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
/*
* Writing any value to intr-mbox-0 clears PCI INTA# and
* chip-internal interrupt pending events.
Expand All @@ -3288,19 +3290,9 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
* event coalescing.
*/
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
tp->last_tag = sblk->status_tag;
rmb();
if (tg3_irq_sync(tp))
goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp)))
if (likely(!tg3_irq_sync(tp)))
netif_rx_schedule(dev); /* schedule NAPI poll */
else {
/* No work, re-enable interrupts. */
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
tp->last_tag << 24);
}
out:

return IRQ_RETVAL(1);
}

Expand Down Expand Up @@ -3330,9 +3322,10 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (tg3_irq_sync(tp))
goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp)))
if (likely(tg3_has_work(tp))) {
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
netif_rx_schedule(dev); /* schedule NAPI poll */
else {
} else {
/* No work, shared interrupt perhaps? re-enable
* interrupts, and flush that PCI write
*/
Expand Down Expand Up @@ -3374,9 +3367,10 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
if (tg3_irq_sync(tp))
goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp)))
if (likely(tg3_has_work(tp))) {
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
netif_rx_schedule(dev); /* schedule NAPI poll */
else {
} else {
/* no work, shared interrupt perhaps? re-enable
* interrupts, and flush that PCI write
*/
Expand Down

0 comments on commit 6148748

Please sign in to comment.