lkml.org 
[lkml]   [2017]   [May]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.18 18/68] netpoll: Check for skb->queue_mapping
    Date
    3.18-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Tushar Dave <tushar.n.dave@oracle.com>


    [ Upstream commit c70b17b775edb21280e9de7531acf6db3b365274 ]

    Reducing real_num_tx_queues needs to be in sync with skb queue_mapping
    otherwise skbs with queue_mapping greater than real_num_tx_queues
    can be sent to the underlying driver and can result in kernel panic.

    One such event is running netconsole and enabling VF on the same
    device. Or running netconsole and changing number of tx queues via
    ethtool on same device.

    e.g.
    Unable to handle kernel NULL pointer dereference
    tsk->{mm,active_mm}->context = 0000000000001525
    tsk->{mm,active_mm}->pgd = fff800130ff9a000
    \|/ ____ \|/
    "@'/ .. \`@"
    /_| \__/ |_\
    \__U_/
    kworker/48:1(475): Oops [#1]
    CPU: 48 PID: 475 Comm: kworker/48:1 Tainted: G OE
    4.11.0-rc3-davem-net+ #7
    Workqueue: events queue_process
    task: fff80013113299c0 task.stack: fff800131132c000
    TSTATE: 0000004480e01600 TPC: 00000000103f9e3c TNPC: 00000000103f9e40 Y:
    00000000 Tainted: G OE
    TPC: <ixgbe_xmit_frame_ring+0x7c/0x6c0 [ixgbe]>
    g0: 0000000000000000 g1: 0000000000003fff g2: 0000000000000000 g3:
    0000000000000001
    g4: fff80013113299c0 g5: fff8001fa6808000 g6: fff800131132c000 g7:
    00000000000000c0
    o0: fff8001fa760c460 o1: fff8001311329a50 o2: fff8001fa7607504 o3:
    0000000000000003
    o4: fff8001f96e63a40 o5: fff8001311d77ec0 sp: fff800131132f0e1 ret_pc:
    000000000049ed94
    RPC: <set_next_entity+0x34/0xb80>
    l0: 0000000000000000 l1: 0000000000000800 l2: 0000000000000000 l3:
    0000000000000000
    l4: 000b2aa30e34b10d l5: 0000000000000000 l6: 0000000000000000 l7:
    fff8001fa7605028
    i0: fff80013111a8a00 i1: fff80013155a0780 i2: 0000000000000000 i3:
    0000000000000000
    i4: 0000000000000000 i5: 0000000000100000 i6: fff800131132f1a1 i7:
    00000000103fa4b0
    I7: <ixgbe_xmit_frame+0x30/0xa0 [ixgbe]>
    Call Trace:
    [00000000103fa4b0] ixgbe_xmit_frame+0x30/0xa0 [ixgbe]
    [0000000000998c74] netpoll_start_xmit+0xf4/0x200
    [0000000000998e10] queue_process+0x90/0x160
    [0000000000485fa8] process_one_work+0x188/0x480
    [0000000000486410] worker_thread+0x170/0x4c0
    [000000000048c6b8] kthread+0xd8/0x120
    [0000000000406064] ret_from_fork+0x1c/0x2c
    [0000000000000000] (null)
    Disabling lock debugging due to kernel taint
    Caller[00000000103fa4b0]: ixgbe_xmit_frame+0x30/0xa0 [ixgbe]
    Caller[0000000000998c74]: netpoll_start_xmit+0xf4/0x200
    Caller[0000000000998e10]: queue_process+0x90/0x160
    Caller[0000000000485fa8]: process_one_work+0x188/0x480
    Caller[0000000000486410]: worker_thread+0x170/0x4c0
    Caller[000000000048c6b8]: kthread+0xd8/0x120
    Caller[0000000000406064]: ret_from_fork+0x1c/0x2c
    Caller[0000000000000000]: (null)

    Signed-off-by: Tushar Dave <tushar.n.dave@oracle.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/core/netpoll.c | 10 ++++++++--
    1 file changed, 8 insertions(+), 2 deletions(-)

    --- a/net/core/netpoll.c
    +++ b/net/core/netpoll.c
    @@ -105,15 +105,21 @@ static void queue_process(struct work_st
    while ((skb = skb_dequeue(&npinfo->txq))) {
    struct net_device *dev = skb->dev;
    struct netdev_queue *txq;
    + unsigned int q_index;

    if (!netif_device_present(dev) || !netif_running(dev)) {
    kfree_skb(skb);
    continue;
    }

    - txq = skb_get_tx_queue(dev, skb);
    -
    local_irq_save(flags);
    + /* check if skb->queue_mapping is still valid */
    + q_index = skb_get_queue_mapping(skb);
    + if (unlikely(q_index >= dev->real_num_tx_queues)) {
    + q_index = q_index % dev->real_num_tx_queues;
    + skb_set_queue_mapping(skb, q_index);
    + }
    + txq = netdev_get_tx_queue(dev, q_index);
    HARD_TX_LOCK(dev, txq, smp_processor_id());
    if (netif_xmit_frozen_or_stopped(txq) ||
    netpoll_start_xmit(skb, dev, txq) != NETDEV_TX_OK) {

    \
     
     \ /
      Last update: 2017-05-05 20:57    [W:3.748 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site