• Pravin B Shelar's avatar
    net: Fix zero-copy head len calculation. · a17ad096
    Pravin B Shelar authored
    In some cases skb head could be locked and entire header
    data is pulled from skb. When skb_zerocopy() called in such cases,
    following BUG is triggered. This patch fixes it by copying entire
    skb in such cases.
    This could be optimized incase this is performance bottleneck.
    
    ---8<---
    kernel BUG at net/core/skbuff.c:2961!
    invalid opcode: 0000 [#1] SMP PTI
    CPU: 2 PID: 0 Comm: swapper/2 Tainted: G           OE     5.4.0-77-generic #86-Ubuntu
    Hardware name: OpenStack Foundation OpenStack Nova, BIOS 1.13.0-1ubuntu1.1 04/01/2014
    RIP: 0010:skb_zerocopy+0x37a/0x3a0
    RSP: 0018:ffffbcc70013ca38 EFLAGS: 00010246
    Call Trace:
     <IRQ>
     queue_userspace_packet+0x2af/0x5e0 [openvswitch]
     ovs_dp_upcall+0x3d/0x60 [openvswitch]
     ovs_dp_process_packet+0x125/0x150 [openvswitch]
     ovs_vport_receive+0x77/0xd0 [openvswitch]
     netdev_port_receive+0x87/0x130 [openvswitch]
     netdev_frame_hook+0x4b/0x60 [openvswitch]
     __netif_receive_skb_core+0x2b4/0xc90
     __netif_receive_skb_one_core+0x3f/0xa0
     __netif_receive_skb+0x18/0x60
     process_backlog+0xa9/0x160
     net_rx_action+0x142/0x390
     __do_softirq+0xe1/0x2d6
     irq_exit+0xae/0xb0
     do_IRQ+0x5a/0xf0
     common_interrupt+0xf/0xf
    
    Code that triggered BUG:
    int
    skb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len, int hlen)
    {
            int i, j = 0;
            int plen = 0; /* length of skb->head fragment */
            int ret;
            struct page *page;
            unsigned int offset;
    
            BUG_ON(!from->head_frag && !hlen);
    Signed-off-by: default avatarPravin B Shelar <pshelar@ovn.org>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    a17ad096
skbuff.c 161 KB