1. 06 May, 2016 2 commits
    • Jon Maxwell's avatar
      cnic: call cp->stop_hw() in cnic_start_hw() on allocation failure · f37bd0cc
      Jon Maxwell authored
      We recently had a system crash in the cnic module. Vmcore analysis confirmed
      that "ip link up" was executed which failed due to an allocation failure
      because of memory fragmentation. Futher analysis revealed that the cnic irq
      vector was still allocated after the "ip link up" that failed. When
      "ip link down" was executed it called free_msi_irqs() which crashed the system
      because the cnic irq was still inuse.
      
      PANIC: "kernel BUG at drivers/pci/msi.c:411!"
      
      The code execution was:
      
      cnic_netdev_event()
      if (event == NETDEV_UP) {
      .
      .
             ▹       if (!cnic_start_hw(dev))
      cnic_start_hw()
      calls cnic_cm_open() which failed with -ENOMEM
      cnic_start_hw() then took the err1 path:
      
      err1:
             cp->free_resc(dev); <---- frees resources but not irq vector
             pci_dev_put(dev->pcidev);
             return err;
      }
      
      This returns control back to cnic_netdev_event() but now the cnic irq vector
      is still allocated even although cnic_cm_open() failed. The next
      "ip link down" while trigger the crash.
      
      The cnic_start_hw() routine is not handling the allocation failure correctly.
      Fix this by checking whether CNIC_DRV_STATE_HANDLES_IRQ flag is set indicating
      that the hardware has been started in cnic_start_hw(). If it has then call
      cp->stop_hw() which frees the cnic irq vector and cnic resources. Otherwise
      just maintain the previous behaviour and free cnic resources.
      
      I reproduced this by injecting an ENOMEM error into cnic_cm_alloc_mem()s return
      code.
      
      # ip link set dev enpX down
      # ip link set dev enpX up <--- hit's allocation failure
      # ip link set dev enpX down <--- crashes here
      
      With this patch I confirmed there was no crash in the reproducer.
      Signed-off-by: default avatarJon Maxwell <jmaxwell37@gmail.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      f37bd0cc
    • Haggai Abramovsky's avatar
      net/mlx4: Avoid wrong virtual mappings · 73898db0
      Haggai Abramovsky authored
      The dma_alloc_coherent() function returns a virtual address which can
      be used for coherent access to the underlying memory.  On some
      architectures, like arm64, undefined behavior results if this memory is
      also accessed via virtual mappings that are not coherent.  Because of
      their undefined nature, operations like virt_to_page() return garbage
      when passed virtual addresses obtained from dma_alloc_coherent().  Any
      subsequent mappings via vmap() of the garbage page values are unusable
      and result in bad things like bus errors (synchronous aborts in ARM64
      speak).
      
      The mlx4 driver contains code that does the equivalent of:
      vmap(virt_to_page(dma_alloc_coherent)), this results in an OOPs when the
      device is opened.
      
      Prevent Ethernet driver to run this problematic code by forcing it to
      allocate contiguous memory. As for the Infiniband driver, at first we
      are trying to allocate contiguous memory, but in case of failure roll
      back to work with fragmented memory.
      Signed-off-by: default avatarHaggai Abramovsky <hagaya@mellanox.com>
      Signed-off-by: default avatarYishai Hadas <yishaih@mellanox.com>
      Reported-by: default avatarDavid Daney <david.daney@cavium.com>
      Tested-by: default avatarSinan Kaya <okaya@codeaurora.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      73898db0
  2. 05 May, 2016 2 commits
  3. 04 May, 2016 36 commits