commit 43bee598bd747dc6849d3c4f32a3a912200073c0
Author: James Chapman <[EMAIL PROTECTED]>
Date:   Sun Apr 6 23:41:29 2008 -0700

    PPPOL2TP: Fix SMP issues in skb reorder queue handling
    
    Upstream commit: e653181dd6b3ad38ce14904351b03a5388f4b0f7
    
    When walking a session's packet reorder queue, use
    skb_queue_walk_safe() since the list could be modified inside the
    loop.
    
    Rearrange the unlinking skbs from the reorder queue such that it is
    done while the queue lock is held in pppol2tp_recv_dequeue() when
    walking the skb list.
    
    A version of this patch was suggested by Jarek Poplawski.
    
    Signed-off-by: James Chapman <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
    Signed-off-by: Chris Wright <[EMAIL PROTECTED]>

diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index ff4a94b..88a7e4e 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -342,10 +342,11 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 
tunnel_id)
 static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct 
sk_buff *skb)
 {
        struct sk_buff *skbp;
+       struct sk_buff *tmp;
        u16 ns = PPPOL2TP_SKB_CB(skb)->ns;
 
        spin_lock_bh(&session->reorder_q.lock);
-       skb_queue_walk(&session->reorder_q, skbp) {
+       skb_queue_walk_safe(&session->reorder_q, skbp, tmp) {
                if (PPPOL2TP_SKB_CB(skbp)->ns > ns) {
                        __skb_insert(skb, skbp->prev, skbp, 
&session->reorder_q);
                        PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
@@ -371,10 +372,9 @@ static void pppol2tp_recv_dequeue_skb(struct 
pppol2tp_session *session, struct s
        int length = PPPOL2TP_SKB_CB(skb)->length;
        struct sock *session_sock = NULL;
 
-       /* We're about to requeue the skb, so unlink it and return resources
+       /* We're about to requeue the skb, so return resources
         * to its current owner (a socket receive buffer).
         */
-       skb_unlink(skb, &session->reorder_q);
        skb_orphan(skb);
 
        tunnel->stats.rx_packets++;
@@ -469,6 +469,11 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session 
*session)
                                goto out;
                        }
                }
+               __skb_unlink(skb, &session->reorder_q);
+
+               /* Process the skb. We release the queue lock while we
+                * do so to let other contexts process the queue.
+                */
                spin_unlock_bh(&session->reorder_q.lock);
                pppol2tp_recv_dequeue_skb(session, skb);
                spin_lock_bh(&session->reorder_q.lock);
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to