linux/drivers/infiniband/ulp/ipoib
Erez Shitrit 16ba3defb8 IB/ipoib: Fix race condition in neigh creation
When using enhanced mode for IPoIB, two threads may execute xmit in
parallel to two different TX queues while the target is the same.
In this case, both of them will add the same neighbor to the path's
neigh link list and we might see the following message:

  list_add double add: new=ffff88024767a348, prev=ffff88024767a348...
  WARNING: lib/list_debug.c:31__list_add_valid+0x4e/0x70
  ipoib_start_xmit+0x477/0x680 [ib_ipoib]
  dev_hard_start_xmit+0xb9/0x3e0
  sch_direct_xmit+0xf9/0x250
  __qdisc_run+0x176/0x5d0
  __dev_queue_xmit+0x1f5/0xb10
  __dev_queue_xmit+0x55/0xb10

Analysis:
Two SKB are scheduled to be transmitted from two cores.
In ipoib_start_xmit, both gets NULL when calling ipoib_neigh_get.
Two calls to neigh_add_path are made. One thread takes the spin-lock
and calls ipoib_neigh_alloc which creates the neigh structure,
then (after the __path_find) the neigh is added to the path's neigh
link list. When the second thread enters the critical section it also
calls ipoib_neigh_alloc but in this case it gets the already allocated
ipoib_neigh structure, which is already linked to the path's neigh
link list and adds it again to the list. Which beside of triggering
the list, it creates a loop in the linked list. This loop leads to
endless loop inside path_rec_completion.

Solution:
Check list_empty(&neigh->list) before adding to the list.
Add a similar fix in "ipoib_multicast.c::ipoib_mcast_send"

Fixes: b63b70d877 ('IPoIB: Use a private hash table for path lookup in xmit path')
Signed-off-by: Erez Shitrit <erezsh@mellanox.com>
Reviewed-by: Alex Vesker <valex@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
2018-01-02 11:09:05 -07:00
..
Kconfig kconfig: rename CONFIG_EMBEDDED to CONFIG_EXPERT 2011-01-20 17:02:05 -08:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ipoib.h IB/ipoib: Change number of TX wqe to 64 2017-10-25 13:36:50 -04:00
ipoib_cm.c IB/ipoib: Restore MM behavior in case of tx_ring allocation failure 2017-12-13 10:31:57 -07:00
ipoib_ethtool.c RDMA/core: Rename kernel modify_cq to better describe its usage 2017-11-13 16:59:22 -05:00
ipoib_fs.c IB/SA: Add OPA path record type 2017-05-01 14:39:02 -04:00
ipoib_ib.c IB/ipoib: Fix lockdep issue found on ipoib_ib_dev_heavy_flush 2017-12-21 16:06:07 -07:00
ipoib_main.c IB/ipoib: Fix race condition in neigh creation 2018-01-02 11:09:05 -07:00
ipoib_multicast.c IB/ipoib: Fix race condition in neigh creation 2018-01-02 11:09:05 -07:00
ipoib_netlink.c net: add netlink_ext_ack argument to rtnl_link_ops.changelink 2017-06-26 23:13:22 -04:00
ipoib_verbs.c IB/ipoib: Use NAPI in UD/TX flows 2017-10-25 13:36:50 -04:00
ipoib_vlan.c IB/ipoib: Fix inconsistency with free_netdev and free_rdma_netdev 2017-09-25 11:47:24 -04:00