Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4fd7ab5949edfdf99be0ceef206c9d0b7f186318
Commit:     4fd7ab5949edfdf99be0ceef206c9d0b7f186318
Parent:     782e3b3b3804c38d5130c7f21d7ec7bf6709023f
Author:     Michael Chan <[EMAIL PROTECTED]>
AuthorDate: Fri Oct 12 01:39:50 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Fri Oct 12 02:01:20 2007 -0700

    [TG3]: Refine napi poll loop.
    
    Need to read and store sblk->status_tag before checking for more work.
    The status tag is later written back to the hardware when enabling
    interrupts to acknowledge how much work has been processed.  If the
    order is reversed, we can end up acknowledging work we haven't
    processed.
    
    When we detect tx error, it is more correct to return the rx
    work_done so far instead of 0.
    
    Signed-off-by: Michael Chan <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 drivers/net/tg3.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e795c33..30b1cca 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -3576,7 +3576,7 @@ static int tg3_poll_work(struct tg3 *tp, int work_done, 
int budget)
        if (sblk->idx[0].tx_consumer != tp->tx_cons) {
                tg3_tx(tp);
                if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
-                       return 0;
+                       return work_done;
        }
 
        /* run RX thread, within the bounds set by NAPI.
@@ -3593,6 +3593,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
 {
        struct tg3 *tp = container_of(napi, struct tg3, napi);
        int work_done = 0;
+       struct tg3_hw_status *sblk = tp->hw_status;
 
        while (1) {
                work_done = tg3_poll_work(tp, work_done, budget);
@@ -3603,15 +3604,17 @@ static int tg3_poll(struct napi_struct *napi, int 
budget)
                if (unlikely(work_done >= budget))
                        break;
 
-               if (likely(!tg3_has_work(tp))) {
-                       struct tg3_hw_status *sblk = tp->hw_status;
-
-                       if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
-                               tp->last_tag = sblk->status_tag;
-                               rmb();
-                       } else
-                               sblk->status &= ~SD_STATUS_UPDATED;
+               if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
+                       /* tp->last_tag is used in tg3_restart_ints() below
+                        * to tell the hw how much work has been processed,
+                        * so we must read it before checking for more work.
+                        */
+                       tp->last_tag = sblk->status_tag;
+                       rmb();
+               } else
+                       sblk->status &= ~SD_STATUS_UPDATED;
 
+               if (likely(!tg3_has_work(tp))) {
                        netif_rx_complete(tp->dev, napi);
                        tg3_restart_ints(tp);
                        break;
@@ -3621,9 +3624,10 @@ static int tg3_poll(struct napi_struct *napi, int budget)
        return work_done;
 
 tx_recovery:
+       /* work_done is guaranteed to be less than budget. */
        netif_rx_complete(tp->dev, napi);
        schedule_work(&tp->reset_task);
-       return 0;
+       return work_done;
 }
 
 static void tg3_irq_quiesce(struct tg3 *tp)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to