lkml.org 
[lkml]   [2008]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectPPPOL2TP: Fix SMP issues in skb reorder queue handling
    -stable review patch.  If anyone has any objections, please let us know.
    ---------------------

    From: James Chapman <jchapman@katalix.com>

    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 <jchapman@katalix.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Chris Wright <chrisw@sous-sol.org>
    ---
    drivers/net/pppol2tp.c | 11 ++++++++---
    1 file changed, 8 insertions(+), 3 deletions(-)

    --- a/drivers/net/pppol2tp.c
    +++ b/drivers/net/pppol2tp.c
    @@ -342,10 +342,11 @@ static struct pppol2tp_tunnel *pppol2tp_
    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(st
    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
    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);
    --


    \
     
     \ /
      Last update: 2008-04-17 03:15    [W:0.030 / U:0.036 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site