Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3ebebccf89b1b6e4fec4de05b245d6c459f27ce8
Commit:     3ebebccf89b1b6e4fec4de05b245d6c459f27ce8
Parent:     792dd90f114a48c210c566f3642b26f699702cb7
Author:     David S. Miller <[EMAIL PROTECTED]>
AuthorDate: Fri Jan 4 23:54:06 2008 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Tue Jan 8 23:29:56 2008 -0800

    [NIU]: Fix potentially stuck TCP socket send queues.
    
    It is possible for the TX ring to have packets sit in it for unbounded
    amounts of time.
    
    The only way to defer TX interrupts in the chip is to periodically set
    "mark" bits, when processing of a TX descriptor with the mark bit set
    is complete it triggers the interrupt for the TX queue's LDG.
    
    A consequence of this kind of scheme is that if packet flow suddenly
    stops, the remaining TX packets will just sit there.
    
    If this happens, since those packets could be charged to TCP socket
    send queues, such sockets could get stuck.
    
    The simplest solution is to divorce the socket ownership of the packet
    once the device takes the SKB, by using skb_orphan() in
    niu_start_xmit().
    
    In hindsight, it would have been much nicer if the chip provided two
    interrupt sources for TX (like basically every other ethernet chip
    does).  Namely, keep the "mark" bit, but also signal the LDG when the
    TX queue becomes completely empty.  That way there is no need to have
    a deadlock breaker like this.
    
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 drivers/net/niu.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index babb1ef..ac36164 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -5208,7 +5208,8 @@ static int niu_start_xmit(struct sk_buff *skb, struct 
net_device *dev)
                }
                kfree_skb(skb);
                skb = skb_new;
-       }
+       } else
+               skb_orphan(skb);
 
        align = ((unsigned long) skb->data & (16 - 1));
        headroom = align + sizeof(struct tx_pkt_hdr);
-
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